LCOV - code coverage report
Current view: top level - globalscripts - utility.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 18 47 38.3 %
Date: 2023-04-02 12:52:40 Functions: 3 9 33.3 %

          Line data    Source code
       1             : /**
       2             :  * "Inside-out" implementation of Fisher-Yates shuffle
       3             :  */
       4             : function shuffleArray(source)
       5             : {
       6           0 :         if (!source.length)
       7           0 :                 return [];
       8             : 
       9           0 :         let result = [source[0]];
      10           0 :         for (let i = 1; i < source.length; ++i)
      11             :         {
      12           0 :                 let j = randIntInclusive(0, i);
      13           0 :                 result[i] = result[j];
      14           0 :                 result[j] = source[i];
      15             :         }
      16           0 :         return result;
      17             : }
      18             : 
      19             : /**
      20             :  * Generates each permutation of the given array and runs the callback function on it.
      21             :  * Uses the given clone function on each item of the array.
      22             :  * Creating arrays with all permutations of the given array has a bad memory footprint.
      23             :  * Algorithm by B. R. Heap. Changes the input array.
      24             :  */
      25             : function heapsPermute(array, cloneFunc, callback)
      26             : {
      27           0 :         let c = new Array(array.length).fill(0);
      28             : 
      29           0 :         callback(array.map(cloneFunc));
      30             : 
      31           0 :         let i = 0;
      32           0 :         while (i < array.length)
      33             :         {
      34           0 :                 if (c[i] < i)
      35             :                 {
      36           0 :                         let swapIndex = i % 2 ? c[i] : 0;
      37           0 :                         let swapValue = cloneFunc(array[swapIndex]);
      38           0 :                         array[swapIndex] = array[i];
      39           0 :                         array[i] = swapValue;
      40             : 
      41           0 :                         callback(array.map(cloneFunc));
      42             : 
      43           0 :                         ++c[i];
      44           0 :                         i = 0;
      45             :                 }
      46             :                 else
      47             :                 {
      48           0 :                         c[i] = 0;
      49           0 :                         ++i;
      50             :                 }
      51             :         }
      52             : }
      53             : 
      54             : /**
      55             :  * Compare two variables recursively. This compares better than a quick
      56             :  * JSON.stringify check since we also check undefineds, Sets and the like.
      57             :  *
      58             :  * @param first - Any javascript instance.
      59             :  * @param second - Any javascript instance.
      60             :  * @return {boolean} Whether first and second are equal.
      61             :  */
      62             : function deepCompare(first, second)
      63             : {
      64             :         // If the value of either variable is empty we can instantly compare
      65             :         // them and check for equality.
      66          54 :         if (first === null || first === undefined ||
      67             :             second === null || second === undefined)
      68           4 :                 return first === second;
      69             : 
      70             :         // Make sure both variables have the same type.
      71          50 :         if (first.constructor !== second.constructor)
      72           1 :                 return false;
      73             : 
      74             :         // We know that the variables are of the same type so all we need to do is
      75             :         // check what type one of the objects is, and then compare them.
      76             : 
      77             :         // Check numbers seperately. Make sure this works with NaN, Infinity etc.
      78          49 :         if (typeof first == "number")
      79          21 :                 return uneval(first) === uneval(second);
      80             : 
      81             :         // Functions and RegExps must have the same reference to be equal.
      82          28 :         if (first instanceof Function || first instanceof RegExp)
      83           0 :                 return first === second;
      84             : 
      85             :         // If we are comparing simple objects, we can just compare them.
      86          28 :         if (first === second || first.valueOf() === second.valueOf())
      87           0 :                 return true;
      88             : 
      89             :         // Dates would have equal valueOf if they are equal.
      90          28 :         if (first instanceof Date)
      91           0 :                 return false;
      92             : 
      93             :         // From now we will assume we have some kind of objects so that
      94             :         // we can do a recursive check of the keys and values.
      95          28 :         if (!(first instanceof Object) || !(second instanceof Object))
      96           0 :                 return false;
      97             : 
      98             :         // We cannot iterate over Sets, so collapse them to Arrays.
      99          28 :         if (first instanceof Set)
     100             :         {
     101           7 :                 first = Array.from(first);
     102           7 :                 second = Array.from(second);
     103             :         }
     104             : 
     105             :         // Objects need the same number of keys in order to be equal.
     106          28 :         const firstKeys = Object.keys(first);
     107          28 :         if (firstKeys.length != Object.keys(second).length)
     108           3 :                 return false;
     109             : 
     110             :         // Make sure that all the object keys on this level of the object are the same.
     111             :         // Finally, we pass all the values of our of each object recursively to
     112             :         // make sure everything matches.
     113          33 :         return Object.keys(second).every(i => firstKeys.includes(i)) &&
     114          30 :                firstKeys.every(i => deepCompare(first[i], second[i]));
     115             : }
     116             : 
     117             : /**
     118             :  * Removes prefixing path from a path or filename, leaving just the file's name (with extension)
     119             :  *
     120             :  * ie. a/b/c/file.ext -> file.ext
     121             :  */
     122             : function basename(path)
     123             : {
     124           0 :         return path.split("/").pop();
     125             : }
     126             : 
     127             : /**
     128             :  * Returns the directories of a given path.
     129             :  *
     130             :  * ie. a/b/c/file.ext -> a/b/c
     131             :  */
     132             : function dirname(path)
     133             : {
     134           0 :         return path.split("/").slice(0, -1).join("/");
     135             : }
     136             : 
     137             : /**
     138             :  * Returns names of files found in the given directory, stripping the directory path and file extension.
     139             :  */
     140             : function listFiles(path, extension, recurse)
     141             : {
     142           0 :         return Engine.ListDirectoryFiles(path, "*" + extension, recurse).map(filename => filename.slice(path.length, -extension.length));
     143             : }
     144             : 

Generated by: LCOV version 1.14