Browse Source

Break adbar-dot and vc out of utils and then include them

nsITobin 4 months ago
parent
commit
5f236550c2
3 changed files with 886 additions and 870 deletions
  1. 676 0
      base/src/utils-adbar.php
  2. 205 0
      base/src/utils-vc.php
  3. 5 870
      base/src/utils.php

+ 676 - 0
base/src/utils-adbar.php

@@ -0,0 +1,676 @@
+<?php
+/*
+    The MIT License (MIT)
+    Copyright (c) 2016-2022 Riku Särkinen
+
+    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+
+
+namespace Adbar { // == | Adbar | =====================================================================================
+
+use Countable;
+use ArrayAccess;
+use ArrayIterator;
+use JsonSerializable;
+use IteratorAggregate;
+use Traversable;
+
+/**
+ * Dot
+ *
+ * This class provides a dot notation access and helper functions for
+ * working with arrays of data. Inspired by Laravel Collection.
+ *
+ * @template TKey of array-key
+ * @template TValue mixed
+ *
+ * @implements \ArrayAccess<TKey, TValue>
+ * @implements \IteratorAggregate<TKey, TValue>
+ */
+class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
+{
+  /**
+   * The stored items
+   *
+   * @var array<TKey, TValue>
+   */
+  protected $items = [];
+
+  /**
+   * The character to use as a delimiter, defaults to dot (.)
+   *
+   * @var non-empty-string
+   */
+  protected $delimiter = ".";
+
+  // ====
+
+  /**
+   * Create a new Dot instance
+   *
+   * @param  mixed  $items
+   * @param  bool  $parse
+   * @param  non-empty-string  $delimiter
+   * @return void
+   */
+  public function __construct($items = [], $parse = false, $delimiter = ".") {
+    $items = $this->getArrayItems($items);
+    $this->delimiter = $delimiter ?: ".";
+    
+    if ($parse) {
+      $this->set($items);
+    }
+    else {
+      $this->items = $items;
+    }
+  }
+
+  /**
+   * Set a given key / value pair or pairs
+   * if the key doesn't exist already
+   *
+   * @param  array<TKey, TValue>|int|string  $keys
+   * @param  mixed  $value
+   * @return $this
+   */
+  public function add($keys, $value = null) {
+    if (is_array($keys)) {
+      foreach ($keys as $key => $value) {
+        $this->add($key, $value);
+      }
+    }
+    elseif ($this->get($keys) === null) {
+      $this->set($keys, $value);
+    }
+
+    return $this;
+  }
+
+  /**
+   * Return all the stored items
+   *
+   * @return array<TKey, TValue>
+   */
+  public function all() { return $this->items; }
+
+  /**
+   * Delete the contents of a given key or keys
+   *
+   * @param  array<TKey>|int|string|null  $keys
+   * @return $this
+   */
+  public function clear($keys = null)
+  {
+    if ($keys === null) {
+      $this->items = [];
+      return $this;
+    }
+
+    $keys = (array) $keys;
+    foreach ($keys as $key) { $this->set($key, []); }
+    return $this;
+  }
+
+  /**
+   * Delete the given key or keys
+   *
+   * @param  array<TKey>|array<TKey, TValue>|int|string  $keys
+   * @return $this
+   */
+  public function delete($keys) {
+    $keys = (array) $keys;
+
+    foreach ($keys as $key) {
+      if ($this->exists($this->items, $key)) {
+        unset($this->items[$key]);
+        continue;
+      }
+
+      $items = &$this->items;
+      $segments = explode($this->delimiter, $key);
+      $lastSegment = array_pop($segments);
+
+      foreach ($segments as $segment) {
+        if (!isset($items[$segment]) || !is_array($items[$segment])) {
+          continue 2;
+        }
+
+        $items = &$items[$segment];
+      }
+
+      unset($items[$lastSegment]);
+    }
+
+    return $this;
+  }
+
+  /**
+   * Checks if the given key exists in the provided array.
+   *
+   * @param  array<TKey, TValue>  $array Array to validate
+   * @param  int|string  $key  The key to look for
+   * @return bool
+   */
+  protected function exists($array, $key) { return array_key_exists($key, $array); }
+
+  /**
+   * Flatten an array with the given character as a key delimiter
+   *
+   * @param  string  $delimiter
+   * @param  mixed  $items
+   * @param  string  $prepend
+   * @return array<TKey, TValue>
+   */
+  public function flatten($delimiter = '.', $items = null, $prepend = '') {
+    $flatten = [];
+
+    if ($items === null) {
+      $items = $this->items;
+    }
+
+    foreach ($items as $key => $value) {
+      if (is_array($value) && !empty($value)) {
+        $flatten[] = $this->flatten($delimiter, $value, $prepend . $key . $delimiter);
+      }
+      else {
+        $flatten[] = [$prepend . $key => $value];
+      }
+    }
+
+    return array_merge(...$flatten);
+  }
+
+  /**
+   * Return the value of a given key
+   *
+   * @param  int|string|null  $key
+   * @param  mixed  $default
+   * @return mixed
+   */
+  public function get($key = null, $default = null) {
+    if ($key === null) { return $this->items; }
+
+    if ($this->exists($this->items, $key)) {
+      return $this->items[$key];
+    }
+
+    if (!is_string($key) || strpos($key, $this->delimiter) === false) {
+      return $default;
+    }
+
+    $items = $this->items;
+
+    foreach (explode($this->delimiter, $key) as $segment) {
+      if (!is_array($items) || !$this->exists($items, $segment)) {
+        return $default;
+      }
+
+      $items = &$items[$segment];
+    }
+
+    return $items;
+  }
+
+  /**
+   * Return the given items as an array
+   *
+   * @param  array<TKey, TValue>|self<TKey, TValue>|object|string  $items
+   * @return array<TKey, TValue>
+   */
+  protected function getArrayItems($items) {
+    if (is_array($items)) { return $items; }
+
+    if ($items instanceof self) {
+      return $items->all();
+    }
+
+    return (array) $items;
+  }
+
+  /**
+   * Check if a given key or keys exists
+   *
+   * @param  array<TKey>|int|string  $keys
+   * @return bool
+   */
+  public function has($keys) {
+    $keys = (array) $keys;
+
+    if (!$this->items || $keys === []) {
+      return false;
+    }
+
+    foreach ($keys as $key) {
+      $items = $this->items;
+
+      if ($this->exists($items, $key)) {
+        continue;
+      }
+
+      foreach (explode($this->delimiter, $key) as $segment) {
+        if (!is_array($items) || !$this->exists($items, $segment)) {
+          return false;
+        }
+
+        $items = $items[$segment];
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * Check if a given key or keys are empty
+   *
+   * @param  array<TKey>|int|string|null  $keys
+   * @return bool
+   */
+  public function isEmpty($keys = null) {
+    if ($keys === null) {
+      return empty($this->items);
+    }
+
+    $keys = (array) $keys;
+
+    foreach ($keys as $key) {
+      if (!empty($this->get($key))) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  // ====
+
+  /**
+   * Merge a given array or a Dot object with the given key
+   * or with the whole Dot object
+   *
+   * @param  array<TKey, TValue>|self<TKey, TValue>|string  $key
+   * @param  array<TKey, TValue>|self<TKey, TValue>  $value
+   * @return $this
+   */
+  public function merge($key, $value = []) {
+    if (is_array($key)) {
+      $this->items = array_merge($this->items, $key);
+    }
+    elseif (is_string($key)) {
+      $items = (array) $this->get($key);
+      $value = array_merge($items, $this->getArrayItems($value));
+
+      $this->set($key, $value);
+    }
+    elseif ($key instanceof self) {
+      $this->items = array_merge($this->items, $key->all());
+    }
+
+    return $this;
+  }
+
+  // ====
+
+  /**
+   * Recursively merge a given array or a Dot object with the given key
+   * or with the whole Dot object.
+   *
+   * Duplicate keys are converted to arrays.
+   *
+   * @param  array<TKey, TValue>|self<TKey, TValue>|string  $key
+   * @param  array<TKey, TValue>|self<TKey, TValue>  $value
+   * @return $this
+   */
+  public function mergeRecursive($key, $value = []) {
+    if (is_array($key)) {
+      $this->items = array_merge_recursive($this->items, $key);
+    }
+    elseif (is_string($key)) {
+      $items = (array) $this->get($key);
+      $value = array_merge_recursive($items, $this->getArrayItems($value));
+
+      $this->set($key, $value);
+    }
+    elseif ($key instanceof self) {
+      $this->items = array_merge_recursive($this->items, $key->all());
+    }
+
+    return $this;
+  }
+
+  // ====
+
+  /**
+   * Recursively merge a given array or a Dot object with the given key
+   * or with the whole Dot object.
+   *
+   * Instead of converting duplicate keys to arrays, the value from
+   * given array will replace the value in Dot object.
+   *
+   * @param  array<TKey, TValue>|self<TKey, TValue>|string  $key
+   * @param  array<TKey, TValue>|self<TKey, TValue>  $value
+   * @return $this
+   */
+  public function mergeRecursiveDistinct($key, $value = []) {
+    if (is_array($key)) {
+      $this->items = $this->arrayMergeRecursiveDistinct($this->items, $key);
+    }
+    elseif (is_string($key)) {
+      $items = (array) $this->get($key);
+      $value = $this->arrayMergeRecursiveDistinct($items, $this->getArrayItems($value));
+
+      $this->set($key, $value);
+    }
+    elseif ($key instanceof self) {
+      $this->items = $this->arrayMergeRecursiveDistinct($this->items, $key->all());
+    }
+
+    return $this;
+  }
+
+  // ====
+
+  /**
+   * Merges two arrays recursively. In contrast to array_merge_recursive,
+   * duplicate keys are not converted to arrays but rather overwrite the
+   * value in the first array with the duplicate value in the second array.
+   *
+   * @param  array<TKey, TValue>|array<TKey, array<TKey, TValue>>  $array1 Initial array to merge
+   * @param  array<TKey, TValue>|array<TKey, array<TKey, TValue>>  $array2 Array to recursively merge
+   * @return array<TKey, TValue>|array<TKey, array<TKey, TValue>>
+   */
+  protected function arrayMergeRecursiveDistinct(array $array1, array $array2) {
+    $merged = &$array1;
+
+    foreach ($array2 as $key => $value) {
+      if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
+        $merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value);
+      }
+      else {
+        $merged[$key] = $value;
+      }
+    }
+
+    return $merged;
+  }
+
+  // ====
+
+  /**
+   * Return the value of a given key and
+   * delete the key
+   *
+   * @param  int|string|null  $key
+   * @param  mixed  $default
+   * @return mixed
+   */
+  public function pull($key = null, $default = null) {
+    if ($key === null) {
+      $value = $this->all();
+      $this->clear();
+
+      return $value;
+    }
+
+    $value = $this->get($key, $default);
+    $this->delete($key);
+
+    return $value;
+  }
+
+  // ====
+
+  /**
+   * Push a given value to the end of the array
+   * in a given key
+   *
+   * @param  mixed  $key
+   * @param  mixed  $value
+   * @return $this
+   */
+  public function push($key, $value = null) {
+    if ($value === null) {
+      $this->items[] = $key;
+
+      return $this;
+    }
+
+    $items = $this->get($key);
+
+    if (is_array($items) || $items === null) {
+      $items[] = $value;
+      $this->set($key, $items);
+    }
+
+    return $this;
+  }
+
+  // ====
+
+  /**
+   * Replace all values or values within the given key
+   * with an array or Dot object
+   *
+   * @param  array<TKey, TValue>|self<TKey, TValue>|string  $key
+   * @param  array<TKey, TValue>|self<TKey, TValue>  $value
+   * @return $this
+   */
+  public function replace($key, $value = []) {
+    if (is_array($key)) {
+      $this->items = array_replace($this->items, $key);
+    }
+    elseif (is_string($key)) {
+      $items = (array) $this->get($key);
+      $value = array_replace($items, $this->getArrayItems($value));
+
+      $this->set($key, $value);
+    }
+    elseif ($key instanceof self) {
+      $this->items = array_replace($this->items, $key->all());
+    }
+
+    return $this;
+  }
+
+  // ====
+
+  /**
+   * Set a given key / value pair or pairs
+   *
+   * @param  array<TKey, TValue>|int|string  $keys
+   * @param  mixed  $value
+   * @return $this
+   */
+  public function set($keys, $value = null) {
+    if (is_array($keys)) {
+      foreach ($keys as $key => $value) {
+        $this->set($key, $value);
+      }
+
+      return $this;
+    }
+
+    $items = &$this->items;
+
+    if (is_string($keys)) {
+      foreach (explode($this->delimiter, $keys) as $key) {
+        if (!isset($items[$key]) || !is_array($items[$key])) {
+          $items[$key] = [];
+        }
+
+        $items = &$items[$key];
+      }
+    }
+
+    $items = $value;
+
+    return $this;
+  }
+
+  // ====
+
+  /**
+   * Replace all items with a given array
+   *
+   * @param  mixed  $items
+   * @return $this
+   */
+  public function setArray($items) {
+    $this->items = $this->getArrayItems($items);
+
+    return $this;
+  }
+
+  // ====
+
+  /**
+   * Replace all items with a given array as a reference
+   *
+   * @param  array<TKey, TValue>  $items
+   * @return $this
+   */
+  public function setReference(array &$items) {
+    $this->items = &$items;
+
+    return $this;
+  }
+
+  // ====
+
+  /**
+   * Return the value of a given key or all the values as JSON
+   *
+   * @param  mixed  $key
+   * @param  int  $options
+   * @return string|false
+   */
+  public function toJson($key = null, $options = 0) {
+    if (is_string($key)) {
+      return json_encode($this->get($key), $options);
+    }
+
+    $options = $key === null ? 0 : $key;
+
+    return json_encode($this->items, $options);
+  }
+
+  // ====
+
+  /**
+   * Output or return a parsable string representation of the
+   * given array when exported by var_export()
+   *
+   * @param  array<TKey, TValue>  $items
+   * @return object
+   */
+  public static function __set_state(array $items): object { return (object) $items; }
+
+  // ====
+
+  /*
+   * --------------------------------------------------------------
+   * ArrayAccess interface
+   * --------------------------------------------------------------
+   */
+
+  /**
+   * Check if a given key exists
+   *
+   * @param  int|string  $key
+   * @return bool
+   */
+  public function offsetExists($key): bool { return $this->has($key); }
+
+  // ====
+
+  /**
+   * Return the value of a given key
+   *
+   * @param  int|string  $key
+   * @return mixed
+   */
+  #[\ReturnTypeWillChange]
+  public function offsetGet($key) { return $this->get($key); }
+
+  // ====
+
+  /**
+   * Set a given value to the given key
+   *
+   * @param int|string|null  $key
+   * @param mixed  $value
+   */
+  public function offsetSet($key, $value): void {
+    if ($key === null) {
+      $this->items[] = $value;
+
+      return;
+    }
+
+    $this->set($key, $value);
+  }
+
+  // ====
+
+  /**
+   * Delete the given key
+   *
+   * @param  int|string  $key
+   * @return void
+   */
+  public function offsetUnset($key): void { $this->delete($key); }
+
+  // ====
+
+  /*
+   * --------------------------------------------------------------
+   * Countable interface
+   * --------------------------------------------------------------
+   */
+
+  /**
+   * Return the number of items in a given key
+   *
+   * @param  int|string|null  $key
+   * @return int
+   */
+  public function count($key = null): int { return count($this->get($key)); }
+
+  // ====
+
+  /*
+   * --------------------------------------------------------------
+   * IteratorAggregate interface
+   * --------------------------------------------------------------
+   */
+
+  /**
+   * Get an iterator for the stored items
+   *
+   * @return \ArrayIterator<TKey, TValue>
+   */
+  public function getIterator(): Traversable { return new ArrayIterator($this->items); }
+
+  // ====
+
+  /*
+   * --------------------------------------------------------------
+   * JsonSerializable interface
+   * --------------------------------------------------------------
+   */
+
+  /**
+   * Return items for JSON serialization
+   *
+   * @return array<TKey, TValue>
+   */
+  public function jsonSerialize(): array { return $this->items; }
+}
+
+} // ==================================================================================================================
+
+?>

+ 205 - 0
base/src/utils-vc.php

@@ -0,0 +1,205 @@
+<?php
+
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+namespace mozilla\vc { // == | nsIVersionComparator | =================================================================
+
+/**
+* Implements Mozilla Toolkit's nsIVersionComparator
+*
+* Version strings are dot-separated sequences of version-parts.
+*
+* A version-part consists of up to four parts, all of which are optional:
+* <number-a><string-b><number-c><string-d (everything else)>
+* A version-part may also consist of a single asterisk "*" which indicates
+* "infinity".
+*
+* Numbers are base-10, and are zero if left out.
+* Strings are compared bytewise.
+*
+* For additional backwards compatibility, if "string-b" is "+" then
+* "number-a" is incremented by 1 and "string-b" becomes "pre".
+*
+* 1.0pre1
+* < 1.0pre2  
+*   < 1.0 == 1.0.0 == 1.0.0.0
+*     < 1.1pre == 1.1pre0 == 1.0+
+*       < 1.1pre1a
+*         < 1.1pre1
+*           < 1.1pre10a
+*             < 1.1pre10
+*
+* Although not required by this interface, it is recommended that
+* numbers remain within the limits of a signed char, i.e. -127 to 128.
+*/
+class ToolkitVersionPart {
+  public $numA = 0;
+  public $strB = null;
+  public $numC = 0;
+  public $extraD = null;
+}
+
+class ToolkitVersionComparator {
+  public static function compare($a, $b) {
+    do {
+      $va = new ToolkitVersionPart();
+      $vb = new ToolkitVersionPart();
+      $a = self::parseVersionPart($a, $va);
+      $b = self::parseVersionPart($b, $vb);
+      
+      $result = self::compareVersionPart($va, $vb);
+      
+      if ($result != 0){
+        break;
+      }
+    }
+
+    while ($a != null || $b != null);
+
+    if ($result >= 1) { $result = 1; }
+    if ($result <= -1) { $result = -1; }
+
+    return $result;
+  }
+  
+  
+  private static function parseVersionPart($aVersion, ToolkitVersionPart $result) {
+    if ($aVersion === null || strlen($aVersion) == 0) {
+      return $aVersion;
+    }
+    
+    $tok = explode(".", trim($aVersion));
+    $part = $tok[0];
+    
+    if ($part == "*") {
+      $result->numA = PHP_INT_MAX;
+      $result->strB = "";
+    }
+    else {
+      $vertok = new ToolkitVersionPartTokenizer($part);
+      $next = $vertok->nextToken();
+      if (is_numeric($next)){
+        $result->numA = $next;
+      }
+      else {
+        $result->numA = 0;
+      }
+      
+      if ($vertok->hasMoreElements()) {
+        $str = $vertok->nextToken();
+        // if part is of type "<num>+"
+        if ($str[0] == '+') {
+          $result->numA++;
+          $result->strB = "pre";
+        }
+        else {
+          // else if part is of type "<num><alpha>..."
+          $result->strB = $str;
+          
+          if ($vertok->hasMoreTokens()) {
+            $next = $vertok->nextToken();
+            if (is_numeric($next)){
+              $result->numC = $next;
+            }
+            else {
+              $result->numC = 0;
+            }
+            if ($vertok->hasMoreTokens()) {
+              $result->extraD = $vertok->getRemainder();
+            }
+          }
+        }
+      }
+    }
+
+    if (sizeOf($tok)>1) {
+      // return everything after "."
+      return substr($aVersion, strlen($part) + 1);
+    }
+
+    return null;
+  }
+  
+  
+  private static function compareVersionPart(ToolkitVersionPart $va, ToolkitVersionPart $vb) {
+    $res = self::compareInt($va->numA, $vb->numA);
+    if ($res != 0) { return $res; }
+    
+    $res = self::compareString($va->strB, $vb->strB);
+    if ($res != 0) { return $res; }
+    
+    $res = self::compareInt($va->numC, $vb->numC);
+    if ($res != 0) { return $res; }
+    
+    return self::compareString($va->extraD, $vb->extraD);
+  }
+  
+  
+  private static function compareInt($n1, $n2) { return $n1 - $n2; }
+  
+  
+  private static function compareString($str1, $str2) {
+    // any string is *before* no string
+    if ($str1 === null) { return ($str2 !== null) ? 1 : 0; }
+    if ($str2 === null) { return -1; }
+    return strcmp($str1, $str2);
+  } 
+}
+
+/**
+ * Specialized tokenizer for Mozilla version strings.  A token can
+ * consist of one of the four sections of a version string:
+ * <number-a><string-b><number-c><string-d (everything else)>
+ */
+class ToolkitVersionPartTokenizer {
+  private $part = '';
+  
+  public function __construct($aPart) { $this->part = $aPart; }
+  
+  public function hasMoreElements() { return strlen($this->part) != 0; }
+  public function hasMoreTokens() { return strlen($this->part) != 0; }
+  public function nextToken() { return $this->nextElement(); }
+  
+  public function nextElement() {
+    if (preg_match('/^[\+\-]?[0-9].*/', $this->part)) {
+      // if string starts with a number...
+      $index = 0;
+      if ($this->part[0] == '+' || $this->part[0] == '-') {
+        $index = 1;
+      }
+      while (($index < strlen($this->part)) && is_numeric($this->part[$index])) {
+        $index++;
+      }
+      $numPart = substr($this->part, 0, $index);
+      $this->part = substr($this->part, $index);
+      return $numPart;
+    }
+    else {
+      // ... or if this is the non-numeric part of version string
+      $index = 0;
+      while (($index < strlen($this->part)) && !is_numeric($this->part[$index])) {
+        $index++;
+      }
+      $alphaPart = substr($this->part, 0, $index);
+      $this->part = substr($this->part, $index);
+      return $alphaPart;
+    }
+  }
+
+  /**
+   * Returns what remains of the original string, without tokenization.  This
+   * method is useful for getting the <string-d (everything else)>;
+   * section of a version string.
+   * 
+   * @return remaining version string
+   */
+  public function getRemainder() { return $this->part; }
+}
+
+} // ==================================================================================================================
+
+?>

+ 5 - 870
base/src/utils.php

@@ -2,12 +2,9 @@
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
-*
-* Portions of this file are under other licenses separated by namespace
-* boundaries. This is noted were applicable.
 **********************************************************************************************************************/
 
-namespace { // == | Setup and Global Constants | ======================================================================
+// == | Setup and Global Constants | ======================================================================
 
 // Check for kRootPath
 if (!defined('kRootPath')) {
@@ -115,9 +112,11 @@ const kSpecialComponentName = 'Special Component';
 
 const PALEMOON_GUID         = '{8de7fcbb-c55c-4fbe-bfc5-fc555c87dbc4}';
 
-// ====================================================================================================================
-
+// --------------------------------------------------------------------------------------------------------------------
 
+# Include vc and adbar-dot
+require_once(dirname(__FILE__) . "/utils-adbar.php");
+require_once(dirname(__FILE__) . "/utils-vc.php");
 
 // ====================================================================================================================
 
@@ -1571,873 +1570,9 @@ class nsConsole {
   }
 }
 
-} // ==================================================================================================================
-// ====================================================================================================================
-
-namespace mozilla\vc { // == | nsIVersionComparator | =================================================================
-
-/**
-* Implements Mozilla Toolkit's nsIVersionComparator
-*
-* Version strings are dot-separated sequences of version-parts.
-*
-* A version-part consists of up to four parts, all of which are optional:
-* <number-a><string-b><number-c><string-d (everything else)>
-* A version-part may also consist of a single asterisk "*" which indicates
-* "infinity".
-*
-* Numbers are base-10, and are zero if left out.
-* Strings are compared bytewise.
-*
-* For additional backwards compatibility, if "string-b" is "+" then
-* "number-a" is incremented by 1 and "string-b" becomes "pre".
-*
-* 1.0pre1
-* < 1.0pre2  
-*   < 1.0 == 1.0.0 == 1.0.0.0
-*     < 1.1pre == 1.1pre0 == 1.0+
-*       < 1.1pre1a
-*         < 1.1pre1
-*           < 1.1pre10a
-*             < 1.1pre10
-*
-* Although not required by this interface, it is recommended that
-* numbers remain within the limits of a signed char, i.e. -127 to 128.
-*/
-class ToolkitVersionPart {
-  public $numA = 0;
-  public $strB = null;
-  public $numC = 0;
-  public $extraD = null;
-}
-
-class ToolkitVersionComparator {
-  public static function compare($a, $b) {
-    do {
-      $va = new ToolkitVersionPart();
-      $vb = new ToolkitVersionPart();
-      $a = self::parseVersionPart($a, $va);
-      $b = self::parseVersionPart($b, $vb);
-      
-      $result = self::compareVersionPart($va, $vb);
-      
-      if ($result != 0){
-        break;
-      }
-    }
-
-    while ($a != null || $b != null);
-
-    if ($result >= 1) { $result = 1; }
-    if ($result <= -1) { $result = -1; }
-
-    return $result;
-  }
-  
-  
-  private static function parseVersionPart($aVersion, ToolkitVersionPart $result) {
-    if ($aVersion === null || strlen($aVersion) == 0) {
-      return $aVersion;
-    }
-    
-    $tok = explode(".", trim($aVersion));
-    $part = $tok[0];
-    
-    if ($part == "*") {
-      $result->numA = PHP_INT_MAX;
-      $result->strB = "";
-    }
-    else {
-      $vertok = new ToolkitVersionPartTokenizer($part);
-      $next = $vertok->nextToken();
-      if (is_numeric($next)){
-        $result->numA = $next;
-      }
-      else {
-        $result->numA = 0;
-      }
-      
-      if ($vertok->hasMoreElements()) {
-        $str = $vertok->nextToken();
-        // if part is of type "<num>+"
-        if ($str[0] == '+') {
-          $result->numA++;
-          $result->strB = "pre";
-        }
-        else {
-          // else if part is of type "<num><alpha>..."
-          $result->strB = $str;
-          
-          if ($vertok->hasMoreTokens()) {
-            $next = $vertok->nextToken();
-            if (is_numeric($next)){
-              $result->numC = $next;
-            }
-            else {
-              $result->numC = 0;
-            }
-            if ($vertok->hasMoreTokens()) {
-              $result->extraD = $vertok->getRemainder();
-            }
-          }
-        }
-      }
-    }
-
-    if (sizeOf($tok)>1) {
-      // return everything after "."
-      return substr($aVersion, strlen($part) + 1);
-    }
-
-    return null;
-  }
-  
-  
-  private static function compareVersionPart(ToolkitVersionPart $va, ToolkitVersionPart $vb) {
-    $res = self::compareInt($va->numA, $vb->numA);
-    if ($res != 0) { return $res; }
-    
-    $res = self::compareString($va->strB, $vb->strB);
-    if ($res != 0) { return $res; }
-    
-    $res = self::compareInt($va->numC, $vb->numC);
-    if ($res != 0) { return $res; }
-    
-    return self::compareString($va->extraD, $vb->extraD);
-  }
-  
-  
-  private static function compareInt($n1, $n2) { return $n1 - $n2; }
-  
-  
-  private static function compareString($str1, $str2) {
-    // any string is *before* no string
-    if ($str1 === null) { return ($str2 !== null) ? 1 : 0; }
-    if ($str2 === null) { return -1; }
-    return strcmp($str1, $str2);
-  } 
-}
-
-/**
- * Specialized tokenizer for Mozilla version strings.  A token can
- * consist of one of the four sections of a version string:
- * <number-a><string-b><number-c><string-d (everything else)>
- */
-class ToolkitVersionPartTokenizer {
-  private $part = '';
-  
-  public function __construct($aPart) { $this->part = $aPart; }
-  
-  public function hasMoreElements() { return strlen($this->part) != 0; }
-  public function hasMoreTokens() { return strlen($this->part) != 0; }
-  public function nextToken() { return $this->nextElement(); }
-  
-  public function nextElement() {
-    if (preg_match('/^[\+\-]?[0-9].*/', $this->part)) {
-      // if string starts with a number...
-      $index = 0;
-      if ($this->part[0] == '+' || $this->part[0] == '-') {
-        $index = 1;
-      }
-      while (($index < strlen($this->part)) && is_numeric($this->part[$index])) {
-        $index++;
-      }
-      $numPart = substr($this->part, 0, $index);
-      $this->part = substr($this->part, $index);
-      return $numPart;
-    }
-    else {
-      // ... or if this is the non-numeric part of version string
-      $index = 0;
-      while (($index < strlen($this->part)) && !is_numeric($this->part[$index])) {
-        $index++;
-      }
-      $alphaPart = substr($this->part, 0, $index);
-      $this->part = substr($this->part, $index);
-      return $alphaPart;
-    }
-  }
-
-  /**
-   * Returns what remains of the original string, without tokenization.  This
-   * method is useful for getting the <string-d (everything else)>;
-   * section of a version string.
-   * 
-   * @return remaining version string
-   */
-  public function getRemainder() { return $this->part; }
-}
-
-} // ==================================================================================================================
-// ====================================================================================================================
-
-namespace Adbar { // == | Adbar | =====================================================================================
-
-use Countable;
-use ArrayAccess;
-use ArrayIterator;
-use JsonSerializable;
-use IteratorAggregate;
-use Traversable;
-
-/**
- * Dot
- *
- * This class provides a dot notation access and helper functions for
- * working with arrays of data. Inspired by Laravel Collection.
- *
- * @template TKey of array-key
- * @template TValue mixed
- *
- * @implements \ArrayAccess<TKey, TValue>
- * @implements \IteratorAggregate<TKey, TValue>
- */
-class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
-{
-  /**
-   * The stored items
-   *
-   * @var array<TKey, TValue>
-   */
-  protected $items = [];
-
-  /**
-   * The character to use as a delimiter, defaults to dot (.)
-   *
-   * @var non-empty-string
-   */
-  protected $delimiter = ".";
-
-  // ====
-
-  /**
-   * Create a new Dot instance
-   *
-   * @param  mixed  $items
-   * @param  bool  $parse
-   * @param  non-empty-string  $delimiter
-   * @return void
-   */
-  public function __construct($items = [], $parse = false, $delimiter = ".") {
-    $items = $this->getArrayItems($items);
-    $this->delimiter = $delimiter ?: ".";
-    
-    if ($parse) {
-      $this->set($items);
-    }
-    else {
-      $this->items = $items;
-    }
-  }
-
-  /**
-   * Set a given key / value pair or pairs
-   * if the key doesn't exist already
-   *
-   * @param  array<TKey, TValue>|int|string  $keys
-   * @param  mixed  $value
-   * @return $this
-   */
-  public function add($keys, $value = null) {
-    if (is_array($keys)) {
-      foreach ($keys as $key => $value) {
-        $this->add($key, $value);
-      }
-    }
-    elseif ($this->get($keys) === null) {
-      $this->set($keys, $value);
-    }
-
-    return $this;
-  }
-
-  /**
-   * Return all the stored items
-   *
-   * @return array<TKey, TValue>
-   */
-  public function all() { return $this->items; }
-
-  /**
-   * Delete the contents of a given key or keys
-   *
-   * @param  array<TKey>|int|string|null  $keys
-   * @return $this
-   */
-  public function clear($keys = null)
-  {
-    if ($keys === null) {
-      $this->items = [];
-      return $this;
-    }
-
-    $keys = (array) $keys;
-    foreach ($keys as $key) { $this->set($key, []); }
-    return $this;
-  }
-
-  /**
-   * Delete the given key or keys
-   *
-   * @param  array<TKey>|array<TKey, TValue>|int|string  $keys
-   * @return $this
-   */
-  public function delete($keys) {
-    $keys = (array) $keys;
-
-    foreach ($keys as $key) {
-      if ($this->exists($this->items, $key)) {
-        unset($this->items[$key]);
-        continue;
-      }
-
-      $items = &$this->items;
-      $segments = explode($this->delimiter, $key);
-      $lastSegment = array_pop($segments);
-
-      foreach ($segments as $segment) {
-        if (!isset($items[$segment]) || !is_array($items[$segment])) {
-          continue 2;
-        }
-
-        $items = &$items[$segment];
-      }
-
-      unset($items[$lastSegment]);
-    }
-
-    return $this;
-  }
-
-  /**
-   * Checks if the given key exists in the provided array.
-   *
-   * @param  array<TKey, TValue>  $array Array to validate
-   * @param  int|string  $key  The key to look for
-   * @return bool
-   */
-  protected function exists($array, $key) { return array_key_exists($key, $array); }
-
-  /**
-   * Flatten an array with the given character as a key delimiter
-   *
-   * @param  string  $delimiter
-   * @param  mixed  $items
-   * @param  string  $prepend
-   * @return array<TKey, TValue>
-   */
-  public function flatten($delimiter = '.', $items = null, $prepend = '') {
-    $flatten = [];
-
-    if ($items === null) {
-      $items = $this->items;
-    }
-
-    foreach ($items as $key => $value) {
-      if (is_array($value) && !empty($value)) {
-        $flatten[] = $this->flatten($delimiter, $value, $prepend . $key . $delimiter);
-      }
-      else {
-        $flatten[] = [$prepend . $key => $value];
-      }
-    }
-
-    return array_merge(...$flatten);
-  }
-
-  /**
-   * Return the value of a given key
-   *
-   * @param  int|string|null  $key
-   * @param  mixed  $default
-   * @return mixed
-   */
-  public function get($key = null, $default = null) {
-    if ($key === null) { return $this->items; }
-
-    if ($this->exists($this->items, $key)) {
-      return $this->items[$key];
-    }
-
-    if (!is_string($key) || strpos($key, $this->delimiter) === false) {
-      return $default;
-    }
-
-    $items = $this->items;
-
-    foreach (explode($this->delimiter, $key) as $segment) {
-      if (!is_array($items) || !$this->exists($items, $segment)) {
-        return $default;
-      }
-
-      $items = &$items[$segment];
-    }
-
-    return $items;
-  }
-
-  /**
-   * Return the given items as an array
-   *
-   * @param  array<TKey, TValue>|self<TKey, TValue>|object|string  $items
-   * @return array<TKey, TValue>
-   */
-  protected function getArrayItems($items) {
-    if (is_array($items)) { return $items; }
-
-    if ($items instanceof self) {
-      return $items->all();
-    }
-
-    return (array) $items;
-  }
-
-  /**
-   * Check if a given key or keys exists
-   *
-   * @param  array<TKey>|int|string  $keys
-   * @return bool
-   */
-  public function has($keys) {
-    $keys = (array) $keys;
-
-    if (!$this->items || $keys === []) {
-      return false;
-    }
-
-    foreach ($keys as $key) {
-      $items = $this->items;
-
-      if ($this->exists($items, $key)) {
-        continue;
-      }
-
-      foreach (explode($this->delimiter, $key) as $segment) {
-        if (!is_array($items) || !$this->exists($items, $segment)) {
-          return false;
-        }
-
-        $items = $items[$segment];
-      }
-    }
-
-    return true;
-  }
-
-  /**
-   * Check if a given key or keys are empty
-   *
-   * @param  array<TKey>|int|string|null  $keys
-   * @return bool
-   */
-  public function isEmpty($keys = null) {
-    if ($keys === null) {
-      return empty($this->items);
-    }
-
-    $keys = (array) $keys;
-
-    foreach ($keys as $key) {
-      if (!empty($this->get($key))) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  // ====
-
-  /**
-   * Merge a given array or a Dot object with the given key
-   * or with the whole Dot object
-   *
-   * @param  array<TKey, TValue>|self<TKey, TValue>|string  $key
-   * @param  array<TKey, TValue>|self<TKey, TValue>  $value
-   * @return $this
-   */
-  public function merge($key, $value = []) {
-    if (is_array($key)) {
-      $this->items = array_merge($this->items, $key);
-    }
-    elseif (is_string($key)) {
-      $items = (array) $this->get($key);
-      $value = array_merge($items, $this->getArrayItems($value));
-
-      $this->set($key, $value);
-    }
-    elseif ($key instanceof self) {
-      $this->items = array_merge($this->items, $key->all());
-    }
-
-    return $this;
-  }
-
-  // ====
-
-  /**
-   * Recursively merge a given array or a Dot object with the given key
-   * or with the whole Dot object.
-   *
-   * Duplicate keys are converted to arrays.
-   *
-   * @param  array<TKey, TValue>|self<TKey, TValue>|string  $key
-   * @param  array<TKey, TValue>|self<TKey, TValue>  $value
-   * @return $this
-   */
-  public function mergeRecursive($key, $value = []) {
-    if (is_array($key)) {
-      $this->items = array_merge_recursive($this->items, $key);
-    }
-    elseif (is_string($key)) {
-      $items = (array) $this->get($key);
-      $value = array_merge_recursive($items, $this->getArrayItems($value));
-
-      $this->set($key, $value);
-    }
-    elseif ($key instanceof self) {
-      $this->items = array_merge_recursive($this->items, $key->all());
-    }
-
-    return $this;
-  }
-
-  // ====
-
-  /**
-   * Recursively merge a given array or a Dot object with the given key
-   * or with the whole Dot object.
-   *
-   * Instead of converting duplicate keys to arrays, the value from
-   * given array will replace the value in Dot object.
-   *
-   * @param  array<TKey, TValue>|self<TKey, TValue>|string  $key
-   * @param  array<TKey, TValue>|self<TKey, TValue>  $value
-   * @return $this
-   */
-  public function mergeRecursiveDistinct($key, $value = []) {
-    if (is_array($key)) {
-      $this->items = $this->arrayMergeRecursiveDistinct($this->items, $key);
-    }
-    elseif (is_string($key)) {
-      $items = (array) $this->get($key);
-      $value = $this->arrayMergeRecursiveDistinct($items, $this->getArrayItems($value));
-
-      $this->set($key, $value);
-    }
-    elseif ($key instanceof self) {
-      $this->items = $this->arrayMergeRecursiveDistinct($this->items, $key->all());
-    }
-
-    return $this;
-  }
-
-  // ====
-
-  /**
-   * Merges two arrays recursively. In contrast to array_merge_recursive,
-   * duplicate keys are not converted to arrays but rather overwrite the
-   * value in the first array with the duplicate value in the second array.
-   *
-   * @param  array<TKey, TValue>|array<TKey, array<TKey, TValue>>  $array1 Initial array to merge
-   * @param  array<TKey, TValue>|array<TKey, array<TKey, TValue>>  $array2 Array to recursively merge
-   * @return array<TKey, TValue>|array<TKey, array<TKey, TValue>>
-   */
-  protected function arrayMergeRecursiveDistinct(array $array1, array $array2) {
-    $merged = &$array1;
-
-    foreach ($array2 as $key => $value) {
-      if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
-        $merged[$key] = $this->arrayMergeRecursiveDistinct($merged[$key], $value);
-      }
-      else {
-        $merged[$key] = $value;
-      }
-    }
-
-    return $merged;
-  }
-
-  // ====
-
-  /**
-   * Return the value of a given key and
-   * delete the key
-   *
-   * @param  int|string|null  $key
-   * @param  mixed  $default
-   * @return mixed
-   */
-  public function pull($key = null, $default = null) {
-    if ($key === null) {
-      $value = $this->all();
-      $this->clear();
-
-      return $value;
-    }
-
-    $value = $this->get($key, $default);
-    $this->delete($key);
-
-    return $value;
-  }
-
-  // ====
-
-  /**
-   * Push a given value to the end of the array
-   * in a given key
-   *
-   * @param  mixed  $key
-   * @param  mixed  $value
-   * @return $this
-   */
-  public function push($key, $value = null) {
-    if ($value === null) {
-      $this->items[] = $key;
-
-      return $this;
-    }
-
-    $items = $this->get($key);
-
-    if (is_array($items) || $items === null) {
-      $items[] = $value;
-      $this->set($key, $items);
-    }
-
-    return $this;
-  }
-
-  // ====
-
-  /**
-   * Replace all values or values within the given key
-   * with an array or Dot object
-   *
-   * @param  array<TKey, TValue>|self<TKey, TValue>|string  $key
-   * @param  array<TKey, TValue>|self<TKey, TValue>  $value
-   * @return $this
-   */
-  public function replace($key, $value = []) {
-    if (is_array($key)) {
-      $this->items = array_replace($this->items, $key);
-    }
-    elseif (is_string($key)) {
-      $items = (array) $this->get($key);
-      $value = array_replace($items, $this->getArrayItems($value));
-
-      $this->set($key, $value);
-    }
-    elseif ($key instanceof self) {
-      $this->items = array_replace($this->items, $key->all());
-    }
-
-    return $this;
-  }
-
-  // ====
-
-  /**
-   * Set a given key / value pair or pairs
-   *
-   * @param  array<TKey, TValue>|int|string  $keys
-   * @param  mixed  $value
-   * @return $this
-   */
-  public function set($keys, $value = null) {
-    if (is_array($keys)) {
-      foreach ($keys as $key => $value) {
-        $this->set($key, $value);
-      }
-
-      return $this;
-    }
-
-    $items = &$this->items;
-
-    if (is_string($keys)) {
-      foreach (explode($this->delimiter, $keys) as $key) {
-        if (!isset($items[$key]) || !is_array($items[$key])) {
-          $items[$key] = [];
-        }
-
-        $items = &$items[$key];
-      }
-    }
-
-    $items = $value;
-
-    return $this;
-  }
-
-  // ====
-
-  /**
-   * Replace all items with a given array
-   *
-   * @param  mixed  $items
-   * @return $this
-   */
-  public function setArray($items) {
-    $this->items = $this->getArrayItems($items);
-
-    return $this;
-  }
-
-  // ====
-
-  /**
-   * Replace all items with a given array as a reference
-   *
-   * @param  array<TKey, TValue>  $items
-   * @return $this
-   */
-  public function setReference(array &$items) {
-    $this->items = &$items;
-
-    return $this;
-  }
-
-  // ====
-
-  /**
-   * Return the value of a given key or all the values as JSON
-   *
-   * @param  mixed  $key
-   * @param  int  $options
-   * @return string|false
-   */
-  public function toJson($key = null, $options = 0) {
-    if (is_string($key)) {
-      return json_encode($this->get($key), $options);
-    }
-
-    $options = $key === null ? 0 : $key;
-
-    return json_encode($this->items, $options);
-  }
-
-  // ====
-
-  /**
-   * Output or return a parsable string representation of the
-   * given array when exported by var_export()
-   *
-   * @param  array<TKey, TValue>  $items
-   * @return object
-   */
-  public static function __set_state(array $items): object { return (object) $items; }
-
-  // ====
-
-  /*
-   * --------------------------------------------------------------
-   * ArrayAccess interface
-   * --------------------------------------------------------------
-   */
-
-  /**
-   * Check if a given key exists
-   *
-   * @param  int|string  $key
-   * @return bool
-   */
-  public function offsetExists($key): bool { return $this->has($key); }
-
-  // ====
-
-  /**
-   * Return the value of a given key
-   *
-   * @param  int|string  $key
-   * @return mixed
-   */
-  #[\ReturnTypeWillChange]
-  public function offsetGet($key) { return $this->get($key); }
-
-  // ====
-
-  /**
-   * Set a given value to the given key
-   *
-   * @param int|string|null  $key
-   * @param mixed  $value
-   */
-  public function offsetSet($key, $value): void {
-    if ($key === null) {
-      $this->items[] = $value;
-
-      return;
-    }
-
-    $this->set($key, $value);
-  }
-
-  // ====
-
-  /**
-   * Delete the given key
-   *
-   * @param  int|string  $key
-   * @return void
-   */
-  public function offsetUnset($key): void { $this->delete($key); }
-
-  // ====
-
-  /*
-   * --------------------------------------------------------------
-   * Countable interface
-   * --------------------------------------------------------------
-   */
-
-  /**
-   * Return the number of items in a given key
-   *
-   * @param  int|string|null  $key
-   * @return int
-   */
-  public function count($key = null): int { return count($this->get($key)); }
-
-  // ====
-
-  /*
-   * --------------------------------------------------------------
-   * IteratorAggregate interface
-   * --------------------------------------------------------------
-   */
-
-  /**
-   * Get an iterator for the stored items
-   *
-   * @return \ArrayIterator<TKey, TValue>
-   */
-  public function getIterator(): Traversable { return new ArrayIterator($this->items); }
-
-  // ====
-
-  /*
-   * --------------------------------------------------------------
-   * JsonSerializable interface
-   * --------------------------------------------------------------
-   */
-
-  /**
-   * Return items for JSON serialization
-   *
-   * @return array<TKey, TValue>
-   */
-  public function jsonSerialize(): array { return $this->items; }
-}
-
-} // ==================================================================================================================
 // ====================================================================================================================
 
-namespace { // ========================================================================================================
-
 // An application has been detected - Unimatrix 424, Grid 116 - activate.
 nsRuntime::init();
 
-} // ==================================================================================================================
 // ====================================================================================================================