PageSourceSearch

https://www.lesmotsontunsens.com/wp-content/plugins/gobrigade-core/assets/js/libs/gbg-hash.js?ver=5.2.112

js lesmotsontunsens.com collected 2026-10-02 10:54:26 UTC 19,072 bytes, 674 lines download raw bytes

1'use strict';
2
3/**
4 * Gbg Object manipulation Utility
5 * Static calls only
6 */
7
8gbg.H = {};
9
10/**
11 * Search safely for a property in an object
12 *
13 * ### Example
14 *      left obj = {
15 *          attr1: 'firstVal',
16 *          attr2: 'secondVal',
17 *          attrObj: {
18 *              subAttr: 'subVal'
19 *          }
20 *      };
21 *      gbg.H.get(obj, 'attr1', false)             returns 'firstVal'
22 *      gbg.H.get(obj, 'attr1.x', false)           returns false
23 *      gbg.H.get(obj, 'attrObj.subAttr', false)   returns 'subVal'
24 *
25 * @param {{}||[]} objectOrArray
26 * @param {string} path
27 * @param {any} defaultVal
28 *
29 * @return {any}
30 */
31gbg.H.get = function (objectOrArray, path, defaultVal = null) {
32
33    if (typeof objectOrArray === 'undefined' || objectOrArray === null ||
34        (typeof objectOrArray !== 'object' && !Array.isArray(objectOrArray))) {
35        return defaultVal;
36    }
37
38    if (typeof objectOrArray[path] !== 'undefined' && objectOrArray[path] !== null) {
39        return objectOrArray[path];
40    }
41
42    let properties = path.split('.'),
43        result = objectOrArray;
44
45    for (let i = 0; i < properties.length; i++) {
46        if (typeof result[properties[i]] === 'undefined' || result[properties[i]] === null || result[properties[i]] === 'null') {
47            return defaultVal;
48        } else {
49            result = result[properties[i]];
50        }
51    }
52
53    return result;
54
55};
56
57/**
58 * Find the first defined and not null attribute of an object
59 * property can be a path.
60 *
61 * ### Example :
62 *
63 *      let object = {code: null, num: 1};
64 *      gbg.H.getFirst(object, ['code', 'id', 'num'], null)
65 *          will return 1
66 *
67 * @param objectOrArray
68 * @param paths
69 * @param defaultVal
70 *
71 * @return {*}
72 */
73gbg.H.getFirst = function (objectOrArray, paths, defaultVal) {
74
75    if (gbg.isEmpty(paths)) {
76        return defaultVal;
77    }
78
79    for (let i = 0; i < paths.length; i++) {
80        let val = gbg.H.get(objectOrArray, paths[i], undefined);
81        if (val !== undefined) {
82            return val;
83        }
84    }
85    return defaultVal;
86
87};
88
89gbg.H.set = function (objectOrArray, path, value) {
90
91    if (typeof objectOrArray === 'undefined' || !objectOrArray || ['object', 'array'].indexOf(typeof objectOrArray) === -1) {
92        return;
93    }
94
95    path = path.split('.');
96
97    let recursiveSet = function(currentObjectOrArray, path, value) {
98        // console.log(path);
99        if (path.length === 1) {
100            currentObjectOrArray[path] = value;
101            // console.log(currentObjectOrArray[path]);
102            return currentObjectOrArray;
103        } else {
104            let firstPathPart = path.shift();
105            // console.log(firstPathPart, path);
106            if (gbg.H.get(currentObjectOrArray, firstPathPart, null) === null) {
107                currentObjectOrArray[firstPathPart] = {};
108            }
109            currentObjectOrArray[firstPathPart] = recursiveSet(currentObjectOrArray[firstPathPart], path, value);
110            return currentObjectOrArray;
111        }
112    };
113
114    return recursiveSet(objectOrArray, path, value);
115};
116
117/**
118 * Flattens a nested array to a flat array.
119 *
120 * For example, flattens an array that was expanded with gbg.H.::unflatten() into a flat array.
121 * ### Example
122 *      [['Super' => ['Man' => 'IsTheBest']]] becomes ['0.Super.Man' => 'IsTheBest']
123 *      [['Super' => ['Woman' => 'IsGoat']]] becomes ['0.Super.Woman' => 'IsGoat']
124 *
125 * @param {[]|{}} $thingy
126 * @param {[]} options
127 *
128 * @return {{}}
129 *
130 */
131
132gbg.H.flatten = function (objectOrArray, options) {
133
134    if (typeof objectOrArray === 'undefined' || !objectOrArray || ['object', 'array'].indexOf(typeof objectOrArray) === -1) {
135        return;
136    }
137
138    options = gbg.extend(options ?? {separator: '.', currentKey: ''}, {separator: '.', currentKey: ''});
139
140    let result          = {},
141        stack           = [],
142        path            = null,
143        //keys            = Object.keys(objectOrArray),
144        attributes      = gbg.H.clone(objectOrArray),
145        tmpSeparator    = '$$$$$';
146
147    while (!gbg.isEmpty(attributes)) {
148        let key         = Object.keys(attributes).shift(),
149            element     = attributes[key];
150
151        //console.log(attributes, key)
152        delete attributes[key];
153
154        // if value is a hierarchical thingy, then process it now,
155        // and register $attributes to continue with it later
156
157        if (!gbg.isEmpty(element) && typeof element === 'object') {
158            if (!gbg.isEmpty(attributes)) {
159                stack.push([gbg.H.clone(attributes), path]);
160            }
161            attributes = gbg.H.clone(element);
162            //path = (path ? path : '') + key + tmpSeparator;
163            path = (path ? path : '') + key + options.separator;
164        } else {
165            result[(path ? path : '') + key] = element;
166        }
167
168        if (gbg.isEmpty(attributes) && !gbg.isEmpty(stack)) {
169            let stackItem = stack.pop();
170            attributes = stackItem[0];
171            path = stackItem[1];
172        }
173    }
174
175    return result;
176
177    // if (options.separator.length === 2) {
178    //     options.separator = [options.separator[0], options.separator[1]];
179    // } else {
180    //     options.separator = [options.separator[0], ''];
181    // }
182
183    // let newResult = Array.isArray(objectOrArray) ? [] : {};
184    //
185    // console.log(result)
186    //
187    // for (let key in result) {
188    //     let newKey = key;
189    //     if (key.indexOf(tmpSeparator) > -1) {
190    //         let keyParts = key.split(tmpSeparator);
191    //         console.log(keyParts)
192    //         for (let i in keyParts) {
193    //             if (i === 0) {
194    //                 newKey = keyParts[i];
195    //                 continue;
196    //             }
197    //             newKey += options.separator[0] + keyParts[i] + options.separator[1];
198    //         }
199    //         newResult[newKey] = result[key];
200    //     } else {
201    //         newResult[key] = result[key];
202    //     }
203    // }
204    // console.log(result)
205
206    // return newResult;
207
208};
209
210/**
211 * Clone an objectOrArray
212 * @param {[]|{}} objectOrArray
213 * @return {[]|{}}
214 */
215gbg.H.clone = function (objectOrArray) {
216    return Object.assign({}, objectOrArray);
217    //
218    // if (Array.isArray(objectOrArray)) {
219    //     return Array.from(objectOrArray);
220    // }
221    // if (typeof objectOrArray === 'object') {
222    //     return Object.assign({}, objectOrArray);
223    // }
224    // return objectOrArray;
225}
226
227/**
228 * Format an object or an array, for example for a select2
229 *
230 * ### Examples :
231 *
232 *      gbg.H.format(
233 *          [ {id: 1, name: 'My name1', 'prop': 'MyProp1'}, {id: 2, name: 'My name2', 'prop': 'MyProp2'} ],
234 *          '{id}',
235 *          '{name} - {prop}',
236 *      )
237 *      returns :
238 *      {
239 *          1: 'My name1 - MyProp1',
240 *          2: 'My name2 - MyProp2',
241 *      }
242 *
243 *      gbg.H.format(
244 *          [ {id: 1, name: 'My name1', 'prop': 'MyProp1'}, {id: 2, name: 'My name2', 'prop': 'MyProp2'} ],
245 *          null,
246 *          {id: '{id}', text: '{name} - {prop}}' },
247 *      )
248 *      returns :
249 *      [
250 *           {
251 *            id: 1,
252 *              text: 'My name1 - MyProp1'
253 *          },
254 *          {
255 *              id: 2,
256 *              text: 'My name2 - MyProp2'
257 *          }
258 *       ]
259 *
260 *
261 * @param objectOrArray
262 * @param keyFormula
263 * @param valueMap
264 */
265gbg.H.format = function (objectOrArray, keyFormula, valueMap) {
266
267    let result = [];
268
269    if (gbg.isEmpty(objectOrArray)) {
270        return [];
271    }
272
273    if (gbg.isEmpty(keyFormula)) {
274        keyFormula = null;
275    }
276
277    for (let k in objectOrArray) {
278
279        let itemV = [],
280            itemK = null;
281
282        if (keyFormula) {
283            itemK = gbg.H.resolveFormula(objectOrArray[k], keyFormula, k);
284        }
285
286        if (!itemK) {
287            itemK = result.length;
288        }
289
290        if (valueMap) {
291            if (typeof valueMap === 'object') {
292                for (let valueFieldK in valueMap) {
293                    itemV[valueFieldK] = gbg.H.resolveFormula(objectOrArray[k], valueMap[valueFieldK], valueFieldK);
294                }
295            } else {
296                itemV = gbg.H.resolveFormula(objectOrArray[k], valueMap, k);
297            }
298        }
299
300        if (itemV) {
301            result[itemK] = itemV;
302        }
303
304    }
305
306    return result;
307
308}
309
310/**
311 * Group an objectOrArray
312 * @param {[]|{}} objectOrArray
313 * @param {string} groupByFormula
314 * @param {[]|string} groupMap
315 * @return {[]|{}}
316 */
317gbg.H.group = function (objectOrArray, groupByFormula, groupMap) {
318
319
320    let result = [];
321
322    if (gbg.isEmpty(objectOrArray) || gbg.isEmpty(groupByFormula)) {
323        return result;
324    }
325
326    if (gbg.isEmpty(groupMap)) {
327        groupMap = null;
328    }
329
330    for (let k in objectOrArray) {
331
332        let itemGroupVal = gbg.H.resolveFormula(objectOrArray[k], groupByFormula, k),
333            itemGroupK = itemGroupVal;
334
335        if (!gbg.isSet(result[itemGroupK])) {
336            result[itemGroupK] = [];
337        }
338
339        let resultItem = {};
340
341        if (!groupMap) {
342
343            result[itemGroupK].push(objectOrArray[k]);
344
345        } else {
346
347            if (typeof groupMap === 'object') {
348
349                if (groupMap.hasOwnProperty('children') && groupMap['children']) {
350                    if (gbg.isEmpty(result[itemGroupK]['children'])) {
351                        result[itemGroupK]['children'] = [];
352                    }
353                    let newChild = null;
354                    if (groupMap['children'] === true || groupMap['children'] === 1) {
355                        newChild = objectOrArray[k];
356                    } else if (typeof groupMap['children'] === 'object') {
357                        newChild = {};
358                        for (let groupChildK in groupMap['children']) {
359                            newChild[groupChildK] = gbg.H.resolveFormula(objectOrArray[k], groupMap['children'][groupChildK], k);
360                        }
361                    } else {
362                        // only a string formula
363                        newChild = gbg.H.resolveFormula(objectOrArray[k], groupMap['children'], k);
364                    }
365                    result[itemGroupK]['children'].push(newChild);
366                }
367
368                for (let groupK in groupMap) {
369                    if (groupK !== 'children' && groupK !== '_key') {
370                        if (typeof groupMap[groupK] === 'undefined' || groupMap[groupK] === null) {
371                            result[itemGroupK][groupK] = groupMap[groupK];
372                        } else {
373                            result[itemGroupK][groupK] = gbg.H.resolveFormula(objectOrArray[k], groupMap[groupK], k);
374                        }
375                    }
376                }
377            } else {
378                result[itemGroupK] = gbg.H.resolveFormula(objectOrArray[k], groupMap, k);
379            }
380        }
381
382    }
383
384    if (gbg.H.get(groupMap, '_key', null) === '{{n}}') {
385        return Object.values(result);
386    } else {
387        return result;
388    }
389
390
391};
392
393/**
394 * Resolve a formula
395 * @param {[]|{}} objectOrArray
396 * @param {string} formula
397 * @param {[]} key
398 * @return {[]|{}}
399 */
400gbg.H.resolveFormula = function (objectOrArray, formula, key) {
401
402    let placeholders = gbg.S.new(formula).getBetweenAll('{', '}');
403    let result = formula;
404
405    // to avoid that integer could be casted to string
406    if (formula === '{{key}}') {
407        return key;
408    }
409
410    if (!placeholders.length) {
411        result = gbg.H.get(objectOrArray, formula);
412    } else {
413        for (let placeholder of placeholders) {
414            let value = null;
415            if (placeholder === '{key}') {
416                value = key;
417            } else if (placeholder === '{val}') {
418                value = objectOrArray;
419            } else {
420                value = gbg.H.get(objectOrArray, placeholder, key);
421            }
422            result = result.replace('{' + placeholder + '}', value);
423        }
424    }
425
426    return result;
427}
428
429/**
430 * Sort an objectOrArray from its keys or values
431 * @param {[]|{}} objectOrArray
432 * @param {string} sortFormula
433 * @param {[]} options
434 * @return {[]|{}}
435 */
436gbg.H.sort = function (objectOrArray, sortFormula = { depth0: ['{{key}}', 'ASC'] }, options = {}) {
437
438    if (gbg.isEmpty(objectOrArray)) {
439        return objectOrArray;
440    }
441
442    options = gbg.extend(options, { currentDepth: 0 });
443
444    if (gbg.isEmpty(sortFormula['depth' + options.currentDepth])) {
445        return objectOrArray;
446    }
447
448    let currentSortFormula = sortFormula['depth' + options.currentDepth];
449    if (typeof currentSortFormula === 'string') {
450        currentSortFormula = [currentSortFormula, 'ASC'];
451    }
452
453    let sortTemp = [],
454        result = [],
455        areKeysIntegers = true;
456
457    for (let k in objectOrArray) {
458
459        if (!gbg.isInteger(k)) {
460            areKeysIntegers = false;
461        }
462
463        let objectOrArrayItem = objectOrArray[k];
464        let temp = { key: k, value: objectOrArrayItem, sortVal: 0 };
465        if (typeof objectOrArrayItem === 'object') {
466            temp.value = gbg.H.sort(objectOrArrayItem, sortFormula, { currentDepth: options.currentDepth + 1 });
467        }
468
469        temp.sortVal = gbg.H.resolveFormula(objectOrArrayItem, currentSortFormula[0], k);
470        if (gbg.isNumeric(temp.sortVal)) {
471            temp.sortVal = parseFloat(temp.sortVal);
472        }
473        sortTemp.push(temp);
474    }
475
476    let sortTemp2 =
477        Object.entries(sortTemp).sort(
478            function (a, b) {
479                if (a[1].sortVal === b[1].sortVal) {
480                    return 0;
481                }
482                let res = (a[1].sortVal > b[1].sortVal) ? 1 : -1;
483                return (currentSortFormula[1].toLowerCase() === 'desc') ? -res : res;
484            }
485        );
486
487    result = (areKeysIntegers ? [] : {});
488
489    for (let k in sortTemp2) {
490        if (areKeysIntegers) {
491            result.push(sortTemp2[k][1].value);
492        } else {
493            result['' + String(sortTemp2[k][1].key)] = sortTemp2[k][1].value;
494        }
495    }
496
497    return result;
498
499}
500
501/**
502 * Remove duplicates in it's values for a variable
503 * @param {[]|{}} objectOrArray
504 * @return {[]|{}}
505 */
506gbg.H.unique = function (objectOrArray) {
507    let valuesTmp = [],
508        values = [];
509    for (let key in objectOrArray) {
510        if (valuesTmp.indexOf(objectOrArray[key]) === -1) {
511            values[key] = objectOrArray[key];
512        }
513        valuesTmp[key] = objectOrArray[key];
514    }
515    return values;
516};
517
518
519gbg.H.filterEmpty = function (objectOrArray) {
520    let type = Array.isArray(objectOrArray) ? 'array' : 'object',
521        sequential = gbg.H.arrayIsSequential(objectOrArray),
522        values = (type === 'array' ? [] : {});
523
524    if (gbg.isEmpty(objectOrArray)) {
525        return objectOrArray;
526    }
527    for (let key in objectOrArray) {
528        if (!gbg.isEmpty(objectOrArray[key])) {
529            if (type === 'array' && sequential) {
530                values.push(objectOrArray[key]);
531            } else {
532                values[key] = objectOrArray[key];
533            }
534        }
535    }
536    return values;
537};
538
539/**
540 * Detect if an array is sequencial (it's indexes are 0, 1, 2, 3, 4, 5, ....)
541 * @param {[]} array
542 * @return {boolean}
543 */
544gbg.H.arrayIsSequential = function (array) {
545    let i = 0;
546    if (!Array.isArray(array)) {
547        return undefined;
548    }
549    for (let key in array) {
550        if (String(key) !== String(i++)) {
551            return false;
552        }
553    }
554    return true;
555}
556
557/**
558 * If variable is not an array, then wrap it into an array
559 * @param {any} variable
560 */
561gbg.H.ensureArray = function (variable) {
562    if (typeof variable === 'undefined' || !variable) { return []; }
563    if (!Array.isArray(variable)) { return [variable]; }
564    return variable;
565};
566
567/*gbg.H.groupBy = function(objectOrArray, groupByFormula, keyFormula = '{{key}}', valueFormula = '{{val}}') {
568
569    let result = [];
570
571    if (gbg.isEmpty(objectOrArray)) {
572        return result;
573    }
574
575    for (let k in objectOrArray) {
576
577        let itemV = [],
578            itemK = null;
579
580        let groupByValue = gbg.H.resolveFormula(objectOrArray[k], groupByFormula, k);
581
582        if (!gbg.isSet(result[groupByValue])) {
583            result[groupByValue] = [];
584        }
585
586        itemK = gbg.H.resolveFormula(objectOrArray[k], keyFormula, k);
587
588        if (!itemK) {
589            itemK = result.length;
590        }
591
592        if (typeof valueField == 'object') {
593            for (let valueFieldK in valueField) {
594                itemV[valueFieldK] = gbg.H.resolveFormula(objectOrArray[k], valueField[valueFieldK], null);
595            }
596        } else {
597            itemV = gbg.H.resolveFormula(objectOrArray[k], valueField, null);
598        }
599
600        if (itemV) {
601            result[itemK] = itemV;
602        }
603
604    }
605
606    return result;
607
608}*/
609
610/*
611let testObj = {
612    x: {
613        y: {
614            z: 'myResult'
615        }
616    }
617};
618
619let testH = [
620    {func: 'get', src: testObj, arg: 'x.y.z', res: 'myResult' },
621    {func: 'get', src: testObj, arg: 'x.y.y', res: undefined },
622];
623
624console.log('gbg.H tests ----------------------');
625
626var i = 0;
627for (let test of testH) {
628    i++;
629    let res = gbg.TESTS._test(gbg.H, test);
630    if (JSON.stringify(res) === JSON.stringify(test.res)) {
631        console.log('test #' + i + ' : ok');
632    } else {
633        console.log('test #' + i + ' : nok --- expected : ', JSON.stringify(test.res), ' | actual : ', JSON.stringify(res));
634    }
635}
636
637console.log(
638    gbg.H.format( [ {id: 1, name: 'My name1', 'prop': 'MyProp1'}, {id: 2, name: 'My name2', 'prop': 'MyProp2'} ],
639          '{id}',
640          '{name} - {prop}'
641    )
642);
643console.log(
644    gbg.H.format( [ {id: 1, name: 'My name1', 'prop': 'MyProp1'}, {id: 2, name: 'My name2', 'prop': 'MyProp2'} ],
645        null,
646        { id: '{id}', text: '{name} - {prop}' }
647    )
648);
649
650const maxSpeed = {
651    car: 300,
652    bike: 60,
653    motorbike: 200,
654    airplane: 1000,
655    helicopter: 400,
656    rocket: 8 * 60 * 60
657};
658
659let sortable = Object.entries(maxSpeed)
660    .sort(([,a],[,b]) => a-b)
661    .reduce((r, [k, v]) => ({ ...r, [k]: v }), {});
662
663console.log(sortable);
664console.log(Object.entries(maxSpeed));
665sortable = Object.entries(maxSpeed)
666    .sort(function([,a],[,b]) { return a - b;})
667    .reduce(function(previous, current, index, array) {
668        array['x'] = current;
669    }, {});
670    //.reduce(function(r, [k, v]) { return { ...r, [k]: v }; } );
671    //.reduce((r, [k, v]) => ({ ...r, [k]: v }), {});
672
673console.log(sortable);
674*/

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.