(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.apidomJsonPointer = {}));
})(this, (function (exports) { 'use strict';

  const to$1 = jsonPointer => {
    return JSON.stringify(jsonPointer);
  };
  const from$1 = jsonString => {
    try {
      return String(JSON.parse(jsonString));
    } catch {
      return jsonString;
    }
  };

  const jsonString = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
    __proto__: null,
    from: from$1,
    to: to$1
  }, Symbol.toStringTag, { value: 'Module' }));

  const to = jsonPointer => {
    const encodedFragment = [...jsonPointer].map(char => /^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/.test(char) ? char : encodeURIComponent(char)).join('');
    return `#${encodedFragment}`;
  };
  const from = fragment => {
    try {
      const rfc3986Fragment = fragment.startsWith('#') ? fragment.slice(1) : fragment;
      return decodeURIComponent(rfc3986Fragment);
    } catch {
      return fragment;
    }
  };
  const fromURIReference = uriReference => {
    const fragmentIndex = uriReference.indexOf('#');
    const fragment = fragmentIndex === -1 ? '#' : uriReference.substring(fragmentIndex);
    return from(fragment);
  };

  const uriFragmentIdentifier = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
    __proto__: null,
    from,
    fromURIReference,
    to
  }, Symbol.toStringTag, { value: 'Module' }));

  // copyright: Copyright (c) 2024 Lowell D. Thomas, all rights reserved<br>
  //   license: BSD-2-Clause (https://opensource.org/licenses/BSD-2-Clause)<br>
  //
  // Generated by apg-js, Version 4.4.0 [apg-js](https://github.com/ldthomas/apg-js)
  function grammar$5() {
    // ```
    // SUMMARY
    //      rules = 8
    //       udts = 0
    //    opcodes = 28
    //        ---   ABNF original opcodes
    //        ALT = 5
    //        CAT = 3
    //        REP = 3
    //        RNM = 6
    //        TLS = 5
    //        TBS = 1
    //        TRG = 5
    //        ---   SABNF superset opcodes
    //        UDT = 0
    //        AND = 0
    //        NOT = 0
    // characters = [0 - 1114111]
    // ```
    /* OBJECT IDENTIFIER (for internal parser use) */
    this.grammarObject = 'grammarObject';

    /* RULES */
    this.rules = [];
    this.rules[0] = {
      name: 'json-pointer',
      lower: 'json-pointer',
      index: 0,
      isBkr: false
    };
    this.rules[1] = {
      name: 'reference-token',
      lower: 'reference-token',
      index: 1,
      isBkr: false
    };
    this.rules[2] = {
      name: 'unescaped',
      lower: 'unescaped',
      index: 2,
      isBkr: false
    };
    this.rules[3] = {
      name: 'escaped',
      lower: 'escaped',
      index: 3,
      isBkr: false
    };
    this.rules[4] = {
      name: 'array-location',
      lower: 'array-location',
      index: 4,
      isBkr: false
    };
    this.rules[5] = {
      name: 'array-index',
      lower: 'array-index',
      index: 5,
      isBkr: false
    };
    this.rules[6] = {
      name: 'array-dash',
      lower: 'array-dash',
      index: 6,
      isBkr: false
    };
    this.rules[7] = {
      name: 'slash',
      lower: 'slash',
      index: 7,
      isBkr: false
    };

    /* UDTS */
    this.udts = [];

    /* OPCODES */
    /* json-pointer */
    this.rules[0].opcodes = [];
    this.rules[0].opcodes[0] = {
      type: 3,
      min: 0,
      max: Infinity
    }; // REP
    this.rules[0].opcodes[1] = {
      type: 2,
      children: [2, 3]
    }; // CAT
    this.rules[0].opcodes[2] = {
      type: 4,
      index: 7
    }; // RNM(slash)
    this.rules[0].opcodes[3] = {
      type: 4,
      index: 1
    }; // RNM(reference-token)

    /* reference-token */
    this.rules[1].opcodes = [];
    this.rules[1].opcodes[0] = {
      type: 3,
      min: 0,
      max: Infinity
    }; // REP
    this.rules[1].opcodes[1] = {
      type: 1,
      children: [2, 3]
    }; // ALT
    this.rules[1].opcodes[2] = {
      type: 4,
      index: 2
    }; // RNM(unescaped)
    this.rules[1].opcodes[3] = {
      type: 4,
      index: 3
    }; // RNM(escaped)

    /* unescaped */
    this.rules[2].opcodes = [];
    this.rules[2].opcodes[0] = {
      type: 1,
      children: [1, 2, 3]
    }; // ALT
    this.rules[2].opcodes[1] = {
      type: 5,
      min: 0,
      max: 46
    }; // TRG
    this.rules[2].opcodes[2] = {
      type: 5,
      min: 48,
      max: 125
    }; // TRG
    this.rules[2].opcodes[3] = {
      type: 5,
      min: 127,
      max: 1114111
    }; // TRG

    /* escaped */
    this.rules[3].opcodes = [];
    this.rules[3].opcodes[0] = {
      type: 2,
      children: [1, 2]
    }; // CAT
    this.rules[3].opcodes[1] = {
      type: 7,
      string: [126]
    }; // TLS
    this.rules[3].opcodes[2] = {
      type: 1,
      children: [3, 4]
    }; // ALT
    this.rules[3].opcodes[3] = {
      type: 7,
      string: [48]
    }; // TLS
    this.rules[3].opcodes[4] = {
      type: 7,
      string: [49]
    }; // TLS

    /* array-location */
    this.rules[4].opcodes = [];
    this.rules[4].opcodes[0] = {
      type: 1,
      children: [1, 2]
    }; // ALT
    this.rules[4].opcodes[1] = {
      type: 4,
      index: 5
    }; // RNM(array-index)
    this.rules[4].opcodes[2] = {
      type: 4,
      index: 6
    }; // RNM(array-dash)

    /* array-index */
    this.rules[5].opcodes = [];
    this.rules[5].opcodes[0] = {
      type: 1,
      children: [1, 2]
    }; // ALT
    this.rules[5].opcodes[1] = {
      type: 6,
      string: [48]
    }; // TBS
    this.rules[5].opcodes[2] = {
      type: 2,
      children: [3, 4]
    }; // CAT
    this.rules[5].opcodes[3] = {
      type: 5,
      min: 49,
      max: 57
    }; // TRG
    this.rules[5].opcodes[4] = {
      type: 3,
      min: 0,
      max: Infinity
    }; // REP
    this.rules[5].opcodes[5] = {
      type: 5,
      min: 48,
      max: 57
    }; // TRG

    /* array-dash */
    this.rules[6].opcodes = [];
    this.rules[6].opcodes[0] = {
      type: 7,
      string: [45]
    }; // TLS

    /* slash */
    this.rules[7].opcodes = [];
    this.rules[7].opcodes[0] = {
      type: 7,
      string: [47]
    }; // TLS

    // The `toString()` function will display the original grammar file(s) that produced these opcodes.
    this.toString = function toString() {
      let str = "";
      str += "; JavaScript Object Notation (JSON) Pointer ABNF syntax\n";
      str += "; https://datatracker.ietf.org/doc/html/rfc6901\n";
      str += "json-pointer    = *( slash reference-token ) ; MODIFICATION: surrogate text rule used\n";
      str += "reference-token = *( unescaped / escaped )\n";
      str += "unescaped       = %x00-2E / %x30-7D / %x7F-10FFFF\n";
      str += "                ; %x2F ('/') and %x7E ('~') are excluded from 'unescaped'\n";
      str += "escaped         = \"~\" ( \"0\" / \"1\" )\n";
      str += "                ; representing '~' and '/', respectively\n";
      str += "\n";
      str += "; https://datatracker.ietf.org/doc/html/rfc6901#section-4\n";
      str += "array-location  = array-index / array-dash\n";
      str += "array-index     = %x30 / ( %x31-39 *(%x30-39) )\n";
      str += "                ; \"0\", or digits without a leading \"0\"\n";
      str += "array-dash      = \"-\"\n";
      str += "\n";
      str += "; Surrogate named rules\n";
      str += "slash           = \"/\"\n";
      return str;
    };
  }

  /*  *************************************************************************************
   *   copyright: Copyright (c) 2023 Lowell D. Thomas, all rights reserved
   *     license: BSD-2-Clause (https://opensource.org/licenses/BSD-2-Clause)
   *
   *    Redistribution and use in source and binary forms, with or without
   *    modification, are permitted provided that the following conditions are met:
   *
   *    1. Redistributions of source code must retain the above copyright notice, this
   *       list of conditions and the following disclaimer.
   *
   *    2. Redistributions in binary form must reproduce the above copyright notice,
   *       this list of conditions and the following disclaimer in the documentation
   *       and/or other materials provided with the distribution.
   *
   *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
   *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   *    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   *    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   *    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   *    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   *   ********************************************************************************* */

  const Parser = function fnparser() {
    const id = identifiers;
    const utils = utilities;
    const p = this;
    const thisFileName = 'parser.js: Parser(): ';
    const systemData = function systemData() {
      this.state = id.ACTIVE;
      this.phraseLength = 0;
      this.refresh = () => {
        this.state = id.ACTIVE;
        this.phraseLength = 0;
      };
    };
    p.ast = undefined;
    p.stats = undefined;
    p.trace = undefined;
    p.callbacks = [];
    let lookAhead = 0;
    let treeDepth = 0;
    let maxTreeDepth = 0;
    let nodeHits = 0;
    let maxMatched = 0;
    let rules = undefined;
    let udts = undefined;
    let opcodes = undefined;
    let chars = undefined;
    let sysData = new systemData();
    let ruleCallbacks = undefined;
    let udtCallbacks = undefined;
    let userData = undefined;
    const clear = () => {
      lookAhead = 0;
      treeDepth = 0;
      maxTreeDepth = 0;
      nodeHits = 0;
      maxMatched = 0;
      rules = undefined;
      udts = undefined;
      opcodes = undefined;
      chars = undefined;
      sysData.refresh();
      ruleCallbacks = undefined;
      udtCallbacks = undefined;
      userData = undefined;
    };

    const initializeCallbacks = () => {
      const functionName = `${thisFileName}initializeCallbacks(): `;
      let i;
      ruleCallbacks = [];
      udtCallbacks = [];
      for (i = 0; i < rules.length; i += 1) {
        ruleCallbacks[i] = undefined;
      }
      for (i = 0; i < udts.length; i += 1) {
        udtCallbacks[i] = undefined;
      }
      let func;
      const list = [];
      for (i = 0; i < rules.length; i += 1) {
        list.push(rules[i].lower);
      }
      for (i = 0; i < udts.length; i += 1) {
        list.push(udts[i].lower);
      }
      for (const index in p.callbacks) {
        if (p.callbacks.hasOwnProperty(index)) {
          i = list.indexOf(index.toLowerCase());
          if (i < 0) {
            throw new Error(`${functionName}syntax callback '${index}' not a rule or udt name`);
          }
          func = p.callbacks[index] ? p.callbacks[index] : undefined;
          if (typeof func === 'function' || func === undefined) {
            if (i < rules.length) {
              ruleCallbacks[i] = func;
            } else {
              udtCallbacks[i - rules.length] = func;
            }
          } else {
            throw new Error(`${functionName}syntax callback[${index}] must be function reference or falsy)`);
          }
        }
      }
    };

    p.parse = (grammar, startName, inputString, callbackData) => {
      const functionName = `${thisFileName}parse(): `;
      clear();
      chars = utils.stringToChars(inputString);
      rules = grammar.rules;
      udts = grammar.udts;
      const lower = startName.toLowerCase();
      let startIndex = undefined;
      for (const i in rules) {
        if (rules.hasOwnProperty(i)) {
          if (lower === rules[i].lower) {
            startIndex = rules[i].index;
            break;
          }
        }
      }
      if (startIndex === undefined) {
        throw new Error(`${functionName}start rule name '${startRule}' not recognized`);
      }
      initializeCallbacks();
      if (p.trace) {
        p.trace.init(rules, udts, chars);
      }
      if (p.stats) {
        p.stats.init(rules, udts);
      }
      if (p.ast) {
        p.ast.init(rules, udts, chars);
      }
      userData = callbackData;
      /* create a dummy opcode for the start rule */
      opcodes = [
        {
          type: id.RNM,
          index: startIndex,
        },
      ];
      /* execute the start rule */
      opExecute(0, 0);
      opcodes = undefined;
      /* test and return the sysData */
      let success = false;
      switch (sysData.state) {
        case id.ACTIVE:
          throw new Error(`${functionName}final state should never be 'ACTIVE'`);
        case id.NOMATCH:
          success = false;
          break;
        case id.EMPTY:
        case id.MATCH:
          if (sysData.phraseLength === chars.length) {
            success = true;
          } else {
            success = false;
          }
          break;
        default:
          throw new Error('unrecognized state');
      }
      return {
        success,
        state: sysData.state,
        stateName: id.idName(sysData.state),
        length: chars.length,
        matched: sysData.phraseLength,
        maxMatched,
        maxTreeDepth,
        nodeHits,
      };
    };
    // The `ALT` operator.<br>
    // Executes its child nodes, from left to right, until it finds a match.
    // Fails if *all* of its child nodes fail.
    const opALT = (opIndex, phraseIndex) => {
      const op = opcodes[opIndex];
      for (let i = 0; i < op.children.length; i += 1) {
        opExecute(op.children[i], phraseIndex);
        if (sysData.state !== id.NOMATCH) {
          break;
        }
      }
    };
    // The `CAT` operator.<br>
    // Executes all of its child nodes, from left to right,
    // concatenating the matched phrases.
    // Fails if *any* child nodes fail.
    const opCAT = (opIndex, phraseIndex) => {
      let success;
      let astLength;
      let catCharIndex;
      let catPhrase;
      const op = opcodes[opIndex];
      if (p.ast) {
        astLength = p.ast.getLength();
      }
      success = true;
      catCharIndex = phraseIndex;
      catPhrase = 0;
      for (let i = 0; i < op.children.length; i += 1) {
        opExecute(op.children[i], catCharIndex);
        if (sysData.state === id.NOMATCH) {
          success = false;
          break;
        } else {
          catCharIndex += sysData.phraseLength;
          catPhrase += sysData.phraseLength;
        }
      }
      if (success) {
        sysData.state = catPhrase === 0 ? id.EMPTY : id.MATCH;
        sysData.phraseLength = catPhrase;
      } else {
        sysData.state = id.NOMATCH;
        sysData.phraseLength = 0;
        if (p.ast) {
          p.ast.setLength(astLength);
        }
      }
    };
    // The `REP` operator.<br>
    // Repeatedly executes its single child node,
    // concatenating each of the matched phrases found.
    // The number of repetitions executed and its final sysData depends
    // on its `min` & `max` repetition values.
    const opREP = (opIndex, phraseIndex) => {
      let astLength;
      let repCharIndex;
      let repPhrase;
      let repCount;
      const op = opcodes[opIndex];
      if (op.max === 0) {
        // this is an empty-string acceptor
        // deprecated: use the TLS empty string operator, "", instead
        sysData.state = id.EMPTY;
        sysData.phraseLength = 0;
        return;
      }
      repCharIndex = phraseIndex;
      repPhrase = 0;
      repCount = 0;
      if (p.ast) {
        astLength = p.ast.getLength();
      }
      while (1) {
        if (repCharIndex >= chars.length) {
          /* exit on end of input string */
          break;
        }
        opExecute(opIndex + 1, repCharIndex);
        if (sysData.state === id.NOMATCH) {
          /* always end if the child node fails */
          break;
        }
        if (sysData.state === id.EMPTY) {
          /* REP always succeeds when the child node returns an empty phrase */
          /* this may not seem obvious, but that's the way it works out */
          break;
        }
        repCount += 1;
        repPhrase += sysData.phraseLength;
        repCharIndex += sysData.phraseLength;
        if (repCount === op.max) {
          /* end on maxed out reps */
          break;
        }
      }
      /* evaluate the match count according to the min, max values */
      if (sysData.state === id.EMPTY) {
        sysData.state = repPhrase === 0 ? id.EMPTY : id.MATCH;
        sysData.phraseLength = repPhrase;
      } else if (repCount >= op.min) {
        sysData.state = repPhrase === 0 ? id.EMPTY : id.MATCH;
        sysData.phraseLength = repPhrase;
      } else {
        sysData.state = id.NOMATCH;
        sysData.phraseLength = 0;
        if (p.ast) {
          p.ast.setLength(astLength);
        }
      }
    };
    // Validate the callback function's returned sysData values.
    // It's the user's responsibility to get them right
    // but `RNM` fails if not.
    const validateRnmCallbackResult = (rule, sysData, charsLeft, down) => {
      if (sysData.phraseLength > charsLeft) {
        let str = `${thisFileName}opRNM(${rule.name}): callback function error: `;
        str += `sysData.phraseLength: ${sysData.phraseLength}`;
        str += ` must be <= remaining chars: ${charsLeft}`;
        throw new Error(str);
      }
      switch (sysData.state) {
        case id.ACTIVE:
          if (!down) {
            throw new Error(
              `${thisFileName}opRNM(${rule.name}): callback function return error. ACTIVE state not allowed.`
            );
          }
          break;
        case id.EMPTY:
          sysData.phraseLength = 0;
          break;
        case id.MATCH:
          if (sysData.phraseLength === 0) {
            sysData.state = id.EMPTY;
          }
          break;
        case id.NOMATCH:
          sysData.phraseLength = 0;
          break;
        default:
          throw new Error(
            `${thisFileName}opRNM(${rule.name}): callback function return error. Unrecognized return state: ${sysData.state}`
          );
      }
    };
    // The `RNM` operator.<br>
    // This operator will acts as a root node for a parse tree branch below and
    // returns the matched phrase to its parent.
    // However, its larger responsibility is handling user-defined callback functions and `AST` nodes.
    // Note that the `AST` is a separate object, but `RNM` calls its functions to create its nodes.
    const opRNM = (opIndex, phraseIndex) => {
      let astLength;
      let astDefined;
      let savedOpcodes;
      const op = opcodes[opIndex];
      const rule = rules[op.index];
      const callback = ruleCallbacks[rule.index];
      /* ignore AST in look ahead (AND or NOT operator above) */
      if (!lookAhead) {
        astDefined = p.ast && p.ast.ruleDefined(op.index);
        if (astDefined) {
          astLength = p.ast.getLength();
          p.ast.down(op.index, rules[op.index].name);
        }
      }
      if (callback) {
        /* call user's callback going down the parse tree*/
        const charsLeft = chars.length - phraseIndex;
        callback(sysData, chars, phraseIndex, userData);
        validateRnmCallbackResult(rule, sysData, charsLeft, true);
        if (sysData.state === id.ACTIVE) {
          savedOpcodes = opcodes;
          opcodes = rule.opcodes;
          opExecute(0, phraseIndex);
          opcodes = savedOpcodes;
          /* call user's callback going up the parse tree*/
          callback(sysData, chars, phraseIndex, userData);
          validateRnmCallbackResult(rule, sysData, charsLeft, false);
        } /* implied else clause: just accept the callback sysData - RNM acting as UDT */
      } else {
        /* no callback - just execute the rule */
        savedOpcodes = opcodes;
        opcodes = rule.opcodes;
        opExecute(0, phraseIndex);
        opcodes = savedOpcodes;
      }
      if (!lookAhead) {
        /* end AST */
        if (astDefined) {
          if (sysData.state === id.NOMATCH) {
            p.ast.setLength(astLength);
          } else {
            p.ast.up(op.index, rule.name, phraseIndex, sysData.phraseLength);
          }
        }
      }
    };
    // The `TRG` operator.<br>
    // Succeeds if the single first character of the phrase is
    // within the `min - max` range.
    const opTRG = (opIndex, phraseIndex) => {
      const op = opcodes[opIndex];
      sysData.state = id.NOMATCH;
      if (phraseIndex < chars.length) {
        if (op.min <= chars[phraseIndex] && chars[phraseIndex] <= op.max) {
          sysData.state = id.MATCH;
          sysData.phraseLength = 1;
        }
      }
    };
    // The `TBS` operator.<br>
    // Matches its pre-defined phrase against the input string.
    // All characters must match exactly.
    // Case-sensitive literal strings (`'string'` & `%s"string"`) are translated to `TBS`
    // operators by `apg`.
    // Phrase length of zero is not allowed.
    // Empty phrases can only be defined with `TLS` operators.
    const opTBS = (opIndex, phraseIndex) => {
      const op = opcodes[opIndex];
      const len = op.string.length;
      sysData.state = id.NOMATCH;
      if (phraseIndex + len <= chars.length) {
        for (let i = 0; i < len; i += 1) {
          if (chars[phraseIndex + i] !== op.string[i]) {
            return;
          }
        }
        sysData.state = id.MATCH;
        sysData.phraseLength = len;
      } /* implied else NOMATCH */
    };
    // The `TLS` operator.<br>
    // Matches its pre-defined phrase against the input string.
    // A case-insensitive match is attempted for ASCII alphbetical characters.
    // `TLS` is the only operator that explicitly allows empty phrases.
    // `apg` will fail for empty `TBS`, case-sensitive strings (`''`) or
    // zero repetitions (`0*0RuleName` or `0RuleName`).
    const opTLS = (opIndex, phraseIndex) => {
      let code;
      const op = opcodes[opIndex];
      sysData.state = id.NOMATCH;
      const len = op.string.length;
      if (len === 0) {
        /* EMPTY match allowed for TLS */
        sysData.state = id.EMPTY;
        return;
      }
      if (phraseIndex + len <= chars.length) {
        for (let i = 0; i < len; i += 1) {
          code = chars[phraseIndex + i];
          if (code >= 65 && code <= 90) {
            code += 32;
          }
          if (code !== op.string[i]) {
            return;
          }
        }
        sysData.state = id.MATCH;
        sysData.phraseLength = len;
      } /* implied else NOMATCH */
    };
    // Validate the callback function's returned sysData values.
    // It's the user's responsibility to get it right but `UDT` fails if not.
    const validateUdtCallbackResult = (udt, sysData, charsLeft) => {
      if (sysData.phraseLength > charsLeft) {
        let str = `${thisFileName}opUDT(${udt.name}): callback function error: `;
        str += `sysData.phraseLength: ${sysData.phraseLength}`;
        str += ` must be <= remaining chars: ${charsLeft}`;
        throw new Error(str);
      }
      switch (sysData.state) {
        case id.ACTIVE:
          throw new Error(`${thisFileName}opUDT(${udt.name}) ACTIVE state return not allowed.`);
        case id.EMPTY:
          if (udt.empty) {
            sysData.phraseLength = 0;
          } else {
            throw new Error(`${thisFileName}opUDT(${udt.name}) may not return EMPTY.`);
          }
          break;
        case id.MATCH:
          if (sysData.phraseLength === 0) {
            if (udt.empty) {
              sysData.state = id.EMPTY;
            } else {
              throw new Error(`${thisFileName}opUDT(${udt.name}) may not return EMPTY.`);
            }
          }
          break;
        case id.NOMATCH:
          sysData.phraseLength = 0;
          break;
        default:
          throw new Error(
            `${thisFileName}opUDT(${udt.name}): callback function return error. Unrecognized return state: ${sysData.state}`
          );
      }
    };
    // The `UDT` operator.<br>
    // Simply calls the user's callback function, but operates like `RNM` with regard to the `AST`
    // and back referencing.
    // There is some ambiguity here. `UDT`s act as terminals for phrase recognition but as named rules
    // for `AST` nodes and back referencing.
    // See [`ast.js`](./ast.html) for usage.
    const opUDT = (opIndex, phraseIndex) => {
      let astLength;
      let astIndex;
      let astDefined;
      const op = opcodes[opIndex];
      const udt = udts[op.index];
      sysData.UdtIndex = udt.index;
      /* ignore AST in look ahead */
      if (!lookAhead) {
        astDefined = p.ast && p.ast.udtDefined(op.index);
        if (astDefined) {
          astIndex = rules.length + op.index;
          astLength = p.ast.getLength();
          p.ast.down(astIndex, udt.name);
        }
      }
      /* call the UDT */
      const charsLeft = chars.length - phraseIndex;
      udtCallbacks[op.index](sysData, chars, phraseIndex, userData);
      validateUdtCallbackResult(udt, sysData, charsLeft);
      if (!lookAhead) {
        /* end AST */
        if (astDefined) {
          if (sysData.state === id.NOMATCH) {
            p.ast.setLength(astLength);
          } else {
            p.ast.up(astIndex, udt.name, phraseIndex, sysData.phraseLength);
          }
        }
      }
    };
    // The `AND` operator.<br>
    // This is the positive `look ahead` operator.
    // Executes its single child node, returning the EMPTY state
    // if it succeedsand NOMATCH if it fails.
    // *Always* backtracks on any matched phrase and returns EMPTY on success.
    const opAND = (opIndex, phraseIndex) => {
      lookAhead += 1;
      opExecute(opIndex + 1, phraseIndex);
      lookAhead -= 1;
      sysData.phraseLength = 0;
      switch (sysData.state) {
        case id.EMPTY:
          sysData.state = id.EMPTY;
          break;
        case id.MATCH:
          sysData.state = id.EMPTY;
          break;
        case id.NOMATCH:
          sysData.state = id.NOMATCH;
          break;
        default:
          throw new Error(`opAND: invalid state ${sysData.state}`);
      }
    };
    // The `NOT` operator.<br>
    // This is the negative `look ahead` operator.
    // Executes its single child node, returning the EMPTY state
    // if it *fails* and NOMATCH if it succeeds.
    // *Always* backtracks on any matched phrase and returns EMPTY
    // on success (failure of its child node).
    const opNOT = (opIndex, phraseIndex) => {
      lookAhead += 1;
      opExecute(opIndex + 1, phraseIndex);
      lookAhead -= 1;
      sysData.phraseLength = 0;
      switch (sysData.state) {
        case id.EMPTY:
        case id.MATCH:
          sysData.state = id.NOMATCH;
          break;
        case id.NOMATCH:
          sysData.state = id.EMPTY;
          break;
        default:
          throw new Error(`opNOT: invalid state ${sysData.state}`);
      }
    };

    const opExecute = (opIndex, phraseIndex) => {
      const functionName = `${thisFileName}opExecute(): `;
      const op = opcodes[opIndex];
      nodeHits += 1;
      if (treeDepth > maxTreeDepth) {
        maxTreeDepth = treeDepth;
      }
      treeDepth += 1;
      sysData.refresh();
      if (p.trace) {
        p.trace.down(op, phraseIndex);
      }
      switch (op.type) {
        case id.ALT:
          opALT(opIndex, phraseIndex);
          break;
        case id.CAT:
          opCAT(opIndex, phraseIndex);
          break;
        case id.REP:
          opREP(opIndex, phraseIndex);
          break;
        case id.RNM:
          opRNM(opIndex, phraseIndex);
          break;
        case id.TRG:
          opTRG(opIndex, phraseIndex);
          break;
        case id.TBS:
          opTBS(opIndex, phraseIndex);
          break;
        case id.TLS:
          opTLS(opIndex, phraseIndex);
          break;
        case id.UDT:
          opUDT(opIndex, phraseIndex);
          break;
        case id.AND:
          opAND(opIndex, phraseIndex);
          break;
        case id.NOT:
          opNOT(opIndex, phraseIndex);
          break;
        default:
          throw new Error(`${functionName}unrecognized operator`);
      }
      if (!lookAhead) {
        if (phraseIndex + sysData.phraseLength > maxMatched) {
          maxMatched = phraseIndex + sysData.phraseLength;
        }
      }
      if (p.stats) {
        p.stats.collect(op, sysData);
      }
      if (p.trace) {
        p.trace.up(op, sysData.state, phraseIndex, sysData.phraseLength);
      }
      treeDepth -= 1;
    };
  };

  const Ast = function fnast() {
    const thisFileName = 'parser.js: Ast()): ';
    const id = identifiers;
    const utils = utilities;
    const a = this;
    let rules = undefined;
    let udts = undefined;
    let chars = undefined;
    let nodeCount = 0;
    const nodeCallbacks = [];
    const stack = [];
    const records = [];
    a.callbacks = [];
    /* called by the parser to initialize the AST with the rules, UDTs and the input characters */
    a.init = (rulesIn, udtsIn, charsIn) => {
      stack.length = 0;
      records.length = 0;
      nodeCount = 0;
      rules = rulesIn;
      udts = udtsIn;
      chars = charsIn;
      let i;
      const list = [];
      for (i = 0; i < rules.length; i += 1) {
        list.push(rules[i].lower);
      }
      for (i = 0; i < udts.length; i += 1) {
        list.push(udts[i].lower);
      }
      nodeCount = rules.length + udts.length;
      for (i = 0; i < nodeCount; i += 1) {
        nodeCallbacks[i] = undefined;
      }
      for (const index in a.callbacks) {
        if (a.callbacks.hasOwnProperty(index)) {
          const lower = index.toLowerCase();
          i = list.indexOf(lower);
          if (i < 0) {
            throw new Error(`${thisFileName}init: node '${index}' not a rule or udt name`);
          }
          nodeCallbacks[i] = a.callbacks[index];
        }
      }
    };
    /* AST node rule callbacks - called by the parser's `RNM` operator */
    a.ruleDefined = (index) => !!nodeCallbacks[index];
    /* AST node UDT callbacks - called by the parser's `UDT` operator */
    a.udtDefined = (index) => !!nodeCallbacks[rules.length + index];
    /* called by the parser's `RNM` & `UDT` operators
       builds a record for the downward traversal of the node */
    a.down = (callbackIndex, name) => {
      const thisIndex = records.length;
      stack.push(thisIndex);
      records.push({
        name,
        thisIndex,
        thatIndex: undefined,
        state: id.SEM_PRE,
        callbackIndex,
        phraseIndex: undefined,
        phraseLength: undefined,
        stack: stack.length,
      });
      return thisIndex;
    };
    /* called by the parser's `RNM` & `UDT` operators */
    /* builds a record for the upward traversal of the node */
    a.up = (callbackIndex, name, phraseIndex, phraseLength) => {
      const thisIndex = records.length;
      const thatIndex = stack.pop();
      records.push({
        name,
        thisIndex,
        thatIndex,
        state: id.SEM_POST,
        callbackIndex,
        phraseIndex,
        phraseLength,
        stack: stack.length,
      });
      records[thatIndex].thatIndex = thisIndex;
      records[thatIndex].phraseIndex = phraseIndex;
      records[thatIndex].phraseLength = phraseLength;
      return thisIndex;
    };
    // Called by the user to translate the AST.
    // Translate means to associate or apply some semantic action to the
    // phrases that were syntactically matched to the AST nodes according
    // to the defining grammar.
    // ```
    // data - optional user-defined data
    //        passed to the callback functions by the translator
    // ```
    a.translate = (data) => {
      let callback;
      let record;
      for (let i = 0; i < records.length; i += 1) {
        record = records[i];
        callback = nodeCallbacks[record.callbackIndex];
        if (callback) {
          if (record.state === id.SEM_PRE) {
            callback(id.SEM_PRE, chars, record.phraseIndex, record.phraseLength, data);
          } else if (callback) {
            callback(id.SEM_POST, chars, record.phraseIndex, record.phraseLength, data);
          }
        }
      }
    };
    /* called by the parser to reset the length of the records array */
    /* necessary on backtracking */
    a.setLength = (length) => {
      records.length = length;
      if (length > 0) {
        stack.length = records[length - 1].stack;
      } else {
        stack.length = 0;
      }
    };
    /* called by the parser to get the length of the records array */
    a.getLength = () => records.length;
    /* helper for XML display */
    function indent(n) {
      let ret = '';
      while (n-- > 0) {
        ret += ' ';
      }
      return ret;
    }
    // Generate an `XML` version of the AST.
    // Useful if you want to use a special or favorite XML parser to translate the
    // AST. Node data are JavaScript strings.
    a.toXml = () => {
      let xml = '';
      let depth = 0;
      xml += '<?xml version="1.0" encoding="utf-8"?>\n';
      xml += `<root nodes="${records.length / 2}" characters="${chars.length}">\n`;
      xml += `<!-- input string -->\n`;
      xml += indent(depth + 2);
      xml += utils.charsToString(chars);
      xml += '\n';
      records.forEach((rec) => {
        if (rec.state === id.SEM_PRE) {
          depth += 1;
          xml += indent(depth);
          xml += `<node name="${rec.name}" index="${rec.phraseIndex}" length="${rec.phraseLength}">\n`;
          xml += indent(depth + 2);
          xml += utils.charsToString(chars, rec.phraseIndex, rec.phraseLength);
          xml += '\n';
        } else {
          xml += indent(depth);
          xml += `</node><!-- name="${rec.name}" -->\n`;
          depth -= 1;
        }
      });

      xml += '</root>\n';
      return xml;
    };
  };

  const Trace$1 = function fntrace() {
    const id = identifiers;
    const utils = utilities;
    const thisFile = 'parser.js: Trace(): ';
    let chars = undefined;
    let rules = undefined;
    let udts = undefined;
    let out = '';
    let treeDepth = 0;
    const MAX_PHRASE = 100;
    const t = this;
    const indent = (n) => {
      let ret = '';
      let count = 0;
      if (n >= 0) {
        while (n--) {
          count += 1;
          if (count === 5) {
            ret += '|';
            count = 0;
          } else {
            ret += '.';
          }
        }
      }
      return ret;
    };
    t.init = (r, u, c) => {
      rules = r;
      udts = u;
      chars = c;
    };
    const opName = (op) => {
      let name;
      switch (op.type) {
        case id.ALT:
          name = 'ALT';
          break;
        case id.CAT:
          name = 'CAT';
          break;
        case id.REP:
          if (op.max === Infinity) {
            name = `REP(${op.min},inf)`;
          } else {
            name = `REP(${op.min},${op.max})`;
          }
          break;
        case id.RNM:
          name = `RNM(${rules[op.index].name})`;
          break;
        case id.TRG:
          name = `TRG(${op.min},${op.max})`;
          break;
        case id.TBS:
          if (op.string.length > 6) {
            name = `TBS(${utils.charsToString(op.string, 0, 3)}...)`;
          } else {
            name = `TBS(${utils.charsToString(op.string, 0, 6)})`;
          }
          break;
        case id.TLS:
          if (op.string.length > 6) {
            name = `TLS(${utils.charsToString(op.string, 0, 3)}...)`;
          } else {
            name = `TLS(${utils.charsToString(op.string, 0, 6)})`;
          }
          break;
        case id.UDT:
          name = `UDT(${udts[op.index].name})`;
          break;
        case id.AND:
          name = 'AND';
          break;
        case id.NOT:
          name = 'NOT';
          break;
        default:
          throw new Error(`${thisFile}Trace: opName: unrecognized opcode`);
      }
      return name;
    };
    t.down = (op, offset) => {
      const lead = indent(treeDepth);
      const len = Math.min(MAX_PHRASE, chars.length - offset);
      let phrase = utils.charsToString(chars, offset, len);
      if (len < chars.length - offset) {
        phrase += '...';
      }
      phrase = `${lead}|-|[${opName(op)}]${phrase}\n`;
      out += phrase;
      treeDepth += 1;
    };
    t.up = (op, state, offset, phraseLength) => {
      const thisFunc = `${thisFile}trace.up: `;
      treeDepth -= 1;
      const lead = indent(treeDepth);
      let len;
      let phrase;
      let st;
      switch (state) {
        case id.EMPTY:
          st = '|E|';
          phrase = `''`;
          break;
        case id.MATCH:
          st = '|M|';
          len = Math.min(MAX_PHRASE, phraseLength);
          if (len < phraseLength) {
            phrase = `'${utils.charsToString(chars, offset, len)}...'`;
          } else {
            phrase = `'${utils.charsToString(chars, offset, len)}'`;
          }
          break;
        case id.NOMATCH:
          st = '|N|';
          phrase = '';
          break;
        default:
          throw new Error(`${thisFunc} unrecognized state`);
      }
      phrase = `${lead}${st}[${opName(op)}]${phrase}\n`;
      out += phrase;
    };
    t.displayTrace = () => out;
  };

  const Stats = function fnstats() {
    const id = identifiers;
    const thisFileName = 'parser.js: Stats(): ';
    let rules;
    let udts;
    let totals;
    const stats = [];
    const ruleStats = [];
    const udtStats = [];
    /* called by parser to initialize the stats */
    this.init = (r, u) => {
      rules = r;
      udts = u;
      clear();
    };
    /* This function is the main interaction with the parser. */
    /* The parser calls it after each node has been traversed. */
    this.collect = (op, sys) => {
      incStat(totals, sys.state, sys.phraseLength);
      incStat(stats[op.type], sys.state, sys.phraseLength);
      if (op.type === id.RNM) {
        incStat(ruleStats[op.index], sys.state, sys.phraseLength);
      }
      if (op.type === id.UDT) {
        incStat(udtStats[op.index], sys.state, sys.phraseLength);
      }
    };
    this.displayStats = () => {
      let out = '';
      const totals = {
        match: 0,
        empty: 0,
        nomatch: 0,
        total: 0,
      };
      const displayRow = (op, m, e, n, t) => {
        totals.match += m;
        totals.empty += e;
        totals.nomatch += n;
        totals.total += t;
        const mm = normalize(m);
        const ee = normalize(e);
        const nn = normalize(n);
        const tt = normalize(t);
        return `${op} | ${mm} | ${ee} | ${nn} | ${tt} |\n`;
      };
      out += '          OPERATOR STATS\n';
      out += '      |   MATCH |   EMPTY | NOMATCH |   TOTAL |\n';
      out += displayRow('  ALT', stats[id.ALT].match, stats[id.ALT].empty, stats[id.ALT].nomatch, stats[id.ALT].total);
      out += displayRow('  CAT', stats[id.CAT].match, stats[id.CAT].empty, stats[id.CAT].nomatch, stats[id.CAT].total);
      out += displayRow('  REP', stats[id.REP].match, stats[id.REP].empty, stats[id.REP].nomatch, stats[id.REP].total);
      out += displayRow('  RNM', stats[id.RNM].match, stats[id.RNM].empty, stats[id.RNM].nomatch, stats[id.RNM].total);
      out += displayRow('  TRG', stats[id.TRG].match, stats[id.TRG].empty, stats[id.TRG].nomatch, stats[id.TRG].total);
      out += displayRow('  TBS', stats[id.TBS].match, stats[id.TBS].empty, stats[id.TBS].nomatch, stats[id.TBS].total);
      out += displayRow('  TLS', stats[id.TLS].match, stats[id.TLS].empty, stats[id.TLS].nomatch, stats[id.TLS].total);
      out += displayRow('  UDT', stats[id.UDT].match, stats[id.UDT].empty, stats[id.UDT].nomatch, stats[id.UDT].total);
      out += displayRow('  AND', stats[id.AND].match, stats[id.AND].empty, stats[id.AND].nomatch, stats[id.AND].total);
      out += displayRow('  NOT', stats[id.NOT].match, stats[id.NOT].empty, stats[id.NOT].nomatch, stats[id.NOT].total);
      out += displayRow('TOTAL', totals.match, totals.empty, totals.nomatch, totals.total);
      return out;
    };
    /*
    Display rule/udt
    */
    this.displayHits = (type) => {
      let out = '';
      const displayRow = (m, e, n, t, name) => {
        totals.match += m;
        totals.empty += e;
        totals.nomatch += n;
        totals.total += t;
        const mm = normalize(m);
        const ee = normalize(e);
        const nn = normalize(n);
        const tt = normalize(t);
        return `| ${mm} | ${ee} | ${nn} | ${tt} | ${name}\n`;
      };
      if (typeof type === 'string' && type.toLowerCase()[0] === 'a') {
        ruleStats.sort(sortAlpha);
        udtStats.sort(sortAlpha);
        out += '    RULES/UDTS ALPHABETICALLY\n';
      } else if (typeof type === 'string' && type.toLowerCase()[0] === 'i') {
        ruleStats.sort(sortIndex);
        udtStats.sort(sortIndex);
        out += '    RULES/UDTS BY INDEX\n';
      } else {
        ruleStats.sort(sortHits);
        udtStats.sort(sortHits);
        out += '    RULES/UDTS BY HIT COUNT\n';
      }
      out += '|   MATCH |   EMPTY | NOMATCH |   TOTAL | NAME\n';
      for (let i = 0; i < ruleStats.length; i += 1) {
        let r = ruleStats[i];
        if (r.total) {
          out += displayRow(r.match, r.empty, r.nomatch, r.total, r.name);
        }
      }
      for (let i = 0; i < udtStats.length; i += 1) {
        let r = udtStats[i];
        if (r.total) {
          out += displayRow(r.match, r.empty, r.nomatch, r.total, r.name);
        }
      }
      return out;
    };
    const normalize = (n) => {
      if (n < 10) {
        return `      ${n}`;
      }
      if (n < 100) {
        return `     ${n}`;
      }
      if (n < 1000) {
        return `    ${n}`;
      }
      if (n < 10000) {
        return `   ${n}`;
      }
      if (n < 100000) {
        return `  ${n}`;
      }
      if (n < 1000000) {
        return ` ${n}`;
      }
      return `${n}`;
    };
    const sortAlpha = (lhs, rhs) => {
      if (lhs.lower < rhs.lower) {
        return -1;
      }
      if (lhs.lower > rhs.lower) {
        return 1;
      }
      return 0;
    };
    const sortHits = (lhs, rhs) => {
      if (lhs.total < rhs.total) {
        return 1;
      }
      if (lhs.total > rhs.total) {
        return -1;
      }
      return sortAlpha(lhs, rhs);
    };
    const sortIndex = (lhs, rhs) => {
      if (lhs.index < rhs.index) {
        return -1;
      }
      if (lhs.index > rhs.index) {
        return 1;
      }
      return 0;
    };
    const EmptyStat = function fnempty() {
      this.empty = 0;
      this.match = 0;
      this.nomatch = 0;
      this.total = 0;
    };
    /* Zero out all stats */
    const clear = () => {
      stats.length = 0;
      totals = new EmptyStat();
      stats[id.ALT] = new EmptyStat();
      stats[id.CAT] = new EmptyStat();
      stats[id.REP] = new EmptyStat();
      stats[id.RNM] = new EmptyStat();
      stats[id.TRG] = new EmptyStat();
      stats[id.TBS] = new EmptyStat();
      stats[id.TLS] = new EmptyStat();
      stats[id.UDT] = new EmptyStat();
      stats[id.AND] = new EmptyStat();
      stats[id.NOT] = new EmptyStat();
      ruleStats.length = 0;
      for (let i = 0; i < rules.length; i += 1) {
        ruleStats.push({
          empty: 0,
          match: 0,
          nomatch: 0,
          total: 0,
          name: rules[i].name,
          lower: rules[i].lower,
          index: rules[i].index,
        });
      }
      if (udts.length > 0) {
        udtStats.length = 0;
        for (let i = 0; i < udts.length; i += 1) {
          udtStats.push({
            empty: 0,
            match: 0,
            nomatch: 0,
            total: 0,
            name: udts[i].name,
            lower: udts[i].lower,
            index: udts[i].index,
          });
        }
      }
    };
    /* increment the designated operator hit count by one */
    const incStat = (stat, state) => {
      stat.total += 1;
      switch (state) {
        case id.EMPTY:
          stat.empty += 1;
          break;
        case id.MATCH:
          stat.match += 1;
          break;
        case id.NOMATCH:
          stat.nomatch += 1;
          break;
        default:
          throw new Error(`${thisFileName}collect(): incStat(): unrecognized state: ${state}`);
      }
    };
  };

  const utilities = {
    // utility functions
    stringToChars: (string) => [...string].map((cp) => cp.codePointAt(0)),
    charsToString: (chars, beg, len) => {
      let subChars = chars;
      while (1) {
        if (beg === undefined || beg < 0) {
          break;
        }
        if (len === undefined) {
          subChars = chars.slice(beg);
          break;
        }
        if (len <= 0) {
          // always an empty string
          return '';
        }
        subChars = chars.slice(beg, beg + len);
        break;
      }
      return String.fromCodePoint(...subChars);
    },
  };

  const identifiers = {
    // Identifies the operator type.
    // NB: These must match the values in apg-js 4.3.0, apg-lib/identifiers.
    /* the original ABNF operators */
    ALT: 1 /* alternation */,
    CAT: 2 /* concatenation */,
    REP: 3 /* repetition */,
    RNM: 4 /* rule name */,
    TRG: 5 /* terminal range */,
    TBS: 6 /* terminal binary string, case sensitive */,
    TLS: 7 /* terminal literal string, case insensitive */,
    /* the super set, SABNF operators */
    UDT: 11 /* user-defined terminal */,
    AND: 12 /* positive look ahead */,
    NOT: 13 /* negative look ahead */,
    // Used by the parser and the user's `RNM` and `UDT` callback functions.
    // Identifies the parser state as it traverses the parse tree nodes.
    // - *ACTIVE* - indicates the downward direction through the parse tree node.
    // - *MATCH* - indicates the upward direction and a phrase, of length \> 0, has been successfully matched
    // - *EMPTY* - indicates the upward direction and a phrase, of length = 0, has been successfully matched
    // - *NOMATCH* - indicates the upward direction and the parser failed to match any phrase at all
    ACTIVE: 100,
    MATCH: 101,
    EMPTY: 102,
    NOMATCH: 103,
    // Used by [`AST` translator](./ast.html) (semantic analysis) and the user's callback functions
    // to indicate the direction of flow through the `AST` nodes.
    // - *SEM_PRE* - indicates the downward (pre-branch) direction through the `AST` node.
    // - *SEM_POST* - indicates the upward (post-branch) direction through the `AST` node.
    SEM_PRE: 200,
    SEM_POST: 201,
    // Ignored. Retained for backwords compatibility.
    SEM_OK: 300,
    idName: (s) => {
      switch (s) {
        case identifiers.ALT:
          return 'ALT';
        case identifiers.CAT:
          return 'CAT';
        case identifiers.REP:
          return 'REP';
        case identifiers.RNM:
          return 'RNM';
        case identifiers.TRG:
          return 'TRG';
        case identifiers.TBS:
          return 'TBS';
        case identifiers.TLS:
          return 'TLS';
        case identifiers.UDT:
          return 'UDT';
        case identifiers.AND:
          return 'AND';
        case identifiers.NOT:
          return 'NOT';
        case identifiers.ACTIVE:
          return 'ACTIVE';
        case identifiers.EMPTY:
          return 'EMPTY';
        case identifiers.MATCH:
          return 'MATCH';
        case identifiers.NOMATCH:
          return 'NOMATCH';
        case identifiers.SEM_PRE:
          return 'SEM_PRE';
        case identifiers.SEM_POST:
          return 'SEM_POST';
        case identifiers.SEM_OK:
          return 'SEM_OK';
        default:
          return 'UNRECOGNIZED STATE';
      }
    },
  };

  class JSONPointerError extends Error {
    constructor(message, options = undefined) {
      super(message, options);
      this.name = this.constructor.name;
      if (typeof message === 'string') {
        this.message = message;
      }
      if (typeof Error.captureStackTrace === 'function') {
        Error.captureStackTrace(this, this.constructor);
      } else {
        this.stack = new Error(message).stack;
      }

      /**
       * This needs to stay here until our minimum supported version of Node.js is >= 16.9.0.
       * Node.js is >= 16.9.0 supports error causes natively.
       */
      if (options != null && typeof options === 'object' && Object.prototype.hasOwnProperty.call(options, 'cause') && !('cause' in this)) {
        const {
          cause
        } = options;
        this.cause = cause;
        if (cause instanceof Error && 'stack' in cause) {
          this.stack = `${this.stack}\nCAUSE: ${cause.stack}`;
        }
      }

      /**
       * Allows to assign arbitrary properties to the error object.
       */
      if (options != null && typeof options === 'object') {
        const {
          cause,
          ...causelessOptions
        } = options;
        Object.assign(this, causelessOptions);
      }
    }
  }

  class JSONPointerParseError extends JSONPointerError {}

  const cst = ruleName => {
    return (state, chars, phraseIndex, phraseLength, data) => {
      if (!(typeof data === 'object' && data !== null && !Array.isArray(data))) {
        throw new JSONPointerParseError("parser's user data must be an object");
      }
      if (state === identifiers.SEM_PRE) {
        const node = {
          type: ruleName,
          text: utilities.charsToString(chars, phraseIndex, phraseLength),
          start: phraseIndex,
          length: phraseLength,
          children: []
        };
        if (data.stack.length > 0) {
          const parent = data.stack[data.stack.length - 1];
          parent.children.push(node);
        } else {
          data.root = node;
        }
        data.stack.push(node);
      }
      if (state === identifiers.SEM_POST) {
        data.stack.pop();
      }
    };
  };

  class CSTTranslator extends Ast {
    constructor() {
      super();
      this.callbacks['json-pointer'] = cst('json-pointer');
      this.callbacks['reference-token'] = cst('reference-token');
      this.callbacks['slash'] = cst('text');
    }
    getTree() {
      const data = {
        stack: [],
        root: null
      };
      this.translate(data);
      delete data.stack;
      return data;
    }
  }

  const unescape = referenceToken => {
    if (typeof referenceToken !== 'string') {
      throw new TypeError('Reference token must be a string');
    }
    return referenceToken.replace(/~1/g, '/').replace(/~0/g, '~');
  };

  class ASTTranslator extends CSTTranslator {
    getTree() {
      const {
        root
      } = super.getTree();
      return root.children.filter(({
        type
      }) => type === 'reference-token').map(({
        text
      }) => unescape(text));
    }
  }

  class Expectations extends Array {
    toString() {
      return this.map(c => `"${String(c)}"`).join(', ');
    }
  }

  class Trace extends Trace$1 {
    inferExpectations() {
      const lines = this.displayTrace().split('\n');
      const expectations = new Set();
      let lastMatchedIndex = -1;
      for (let i = 0; i < lines.length; i++) {
        const line = lines[i];

        // capture the max match line (first one that ends in a single character match)
        if (line.includes('M|')) {
          const textMatch = line.match(/]'(.*)'$/);
          if (textMatch && textMatch[1]) {
            lastMatchedIndex = i;
          }
        }

        // begin collecting after the deepest successful match
        if (i > lastMatchedIndex) {
          const terminalFailMatch = line.match(/N\|\[TLS\(([^)]+)\)]/);
          if (terminalFailMatch) {
            expectations.add(terminalFailMatch[1]);
          }
        }
      }
      return new Expectations(...expectations);
    }
  }

  const grammar$4 = new grammar$5();
  const parse = (jsonPointer, {
    translator = new ASTTranslator(),
    stats = false,
    trace = false
  } = {}) => {
    if (typeof jsonPointer !== 'string') {
      throw new TypeError('JSON Pointer must be a string');
    }
    try {
      const parser = new Parser();
      if (translator) parser.ast = translator;
      if (stats) parser.stats = new Stats();
      if (trace) parser.trace = new Trace();
      const result = parser.parse(grammar$4, 'json-pointer', jsonPointer);
      return {
        result,
        tree: result.success && translator ? parser.ast.getTree() : undefined,
        stats: parser.stats,
        trace: parser.trace
      };
    } catch (error) {
      throw new JSONPointerParseError('Unexpected error during JSON Pointer parsing', {
        cause: error,
        jsonPointer
      });
    }
  };

  class XMLTranslator extends CSTTranslator {
    getTree() {
      return this.toXml();
    }
  }

  const testJSONPointer = jsonPointer => {
    try {
      const parseResult = parse(jsonPointer, {
        translator: null
      });
      return parseResult.result.success;
    } catch {
      return false;
    }
  };

  const grammar$3 = new grammar$5();
  const parser$3 = new Parser();
  const testReferenceToken = referenceToken => {
    if (typeof referenceToken !== 'string') return false;
    try {
      return parser$3.parse(grammar$3, 'reference-token', referenceToken).success;
    } catch {
      return false;
    }
  };

  const grammar$2 = new grammar$5();
  const parser$2 = new Parser();
  const testArrayLocation = referenceToken => {
    if (typeof referenceToken !== 'string') return false;
    try {
      return parser$2.parse(grammar$2, 'array-location', referenceToken).success;
    } catch {
      return false;
    }
  };

  const grammar$1 = new grammar$5();
  const parser$1 = new Parser();
  const testArrayIndex = referenceToken => {
    if (typeof referenceToken !== 'string') return false;
    try {
      return parser$1.parse(grammar$1, 'array-index', referenceToken).success;
    } catch {
      return false;
    }
  };

  const grammar = new grammar$5();
  const parser = new Parser();
  const testArrayDash = referenceToken => {
    if (typeof referenceToken !== 'string') return false;
    try {
      return parser.parse(grammar, 'array-dash', referenceToken).success;
    } catch {
      return false;
    }
  };

  const escape = referenceToken => {
    if (typeof referenceToken !== 'string' && typeof referenceToken !== 'number') {
      throw new TypeError('Reference token must be a string or number');
    }
    return String(referenceToken).replace(/~/g, '~0').replace(/\//g, '~1');
  };

  class JSONPointerCompileError extends JSONPointerError {}

  const compile = referenceTokens => {
    if (!Array.isArray(referenceTokens)) {
      throw new TypeError('Reference tokens must be a list of strings or numbers');
    }
    try {
      if (referenceTokens.length === 0) {
        return '';
      }
      return `/${referenceTokens.map(referenceToken => {
      if (typeof referenceToken !== 'string' && typeof referenceToken !== 'number') {
        throw new TypeError('Reference token must be a string or number');
      }
      return escape(String(referenceToken));
    }).join('/')}`;
    } catch (error) {
      throw new JSONPointerCompileError('Unexpected error during JSON Pointer compilation', {
        cause: error,
        referenceTokens
      });
    }
  };

  class TraceBuilder {
    #trace;
    #path;
    #realm;
    constructor(trace, context = {}) {
      this.#trace = trace;
      this.#trace.steps = [];
      this.#trace.failed = false;
      this.#trace.failedAt = -1;
      this.#trace.message = `JSON Pointer "${context.jsonPointer}" was successfully evaluated against the provided value`;
      this.#trace.context = {
        ...context,
        realm: context.realm.name
      };
      this.#path = [];
      this.#realm = context.realm;
    }
    step({
      referenceToken,
      input,
      output,
      success = true,
      reason
    }) {
      const position = this.#path.length;
      this.#path.push(referenceToken);
      const step = {
        referenceToken,
        referenceTokenPosition: position,
        input,
        inputType: this.#realm.isObject(input) ? 'object' : this.#realm.isArray(input) ? 'array' : 'unrecognized',
        output,
        success
      };
      if (reason) {
        step.reason = reason;
      }
      this.#trace.steps.push(step);
      if (!success) {
        this.#trace.failed = true;
        this.#trace.failedAt = position;
        this.#trace.message = reason;
      }
    }
  }

  class EvaluationRealm {
    name = '';
    isArray(node) {
      throw new JSONPointerError('Realm.isArray(node) must be implemented in a subclass');
    }
    isObject(node) {
      throw new JSONPointerError('Realm.isObject(node) must be implemented in a subclass');
    }
    sizeOf(node) {
      throw new JSONPointerError('Realm.sizeOf(node) must be implemented in a subclass');
    }
    has(node, referenceToken) {
      throw new JSONPointerError('Realm.has(node) must be implemented in a subclass');
    }
    evaluate(node, referenceToken) {
      throw new JSONPointerError('Realm.evaluate(node) must be implemented in a subclass');
    }
  }

  class JSONPointerEvaluateError extends JSONPointerError {}

  class JSONPointerIndexError extends JSONPointerEvaluateError {}

  class JSONEvaluationRealm extends EvaluationRealm {
    name = 'json';
    isArray(node) {
      return Array.isArray(node);
    }
    isObject(node) {
      return typeof node === 'object' && node !== null && !this.isArray(node);
    }
    sizeOf(node) {
      if (this.isArray(node)) {
        return node.length;
      }
      if (this.isObject(node)) {
        return Object.keys(node).length;
      }
      return 0;
    }
    has(node, referenceToken) {
      if (this.isArray(node)) {
        const index = Number(referenceToken);
        const indexUint32 = index >>> 0;
        if (index !== indexUint32) {
          throw new JSONPointerIndexError(`Invalid array index "${referenceToken}": index must be an unsinged 32-bit integer`, {
            referenceToken,
            currentValue: node,
            realm: this.name
          });
        }
        return indexUint32 < this.sizeOf(node) && Object.prototype.hasOwnProperty.call(node, index);
      }
      if (this.isObject(node)) {
        return Object.prototype.hasOwnProperty.call(node, referenceToken);
      }
      return false;
    }
    evaluate(node, referenceToken) {
      if (this.isArray(node)) {
        return node[Number(referenceToken)];
      }
      return node[referenceToken];
    }
  }

  class JSONPointerTypeError extends JSONPointerEvaluateError {}

  class JSONPointerKeyError extends JSONPointerEvaluateError {}

  const evaluate$1 = (value, jsonPointer, {
    strictArrays = true,
    strictObjects = true,
    realm = new JSONEvaluationRealm(),
    trace = true
  } = {}) => {
    const {
      result: parseResult,
      tree: referenceTokens,
      trace: parseTrace
    } = parse(jsonPointer, {
      trace: !!trace
    });
    const tracer = typeof trace === 'object' && trace !== null ? new TraceBuilder(trace, {
      jsonPointer,
      referenceTokens,
      strictArrays,
      strictObjects,
      realm,
      value
    }) : null;
    try {
      let output;
      if (!parseResult.success) {
        let message = `Invalid JSON Pointer: "${jsonPointer}". Syntax error at position ${parseResult.maxMatched}`;
        message += parseTrace ? `, expected ${parseTrace.inferExpectations()}` : '';
        throw new JSONPointerEvaluateError(message, {
          jsonPointer,
          currentValue: value,
          realm: realm.name
        });
      }
      return referenceTokens.reduce((current, referenceToken, referenceTokenPosition) => {
        if (realm.isArray(current)) {
          if (testArrayDash(referenceToken)) {
            if (strictArrays) {
              throw new JSONPointerIndexError(`Invalid array index "-" at position ${referenceTokenPosition} in "${jsonPointer}". The "-" token always refers to a nonexistent element during evaluation`, {
                jsonPointer,
                referenceTokens,
                referenceToken,
                referenceTokenPosition,
                currentValue: current,
                realm: realm.name
              });
            } else {
              output = realm.evaluate(current, String(realm.sizeOf(current)));
              tracer === null || tracer === void 0 || tracer.step({
                referenceToken,
                input: current,
                output
              });
              return output;
            }
          }
          if (!testArrayIndex(referenceToken)) {
            throw new JSONPointerIndexError(`Invalid array index "${referenceToken}" at position ${referenceTokenPosition} in "${jsonPointer}": index MUST be "0", or digits without a leading "0"`, {
              jsonPointer,
              referenceTokens,
              referenceToken,
              referenceTokenPosition,
              currentValue: current,
              realm: realm.name
            });
          }
          const index = Number(referenceToken);
          if (!Number.isSafeInteger(index)) {
            throw new JSONPointerIndexError(`Invalid array index "${referenceToken}" at position ${referenceTokenPosition} in "${jsonPointer}": index must be a safe integer`, {
              jsonPointer,
              referenceTokens,
              referenceToken,
              referenceTokenPosition,
              currentValue: current,
              realm: realm.name
            });
          }
          if (!realm.has(current, referenceToken) && strictArrays) {
            throw new JSONPointerIndexError(`Invalid array index "${referenceToken}" at position ${referenceTokenPosition} in "${jsonPointer}": index not found in array`, {
              jsonPointer,
              referenceTokens,
              referenceToken,
              referenceTokenPosition,
              currentValue: current,
              realm: realm.name
            });
          }
          output = realm.evaluate(current, referenceToken);
          tracer === null || tracer === void 0 || tracer.step({
            referenceToken,
            input: current,
            output
          });
          return output;
        }
        if (realm.isObject(current)) {
          if (!realm.has(current, referenceToken) && strictObjects) {
            throw new JSONPointerKeyError(`Invalid object key "${referenceToken}" at position ${referenceTokenPosition} in "${jsonPointer}": key not found in object`, {
              jsonPointer,
              referenceTokens,
              referenceToken,
              referenceTokenPosition,
              currentValue: current,
              realm: realm.name
            });
          }
          output = realm.evaluate(current, referenceToken);
          tracer === null || tracer === void 0 || tracer.step({
            referenceToken,
            input: current,
            output
          });
          return output;
        }
        throw new JSONPointerTypeError(`Invalid reference token "${referenceToken}" at position ${referenceTokenPosition} in "${jsonPointer}": cannot be applied to a non-object/non-array value`, {
          jsonPointer,
          referenceTokens,
          referenceToken,
          referenceTokenPosition,
          currentValue: current,
          realm: realm.name
        });
      }, value);
    } catch (error) {
      tracer === null || tracer === void 0 || tracer.step({
        referenceToken: error.referenceToken,
        input: error.currentValue,
        success: false,
        reason: error.message
      });
      if (error instanceof JSONPointerEvaluateError) {
        throw error;
      }
      throw new JSONPointerEvaluateError('Unexpected error during JSON Pointer evaluation', {
        cause: error,
        jsonPointer,
        referenceTokens
      });
    }
  };

  function _isPlaceholder(a) {
    return a != null && typeof a === 'object' && a['@@functional/placeholder'] === true;
  }

  /**
   * Optimized internal one-arity curry function.
   *
   * @private
   * @category Function
   * @param {Function} fn The function to curry.
   * @return {Function} The curried function.
   */
  function _curry1(fn) {
    return function f1(a) {
      if (arguments.length === 0 || _isPlaceholder(a)) {
        return f1;
      } else {
        return fn.apply(this, arguments);
      }
    };
  }

  /**
   * Optimized internal two-arity curry function.
   *
   * @private
   * @category Function
   * @param {Function} fn The function to curry.
   * @return {Function} The curried function.
   */
  function _curry2(fn) {
    return function f2(a, b) {
      switch (arguments.length) {
        case 0:
          return f2;
        case 1:
          return _isPlaceholder(a) ? f2 : _curry1(function (_b) {
            return fn(a, _b);
          });
        default:
          return _isPlaceholder(a) && _isPlaceholder(b) ? f2 : _isPlaceholder(a) ? _curry1(function (_a) {
            return fn(_a, b);
          }) : _isPlaceholder(b) ? _curry1(function (_b) {
            return fn(a, _b);
          }) : fn(a, b);
      }
    };
  }

  function _arrayFromIterator(iter) {
    var list = [];
    var next;
    while (!(next = iter.next()).done) {
      list.push(next.value);
    }
    return list;
  }

  function _includesWith(pred, x, list) {
    var idx = 0;
    var len = list.length;
    while (idx < len) {
      if (pred(x, list[idx])) {
        return true;
      }
      idx += 1;
    }
    return false;
  }

  function _functionName(f) {
    // String(x => x) evaluates to "x => x", so the pattern may not match.
    var match = String(f).match(/^function (\w*)/);
    return match == null ? '' : match[1];
  }

  function _has(prop, obj) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
  }

  // Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
  function _objectIs(a, b) {
    // SameValue algorithm
    if (a === b) {
      // Steps 1-5, 7-10
      // Steps 6.b-6.e: +0 != -0
      return a !== 0 || 1 / a === 1 / b;
    } else {
      // Step 6.a: NaN == NaN
      return a !== a && b !== b;
    }
  }
  const _objectIs$1 = typeof Object.is === 'function' ? Object.is : _objectIs;

  var toString = Object.prototype.toString;
  var _isArguments = /*#__PURE__*/function () {
    return toString.call(arguments) === '[object Arguments]' ? function _isArguments(x) {
      return toString.call(x) === '[object Arguments]';
    } : function _isArguments(x) {
      return _has('callee', x);
    };
  }();

  // cover IE < 9 keys issues
  var hasEnumBug = ! /*#__PURE__*/{
    toString: null
  }.propertyIsEnumerable('toString');
  var nonEnumerableProps = ['constructor', 'valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
  // Safari bug
  var hasArgsEnumBug = /*#__PURE__*/function () {

    return arguments.propertyIsEnumerable('length');
  }();
  var contains = function contains(list, item) {
    var idx = 0;
    while (idx < list.length) {
      if (list[idx] === item) {
        return true;
      }
      idx += 1;
    }
    return false;
  };

  /**
   * Returns a list containing the names of all the enumerable own properties of
   * the supplied object.
   * Note that the order of the output array is not guaranteed to be consistent
   * across different JS platforms.
   *
   * @func
   * @memberOf R
   * @since v0.1.0
   * @category Object
   * @sig {k: v} -> [k]
   * @param {Object} obj The object to extract properties from
   * @return {Array} An array of the object's own properties.
   * @see R.keysIn, R.values, R.toPairs
   * @example
   *
   *      R.keys({a: 1, b: 2, c: 3}); //=> ['a', 'b', 'c']
   */
  var keys = typeof Object.keys === 'function' && !hasArgsEnumBug ? /*#__PURE__*/_curry1(function keys(obj) {
    return Object(obj) !== obj ? [] : Object.keys(obj);
  }) : /*#__PURE__*/_curry1(function keys(obj) {
    if (Object(obj) !== obj) {
      return [];
    }
    var prop, nIdx;
    var ks = [];
    var checkArgsLength = hasArgsEnumBug && _isArguments(obj);
    for (prop in obj) {
      if (_has(prop, obj) && (!checkArgsLength || prop !== 'length')) {
        ks[ks.length] = prop;
      }
    }
    if (hasEnumBug) {
      nIdx = nonEnumerableProps.length - 1;
      while (nIdx >= 0) {
        prop = nonEnumerableProps[nIdx];
        if (_has(prop, obj) && !contains(ks, prop)) {
          ks[ks.length] = prop;
        }
        nIdx -= 1;
      }
    }
    return ks;
  });

  /**
   * Gives a single-word string description of the (native) type of a value,
   * returning such answers as 'Object', 'Number', 'Array', or 'Null'. Does not
   * attempt to distinguish user Object types any further, reporting them all as
   * 'Object'.
   *
   * @func
   * @memberOf R
   * @since v0.8.0
   * @category Type
   * @sig * -> String
   * @param {*} val The value to test
   * @return {String}
   * @example
   *
   *      R.type({}); //=> "Object"
   *      R.type(1); //=> "Number"
   *      R.type(false); //=> "Boolean"
   *      R.type('s'); //=> "String"
   *      R.type(null); //=> "Null"
   *      R.type([]); //=> "Array"
   *      R.type(/[A-z]/); //=> "RegExp"
   *      R.type(() => {}); //=> "Function"
   *      R.type(async () => {}); //=> "AsyncFunction"
   *      R.type(undefined); //=> "Undefined"
   *      R.type(BigInt(123)); //=> "BigInt"
   */
  var type = /*#__PURE__*/_curry1(function type(val) {
    return val === null ? 'Null' : val === undefined ? 'Undefined' : Object.prototype.toString.call(val).slice(8, -1);
  });

  /**
   * private _uniqContentEquals function.
   * That function is checking equality of 2 iterator contents with 2 assumptions
   * - iterators lengths are the same
   * - iterators values are unique
   *
   * false-positive result will be returned for comparison of, e.g.
   * - [1,2,3] and [1,2,3,4]
   * - [1,1,1] and [1,2,3]
   * */

  function _uniqContentEquals(aIterator, bIterator, stackA, stackB) {
    var a = _arrayFromIterator(aIterator);
    var b = _arrayFromIterator(bIterator);
    function eq(_a, _b) {
      return _equals(_a, _b, stackA.slice(), stackB.slice());
    }

    // if *a* array contains any element that is not included in *b*
    return !_includesWith(function (b, aItem) {
      return !_includesWith(eq, aItem, b);
    }, b, a);
  }
  function _equals(a, b, stackA, stackB) {
    if (_objectIs$1(a, b)) {
      return true;
    }
    var typeA = type(a);
    if (typeA !== type(b)) {
      return false;
    }
    if (typeof a['fantasy-land/equals'] === 'function' || typeof b['fantasy-land/equals'] === 'function') {
      return typeof a['fantasy-land/equals'] === 'function' && a['fantasy-land/equals'](b) && typeof b['fantasy-land/equals'] === 'function' && b['fantasy-land/equals'](a);
    }
    if (typeof a.equals === 'function' || typeof b.equals === 'function') {
      return typeof a.equals === 'function' && a.equals(b) && typeof b.equals === 'function' && b.equals(a);
    }
    switch (typeA) {
      case 'Arguments':
      case 'Array':
      case 'Object':
        if (typeof a.constructor === 'function' && _functionName(a.constructor) === 'Promise') {
          return a === b;
        }
        break;
      case 'Boolean':
      case 'Number':
      case 'String':
        if (!(typeof a === typeof b && _objectIs$1(a.valueOf(), b.valueOf()))) {
          return false;
        }
        break;
      case 'Date':
        if (!_objectIs$1(a.valueOf(), b.valueOf())) {
          return false;
        }
        break;
      case 'Error':
        return a.name === b.name && a.message === b.message;
      case 'RegExp':
        if (!(a.source === b.source && a.global === b.global && a.ignoreCase === b.ignoreCase && a.multiline === b.multiline && a.sticky === b.sticky && a.unicode === b.unicode)) {
          return false;
        }
        break;
    }
    var idx = stackA.length - 1;
    while (idx >= 0) {
      if (stackA[idx] === a) {
        return stackB[idx] === b;
      }
      idx -= 1;
    }
    switch (typeA) {
      case 'Map':
        if (a.size !== b.size) {
          return false;
        }
        return _uniqContentEquals(a.entries(), b.entries(), stackA.concat([a]), stackB.concat([b]));
      case 'Set':
        if (a.size !== b.size) {
          return false;
        }
        return _uniqContentEquals(a.values(), b.values(), stackA.concat([a]), stackB.concat([b]));
      case 'Arguments':
      case 'Array':
      case 'Object':
      case 'Boolean':
      case 'Number':
      case 'String':
      case 'Date':
      case 'Error':
      case 'RegExp':
      case 'Int8Array':
      case 'Uint8Array':
      case 'Uint8ClampedArray':
      case 'Int16Array':
      case 'Uint16Array':
      case 'Int32Array':
      case 'Uint32Array':
      case 'Float32Array':
      case 'Float64Array':
      case 'ArrayBuffer':
        break;
      default:
        // Values of other types are only equal if identical.
        return false;
    }
    var keysA = keys(a);
    if (keysA.length !== keys(b).length) {
      return false;
    }
    var extendedStackA = stackA.concat([a]);
    var extendedStackB = stackB.concat([b]);
    idx = keysA.length - 1;
    while (idx >= 0) {
      var key = keysA[idx];
      if (!(_has(key, b) && _equals(b[key], a[key], extendedStackA, extendedStackB))) {
        return false;
      }
      idx -= 1;
    }
    return true;
  }

  /**
   * Returns `true` if its arguments are equivalent, `false` otherwise. Handles
   * cyclical data structures.
   *
   * Dispatches symmetrically to the `equals` methods of both arguments, if
   * present.
   *
   * @func
   * @memberOf R
   * @since v0.15.0
   * @category Relation
   * @sig a -> b -> Boolean
   * @param {*} a
   * @param {*} b
   * @return {Boolean}
   * @example
   *
   *      R.equals(1, 1); //=> true
   *      R.equals(1, '1'); //=> false
   *      R.equals([1, 2, 3], [1, 2, 3]); //=> true
   *
   *      const a = {}; a.v = a;
   *      const b = {}; b.v = b;
   *      R.equals(a, b); //=> true
   */
  var equals = /*#__PURE__*/_curry2(function equals(a, b) {
    return _equals(a, b, [], []);
  });

  /**
   * Returns a function that always returns the given value. Note that for
   * non-primitives the value returned is a reference to the original value.
   *
   * This function is known as `const`, `constant`, or `K` (for K combinator) in
   * other languages and libraries.
   *
   * @func
   * @memberOf R
   * @since v0.1.0
   * @category Function
   * @sig a -> (* -> a)
   * @param {*} val The value to wrap in a function
   * @return {Function} A Function :: * -> val.
   * @example
   *
   *      const t = R.always('Tee');
   *      t(); //=> 'Tee'
   */
  var always = /*#__PURE__*/_curry1(function always(val) {
    return function () {
      return val;
    };
  });

  /**
   * A function that returns `undefined`.
   *
   * @func stubUndefined
   * @memberOf RA
   * @since {@link https://char0n.github.io/ramda-adjunct/1.0.0|v1.0.0}
   * @category Function
   * @sig ... -> undefined
   * @return {undefined}
   * @example
   *
   * RA.stubUndefined(); //=> undefined
   * RA.stubUndefined(1, 2, 3); //=> undefined
   */
  var stubUndefined = always(void 0); // eslint-disable-line no-void

  /**
   * Checks if input value is `undefined`.
   *
   * @func isUndefined
   * @memberOf RA
   * @since {@link https://char0n.github.io/ramda-adjunct/0.0.1|v0.0.1}
   * @category Type
   * @sig * -> Boolean
   * @param {*} val The value to test
   * @return {boolean}
   * @see {@link RA.isNotUndefined|isNotUndefined}
   * @example
   *
   * RA.isUndefined(1); //=> false
   * RA.isUndefined(undefined); //=> true
   * RA.isUndefined(null); //=> false
   */
  var isUndefined = equals(stubUndefined());

  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

  var minim = {};

  /**
   * Checks if `value` is `null`.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
   * @example
   *
   * _.isNull(null);
   * // => true
   *
   * _.isNull(void 0);
   * // => false
   */

  var isNull_1;
  var hasRequiredIsNull;

  function requireIsNull () {
  	if (hasRequiredIsNull) return isNull_1;
  	hasRequiredIsNull = 1;
  	function isNull(value) {
  	  return value === null;
  	}

  	isNull_1 = isNull;
  	return isNull_1;
  }

  /** Detect free variable `global` from Node.js. */

  var _freeGlobal;
  var hasRequired_freeGlobal;

  function require_freeGlobal () {
  	if (hasRequired_freeGlobal) return _freeGlobal;
  	hasRequired_freeGlobal = 1;
  	var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;

  	_freeGlobal = freeGlobal;
  	return _freeGlobal;
  }

  var _root;
  var hasRequired_root;

  function require_root () {
  	if (hasRequired_root) return _root;
  	hasRequired_root = 1;
  	var freeGlobal = require_freeGlobal();

  	/** Detect free variable `self`. */
  	var freeSelf = typeof self == 'object' && self && self.Object === Object && self;

  	/** Used as a reference to the global object. */
  	var root = freeGlobal || freeSelf || Function('return this')();

  	_root = root;
  	return _root;
  }

  var _Symbol;
  var hasRequired_Symbol;

  function require_Symbol () {
  	if (hasRequired_Symbol) return _Symbol;
  	hasRequired_Symbol = 1;
  	var root = require_root();

  	/** Built-in value references. */
  	var Symbol = root.Symbol;

  	_Symbol = Symbol;
  	return _Symbol;
  }

  var _getRawTag;
  var hasRequired_getRawTag;

  function require_getRawTag () {
  	if (hasRequired_getRawTag) return _getRawTag;
  	hasRequired_getRawTag = 1;
  	var Symbol = require_Symbol();

  	/** Used for built-in method references. */
  	var objectProto = Object.prototype;

  	/** Used to check objects for own properties. */
  	var hasOwnProperty = objectProto.hasOwnProperty;

  	/**
  	 * Used to resolve the
  	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  	 * of values.
  	 */
  	var nativeObjectToString = objectProto.toString;

  	/** Built-in value references. */
  	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;

  	/**
  	 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
  	 *
  	 * @private
  	 * @param {*} value The value to query.
  	 * @returns {string} Returns the raw `toStringTag`.
  	 */
  	function getRawTag(value) {
  	  var isOwn = hasOwnProperty.call(value, symToStringTag),
  	      tag = value[symToStringTag];

  	  try {
  	    value[symToStringTag] = undefined;
  	    var unmasked = true;
  	  } catch (e) {}

  	  var result = nativeObjectToString.call(value);
  	  if (unmasked) {
  	    if (isOwn) {
  	      value[symToStringTag] = tag;
  	    } else {
  	      delete value[symToStringTag];
  	    }
  	  }
  	  return result;
  	}

  	_getRawTag = getRawTag;
  	return _getRawTag;
  }

  /** Used for built-in method references. */

  var _objectToString;
  var hasRequired_objectToString;

  function require_objectToString () {
  	if (hasRequired_objectToString) return _objectToString;
  	hasRequired_objectToString = 1;
  	var objectProto = Object.prototype;

  	/**
  	 * Used to resolve the
  	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  	 * of values.
  	 */
  	var nativeObjectToString = objectProto.toString;

  	/**
  	 * Converts `value` to a string using `Object.prototype.toString`.
  	 *
  	 * @private
  	 * @param {*} value The value to convert.
  	 * @returns {string} Returns the converted string.
  	 */
  	function objectToString(value) {
  	  return nativeObjectToString.call(value);
  	}

  	_objectToString = objectToString;
  	return _objectToString;
  }

  var _baseGetTag;
  var hasRequired_baseGetTag;

  function require_baseGetTag () {
  	if (hasRequired_baseGetTag) return _baseGetTag;
  	hasRequired_baseGetTag = 1;
  	var Symbol = require_Symbol(),
  	    getRawTag = require_getRawTag(),
  	    objectToString = require_objectToString();

  	/** `Object#toString` result references. */
  	var nullTag = '[object Null]',
  	    undefinedTag = '[object Undefined]';

  	/** Built-in value references. */
  	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;

  	/**
  	 * The base implementation of `getTag` without fallbacks for buggy environments.
  	 *
  	 * @private
  	 * @param {*} value The value to query.
  	 * @returns {string} Returns the `toStringTag`.
  	 */
  	function baseGetTag(value) {
  	  if (value == null) {
  	    return value === undefined ? undefinedTag : nullTag;
  	  }
  	  return (symToStringTag && symToStringTag in Object(value))
  	    ? getRawTag(value)
  	    : objectToString(value);
  	}

  	_baseGetTag = baseGetTag;
  	return _baseGetTag;
  }

  /**
   * Checks if `value` is classified as an `Array` object.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is an array, else `false`.
   * @example
   *
   * _.isArray([1, 2, 3]);
   * // => true
   *
   * _.isArray(document.body.children);
   * // => false
   *
   * _.isArray('abc');
   * // => false
   *
   * _.isArray(_.noop);
   * // => false
   */

  var isArray_1;
  var hasRequiredIsArray;

  function requireIsArray () {
  	if (hasRequiredIsArray) return isArray_1;
  	hasRequiredIsArray = 1;
  	var isArray = Array.isArray;

  	isArray_1 = isArray;
  	return isArray_1;
  }

  /**
   * Checks if `value` is object-like. A value is object-like if it's not `null`
   * and has a `typeof` result of "object".
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
   * @example
   *
   * _.isObjectLike({});
   * // => true
   *
   * _.isObjectLike([1, 2, 3]);
   * // => true
   *
   * _.isObjectLike(_.noop);
   * // => false
   *
   * _.isObjectLike(null);
   * // => false
   */

  var isObjectLike_1;
  var hasRequiredIsObjectLike;

  function requireIsObjectLike () {
  	if (hasRequiredIsObjectLike) return isObjectLike_1;
  	hasRequiredIsObjectLike = 1;
  	function isObjectLike(value) {
  	  return value != null && typeof value == 'object';
  	}

  	isObjectLike_1 = isObjectLike;
  	return isObjectLike_1;
  }

  var isString_1;
  var hasRequiredIsString;

  function requireIsString () {
  	if (hasRequiredIsString) return isString_1;
  	hasRequiredIsString = 1;
  	var baseGetTag = require_baseGetTag(),
  	    isArray = requireIsArray(),
  	    isObjectLike = requireIsObjectLike();

  	/** `Object#toString` result references. */
  	var stringTag = '[object String]';

  	/**
  	 * Checks if `value` is classified as a `String` primitive or object.
  	 *
  	 * @static
  	 * @since 0.1.0
  	 * @memberOf _
  	 * @category Lang
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is a string, else `false`.
  	 * @example
  	 *
  	 * _.isString('abc');
  	 * // => true
  	 *
  	 * _.isString(1);
  	 * // => false
  	 */
  	function isString(value) {
  	  return typeof value == 'string' ||
  	    (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
  	}

  	isString_1 = isString;
  	return isString_1;
  }

  var isNumber_1;
  var hasRequiredIsNumber;

  function requireIsNumber () {
  	if (hasRequiredIsNumber) return isNumber_1;
  	hasRequiredIsNumber = 1;
  	var baseGetTag = require_baseGetTag(),
  	    isObjectLike = requireIsObjectLike();

  	/** `Object#toString` result references. */
  	var numberTag = '[object Number]';

  	/**
  	 * Checks if `value` is classified as a `Number` primitive or object.
  	 *
  	 * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
  	 * classified as numbers, use the `_.isFinite` method.
  	 *
  	 * @static
  	 * @memberOf _
  	 * @since 0.1.0
  	 * @category Lang
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is a number, else `false`.
  	 * @example
  	 *
  	 * _.isNumber(3);
  	 * // => true
  	 *
  	 * _.isNumber(Number.MIN_VALUE);
  	 * // => true
  	 *
  	 * _.isNumber(Infinity);
  	 * // => true
  	 *
  	 * _.isNumber('3');
  	 * // => false
  	 */
  	function isNumber(value) {
  	  return typeof value == 'number' ||
  	    (isObjectLike(value) && baseGetTag(value) == numberTag);
  	}

  	isNumber_1 = isNumber;
  	return isNumber_1;
  }

  var isBoolean_1;
  var hasRequiredIsBoolean;

  function requireIsBoolean () {
  	if (hasRequiredIsBoolean) return isBoolean_1;
  	hasRequiredIsBoolean = 1;
  	var baseGetTag = require_baseGetTag(),
  	    isObjectLike = requireIsObjectLike();

  	/** `Object#toString` result references. */
  	var boolTag = '[object Boolean]';

  	/**
  	 * Checks if `value` is classified as a boolean primitive or object.
  	 *
  	 * @static
  	 * @memberOf _
  	 * @since 0.1.0
  	 * @category Lang
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
  	 * @example
  	 *
  	 * _.isBoolean(false);
  	 * // => true
  	 *
  	 * _.isBoolean(null);
  	 * // => false
  	 */
  	function isBoolean(value) {
  	  return value === true || value === false ||
  	    (isObjectLike(value) && baseGetTag(value) == boolTag);
  	}

  	isBoolean_1 = isBoolean;
  	return isBoolean_1;
  }

  /**
   * Checks if `value` is the
   * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
   * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
   * @example
   *
   * _.isObject({});
   * // => true
   *
   * _.isObject([1, 2, 3]);
   * // => true
   *
   * _.isObject(_.noop);
   * // => true
   *
   * _.isObject(null);
   * // => false
   */

  var isObject_1;
  var hasRequiredIsObject;

  function requireIsObject () {
  	if (hasRequiredIsObject) return isObject_1;
  	hasRequiredIsObject = 1;
  	function isObject(value) {
  	  var type = typeof value;
  	  return value != null && (type == 'object' || type == 'function');
  	}

  	isObject_1 = isObject;
  	return isObject_1;
  }

  /**
   * @class JSONSerialiser
   *
   * @param {Namespace} namespace
   *
   * @property {Namespace} namespace
   */

  var JSONSerialiser_1;
  var hasRequiredJSONSerialiser;

  function requireJSONSerialiser () {
  	if (hasRequiredJSONSerialiser) return JSONSerialiser_1;
  	hasRequiredJSONSerialiser = 1;
  	class JSONSerialiser {
  	  constructor(namespace) {
  	    this.namespace = namespace || new this.Namespace();
  	  }

  	  /**
  	   * @param {Element} element
  	   * @returns {object}
  	   */
  	  serialise(element) {
  	    if (!(element instanceof this.namespace.elements.Element)) {
  	      throw new TypeError(`Given element \`${element}\` is not an Element instance`);
  	    }

  	    const payload = {
  	      element: element.element,
  	    };

  	    if (element._meta && element._meta.length > 0) {
  	      payload.meta = this.serialiseObject(element.meta);
  	    }

  	    if (element._attributes && element._attributes.length > 0) {
  	      payload.attributes = this.serialiseObject(element.attributes);
  	    }

  	    const content = this.serialiseContent(element.content);

  	    if (content !== undefined) {
  	      payload.content = content;
  	    }

  	    return payload;
  	  }

  	  /**
  	   * @param {object} value
  	   * @returns {Element}
  	   */
  	  deserialise(value) {
  	    if (!value.element) {
  	      throw new Error('Given value is not an object containing an element name');
  	    }

  	    const ElementClass = this.namespace.getElementClass(value.element);
  	    const element = new ElementClass();

  	    if (element.element !== value.element) {
  	      element.element = value.element;
  	    }

  	    if (value.meta) {
  	      this.deserialiseObject(value.meta, element.meta);
  	    }

  	    if (value.attributes) {
  	      this.deserialiseObject(value.attributes, element.attributes);
  	    }

  	    const content = this.deserialiseContent(value.content);
  	    if (content !== undefined || element.content === null) {
  	      element.content = content;
  	    }

  	    return element;
  	  }

  	  // Private API

  	  serialiseContent(content) {
  	    if (content instanceof this.namespace.elements.Element) {
  	      return this.serialise(content);
  	    }

  	    if (content instanceof this.namespace.KeyValuePair) {
  	      const pair = {
  	        key: this.serialise(content.key),
  	      };

  	      if (content.value) {
  	        pair.value = this.serialise(content.value);
  	      }

  	      return pair;
  	    }

  	    if (content && content.map) {
  	      if (content.length === 0) {
  	        return undefined;
  	      }

  	      return content.map(this.serialise, this);
  	    }

  	    return content;
  	  }

  	  deserialiseContent(content) {
  	    if (content) {
  	      if (content.element) {
  	        return this.deserialise(content);
  	      }

  	      if (content.key) {
  	        const pair = new this.namespace.KeyValuePair(this.deserialise(content.key));

  	        if (content.value) {
  	          pair.value = this.deserialise(content.value);
  	        }

  	        return pair;
  	      }

  	      if (content.map) {
  	        return content.map(this.deserialise, this);
  	      }
  	    }

  	    return content;
  	  }

  	  serialiseObject(obj) {
  	    const result = {};

  	    obj.forEach((value, key) => {
  	      if (value) {
  	        result[key.toValue()] = this.serialise(value);
  	      }
  	    });

  	    if (Object.keys(result).length === 0) {
  	      return undefined;
  	    }

  	    return result;
  	  }

  	  deserialiseObject(from, to) {
  	    Object.keys(from).forEach((key) => {
  	      to.set(key, this.deserialise(from[key]));
  	    });
  	  }
  	}


  	JSONSerialiser_1 = JSONSerialiser;
  	return JSONSerialiser_1;
  }

  /**
   * Removes all key-value entries from the list cache.
   *
   * @private
   * @name clear
   * @memberOf ListCache
   */

  var _listCacheClear;
  var hasRequired_listCacheClear;

  function require_listCacheClear () {
  	if (hasRequired_listCacheClear) return _listCacheClear;
  	hasRequired_listCacheClear = 1;
  	function listCacheClear() {
  	  this.__data__ = [];
  	  this.size = 0;
  	}

  	_listCacheClear = listCacheClear;
  	return _listCacheClear;
  }

  /**
   * Performs a
   * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
   * comparison between two values to determine if they are equivalent.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to compare.
   * @param {*} other The other value to compare.
   * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
   * @example
   *
   * var object = { 'a': 1 };
   * var other = { 'a': 1 };
   *
   * _.eq(object, object);
   * // => true
   *
   * _.eq(object, other);
   * // => false
   *
   * _.eq('a', 'a');
   * // => true
   *
   * _.eq('a', Object('a'));
   * // => false
   *
   * _.eq(NaN, NaN);
   * // => true
   */

  var eq_1;
  var hasRequiredEq;

  function requireEq () {
  	if (hasRequiredEq) return eq_1;
  	hasRequiredEq = 1;
  	function eq(value, other) {
  	  return value === other || (value !== value && other !== other);
  	}

  	eq_1 = eq;
  	return eq_1;
  }

  var _assocIndexOf;
  var hasRequired_assocIndexOf;

  function require_assocIndexOf () {
  	if (hasRequired_assocIndexOf) return _assocIndexOf;
  	hasRequired_assocIndexOf = 1;
  	var eq = requireEq();

  	/**
  	 * Gets the index at which the `key` is found in `array` of key-value pairs.
  	 *
  	 * @private
  	 * @param {Array} array The array to inspect.
  	 * @param {*} key The key to search for.
  	 * @returns {number} Returns the index of the matched value, else `-1`.
  	 */
  	function assocIndexOf(array, key) {
  	  var length = array.length;
  	  while (length--) {
  	    if (eq(array[length][0], key)) {
  	      return length;
  	    }
  	  }
  	  return -1;
  	}

  	_assocIndexOf = assocIndexOf;
  	return _assocIndexOf;
  }

  var _listCacheDelete;
  var hasRequired_listCacheDelete;

  function require_listCacheDelete () {
  	if (hasRequired_listCacheDelete) return _listCacheDelete;
  	hasRequired_listCacheDelete = 1;
  	var assocIndexOf = require_assocIndexOf();

  	/** Used for built-in method references. */
  	var arrayProto = Array.prototype;

  	/** Built-in value references. */
  	var splice = arrayProto.splice;

  	/**
  	 * Removes `key` and its value from the list cache.
  	 *
  	 * @private
  	 * @name delete
  	 * @memberOf ListCache
  	 * @param {string} key The key of the value to remove.
  	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  	 */
  	function listCacheDelete(key) {
  	  var data = this.__data__,
  	      index = assocIndexOf(data, key);

  	  if (index < 0) {
  	    return false;
  	  }
  	  var lastIndex = data.length - 1;
  	  if (index == lastIndex) {
  	    data.pop();
  	  } else {
  	    splice.call(data, index, 1);
  	  }
  	  --this.size;
  	  return true;
  	}

  	_listCacheDelete = listCacheDelete;
  	return _listCacheDelete;
  }

  var _listCacheGet;
  var hasRequired_listCacheGet;

  function require_listCacheGet () {
  	if (hasRequired_listCacheGet) return _listCacheGet;
  	hasRequired_listCacheGet = 1;
  	var assocIndexOf = require_assocIndexOf();

  	/**
  	 * Gets the list cache value for `key`.
  	 *
  	 * @private
  	 * @name get
  	 * @memberOf ListCache
  	 * @param {string} key The key of the value to get.
  	 * @returns {*} Returns the entry value.
  	 */
  	function listCacheGet(key) {
  	  var data = this.__data__,
  	      index = assocIndexOf(data, key);

  	  return index < 0 ? undefined : data[index][1];
  	}

  	_listCacheGet = listCacheGet;
  	return _listCacheGet;
  }

  var _listCacheHas;
  var hasRequired_listCacheHas;

  function require_listCacheHas () {
  	if (hasRequired_listCacheHas) return _listCacheHas;
  	hasRequired_listCacheHas = 1;
  	var assocIndexOf = require_assocIndexOf();

  	/**
  	 * Checks if a list cache value for `key` exists.
  	 *
  	 * @private
  	 * @name has
  	 * @memberOf ListCache
  	 * @param {string} key The key of the entry to check.
  	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  	 */
  	function listCacheHas(key) {
  	  return assocIndexOf(this.__data__, key) > -1;
  	}

  	_listCacheHas = listCacheHas;
  	return _listCacheHas;
  }

  var _listCacheSet;
  var hasRequired_listCacheSet;

  function require_listCacheSet () {
  	if (hasRequired_listCacheSet) return _listCacheSet;
  	hasRequired_listCacheSet = 1;
  	var assocIndexOf = require_assocIndexOf();

  	/**
  	 * Sets the list cache `key` to `value`.
  	 *
  	 * @private
  	 * @name set
  	 * @memberOf ListCache
  	 * @param {string} key The key of the value to set.
  	 * @param {*} value The value to set.
  	 * @returns {Object} Returns the list cache instance.
  	 */
  	function listCacheSet(key, value) {
  	  var data = this.__data__,
  	      index = assocIndexOf(data, key);

  	  if (index < 0) {
  	    ++this.size;
  	    data.push([key, value]);
  	  } else {
  	    data[index][1] = value;
  	  }
  	  return this;
  	}

  	_listCacheSet = listCacheSet;
  	return _listCacheSet;
  }

  var _ListCache;
  var hasRequired_ListCache;

  function require_ListCache () {
  	if (hasRequired_ListCache) return _ListCache;
  	hasRequired_ListCache = 1;
  	var listCacheClear = require_listCacheClear(),
  	    listCacheDelete = require_listCacheDelete(),
  	    listCacheGet = require_listCacheGet(),
  	    listCacheHas = require_listCacheHas(),
  	    listCacheSet = require_listCacheSet();

  	/**
  	 * Creates an list cache object.
  	 *
  	 * @private
  	 * @constructor
  	 * @param {Array} [entries] The key-value pairs to cache.
  	 */
  	function ListCache(entries) {
  	  var index = -1,
  	      length = entries == null ? 0 : entries.length;

  	  this.clear();
  	  while (++index < length) {
  	    var entry = entries[index];
  	    this.set(entry[0], entry[1]);
  	  }
  	}

  	// Add methods to `ListCache`.
  	ListCache.prototype.clear = listCacheClear;
  	ListCache.prototype['delete'] = listCacheDelete;
  	ListCache.prototype.get = listCacheGet;
  	ListCache.prototype.has = listCacheHas;
  	ListCache.prototype.set = listCacheSet;

  	_ListCache = ListCache;
  	return _ListCache;
  }

  var _stackClear;
  var hasRequired_stackClear;

  function require_stackClear () {
  	if (hasRequired_stackClear) return _stackClear;
  	hasRequired_stackClear = 1;
  	var ListCache = require_ListCache();

  	/**
  	 * Removes all key-value entries from the stack.
  	 *
  	 * @private
  	 * @name clear
  	 * @memberOf Stack
  	 */
  	function stackClear() {
  	  this.__data__ = new ListCache;
  	  this.size = 0;
  	}

  	_stackClear = stackClear;
  	return _stackClear;
  }

  /**
   * Removes `key` and its value from the stack.
   *
   * @private
   * @name delete
   * @memberOf Stack
   * @param {string} key The key of the value to remove.
   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
   */

  var _stackDelete;
  var hasRequired_stackDelete;

  function require_stackDelete () {
  	if (hasRequired_stackDelete) return _stackDelete;
  	hasRequired_stackDelete = 1;
  	function stackDelete(key) {
  	  var data = this.__data__,
  	      result = data['delete'](key);

  	  this.size = data.size;
  	  return result;
  	}

  	_stackDelete = stackDelete;
  	return _stackDelete;
  }

  /**
   * Gets the stack value for `key`.
   *
   * @private
   * @name get
   * @memberOf Stack
   * @param {string} key The key of the value to get.
   * @returns {*} Returns the entry value.
   */

  var _stackGet;
  var hasRequired_stackGet;

  function require_stackGet () {
  	if (hasRequired_stackGet) return _stackGet;
  	hasRequired_stackGet = 1;
  	function stackGet(key) {
  	  return this.__data__.get(key);
  	}

  	_stackGet = stackGet;
  	return _stackGet;
  }

  /**
   * Checks if a stack value for `key` exists.
   *
   * @private
   * @name has
   * @memberOf Stack
   * @param {string} key The key of the entry to check.
   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
   */

  var _stackHas;
  var hasRequired_stackHas;

  function require_stackHas () {
  	if (hasRequired_stackHas) return _stackHas;
  	hasRequired_stackHas = 1;
  	function stackHas(key) {
  	  return this.__data__.has(key);
  	}

  	_stackHas = stackHas;
  	return _stackHas;
  }

  var isFunction_1;
  var hasRequiredIsFunction;

  function requireIsFunction () {
  	if (hasRequiredIsFunction) return isFunction_1;
  	hasRequiredIsFunction = 1;
  	var baseGetTag = require_baseGetTag(),
  	    isObject = requireIsObject();

  	/** `Object#toString` result references. */
  	var asyncTag = '[object AsyncFunction]',
  	    funcTag = '[object Function]',
  	    genTag = '[object GeneratorFunction]',
  	    proxyTag = '[object Proxy]';

  	/**
  	 * Checks if `value` is classified as a `Function` object.
  	 *
  	 * @static
  	 * @memberOf _
  	 * @since 0.1.0
  	 * @category Lang
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
  	 * @example
  	 *
  	 * _.isFunction(_);
  	 * // => true
  	 *
  	 * _.isFunction(/abc/);
  	 * // => false
  	 */
  	function isFunction(value) {
  	  if (!isObject(value)) {
  	    return false;
  	  }
  	  // The use of `Object#toString` avoids issues with the `typeof` operator
  	  // in Safari 9 which returns 'object' for typed arrays and other constructors.
  	  var tag = baseGetTag(value);
  	  return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
  	}

  	isFunction_1 = isFunction;
  	return isFunction_1;
  }

  var _coreJsData;
  var hasRequired_coreJsData;

  function require_coreJsData () {
  	if (hasRequired_coreJsData) return _coreJsData;
  	hasRequired_coreJsData = 1;
  	var root = require_root();

  	/** Used to detect overreaching core-js shims. */
  	var coreJsData = root['__core-js_shared__'];

  	_coreJsData = coreJsData;
  	return _coreJsData;
  }

  var _isMasked;
  var hasRequired_isMasked;

  function require_isMasked () {
  	if (hasRequired_isMasked) return _isMasked;
  	hasRequired_isMasked = 1;
  	var coreJsData = require_coreJsData();

  	/** Used to detect methods masquerading as native. */
  	var maskSrcKey = (function() {
  	  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
  	  return uid ? ('Symbol(src)_1.' + uid) : '';
  	}());

  	/**
  	 * Checks if `func` has its source masked.
  	 *
  	 * @private
  	 * @param {Function} func The function to check.
  	 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
  	 */
  	function isMasked(func) {
  	  return !!maskSrcKey && (maskSrcKey in func);
  	}

  	_isMasked = isMasked;
  	return _isMasked;
  }

  /** Used for built-in method references. */

  var _toSource;
  var hasRequired_toSource;

  function require_toSource () {
  	if (hasRequired_toSource) return _toSource;
  	hasRequired_toSource = 1;
  	var funcProto = Function.prototype;

  	/** Used to resolve the decompiled source of functions. */
  	var funcToString = funcProto.toString;

  	/**
  	 * Converts `func` to its source code.
  	 *
  	 * @private
  	 * @param {Function} func The function to convert.
  	 * @returns {string} Returns the source code.
  	 */
  	function toSource(func) {
  	  if (func != null) {
  	    try {
  	      return funcToString.call(func);
  	    } catch (e) {}
  	    try {
  	      return (func + '');
  	    } catch (e) {}
  	  }
  	  return '';
  	}

  	_toSource = toSource;
  	return _toSource;
  }

  var _baseIsNative;
  var hasRequired_baseIsNative;

  function require_baseIsNative () {
  	if (hasRequired_baseIsNative) return _baseIsNative;
  	hasRequired_baseIsNative = 1;
  	var isFunction = requireIsFunction(),
  	    isMasked = require_isMasked(),
  	    isObject = requireIsObject(),
  	    toSource = require_toSource();

  	/**
  	 * Used to match `RegExp`
  	 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
  	 */
  	var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;

  	/** Used to detect host constructors (Safari). */
  	var reIsHostCtor = /^\[object .+?Constructor\]$/;

  	/** Used for built-in method references. */
  	var funcProto = Function.prototype,
  	    objectProto = Object.prototype;

  	/** Used to resolve the decompiled source of functions. */
  	var funcToString = funcProto.toString;

  	/** Used to check objects for own properties. */
  	var hasOwnProperty = objectProto.hasOwnProperty;

  	/** Used to detect if a method is native. */
  	var reIsNative = RegExp('^' +
  	  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
  	  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  	);

  	/**
  	 * The base implementation of `_.isNative` without bad shim checks.
  	 *
  	 * @private
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is a native function,
  	 *  else `false`.
  	 */
  	function baseIsNative(value) {
  	  if (!isObject(value) || isMasked(value)) {
  	    return false;
  	  }
  	  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
  	  return pattern.test(toSource(value));
  	}

  	_baseIsNative = baseIsNative;
  	return _baseIsNative;
  }

  /**
   * Gets the value at `key` of `object`.
   *
   * @private
   * @param {Object} [object] The object to query.
   * @param {string} key The key of the property to get.
   * @returns {*} Returns the property value.
   */

  var _getValue;
  var hasRequired_getValue;

  function require_getValue () {
  	if (hasRequired_getValue) return _getValue;
  	hasRequired_getValue = 1;
  	function getValue(object, key) {
  	  return object == null ? undefined : object[key];
  	}

  	_getValue = getValue;
  	return _getValue;
  }

  var _getNative;
  var hasRequired_getNative;

  function require_getNative () {
  	if (hasRequired_getNative) return _getNative;
  	hasRequired_getNative = 1;
  	var baseIsNative = require_baseIsNative(),
  	    getValue = require_getValue();

  	/**
  	 * Gets the native function at `key` of `object`.
  	 *
  	 * @private
  	 * @param {Object} object The object to query.
  	 * @param {string} key The key of the method to get.
  	 * @returns {*} Returns the function if it's native, else `undefined`.
  	 */
  	function getNative(object, key) {
  	  var value = getValue(object, key);
  	  return baseIsNative(value) ? value : undefined;
  	}

  	_getNative = getNative;
  	return _getNative;
  }

  var _Map;
  var hasRequired_Map;

  function require_Map () {
  	if (hasRequired_Map) return _Map;
  	hasRequired_Map = 1;
  	var getNative = require_getNative(),
  	    root = require_root();

  	/* Built-in method references that are verified to be native. */
  	var Map = getNative(root, 'Map');

  	_Map = Map;
  	return _Map;
  }

  var _nativeCreate;
  var hasRequired_nativeCreate;

  function require_nativeCreate () {
  	if (hasRequired_nativeCreate) return _nativeCreate;
  	hasRequired_nativeCreate = 1;
  	var getNative = require_getNative();

  	/* Built-in method references that are verified to be native. */
  	var nativeCreate = getNative(Object, 'create');

  	_nativeCreate = nativeCreate;
  	return _nativeCreate;
  }

  var _hashClear;
  var hasRequired_hashClear;

  function require_hashClear () {
  	if (hasRequired_hashClear) return _hashClear;
  	hasRequired_hashClear = 1;
  	var nativeCreate = require_nativeCreate();

  	/**
  	 * Removes all key-value entries from the hash.
  	 *
  	 * @private
  	 * @name clear
  	 * @memberOf Hash
  	 */
  	function hashClear() {
  	  this.__data__ = nativeCreate ? nativeCreate(null) : {};
  	  this.size = 0;
  	}

  	_hashClear = hashClear;
  	return _hashClear;
  }

  /**
   * Removes `key` and its value from the hash.
   *
   * @private
   * @name delete
   * @memberOf Hash
   * @param {Object} hash The hash to modify.
   * @param {string} key The key of the value to remove.
   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
   */

  var _hashDelete;
  var hasRequired_hashDelete;

  function require_hashDelete () {
  	if (hasRequired_hashDelete) return _hashDelete;
  	hasRequired_hashDelete = 1;
  	function hashDelete(key) {
  	  var result = this.has(key) && delete this.__data__[key];
  	  this.size -= result ? 1 : 0;
  	  return result;
  	}

  	_hashDelete = hashDelete;
  	return _hashDelete;
  }

  var _hashGet;
  var hasRequired_hashGet;

  function require_hashGet () {
  	if (hasRequired_hashGet) return _hashGet;
  	hasRequired_hashGet = 1;
  	var nativeCreate = require_nativeCreate();

  	/** Used to stand-in for `undefined` hash values. */
  	var HASH_UNDEFINED = '__lodash_hash_undefined__';

  	/** Used for built-in method references. */
  	var objectProto = Object.prototype;

  	/** Used to check objects for own properties. */
  	var hasOwnProperty = objectProto.hasOwnProperty;

  	/**
  	 * Gets the hash value for `key`.
  	 *
  	 * @private
  	 * @name get
  	 * @memberOf Hash
  	 * @param {string} key The key of the value to get.
  	 * @returns {*} Returns the entry value.
  	 */
  	function hashGet(key) {
  	  var data = this.__data__;
  	  if (nativeCreate) {
  	    var result = data[key];
  	    return result === HASH_UNDEFINED ? undefined : result;
  	  }
  	  return hasOwnProperty.call(data, key) ? data[key] : undefined;
  	}

  	_hashGet = hashGet;
  	return _hashGet;
  }

  var _hashHas;
  var hasRequired_hashHas;

  function require_hashHas () {
  	if (hasRequired_hashHas) return _hashHas;
  	hasRequired_hashHas = 1;
  	var nativeCreate = require_nativeCreate();

  	/** Used for built-in method references. */
  	var objectProto = Object.prototype;

  	/** Used to check objects for own properties. */
  	var hasOwnProperty = objectProto.hasOwnProperty;

  	/**
  	 * Checks if a hash value for `key` exists.
  	 *
  	 * @private
  	 * @name has
  	 * @memberOf Hash
  	 * @param {string} key The key of the entry to check.
  	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  	 */
  	function hashHas(key) {
  	  var data = this.__data__;
  	  return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
  	}

  	_hashHas = hashHas;
  	return _hashHas;
  }

  var _hashSet;
  var hasRequired_hashSet;

  function require_hashSet () {
  	if (hasRequired_hashSet) return _hashSet;
  	hasRequired_hashSet = 1;
  	var nativeCreate = require_nativeCreate();

  	/** Used to stand-in for `undefined` hash values. */
  	var HASH_UNDEFINED = '__lodash_hash_undefined__';

  	/**
  	 * Sets the hash `key` to `value`.
  	 *
  	 * @private
  	 * @name set
  	 * @memberOf Hash
  	 * @param {string} key The key of the value to set.
  	 * @param {*} value The value to set.
  	 * @returns {Object} Returns the hash instance.
  	 */
  	function hashSet(key, value) {
  	  var data = this.__data__;
  	  this.size += this.has(key) ? 0 : 1;
  	  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
  	  return this;
  	}

  	_hashSet = hashSet;
  	return _hashSet;
  }

  var _Hash;
  var hasRequired_Hash;

  function require_Hash () {
  	if (hasRequired_Hash) return _Hash;
  	hasRequired_Hash = 1;
  	var hashClear = require_hashClear(),
  	    hashDelete = require_hashDelete(),
  	    hashGet = require_hashGet(),
  	    hashHas = require_hashHas(),
  	    hashSet = require_hashSet();

  	/**
  	 * Creates a hash object.
  	 *
  	 * @private
  	 * @constructor
  	 * @param {Array} [entries] The key-value pairs to cache.
  	 */
  	function Hash(entries) {
  	  var index = -1,
  	      length = entries == null ? 0 : entries.length;

  	  this.clear();
  	  while (++index < length) {
  	    var entry = entries[index];
  	    this.set(entry[0], entry[1]);
  	  }
  	}

  	// Add methods to `Hash`.
  	Hash.prototype.clear = hashClear;
  	Hash.prototype['delete'] = hashDelete;
  	Hash.prototype.get = hashGet;
  	Hash.prototype.has = hashHas;
  	Hash.prototype.set = hashSet;

  	_Hash = Hash;
  	return _Hash;
  }

  var _mapCacheClear;
  var hasRequired_mapCacheClear;

  function require_mapCacheClear () {
  	if (hasRequired_mapCacheClear) return _mapCacheClear;
  	hasRequired_mapCacheClear = 1;
  	var Hash = require_Hash(),
  	    ListCache = require_ListCache(),
  	    Map = require_Map();

  	/**
  	 * Removes all key-value entries from the map.
  	 *
  	 * @private
  	 * @name clear
  	 * @memberOf MapCache
  	 */
  	function mapCacheClear() {
  	  this.size = 0;
  	  this.__data__ = {
  	    'hash': new Hash,
  	    'map': new (Map || ListCache),
  	    'string': new Hash
  	  };
  	}

  	_mapCacheClear = mapCacheClear;
  	return _mapCacheClear;
  }

  /**
   * Checks if `value` is suitable for use as unique object key.
   *
   * @private
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
   */

  var _isKeyable;
  var hasRequired_isKeyable;

  function require_isKeyable () {
  	if (hasRequired_isKeyable) return _isKeyable;
  	hasRequired_isKeyable = 1;
  	function isKeyable(value) {
  	  var type = typeof value;
  	  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
  	    ? (value !== '__proto__')
  	    : (value === null);
  	}

  	_isKeyable = isKeyable;
  	return _isKeyable;
  }

  var _getMapData;
  var hasRequired_getMapData;

  function require_getMapData () {
  	if (hasRequired_getMapData) return _getMapData;
  	hasRequired_getMapData = 1;
  	var isKeyable = require_isKeyable();

  	/**
  	 * Gets the data for `map`.
  	 *
  	 * @private
  	 * @param {Object} map The map to query.
  	 * @param {string} key The reference key.
  	 * @returns {*} Returns the map data.
  	 */
  	function getMapData(map, key) {
  	  var data = map.__data__;
  	  return isKeyable(key)
  	    ? data[typeof key == 'string' ? 'string' : 'hash']
  	    : data.map;
  	}

  	_getMapData = getMapData;
  	return _getMapData;
  }

  var _mapCacheDelete;
  var hasRequired_mapCacheDelete;

  function require_mapCacheDelete () {
  	if (hasRequired_mapCacheDelete) return _mapCacheDelete;
  	hasRequired_mapCacheDelete = 1;
  	var getMapData = require_getMapData();

  	/**
  	 * Removes `key` and its value from the map.
  	 *
  	 * @private
  	 * @name delete
  	 * @memberOf MapCache
  	 * @param {string} key The key of the value to remove.
  	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  	 */
  	function mapCacheDelete(key) {
  	  var result = getMapData(this, key)['delete'](key);
  	  this.size -= result ? 1 : 0;
  	  return result;
  	}

  	_mapCacheDelete = mapCacheDelete;
  	return _mapCacheDelete;
  }

  var _mapCacheGet;
  var hasRequired_mapCacheGet;

  function require_mapCacheGet () {
  	if (hasRequired_mapCacheGet) return _mapCacheGet;
  	hasRequired_mapCacheGet = 1;
  	var getMapData = require_getMapData();

  	/**
  	 * Gets the map value for `key`.
  	 *
  	 * @private
  	 * @name get
  	 * @memberOf MapCache
  	 * @param {string} key The key of the value to get.
  	 * @returns {*} Returns the entry value.
  	 */
  	function mapCacheGet(key) {
  	  return getMapData(this, key).get(key);
  	}

  	_mapCacheGet = mapCacheGet;
  	return _mapCacheGet;
  }

  var _mapCacheHas;
  var hasRequired_mapCacheHas;

  function require_mapCacheHas () {
  	if (hasRequired_mapCacheHas) return _mapCacheHas;
  	hasRequired_mapCacheHas = 1;
  	var getMapData = require_getMapData();

  	/**
  	 * Checks if a map value for `key` exists.
  	 *
  	 * @private
  	 * @name has
  	 * @memberOf MapCache
  	 * @param {string} key The key of the entry to check.
  	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  	 */
  	function mapCacheHas(key) {
  	  return getMapData(this, key).has(key);
  	}

  	_mapCacheHas = mapCacheHas;
  	return _mapCacheHas;
  }

  var _mapCacheSet;
  var hasRequired_mapCacheSet;

  function require_mapCacheSet () {
  	if (hasRequired_mapCacheSet) return _mapCacheSet;
  	hasRequired_mapCacheSet = 1;
  	var getMapData = require_getMapData();

  	/**
  	 * Sets the map `key` to `value`.
  	 *
  	 * @private
  	 * @name set
  	 * @memberOf MapCache
  	 * @param {string} key The key of the value to set.
  	 * @param {*} value The value to set.
  	 * @returns {Object} Returns the map cache instance.
  	 */
  	function mapCacheSet(key, value) {
  	  var data = getMapData(this, key),
  	      size = data.size;

  	  data.set(key, value);
  	  this.size += data.size == size ? 0 : 1;
  	  return this;
  	}

  	_mapCacheSet = mapCacheSet;
  	return _mapCacheSet;
  }

  var _MapCache;
  var hasRequired_MapCache;

  function require_MapCache () {
  	if (hasRequired_MapCache) return _MapCache;
  	hasRequired_MapCache = 1;
  	var mapCacheClear = require_mapCacheClear(),
  	    mapCacheDelete = require_mapCacheDelete(),
  	    mapCacheGet = require_mapCacheGet(),
  	    mapCacheHas = require_mapCacheHas(),
  	    mapCacheSet = require_mapCacheSet();

  	/**
  	 * Creates a map cache object to store key-value pairs.
  	 *
  	 * @private
  	 * @constructor
  	 * @param {Array} [entries] The key-value pairs to cache.
  	 */
  	function MapCache(entries) {
  	  var index = -1,
  	      length = entries == null ? 0 : entries.length;

  	  this.clear();
  	  while (++index < length) {
  	    var entry = entries[index];
  	    this.set(entry[0], entry[1]);
  	  }
  	}

  	// Add methods to `MapCache`.
  	MapCache.prototype.clear = mapCacheClear;
  	MapCache.prototype['delete'] = mapCacheDelete;
  	MapCache.prototype.get = mapCacheGet;
  	MapCache.prototype.has = mapCacheHas;
  	MapCache.prototype.set = mapCacheSet;

  	_MapCache = MapCache;
  	return _MapCache;
  }

  var _stackSet;
  var hasRequired_stackSet;

  function require_stackSet () {
  	if (hasRequired_stackSet) return _stackSet;
  	hasRequired_stackSet = 1;
  	var ListCache = require_ListCache(),
  	    Map = require_Map(),
  	    MapCache = require_MapCache();

  	/** Used as the size to enable large array optimizations. */
  	var LARGE_ARRAY_SIZE = 200;

  	/**
  	 * Sets the stack `key` to `value`.
  	 *
  	 * @private
  	 * @name set
  	 * @memberOf Stack
  	 * @param {string} key The key of the value to set.
  	 * @param {*} value The value to set.
  	 * @returns {Object} Returns the stack cache instance.
  	 */
  	function stackSet(key, value) {
  	  var data = this.__data__;
  	  if (data instanceof ListCache) {
  	    var pairs = data.__data__;
  	    if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
  	      pairs.push([key, value]);
  	      this.size = ++data.size;
  	      return this;
  	    }
  	    data = this.__data__ = new MapCache(pairs);
  	  }
  	  data.set(key, value);
  	  this.size = data.size;
  	  return this;
  	}

  	_stackSet = stackSet;
  	return _stackSet;
  }

  var _Stack;
  var hasRequired_Stack;

  function require_Stack () {
  	if (hasRequired_Stack) return _Stack;
  	hasRequired_Stack = 1;
  	var ListCache = require_ListCache(),
  	    stackClear = require_stackClear(),
  	    stackDelete = require_stackDelete(),
  	    stackGet = require_stackGet(),
  	    stackHas = require_stackHas(),
  	    stackSet = require_stackSet();

  	/**
  	 * Creates a stack cache object to store key-value pairs.
  	 *
  	 * @private
  	 * @constructor
  	 * @param {Array} [entries] The key-value pairs to cache.
  	 */
  	function Stack(entries) {
  	  var data = this.__data__ = new ListCache(entries);
  	  this.size = data.size;
  	}

  	// Add methods to `Stack`.
  	Stack.prototype.clear = stackClear;
  	Stack.prototype['delete'] = stackDelete;
  	Stack.prototype.get = stackGet;
  	Stack.prototype.has = stackHas;
  	Stack.prototype.set = stackSet;

  	_Stack = Stack;
  	return _Stack;
  }

  /** Used to stand-in for `undefined` hash values. */

  var _setCacheAdd;
  var hasRequired_setCacheAdd;

  function require_setCacheAdd () {
  	if (hasRequired_setCacheAdd) return _setCacheAdd;
  	hasRequired_setCacheAdd = 1;
  	var HASH_UNDEFINED = '__lodash_hash_undefined__';

  	/**
  	 * Adds `value` to the array cache.
  	 *
  	 * @private
  	 * @name add
  	 * @memberOf SetCache
  	 * @alias push
  	 * @param {*} value The value to cache.
  	 * @returns {Object} Returns the cache instance.
  	 */
  	function setCacheAdd(value) {
  	  this.__data__.set(value, HASH_UNDEFINED);
  	  return this;
  	}

  	_setCacheAdd = setCacheAdd;
  	return _setCacheAdd;
  }

  /**
   * Checks if `value` is in the array cache.
   *
   * @private
   * @name has
   * @memberOf SetCache
   * @param {*} value The value to search for.
   * @returns {boolean} Returns `true` if `value` is found, else `false`.
   */

  var _setCacheHas;
  var hasRequired_setCacheHas;

  function require_setCacheHas () {
  	if (hasRequired_setCacheHas) return _setCacheHas;
  	hasRequired_setCacheHas = 1;
  	function setCacheHas(value) {
  	  return this.__data__.has(value);
  	}

  	_setCacheHas = setCacheHas;
  	return _setCacheHas;
  }

  var _SetCache;
  var hasRequired_SetCache;

  function require_SetCache () {
  	if (hasRequired_SetCache) return _SetCache;
  	hasRequired_SetCache = 1;
  	var MapCache = require_MapCache(),
  	    setCacheAdd = require_setCacheAdd(),
  	    setCacheHas = require_setCacheHas();

  	/**
  	 *
  	 * Creates an array cache object to store unique values.
  	 *
  	 * @private
  	 * @constructor
  	 * @param {Array} [values] The values to cache.
  	 */
  	function SetCache(values) {
  	  var index = -1,
  	      length = values == null ? 0 : values.length;

  	  this.__data__ = new MapCache;
  	  while (++index < length) {
  	    this.add(values[index]);
  	  }
  	}

  	// Add methods to `SetCache`.
  	SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
  	SetCache.prototype.has = setCacheHas;

  	_SetCache = SetCache;
  	return _SetCache;
  }

  /**
   * A specialized version of `_.some` for arrays without support for iteratee
   * shorthands.
   *
   * @private
   * @param {Array} [array] The array to iterate over.
   * @param {Function} predicate The function invoked per iteration.
   * @returns {boolean} Returns `true` if any element passes the predicate check,
   *  else `false`.
   */

  var _arraySome;
  var hasRequired_arraySome;

  function require_arraySome () {
  	if (hasRequired_arraySome) return _arraySome;
  	hasRequired_arraySome = 1;
  	function arraySome(array, predicate) {
  	  var index = -1,
  	      length = array == null ? 0 : array.length;

  	  while (++index < length) {
  	    if (predicate(array[index], index, array)) {
  	      return true;
  	    }
  	  }
  	  return false;
  	}

  	_arraySome = arraySome;
  	return _arraySome;
  }

  /**
   * Checks if a `cache` value for `key` exists.
   *
   * @private
   * @param {Object} cache The cache to query.
   * @param {string} key The key of the entry to check.
   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
   */

  var _cacheHas;
  var hasRequired_cacheHas;

  function require_cacheHas () {
  	if (hasRequired_cacheHas) return _cacheHas;
  	hasRequired_cacheHas = 1;
  	function cacheHas(cache, key) {
  	  return cache.has(key);
  	}

  	_cacheHas = cacheHas;
  	return _cacheHas;
  }

  var _equalArrays;
  var hasRequired_equalArrays;

  function require_equalArrays () {
  	if (hasRequired_equalArrays) return _equalArrays;
  	hasRequired_equalArrays = 1;
  	var SetCache = require_SetCache(),
  	    arraySome = require_arraySome(),
  	    cacheHas = require_cacheHas();

  	/** Used to compose bitmasks for value comparisons. */
  	var COMPARE_PARTIAL_FLAG = 1,
  	    COMPARE_UNORDERED_FLAG = 2;

  	/**
  	 * A specialized version of `baseIsEqualDeep` for arrays with support for
  	 * partial deep comparisons.
  	 *
  	 * @private
  	 * @param {Array} array The array to compare.
  	 * @param {Array} other The other array to compare.
  	 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  	 * @param {Function} customizer The function to customize comparisons.
  	 * @param {Function} equalFunc The function to determine equivalents of values.
  	 * @param {Object} stack Tracks traversed `array` and `other` objects.
  	 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
  	 */
  	function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
  	  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
  	      arrLength = array.length,
  	      othLength = other.length;

  	  if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
  	    return false;
  	  }
  	  // Check that cyclic values are equal.
  	  var arrStacked = stack.get(array);
  	  var othStacked = stack.get(other);
  	  if (arrStacked && othStacked) {
  	    return arrStacked == other && othStacked == array;
  	  }
  	  var index = -1,
  	      result = true,
  	      seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;

  	  stack.set(array, other);
  	  stack.set(other, array);

  	  // Ignore non-index properties.
  	  while (++index < arrLength) {
  	    var arrValue = array[index],
  	        othValue = other[index];

  	    if (customizer) {
  	      var compared = isPartial
  	        ? customizer(othValue, arrValue, index, other, array, stack)
  	        : customizer(arrValue, othValue, index, array, other, stack);
  	    }
  	    if (compared !== undefined) {
  	      if (compared) {
  	        continue;
  	      }
  	      result = false;
  	      break;
  	    }
  	    // Recursively compare arrays (susceptible to call stack limits).
  	    if (seen) {
  	      if (!arraySome(other, function(othValue, othIndex) {
  	            if (!cacheHas(seen, othIndex) &&
  	                (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
  	              return seen.push(othIndex);
  	            }
  	          })) {
  	        result = false;
  	        break;
  	      }
  	    } else if (!(
  	          arrValue === othValue ||
  	            equalFunc(arrValue, othValue, bitmask, customizer, stack)
  	        )) {
  	      result = false;
  	      break;
  	    }
  	  }
  	  stack['delete'](array);
  	  stack['delete'](other);
  	  return result;
  	}

  	_equalArrays = equalArrays;
  	return _equalArrays;
  }

  var _Uint8Array;
  var hasRequired_Uint8Array;

  function require_Uint8Array () {
  	if (hasRequired_Uint8Array) return _Uint8Array;
  	hasRequired_Uint8Array = 1;
  	var root = require_root();

  	/** Built-in value references. */
  	var Uint8Array = root.Uint8Array;

  	_Uint8Array = Uint8Array;
  	return _Uint8Array;
  }

  /**
   * Converts `map` to its key-value pairs.
   *
   * @private
   * @param {Object} map The map to convert.
   * @returns {Array} Returns the key-value pairs.
   */

  var _mapToArray;
  var hasRequired_mapToArray;

  function require_mapToArray () {
  	if (hasRequired_mapToArray) return _mapToArray;
  	hasRequired_mapToArray = 1;
  	function mapToArray(map) {
  	  var index = -1,
  	      result = Array(map.size);

  	  map.forEach(function(value, key) {
  	    result[++index] = [key, value];
  	  });
  	  return result;
  	}

  	_mapToArray = mapToArray;
  	return _mapToArray;
  }

  /**
   * Converts `set` to an array of its values.
   *
   * @private
   * @param {Object} set The set to convert.
   * @returns {Array} Returns the values.
   */

  var _setToArray;
  var hasRequired_setToArray;

  function require_setToArray () {
  	if (hasRequired_setToArray) return _setToArray;
  	hasRequired_setToArray = 1;
  	function setToArray(set) {
  	  var index = -1,
  	      result = Array(set.size);

  	  set.forEach(function(value) {
  	    result[++index] = value;
  	  });
  	  return result;
  	}

  	_setToArray = setToArray;
  	return _setToArray;
  }

  var _equalByTag;
  var hasRequired_equalByTag;

  function require_equalByTag () {
  	if (hasRequired_equalByTag) return _equalByTag;
  	hasRequired_equalByTag = 1;
  	var Symbol = require_Symbol(),
  	    Uint8Array = require_Uint8Array(),
  	    eq = requireEq(),
  	    equalArrays = require_equalArrays(),
  	    mapToArray = require_mapToArray(),
  	    setToArray = require_setToArray();

  	/** Used to compose bitmasks for value comparisons. */
  	var COMPARE_PARTIAL_FLAG = 1,
  	    COMPARE_UNORDERED_FLAG = 2;

  	/** `Object#toString` result references. */
  	var boolTag = '[object Boolean]',
  	    dateTag = '[object Date]',
  	    errorTag = '[object Error]',
  	    mapTag = '[object Map]',
  	    numberTag = '[object Number]',
  	    regexpTag = '[object RegExp]',
  	    setTag = '[object Set]',
  	    stringTag = '[object String]',
  	    symbolTag = '[object Symbol]';

  	var arrayBufferTag = '[object ArrayBuffer]',
  	    dataViewTag = '[object DataView]';

  	/** Used to convert symbols to primitives and strings. */
  	var symbolProto = Symbol ? Symbol.prototype : undefined,
  	    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;

  	/**
  	 * A specialized version of `baseIsEqualDeep` for comparing objects of
  	 * the same `toStringTag`.
  	 *
  	 * **Note:** This function only supports comparing values with tags of
  	 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
  	 *
  	 * @private
  	 * @param {Object} object The object to compare.
  	 * @param {Object} other The other object to compare.
  	 * @param {string} tag The `toStringTag` of the objects to compare.
  	 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  	 * @param {Function} customizer The function to customize comparisons.
  	 * @param {Function} equalFunc The function to determine equivalents of values.
  	 * @param {Object} stack Tracks traversed `object` and `other` objects.
  	 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  	 */
  	function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
  	  switch (tag) {
  	    case dataViewTag:
  	      if ((object.byteLength != other.byteLength) ||
  	          (object.byteOffset != other.byteOffset)) {
  	        return false;
  	      }
  	      object = object.buffer;
  	      other = other.buffer;

  	    case arrayBufferTag:
  	      if ((object.byteLength != other.byteLength) ||
  	          !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
  	        return false;
  	      }
  	      return true;

  	    case boolTag:
  	    case dateTag:
  	    case numberTag:
  	      // Coerce booleans to `1` or `0` and dates to milliseconds.
  	      // Invalid dates are coerced to `NaN`.
  	      return eq(+object, +other);

  	    case errorTag:
  	      return object.name == other.name && object.message == other.message;

  	    case regexpTag:
  	    case stringTag:
  	      // Coerce regexes to strings and treat strings, primitives and objects,
  	      // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
  	      // for more details.
  	      return object == (other + '');

  	    case mapTag:
  	      var convert = mapToArray;

  	    case setTag:
  	      var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
  	      convert || (convert = setToArray);

  	      if (object.size != other.size && !isPartial) {
  	        return false;
  	      }
  	      // Assume cyclic values are equal.
  	      var stacked = stack.get(object);
  	      if (stacked) {
  	        return stacked == other;
  	      }
  	      bitmask |= COMPARE_UNORDERED_FLAG;

  	      // Recursively compare objects (susceptible to call stack limits).
  	      stack.set(object, other);
  	      var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
  	      stack['delete'](object);
  	      return result;

  	    case symbolTag:
  	      if (symbolValueOf) {
  	        return symbolValueOf.call(object) == symbolValueOf.call(other);
  	      }
  	  }
  	  return false;
  	}

  	_equalByTag = equalByTag;
  	return _equalByTag;
  }

  /**
   * Appends the elements of `values` to `array`.
   *
   * @private
   * @param {Array} array The array to modify.
   * @param {Array} values The values to append.
   * @returns {Array} Returns `array`.
   */

  var _arrayPush;
  var hasRequired_arrayPush;

  function require_arrayPush () {
  	if (hasRequired_arrayPush) return _arrayPush;
  	hasRequired_arrayPush = 1;
  	function arrayPush(array, values) {
  	  var index = -1,
  	      length = values.length,
  	      offset = array.length;

  	  while (++index < length) {
  	    array[offset + index] = values[index];
  	  }
  	  return array;
  	}

  	_arrayPush = arrayPush;
  	return _arrayPush;
  }

  var _baseGetAllKeys;
  var hasRequired_baseGetAllKeys;

  function require_baseGetAllKeys () {
  	if (hasRequired_baseGetAllKeys) return _baseGetAllKeys;
  	hasRequired_baseGetAllKeys = 1;
  	var arrayPush = require_arrayPush(),
  	    isArray = requireIsArray();

  	/**
  	 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
  	 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
  	 * symbols of `object`.
  	 *
  	 * @private
  	 * @param {Object} object The object to query.
  	 * @param {Function} keysFunc The function to get the keys of `object`.
  	 * @param {Function} symbolsFunc The function to get the symbols of `object`.
  	 * @returns {Array} Returns the array of property names and symbols.
  	 */
  	function baseGetAllKeys(object, keysFunc, symbolsFunc) {
  	  var result = keysFunc(object);
  	  return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
  	}

  	_baseGetAllKeys = baseGetAllKeys;
  	return _baseGetAllKeys;
  }

  /**
   * A specialized version of `_.filter` for arrays without support for
   * iteratee shorthands.
   *
   * @private
   * @param {Array} [array] The array to iterate over.
   * @param {Function} predicate The function invoked per iteration.
   * @returns {Array} Returns the new filtered array.
   */

  var _arrayFilter;
  var hasRequired_arrayFilter;

  function require_arrayFilter () {
  	if (hasRequired_arrayFilter) return _arrayFilter;
  	hasRequired_arrayFilter = 1;
  	function arrayFilter(array, predicate) {
  	  var index = -1,
  	      length = array == null ? 0 : array.length,
  	      resIndex = 0,
  	      result = [];

  	  while (++index < length) {
  	    var value = array[index];
  	    if (predicate(value, index, array)) {
  	      result[resIndex++] = value;
  	    }
  	  }
  	  return result;
  	}

  	_arrayFilter = arrayFilter;
  	return _arrayFilter;
  }

  /**
   * This method returns a new empty array.
   *
   * @static
   * @memberOf _
   * @since 4.13.0
   * @category Util
   * @returns {Array} Returns the new empty array.
   * @example
   *
   * var arrays = _.times(2, _.stubArray);
   *
   * console.log(arrays);
   * // => [[], []]
   *
   * console.log(arrays[0] === arrays[1]);
   * // => false
   */

  var stubArray_1;
  var hasRequiredStubArray;

  function requireStubArray () {
  	if (hasRequiredStubArray) return stubArray_1;
  	hasRequiredStubArray = 1;
  	function stubArray() {
  	  return [];
  	}

  	stubArray_1 = stubArray;
  	return stubArray_1;
  }

  var _getSymbols;
  var hasRequired_getSymbols;

  function require_getSymbols () {
  	if (hasRequired_getSymbols) return _getSymbols;
  	hasRequired_getSymbols = 1;
  	var arrayFilter = require_arrayFilter(),
  	    stubArray = requireStubArray();

  	/** Used for built-in method references. */
  	var objectProto = Object.prototype;

  	/** Built-in value references. */
  	var propertyIsEnumerable = objectProto.propertyIsEnumerable;

  	/* Built-in method references for those with the same name as other `lodash` methods. */
  	var nativeGetSymbols = Object.getOwnPropertySymbols;

  	/**
  	 * Creates an array of the own enumerable symbols of `object`.
  	 *
  	 * @private
  	 * @param {Object} object The object to query.
  	 * @returns {Array} Returns the array of symbols.
  	 */
  	var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
  	  if (object == null) {
  	    return [];
  	  }
  	  object = Object(object);
  	  return arrayFilter(nativeGetSymbols(object), function(symbol) {
  	    return propertyIsEnumerable.call(object, symbol);
  	  });
  	};

  	_getSymbols = getSymbols;
  	return _getSymbols;
  }

  /**
   * The base implementation of `_.times` without support for iteratee shorthands
   * or max array length checks.
   *
   * @private
   * @param {number} n The number of times to invoke `iteratee`.
   * @param {Function} iteratee The function invoked per iteration.
   * @returns {Array} Returns the array of results.
   */

  var _baseTimes;
  var hasRequired_baseTimes;

  function require_baseTimes () {
  	if (hasRequired_baseTimes) return _baseTimes;
  	hasRequired_baseTimes = 1;
  	function baseTimes(n, iteratee) {
  	  var index = -1,
  	      result = Array(n);

  	  while (++index < n) {
  	    result[index] = iteratee(index);
  	  }
  	  return result;
  	}

  	_baseTimes = baseTimes;
  	return _baseTimes;
  }

  var _baseIsArguments;
  var hasRequired_baseIsArguments;

  function require_baseIsArguments () {
  	if (hasRequired_baseIsArguments) return _baseIsArguments;
  	hasRequired_baseIsArguments = 1;
  	var baseGetTag = require_baseGetTag(),
  	    isObjectLike = requireIsObjectLike();

  	/** `Object#toString` result references. */
  	var argsTag = '[object Arguments]';

  	/**
  	 * The base implementation of `_.isArguments`.
  	 *
  	 * @private
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  	 */
  	function baseIsArguments(value) {
  	  return isObjectLike(value) && baseGetTag(value) == argsTag;
  	}

  	_baseIsArguments = baseIsArguments;
  	return _baseIsArguments;
  }

  var isArguments_1;
  var hasRequiredIsArguments;

  function requireIsArguments () {
  	if (hasRequiredIsArguments) return isArguments_1;
  	hasRequiredIsArguments = 1;
  	var baseIsArguments = require_baseIsArguments(),
  	    isObjectLike = requireIsObjectLike();

  	/** Used for built-in method references. */
  	var objectProto = Object.prototype;

  	/** Used to check objects for own properties. */
  	var hasOwnProperty = objectProto.hasOwnProperty;

  	/** Built-in value references. */
  	var propertyIsEnumerable = objectProto.propertyIsEnumerable;

  	/**
  	 * Checks if `value` is likely an `arguments` object.
  	 *
  	 * @static
  	 * @memberOf _
  	 * @since 0.1.0
  	 * @category Lang
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  	 *  else `false`.
  	 * @example
  	 *
  	 * _.isArguments(function() { return arguments; }());
  	 * // => true
  	 *
  	 * _.isArguments([1, 2, 3]);
  	 * // => false
  	 */
  	var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
  	  return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
  	    !propertyIsEnumerable.call(value, 'callee');
  	};

  	isArguments_1 = isArguments;
  	return isArguments_1;
  }

  var isBuffer = {exports: {}};

  /**
   * This method returns `false`.
   *
   * @static
   * @memberOf _
   * @since 4.13.0
   * @category Util
   * @returns {boolean} Returns `false`.
   * @example
   *
   * _.times(2, _.stubFalse);
   * // => [false, false]
   */

  var stubFalse_1;
  var hasRequiredStubFalse;

  function requireStubFalse () {
  	if (hasRequiredStubFalse) return stubFalse_1;
  	hasRequiredStubFalse = 1;
  	function stubFalse() {
  	  return false;
  	}

  	stubFalse_1 = stubFalse;
  	return stubFalse_1;
  }

  isBuffer.exports;

  var hasRequiredIsBuffer;

  function requireIsBuffer () {
  	if (hasRequiredIsBuffer) return isBuffer.exports;
  	hasRequiredIsBuffer = 1;
  	(function (module, exports$1) {
  		var root = require_root(),
  		    stubFalse = requireStubFalse();

  		/** Detect free variable `exports`. */
  		var freeExports = exports$1 && !exports$1.nodeType && exports$1;

  		/** Detect free variable `module`. */
  		var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;

  		/** Detect the popular CommonJS extension `module.exports`. */
  		var moduleExports = freeModule && freeModule.exports === freeExports;

  		/** Built-in value references. */
  		var Buffer = moduleExports ? root.Buffer : undefined;

  		/* Built-in method references for those with the same name as other `lodash` methods. */
  		var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;

  		/**
  		 * Checks if `value` is a buffer.
  		 *
  		 * @static
  		 * @memberOf _
  		 * @since 4.3.0
  		 * @category Lang
  		 * @param {*} value The value to check.
  		 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
  		 * @example
  		 *
  		 * _.isBuffer(new Buffer(2));
  		 * // => true
  		 *
  		 * _.isBuffer(new Uint8Array(2));
  		 * // => false
  		 */
  		var isBuffer = nativeIsBuffer || stubFalse;

  		module.exports = isBuffer; 
  	} (isBuffer, isBuffer.exports));
  	return isBuffer.exports;
  }

  /** Used as references for various `Number` constants. */

  var _isIndex;
  var hasRequired_isIndex;

  function require_isIndex () {
  	if (hasRequired_isIndex) return _isIndex;
  	hasRequired_isIndex = 1;
  	var MAX_SAFE_INTEGER = 9007199254740991;

  	/** Used to detect unsigned integer values. */
  	var reIsUint = /^(?:0|[1-9]\d*)$/;

  	/**
  	 * Checks if `value` is a valid array-like index.
  	 *
  	 * @private
  	 * @param {*} value The value to check.
  	 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
  	 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
  	 */
  	function isIndex(value, length) {
  	  var type = typeof value;
  	  length = length == null ? MAX_SAFE_INTEGER : length;

  	  return !!length &&
  	    (type == 'number' ||
  	      (type != 'symbol' && reIsUint.test(value))) &&
  	        (value > -1 && value % 1 == 0 && value < length);
  	}

  	_isIndex = isIndex;
  	return _isIndex;
  }

  /** Used as references for various `Number` constants. */

  var isLength_1;
  var hasRequiredIsLength;

  function requireIsLength () {
  	if (hasRequiredIsLength) return isLength_1;
  	hasRequiredIsLength = 1;
  	var MAX_SAFE_INTEGER = 9007199254740991;

  	/**
  	 * Checks if `value` is a valid array-like length.
  	 *
  	 * **Note:** This method is loosely based on
  	 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
  	 *
  	 * @static
  	 * @memberOf _
  	 * @since 4.0.0
  	 * @category Lang
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
  	 * @example
  	 *
  	 * _.isLength(3);
  	 * // => true
  	 *
  	 * _.isLength(Number.MIN_VALUE);
  	 * // => false
  	 *
  	 * _.isLength(Infinity);
  	 * // => false
  	 *
  	 * _.isLength('3');
  	 * // => false
  	 */
  	function isLength(value) {
  	  return typeof value == 'number' &&
  	    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
  	}

  	isLength_1 = isLength;
  	return isLength_1;
  }

  var _baseIsTypedArray;
  var hasRequired_baseIsTypedArray;

  function require_baseIsTypedArray () {
  	if (hasRequired_baseIsTypedArray) return _baseIsTypedArray;
  	hasRequired_baseIsTypedArray = 1;
  	var baseGetTag = require_baseGetTag(),
  	    isLength = requireIsLength(),
  	    isObjectLike = requireIsObjectLike();

  	/** `Object#toString` result references. */
  	var argsTag = '[object Arguments]',
  	    arrayTag = '[object Array]',
  	    boolTag = '[object Boolean]',
  	    dateTag = '[object Date]',
  	    errorTag = '[object Error]',
  	    funcTag = '[object Function]',
  	    mapTag = '[object Map]',
  	    numberTag = '[object Number]',
  	    objectTag = '[object Object]',
  	    regexpTag = '[object RegExp]',
  	    setTag = '[object Set]',
  	    stringTag = '[object String]',
  	    weakMapTag = '[object WeakMap]';

  	var arrayBufferTag = '[object ArrayBuffer]',
  	    dataViewTag = '[object DataView]',
  	    float32Tag = '[object Float32Array]',
  	    float64Tag = '[object Float64Array]',
  	    int8Tag = '[object Int8Array]',
  	    int16Tag = '[object Int16Array]',
  	    int32Tag = '[object Int32Array]',
  	    uint8Tag = '[object Uint8Array]',
  	    uint8ClampedTag = '[object Uint8ClampedArray]',
  	    uint16Tag = '[object Uint16Array]',
  	    uint32Tag = '[object Uint32Array]';

  	/** Used to identify `toStringTag` values of typed arrays. */
  	var typedArrayTags = {};
  	typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
  	typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
  	typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
  	typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
  	typedArrayTags[uint32Tag] = true;
  	typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
  	typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
  	typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
  	typedArrayTags[errorTag] = typedArrayTags[funcTag] =
  	typedArrayTags[mapTag] = typedArrayTags[numberTag] =
  	typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
  	typedArrayTags[setTag] = typedArrayTags[stringTag] =
  	typedArrayTags[weakMapTag] = false;

  	/**
  	 * The base implementation of `_.isTypedArray` without Node.js optimizations.
  	 *
  	 * @private
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
  	 */
  	function baseIsTypedArray(value) {
  	  return isObjectLike(value) &&
  	    isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
  	}

  	_baseIsTypedArray = baseIsTypedArray;
  	return _baseIsTypedArray;
  }

  /**
   * The base implementation of `_.unary` without support for storing metadata.
   *
   * @private
   * @param {Function} func The function to cap arguments for.
   * @returns {Function} Returns the new capped function.
   */

  var _baseUnary;
  var hasRequired_baseUnary;

  function require_baseUnary () {
  	if (hasRequired_baseUnary) return _baseUnary;
  	hasRequired_baseUnary = 1;
  	function baseUnary(func) {
  	  return function(value) {
  	    return func(value);
  	  };
  	}

  	_baseUnary = baseUnary;
  	return _baseUnary;
  }

  var _nodeUtil = {exports: {}};

  _nodeUtil.exports;

  var hasRequired_nodeUtil;

  function require_nodeUtil () {
  	if (hasRequired_nodeUtil) return _nodeUtil.exports;
  	hasRequired_nodeUtil = 1;
  	(function (module, exports$1) {
  		var freeGlobal = require_freeGlobal();

  		/** Detect free variable `exports`. */
  		var freeExports = exports$1 && !exports$1.nodeType && exports$1;

  		/** Detect free variable `module`. */
  		var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;

  		/** Detect the popular CommonJS extension `module.exports`. */
  		var moduleExports = freeModule && freeModule.exports === freeExports;

  		/** Detect free variable `process` from Node.js. */
  		var freeProcess = moduleExports && freeGlobal.process;

  		/** Used to access faster Node.js helpers. */
  		var nodeUtil = (function() {
  		  try {
  		    // Use `util.types` for Node.js 10+.
  		    var types = freeModule && freeModule.require && freeModule.require('util').types;

  		    if (types) {
  		      return types;
  		    }

  		    // Legacy `process.binding('util')` for Node.js < 10.
  		    return freeProcess && freeProcess.binding && freeProcess.binding('util');
  		  } catch (e) {}
  		}());

  		module.exports = nodeUtil; 
  	} (_nodeUtil, _nodeUtil.exports));
  	return _nodeUtil.exports;
  }

  var isTypedArray_1;
  var hasRequiredIsTypedArray;

  function requireIsTypedArray () {
  	if (hasRequiredIsTypedArray) return isTypedArray_1;
  	hasRequiredIsTypedArray = 1;
  	var baseIsTypedArray = require_baseIsTypedArray(),
  	    baseUnary = require_baseUnary(),
  	    nodeUtil = require_nodeUtil();

  	/* Node.js helper references. */
  	var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;

  	/**
  	 * Checks if `value` is classified as a typed array.
  	 *
  	 * @static
  	 * @memberOf _
  	 * @since 3.0.0
  	 * @category Lang
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
  	 * @example
  	 *
  	 * _.isTypedArray(new Uint8Array);
  	 * // => true
  	 *
  	 * _.isTypedArray([]);
  	 * // => false
  	 */
  	var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;

  	isTypedArray_1 = isTypedArray;
  	return isTypedArray_1;
  }

  var _arrayLikeKeys;
  var hasRequired_arrayLikeKeys;

  function require_arrayLikeKeys () {
  	if (hasRequired_arrayLikeKeys) return _arrayLikeKeys;
  	hasRequired_arrayLikeKeys = 1;
  	var baseTimes = require_baseTimes(),
  	    isArguments = requireIsArguments(),
  	    isArray = requireIsArray(),
  	    isBuffer = requireIsBuffer(),
  	    isIndex = require_isIndex(),
  	    isTypedArray = requireIsTypedArray();

  	/** Used for built-in method references. */
  	var objectProto = Object.prototype;

  	/** Used to check objects for own properties. */
  	var hasOwnProperty = objectProto.hasOwnProperty;

  	/**
  	 * Creates an array of the enumerable property names of the array-like `value`.
  	 *
  	 * @private
  	 * @param {*} value The value to query.
  	 * @param {boolean} inherited Specify returning inherited property names.
  	 * @returns {Array} Returns the array of property names.
  	 */
  	function arrayLikeKeys(value, inherited) {
  	  var isArr = isArray(value),
  	      isArg = !isArr && isArguments(value),
  	      isBuff = !isArr && !isArg && isBuffer(value),
  	      isType = !isArr && !isArg && !isBuff && isTypedArray(value),
  	      skipIndexes = isArr || isArg || isBuff || isType,
  	      result = skipIndexes ? baseTimes(value.length, String) : [],
  	      length = result.length;

  	  for (var key in value) {
  	    if ((inherited || hasOwnProperty.call(value, key)) &&
  	        !(skipIndexes && (
  	           // Safari 9 has enumerable `arguments.length` in strict mode.
  	           key == 'length' ||
  	           // Node.js 0.10 has enumerable non-index properties on buffers.
  	           (isBuff && (key == 'offset' || key == 'parent')) ||
  	           // PhantomJS 2 has enumerable non-index properties on typed arrays.
  	           (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
  	           // Skip index properties.
  	           isIndex(key, length)
  	        ))) {
  	      result.push(key);
  	    }
  	  }
  	  return result;
  	}

  	_arrayLikeKeys = arrayLikeKeys;
  	return _arrayLikeKeys;
  }

  /** Used for built-in method references. */

  var _isPrototype;
  var hasRequired_isPrototype;

  function require_isPrototype () {
  	if (hasRequired_isPrototype) return _isPrototype;
  	hasRequired_isPrototype = 1;
  	var objectProto = Object.prototype;

  	/**
  	 * Checks if `value` is likely a prototype object.
  	 *
  	 * @private
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
  	 */
  	function isPrototype(value) {
  	  var Ctor = value && value.constructor,
  	      proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;

  	  return value === proto;
  	}

  	_isPrototype = isPrototype;
  	return _isPrototype;
  }

  /**
   * Creates a unary function that invokes `func` with its argument transformed.
   *
   * @private
   * @param {Function} func The function to wrap.
   * @param {Function} transform The argument transform.
   * @returns {Function} Returns the new function.
   */

  var _overArg;
  var hasRequired_overArg;

  function require_overArg () {
  	if (hasRequired_overArg) return _overArg;
  	hasRequired_overArg = 1;
  	function overArg(func, transform) {
  	  return function(arg) {
  	    return func(transform(arg));
  	  };
  	}

  	_overArg = overArg;
  	return _overArg;
  }

  var _nativeKeys;
  var hasRequired_nativeKeys;

  function require_nativeKeys () {
  	if (hasRequired_nativeKeys) return _nativeKeys;
  	hasRequired_nativeKeys = 1;
  	var overArg = require_overArg();

  	/* Built-in method references for those with the same name as other `lodash` methods. */
  	var nativeKeys = overArg(Object.keys, Object);

  	_nativeKeys = nativeKeys;
  	return _nativeKeys;
  }

  var _baseKeys;
  var hasRequired_baseKeys;

  function require_baseKeys () {
  	if (hasRequired_baseKeys) return _baseKeys;
  	hasRequired_baseKeys = 1;
  	var isPrototype = require_isPrototype(),
  	    nativeKeys = require_nativeKeys();

  	/** Used for built-in method references. */
  	var objectProto = Object.prototype;

  	/** Used to check objects for own properties. */
  	var hasOwnProperty = objectProto.hasOwnProperty;

  	/**
  	 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
  	 *
  	 * @private
  	 * @param {Object} object The object to query.
  	 * @returns {Array} Returns the array of property names.
  	 */
  	function baseKeys(object) {
  	  if (!isPrototype(object)) {
  	    return nativeKeys(object);
  	  }
  	  var result = [];
  	  for (var key in Object(object)) {
  	    if (hasOwnProperty.call(object, key) && key != 'constructor') {
  	      result.push(key);
  	    }
  	  }
  	  return result;
  	}

  	_baseKeys = baseKeys;
  	return _baseKeys;
  }

  var isArrayLike_1;
  var hasRequiredIsArrayLike;

  function requireIsArrayLike () {
  	if (hasRequiredIsArrayLike) return isArrayLike_1;
  	hasRequiredIsArrayLike = 1;
  	var isFunction = requireIsFunction(),
  	    isLength = requireIsLength();

  	/**
  	 * Checks if `value` is array-like. A value is considered array-like if it's
  	 * not a function and has a `value.length` that's an integer greater than or
  	 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
  	 *
  	 * @static
  	 * @memberOf _
  	 * @since 4.0.0
  	 * @category Lang
  	 * @param {*} value The value to check.
  	 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
  	 * @example
  	 *
  	 * _.isArrayLike([1, 2, 3]);
  	 * // => true
  	 *
  	 * _.isArrayLike(document.body.children);
  	 * // => true
  	 *
  	 * _.isArrayLike('abc');
  	 * // => true
  	 *
  	 * _.isArrayLike(_.noop);
  	 * // => false
  	 */
  	function isArrayLike(value) {
  	  return value != null && isLength(value.length) && !isFunction(value);
  	}

  	isArrayLike_1 = isArrayLike;
  	return isArrayLike_1;
  }

  var keys_1;
  var hasRequiredKeys;

  function requireKeys () {
  	if (hasRequiredKeys) return keys_1;
  	hasRequiredKeys = 1;
  	var arrayLikeKeys = require_arrayLikeKeys(),
  	    baseKeys = require_baseKeys(),
  	    isArrayLike = requireIsArrayLike();

  	/**
  	 * Creates an array of the own enumerable property names of `object`.
  	 *
  	 * **Note:** Non-object values are coerced to objects. See the
  	 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
  	 * for more details.
  	 *
  	 * @static
  	 * @since 0.1.0
  	 * @memberOf _
  	 * @category Object
  	 * @param {Object} object The object to query.
  	 * @returns {Array} Returns the array of property names.
  	 * @example
  	 *
  	 * function Foo() {
  	 *   this.a = 1;
  	 *   this.b = 2;
  	 * }
  	 *
  	 * Foo.prototype.c = 3;
  	 *
  	 * _.keys(new Foo);
  	 * // => ['a', 'b'] (iteration order is not guaranteed)
  	 *
  	 * _.keys('hi');
  	 * // => ['0', '1']
  	 */
  	function keys(object) {
  	  return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
  	}

  	keys_1 = keys;
  	return keys_1;
  }

  var _getAllKeys;
  var hasRequired_getAllKeys;

  function require_getAllKeys () {
  	if (hasRequired_getAllKeys) return _getAllKeys;
  	hasRequired_getAllKeys = 1;
  	var baseGetAllKeys = require_baseGetAllKeys(),
  	    getSymbols = require_getSymbols(),
  	    keys = requireKeys();

  	/**
  	 * Creates an array of own enumerable property names and symbols of `object`.
  	 *
  	 * @private
  	 * @param {Object} object The object to query.
  	 * @returns {Array} Returns the array of property names and symbols.
  	 */
  	function getAllKeys(object) {
  	  return baseGetAllKeys(object, keys, getSymbols);
  	}

  	_getAllKeys = getAllKeys;
  	return _getAllKeys;
  }

  var _equalObjects;
  var hasRequired_equalObjects;

  function require_equalObjects () {
  	if (hasRequired_equalObjects) return _equalObjects;
  	hasRequired_equalObjects = 1;
  	var getAllKeys = require_getAllKeys();

  	/** Used to compose bitmasks for value comparisons. */
  	var COMPARE_PARTIAL_FLAG = 1;

  	/** Used for built-in method references. */
  	var objectProto = Object.prototype;

  	/** Used to check objects for own properties. */
  	var hasOwnProperty = objectProto.hasOwnProperty;

  	/**
  	 * A specialized version of `baseIsEqualDeep` for objects with support for
  	 * partial deep comparisons.
  	 *
  	 * @private
  	 * @param {Object} object The object to compare.
  	 * @param {Object} other The other object to compare.
  	 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  	 * @param {Function} customizer The function to customize comparisons.
  	 * @param {Function} equalFunc The function to determine equivalents of values.
  	 * @param {Object} stack Tracks traversed `object` and `other` objects.
  	 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  	 */
  	function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
  	  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
  	      objProps = getAllKeys(object),
  	      objLength = objProps.length,
  	      othProps = getAllKeys(other),
  	      othLength = othProps.length;

  	  if (objLength != othLength && !isPartial) {
  	    return false;
  	  }
  	  var index = objLength;
  	  while (index--) {
  	    var key = objProps[index];
  	    if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
  	      return false;
  	    }
  	  }
  	  // Check that cyclic values are equal.
  	  var objStacked = stack.get(object);
  	  var othStacked = stack.get(other);
  	  if (objStacked && othStacked) {
  	    return objStacked == other && othStacked == object;
  	  }
  	  var result = true;
  	  stack.set(object, other);
  	  stack.set(other, object);

  	  var skipCtor = isPartial;
  	  while (++index < objLength) {
  	    key = objProps[index];
  	    var objValue = object[key],
  	        othValue = other[key];

  	    if (customizer) {
  	      var compared = isPartial
  	        ? customizer(othValue, objValue, key, other, object, stack)
  	        : customizer(objValue, othValue, key, object, other, stack);
  	    }
  	    // Recursively compare objects (susceptible to call stack limits).
  	    if (!(compared === undefined
  	          ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
  	          : compared
  	        )) {
  	      result = false;
  	      break;
  	    }
  	    skipCtor || (skipCtor = key == 'constructor');
  	  }
  	  if (result && !skipCtor) {
  	    var objCtor = object.constructor,
  	        othCtor = other.constructor;

  	    // Non `Object` object instances with different constructors are not equal.
  	    if (objCtor != othCtor &&
  	        ('constructor' in object && 'constructor' in other) &&
  	        !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
  	          typeof othCtor == 'function' && othCtor instanceof othCtor)) {
  	      result = false;
  	    }
  	  }
  	  stack['delete'](object);
  	  stack['delete'](other);
  	  return result;
  	}

  	_equalObjects = equalObjects;
  	return _equalObjects;
  }

  var _DataView;
  var hasRequired_DataView;

  function require_DataView () {
  	if (hasRequired_DataView) return _DataView;
  	hasRequired_DataView = 1;
  	var getNative = require_getNative(),
  	    root = require_root();

  	/* Built-in method references that are verified to be native. */
  	var DataView = getNative(root, 'DataView');

  	_DataView = DataView;
  	return _DataView;
  }

  var _Promise;
  var hasRequired_Promise;

  function require_Promise () {
  	if (hasRequired_Promise) return _Promise;
  	hasRequired_Promise = 1;
  	var getNative = require_getNative(),
  	    root = require_root();

  	/* Built-in method references that are verified to be native. */
  	var Promise = getNative(root, 'Promise');

  	_Promise = Promise;
  	return _Promise;
  }

  var _Set;
  var hasRequired_Set;

  function require_Set () {
  	if (hasRequired_Set) return _Set;
  	hasRequired_Set = 1;
  	var getNative = require_getNative(),
  	    root = require_root();

  	/* Built-in method references that are verified to be native. */
  	var Set = getNative(root, 'Set');

  	_Set = Set;
  	return _Set;
  }

  var _WeakMap;
  var hasRequired_WeakMap;

  function require_WeakMap () {
  	if (hasRequired_WeakMap) return _WeakMap;
  	hasRequired_WeakMap = 1;
  	var getNative = require_getNative(),
  	    root = require_root();

  	/* Built-in method references that are verified to be native. */
  	var WeakMap = getNative(root, 'WeakMap');

  	_WeakMap = WeakMap;
  	return _WeakMap;
  }

  var _getTag;
  var hasRequired_getTag;

  function require_getTag () {
  	if (hasRequired_getTag) return _getTag;
  	hasRequired_getTag = 1;
  	var DataView = require_DataView(),
  	    Map = require_Map(),
  	    Promise = require_Promise(),
  	    Set = require_Set(),
  	    WeakMap = require_WeakMap(),
  	    baseGetTag = require_baseGetTag(),
  	    toSource = require_toSource();

  	/** `Object#toString` result references. */
  	var mapTag = '[object Map]',
  	    objectTag = '[object Object]',
  	    promiseTag = '[object Promise]',
  	    setTag = '[object Set]',
  	    weakMapTag = '[object WeakMap]';

  	var dataViewTag = '[object DataView]';

  	/** Used to detect maps, sets, and weakmaps. */
  	var dataViewCtorString = toSource(DataView),
  	    mapCtorString = toSource(Map),
  	    promiseCtorString = toSource(Promise),
  	    setCtorString = toSource(Set),
  	    weakMapCtorString = toSource(WeakMap);

  	/**
  	 * Gets the `toStringTag` of `value`.
  	 *
  	 * @private
  	 * @param {*} value The value to query.
  	 * @returns {string} Returns the `toStringTag`.
  	 */
  	var getTag = baseGetTag;

  	// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
  	if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
  	    (Map && getTag(new Map) != mapTag) ||
  	    (Promise && getTag(Promise.resolve()) != promiseTag) ||
  	    (Set && getTag(new Set) != setTag) ||
  	    (WeakMap && getTag(new WeakMap) != weakMapTag)) {
  	  getTag = function(value) {
  	    var result = baseGetTag(value),
  	        Ctor = result == objectTag ? value.constructor : undefined,
  	        ctorString = Ctor ? toSource(Ctor) : '';

  	    if (ctorString) {
  	      switch (ctorString) {
  	        case dataViewCtorString: return dataViewTag;
  	        case mapCtorString: return mapTag;
  	        case promiseCtorString: return promiseTag;
  	        case setCtorString: return setTag;
  	        case weakMapCtorString: return weakMapTag;
  	      }
  	    }
  	    return result;
  	  };
  	}

  	_getTag = getTag;
  	return _getTag;
  }

  var _baseIsEqualDeep;
  var hasRequired_baseIsEqualDeep;

  function require_baseIsEqualDeep () {
  	if (hasRequired_baseIsEqualDeep) return _baseIsEqualDeep;
  	hasRequired_baseIsEqualDeep = 1;
  	var Stack = require_Stack(),
  	    equalArrays = require_equalArrays(),
  	    equalByTag = require_equalByTag(),
  	    equalObjects = require_equalObjects(),
  	    getTag = require_getTag(),
  	    isArray = requireIsArray(),
  	    isBuffer = requireIsBuffer(),
  	    isTypedArray = requireIsTypedArray();

  	/** Used to compose bitmasks for value comparisons. */
  	var COMPARE_PARTIAL_FLAG = 1;

  	/** `Object#toString` result references. */
  	var argsTag = '[object Arguments]',
  	    arrayTag = '[object Array]',
  	    objectTag = '[object Object]';

  	/** Used for built-in method references. */
  	var objectProto = Object.prototype;

  	/** Used to check objects for own properties. */
  	var hasOwnProperty = objectProto.hasOwnProperty;

  	/**
  	 * A specialized version of `baseIsEqual` for arrays and objects which performs
  	 * deep comparisons and tracks traversed objects enabling objects with circular
  	 * references to be compared.
  	 *
  	 * @private
  	 * @param {Object} object The object to compare.
  	 * @param {Object} other The other object to compare.
  	 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  	 * @param {Function} customizer The function to customize comparisons.
  	 * @param {Function} equalFunc The function to determine equivalents of values.
  	 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
  	 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  	 */
  	function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
  	  var objIsArr = isArray(object),
  	      othIsArr = isArray(other),
  	      objTag = objIsArr ? arrayTag : getTag(object),
  	      othTag = othIsArr ? arrayTag : getTag(other);

  	  objTag = objTag == argsTag ? objectTag : objTag;
  	  othTag = othTag == argsTag ? objectTag : othTag;

  	  var objIsObj = objTag == objectTag,
  	      othIsObj = othTag == objectTag,
  	      isSameTag = objTag == othTag;

  	  if (isSameTag && isBuffer(object)) {
  	    if (!isBuffer(other)) {
  	      return false;
  	    }
  	    objIsArr = true;
  	    objIsObj = false;
  	  }
  	  if (isSameTag && !objIsObj) {
  	    stack || (stack = new Stack);
  	    return (objIsArr || isTypedArray(object))
  	      ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
  	      : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
  	  }
  	  if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
  	    var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
  	        othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');

  	    if (objIsWrapped || othIsWrapped) {
  	      var objUnwrapped = objIsWrapped ? object.value() : object,
  	          othUnwrapped = othIsWrapped ? other.value() : other;

  	      stack || (stack = new Stack);
  	      return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
  	    }
  	  }
  	  if (!isSameTag) {
  	    return false;
  	  }
  	  stack || (stack = new Stack);
  	  return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
  	}

  	_baseIsEqualDeep = baseIsEqualDeep;
  	return _baseIsEqualDeep;
  }

  var _baseIsEqual;
  var hasRequired_baseIsEqual;

  function require_baseIsEqual () {
  	if (hasRequired_baseIsEqual) return _baseIsEqual;
  	hasRequired_baseIsEqual = 1;
  	var baseIsEqualDeep = require_baseIsEqualDeep(),
  	    isObjectLike = requireIsObjectLike();

  	/**
  	 * The base implementation of `_.isEqual` which supports partial comparisons
  	 * and tracks traversed objects.
  	 *
  	 * @private
  	 * @param {*} value The value to compare.
  	 * @param {*} other The other value to compare.
  	 * @param {boolean} bitmask The bitmask flags.
  	 *  1 - Unordered comparison
  	 *  2 - Partial comparison
  	 * @param {Function} [customizer] The function to customize comparisons.
  	 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
  	 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  	 */
  	function baseIsEqual(value, other, bitmask, customizer, stack) {
  	  if (value === other) {
  	    return true;
  	  }
  	  if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
  	    return value !== value && other !== other;
  	  }
  	  return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
  	}

  	_baseIsEqual = baseIsEqual;
  	return _baseIsEqual;
  }

  var isEqual_1;
  var hasRequiredIsEqual;

  function requireIsEqual () {
  	if (hasRequiredIsEqual) return isEqual_1;
  	hasRequiredIsEqual = 1;
  	var baseIsEqual = require_baseIsEqual();

  	/**
  	 * Performs a deep comparison between two values to determine if they are
  	 * equivalent.
  	 *
  	 * **Note:** This method supports comparing arrays, array buffers, booleans,
  	 * date objects, error objects, maps, numbers, `Object` objects, regexes,
  	 * sets, strings, symbols, and typed arrays. `Object` objects are compared
  	 * by their own, not inherited, enumerable properties. Functions and DOM
  	 * nodes are compared by strict equality, i.e. `===`.
  	 *
  	 * @static
  	 * @memberOf _
  	 * @since 0.1.0
  	 * @category Lang
  	 * @param {*} value The value to compare.
  	 * @param {*} other The other value to compare.
  	 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  	 * @example
  	 *
  	 * var object = { 'a': 1 };
  	 * var other = { 'a': 1 };
  	 *
  	 * _.isEqual(object, other);
  	 * // => true
  	 *
  	 * object === other;
  	 * // => false
  	 */
  	function isEqual(value, other) {
  	  return baseIsEqual(value, other);
  	}

  	isEqual_1 = isEqual;
  	return isEqual_1;
  }

  /**
   * @class
   *
   * @property {Element} key
   * @property {Element} value
   */

  var KeyValuePair_1;
  var hasRequiredKeyValuePair;

  function requireKeyValuePair () {
  	if (hasRequiredKeyValuePair) return KeyValuePair_1;
  	hasRequiredKeyValuePair = 1;
  	class KeyValuePair {
  	  constructor(key, value) {
  	    this.key = key;
  	    this.value = value;
  	  }

  	  /**
  	   * @returns {KeyValuePair}
  	   */
  	  clone() {
  	    const clone = new KeyValuePair();

  	    if (this.key) {
  	      clone.key = this.key.clone();
  	    }

  	    if (this.value) {
  	      clone.value = this.value.clone();
  	    }

  	    return clone;
  	  }
  	}

  	KeyValuePair_1 = KeyValuePair;
  	return KeyValuePair_1;
  }

  /** Error message constants. */

  var negate_1;
  var hasRequiredNegate;

  function requireNegate () {
  	if (hasRequiredNegate) return negate_1;
  	hasRequiredNegate = 1;
  	var FUNC_ERROR_TEXT = 'Expected a function';

  	/**
  	 * Creates a function that negates the result of the predicate `func`. The
  	 * `func` predicate is invoked with the `this` binding and arguments of the
  	 * created function.
  	 *
  	 * @static
  	 * @memberOf _
  	 * @since 3.0.0
  	 * @category Function
  	 * @param {Function} predicate The predicate to negate.
  	 * @returns {Function} Returns the new negated function.
  	 * @example
  	 *
  	 * function isEven(n) {
  	 *   return n % 2 == 0;
  	 * }
  	 *
  	 * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
  	 * // => [1, 3, 5]
  	 */
  	function negate(predicate) {
  	  if (typeof predicate != 'function') {
  	    throw new TypeError(FUNC_ERROR_TEXT);
  	  }
  	  return function() {
  	    var args = arguments;
  	    switch (args.length) {
  	      case 0: return !predicate.call(this);
  	      case 1: return !predicate.call(this, args[0]);
  	      case 2: return !predicate.call(this, args[0], args[1]);
  	      case 3: return !predicate.call(this, args[0], args[1], args[2]);
  	    }
  	    return !predicate.apply(this, args);
  	  };
  	}

  	negate_1 = negate;
  	return negate_1;
  }

  var ArraySlice_1;
  var hasRequiredArraySlice;

  function requireArraySlice () {
  	if (hasRequiredArraySlice) return ArraySlice_1;
  	hasRequiredArraySlice = 1;
  	const negate = requireNegate();

  	// Coerces an a parameter into a callback for matching elements.
  	// This accepts an element name, an element type and returns a
  	// callback to match for those elements.
  	function coerceElementMatchingCallback(value) {
  	  // Element Name
  	  if (typeof value === 'string') {
  	    return element => element.element === value;
  	  }

  	  // Element Type
  	  if (value.constructor && value.extend) {
  	    return element => element instanceof value;
  	  }

  	  return value;
  	}

  	/**
  	 * @class
  	 *
  	 * @param {Element[]} elements
  	 *
  	 * @property {Element[]} elements
  	 */
  	class ArraySlice {
  	  constructor(elements) {
  	    this.elements = elements || [];
  	  }

  	  /**
  	   * @returns {Array}
  	   */
  	  toValue() {
  	    return this.elements.map(element => element.toValue());
  	  }

  	  // High Order Functions

  	  /**
  	   * @param callback - Function to execute for each element
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @returns {array} A new array with each element being the result of the callback function
  	   */
  	  map(callback, thisArg) {
  	    return this.elements.map(callback, thisArg);
  	  }

  	  /**
  	   * Maps and then flattens the results.
  	   * @param callback - Function to execute for each element.
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @returns {array}
  	   */
  	  flatMap(callback, thisArg) {
  	    return this
  	      .map(callback, thisArg)
  	      .reduce((a, b) => a.concat(b), []);
  	  }

  	  /**
  	   * Returns an array containing the truthy results of calling the given transformation with each element of this sequence
  	   * @param transform - A closure that accepts an element of this array as its argument and returns an optional value.
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @memberof ArraySlice.prototype
  	   * @returns An array of the non-undefined results of calling transform with each element of the array
  	   */
  	  compactMap(transform, thisArg) {
  	    const results = [];

  	    this.forEach((element) => {
  	      const result = transform.bind(thisArg)(element);

  	      if (result) {
  	        results.push(result);
  	      }
  	    });

  	    return results;
  	  }

  	  /**
  	   * @param callback - Function to execute for each element. This may be a callback, an element name or an element class.
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @returns {ArraySlice}
  	   * @memberof ArraySlice.prototype
  	   */
  	  filter(callback, thisArg) {
  	    callback = coerceElementMatchingCallback(callback);
  	    return new ArraySlice(this.elements.filter(callback, thisArg));
  	  }

  	  /**
  	   * @param callback - Function to execute for each element. This may be a callback, an element name or an element class.
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @returns {ArraySlice}
  	   * @memberof ArraySlice.prototype
  	   */
  	  reject(callback, thisArg) {
  	    callback = coerceElementMatchingCallback(callback);
  	    return new ArraySlice(this.elements.filter(negate(callback), thisArg));
  	  }

  	  /**
  	   * Returns the first element in the array that satisfies the given value
  	   * @param callback - Function to execute for each element. This may be a callback, an element name or an element class.
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @returns {Element}
  	   * @memberof ArraySlice.prototype
  	   */
  	  find(callback, thisArg) {
  	    callback = coerceElementMatchingCallback(callback);
  	    return this.elements.find(callback, thisArg);
  	  }

  	  /**
  	   * @param callback - Function to execute for each element
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @memberof ArraySlice.prototype
  	   */
  	  forEach(callback, thisArg) {
  	    this.elements.forEach(callback, thisArg);
  	  }

  	  /**
  	   * @param callback - Function to execute for each element
  	   * @param initialValue
  	   * @memberof ArraySlice.prototype
  	   */
  	  reduce(callback, initialValue) {
  	    return this.elements.reduce(callback, initialValue);
  	  }

  	  /**
  	   * @param value
  	   * @returns {boolean}
  	   * @memberof ArraySlice.prototype
  	   */
  	  includes(value) {
  	    return this.elements.some(element => element.equals(value));
  	  }

  	  // Mutation

  	  /**
  	   * Removes the first element from the slice
  	   * @returns {Element} The removed element or undefined if the slice is empty
  	   * @memberof ArraySlice.prototype
  	   */
  	  shift() {
  	    return this.elements.shift();
  	  }

  	  /**
  	   * Adds the given element to the begining of the slice
  	   * @parameter {Element} value
  	   * @memberof ArraySlice.prototype
  	   */
  	  unshift(value) {
  	    this.elements.unshift(this.refract(value));
  	  }

  	  /**
  	   * Adds the given element to the end of the slice
  	   * @parameter {Element} value
  	   * @memberof ArraySlice.prototype
  	   */
  	  push(value) {
  	    this.elements.push(this.refract(value));
  	    return this;
  	  }

  	  /**
  	   * @parameter {Element} value
  	   * @memberof ArraySlice.prototype
  	   */
  	  add(value) {
  	    this.push(value);
  	  }

  	  // Accessors

  	  /**
  	   * @parameter {number} index
  	   * @returns {Element}
  	   * @memberof ArraySlice.prototype
  	   */
  	  get(index) {
  	    return this.elements[index];
  	  }

  	  /**
  	   * @parameter {number} index
  	   * @memberof ArraySlice.prototype
  	   */
  	  getValue(index) {
  	    const element = this.elements[index];

  	    if (element) {
  	      return element.toValue();
  	    }

  	    return undefined;
  	  }

  	  /**
  	   * Returns the number of elements in the slice
  	   * @type number
  	   */
  	  get length() {
  	    return this.elements.length;
  	  }

  	  /**
  	   * Returns whether the slice is empty
  	   * @type boolean
  	   */
  	  get isEmpty() {
  	    return this.elements.length === 0;
  	  }

  	  /**
  	   * Returns the first element in the slice or undefined if the slice is empty
  	   * @type Element
  	   */
  	  get first() {
  	    return this.elements[0];
  	  }
  	}

  	if (typeof Symbol !== 'undefined') {
  	  ArraySlice.prototype[Symbol.iterator] = function symbol() {
  	    return this.elements[Symbol.iterator]();
  	  };
  	}

  	ArraySlice_1 = ArraySlice;
  	return ArraySlice_1;
  }

  var Element_1;
  var hasRequiredElement;

  function requireElement () {
  	if (hasRequiredElement) return Element_1;
  	hasRequiredElement = 1;
  	const isEqual = requireIsEqual();
  	const KeyValuePair = requireKeyValuePair();
  	const ArraySlice = requireArraySlice();

  	/**
  	 * @class
  	 *
  	 * @param content
  	 * @param meta
  	 * @param attributes
  	 *
  	 * @property {string} element
  	 */
  	class Element {
  	  constructor(content, meta, attributes) {
  	    // Lazy load this.meta and this.attributes because it's a Minim element
  	    // Otherwise, we get into circuluar calls
  	    if (meta) {
  	      this.meta = meta;
  	    }

  	    if (attributes) {
  	      this.attributes = attributes;
  	    }

  	    this.content = content;
  	  }

  	  /**
  	   * Freezes the element to prevent any mutation.
  	   * A frozen element will add `parent` property to every child element
  	   * to allow traversing up the element tree.
  	   */
  	  freeze() {
  	    if (Object.isFrozen(this)) {
  	      return;
  	    }

  	    if (this._meta) {
  	      this.meta.parent = this;
  	      this.meta.freeze();
  	    }

  	    if (this._attributes) {
  	      this.attributes.parent = this;
  	      this.attributes.freeze();
  	    }

  	    this.children.forEach((element) => {
  	      element.parent = this;
  	      element.freeze();
  	    }, this);

  	    if (this.content && Array.isArray(this.content)) {
  	      Object.freeze(this.content);
  	    }

  	    Object.freeze(this);
  	  }

  	  primitive() {

  	  }

  	  /**
  	   * Creates a deep clone of the instance
  	   */
  	  clone() {
  	    const copy = new this.constructor();

  	    copy.element = this.element;

  	    if (this.meta.length) {
  	      copy._meta = this.meta.clone();
  	    }

  	    if (this.attributes.length) {
  	      copy._attributes = this.attributes.clone();
  	    }

  	    if (this.content) {
  	      if (this.content.clone) {
  	        copy.content = this.content.clone();
  	      } else if (Array.isArray(this.content)) {
  	        copy.content = this.content.map(element => element.clone());
  	      } else {
  	        copy.content = this.content;
  	      }
  	    } else {
  	      copy.content = this.content;
  	    }

  	    return copy;
  	  }

  	  /**
  	   */
  	  toValue() {
  	    if (this.content instanceof Element) {
  	      return this.content.toValue();
  	    }

  	    if (this.content instanceof KeyValuePair) {
  	      return {
  	        key: this.content.key.toValue(),
  	        value: this.content.value ? this.content.value.toValue() : undefined,
  	      };
  	    }

  	    if (this.content && this.content.map) {
  	      return this.content.map(element => element.toValue(), this);
  	    }

  	    return this.content;
  	  }

  	  /**
  	   * Creates a reference pointing at the Element
  	   * @returns {RefElement}
  	   * @memberof Element.prototype
  	   */
  	  toRef(path) {
  	    if (this.id.toValue() === '') {
  	      throw Error('Cannot create reference to an element that does not contain an ID');
  	    }

  	    const ref = new this.RefElement(this.id.toValue());

  	    if (path) {
  	      ref.path = path;
  	    }

  	    return ref;
  	  }

  	  /**
  	   * Finds the given elements in the element tree.
  	   * When providing multiple element names, you must first freeze the element.
  	   *
  	   * @param names {...elementNames}
  	   * @returns {ArraySlice}
  	   */
  	  findRecursive(...elementNames) {
  	    if (arguments.length > 1 && !this.isFrozen) {
  	      throw new Error('Cannot find recursive with multiple element names without first freezing the element. Call `element.freeze()`');
  	    }

  	    const elementName = elementNames.pop();
  	    let elements = new ArraySlice();

  	    const append = (array, element) => {
  	      array.push(element);
  	      return array;
  	    };

  	    // Checks the given element and appends element/sub-elements
  	    // that match element name to given array
  	    const checkElement = (array, element) => {
  	      if (element.element === elementName) {
  	        array.push(element);
  	      }

  	      const items = element.findRecursive(elementName);
  	      if (items) {
  	        items.reduce(append, array);
  	      }

  	      if (element.content instanceof KeyValuePair) {
  	        if (element.content.key) {
  	          checkElement(array, element.content.key);
  	        }

  	        if (element.content.value) {
  	          checkElement(array, element.content.value);
  	        }
  	      }

  	      return array;
  	    };

  	    if (this.content) {
  	      // Direct Element
  	      if (this.content.element) {
  	        checkElement(elements, this.content);
  	      }

  	      // Element Array
  	      if (Array.isArray(this.content)) {
  	        this.content.reduce(checkElement, elements);
  	      }
  	    }

  	    if (!elementNames.isEmpty) {
  	      elements = elements.filter((element) => {
  	        let parentElements = element.parents.map(e => e.element);

  	        // eslint-disable-next-line no-restricted-syntax
  	        for (const namesIndex in elementNames) {
  	          const name = elementNames[namesIndex];
  	          const index = parentElements.indexOf(name);

  	          if (index !== -1) {
  	            parentElements = parentElements.splice(0, index);
  	          } else {
  	            return false;
  	          }
  	        }

  	        return true;
  	      });
  	    }

  	    return elements;
  	  }

  	  set(content) {
  	    this.content = content;
  	    return this;
  	  }

  	  equals(value) {
  	    return isEqual(this.toValue(), value);
  	  }

  	  getMetaProperty(name, value) {
  	    if (!this.meta.hasKey(name)) {
  	      if (this.isFrozen) {
  	        const element = this.refract(value);
  	        element.freeze();
  	        return element;
  	      }

  	      this.meta.set(name, value);
  	    }

  	    return this.meta.get(name);
  	  }

  	  setMetaProperty(name, value) {
  	    this.meta.set(name, value);
  	  }

  	  /**
  	   * @type String
  	   */
  	  get element() {
  	    // Returns 'element' so we don't have undefined as element
  	    return this._storedElement || 'element';
  	  }

  	  set element(element) {
  	    this._storedElement = element;
  	  }

  	  get content() {
  	    return this._content;
  	  }

  	  set content(value) {
  	    if (value instanceof Element) {
  	      this._content = value;
  	    } else if (value instanceof ArraySlice) {
  	      this.content = value.elements;
  	    } else if (
  	      typeof value == 'string'
  	      || typeof value == 'number'
  	      || typeof value == 'boolean'
  	      || value === 'null'
  	      || value == undefined
  	    ) {
  	      // Primitive Values
  	      this._content = value;
  	    } else if (value instanceof KeyValuePair) {
  	      this._content = value;
  	    } else if (Array.isArray(value)) {
  	      this._content = value.map(this.refract);
  	    } else if (typeof value === 'object') {
  	      this._content = Object.keys(value).map(key => new this.MemberElement(key, value[key]));
  	    } else {
  	      throw new Error('Cannot set content to given value');
  	    }
  	  }

  	  /**
  	   * @type ObjectElement
  	   */
  	  get meta() {
  	    if (!this._meta) {
  	      if (this.isFrozen) {
  	        const meta = new this.ObjectElement();
  	        meta.freeze();
  	        return meta;
  	      }

  	      this._meta = new this.ObjectElement();
  	    }

  	    return this._meta;
  	  }

  	  set meta(value) {
  	    if (value instanceof this.ObjectElement) {
  	      this._meta = value;
  	    } else {
  	      this.meta.set(value || {});
  	    }
  	  }

  	  /**
  	   * The attributes property defines attributes about the given instance
  	   * of the element, as specified by the element property.
  	   *
  	   * @type ObjectElement
  	   */
  	  get attributes() {
  	    if (!this._attributes) {
  	      if (this.isFrozen) {
  	        const meta = new this.ObjectElement();
  	        meta.freeze();
  	        return meta;
  	      }

  	      this._attributes = new this.ObjectElement();
  	    }

  	    return this._attributes;
  	  }

  	  set attributes(value) {
  	    if (value instanceof this.ObjectElement) {
  	      this._attributes = value;
  	    } else {
  	      this.attributes.set(value || {});
  	    }
  	  }

  	  /**
  	   * Unique Identifier, MUST be unique throughout an entire element tree.
  	   * @type StringElement
  	   */
  	  get id() {
  	    return this.getMetaProperty('id', '');
  	  }

  	  set id(element) {
  	    this.setMetaProperty('id', element);
  	  }

  	  /**
  	   * @type ArrayElement
  	   */
  	  get classes() {
  	    return this.getMetaProperty('classes', []);
  	  }

  	  set classes(element) {
  	    this.setMetaProperty('classes', element);
  	  }

  	  /**
  	   * Human-readable title of element
  	   * @type StringElement
  	   */
  	  get title() {
  	    return this.getMetaProperty('title', '');
  	  }

  	  set title(element) {
  	    this.setMetaProperty('title', element);
  	  }

  	  /**
  	   * Human-readable description of element
  	   * @type StringElement
  	   */
  	  get description() {
  	    return this.getMetaProperty('description', '');
  	  }

  	  set description(element) {
  	    this.setMetaProperty('description', element);
  	  }

  	  /**
  	   * @type ArrayElement
  	   */
  	  get links() {
  	    return this.getMetaProperty('links', []);
  	  }

  	  set links(element) {
  	    this.setMetaProperty('links', element);
  	  }

  	  /**
  	   * Returns whether the element is frozen.
  	   * @type boolean
  	   * @see freeze
  	   */
  	  get isFrozen() {
  	    return Object.isFrozen(this);
  	  }

  	  /**
  	   * Returns all of the parent elements.
  	   * @type ArraySlice
  	   */
  	  get parents() {
  	    let { parent } = this;
  	    const parents = new ArraySlice();

  	    while (parent) {
  	      parents.push(parent);

  	      // eslint-disable-next-line prefer-destructuring
  	      parent = parent.parent;
  	    }

  	    return parents;
  	  }

  	  /**
  	   * Returns all of the children elements found within the element.
  	   * @type ArraySlice
  	   * @see recursiveChildren
  	   */
  	  get children() {
  	    if (Array.isArray(this.content)) {
  	      return new ArraySlice(this.content);
  	    }

  	    if (this.content instanceof KeyValuePair) {
  	      const children = new ArraySlice([this.content.key]);

  	      if (this.content.value) {
  	        children.push(this.content.value);
  	      }

  	      return children;
  	    }

  	    if (this.content instanceof Element) {
  	      return new ArraySlice([this.content]);
  	    }

  	    return new ArraySlice();
  	  }

  	  /**
  	  * Returns all of the children elements found within the element recursively.
  	  * @type ArraySlice
  	  * @see children
  	  */
  	  get recursiveChildren() {
  	    const children = new ArraySlice();

  	    this.children.forEach((element) => {
  	      children.push(element);

  	      element.recursiveChildren.forEach((child) => {
  	        children.push(child);
  	      });
  	    });

  	    return children;
  	  }
  	}

  	Element_1 = Element;
  	return Element_1;
  }

  var NullElement_1;
  var hasRequiredNullElement;

  function requireNullElement () {
  	if (hasRequiredNullElement) return NullElement_1;
  	hasRequiredNullElement = 1;
  	const Element = requireElement();

  	/**
  	 */
  	class NullElement extends Element {
  	  constructor(content, meta, attributes) {
  	    super(content || null, meta, attributes);
  	    this.element = 'null';
  	  }

  	  primitive() {
  	    return 'null';
  	  }

  	  set() {
  	    return new Error('Cannot set the value of null');
  	  }
  	}

  	NullElement_1 = NullElement;
  	return NullElement_1;
  }

  var StringElement_1;
  var hasRequiredStringElement;

  function requireStringElement () {
  	if (hasRequiredStringElement) return StringElement_1;
  	hasRequiredStringElement = 1;
  	const Element = requireElement();

  	/**
  	 * @class StringElement
  	 *
  	 * @param {string} content
  	 * @param meta
  	 * @param attributes
  	 */
  	StringElement_1 = class StringElement extends Element {
  	  constructor(content, meta, attributes) {
  	    super(content, meta, attributes);
  	    this.element = 'string';
  	  }

  	  primitive() {
  	    return 'string';
  	  }

  	  /**
  	   * The length of the string.
  	   * @type number
  	   */
  	  get length() {
  	    return this.content.length;
  	  }
  	};
  	return StringElement_1;
  }

  var NumberElement_1;
  var hasRequiredNumberElement;

  function requireNumberElement () {
  	if (hasRequiredNumberElement) return NumberElement_1;
  	hasRequiredNumberElement = 1;
  	const Element = requireElement();

  	/**
  	 * @class NumberElement
  	 *
  	 * @param {number} content
  	 * @param meta
  	 * @param attributes
  	 */
  	NumberElement_1 = class NumberElement extends Element {
  	  constructor(content, meta, attributes) {
  	    super(content, meta, attributes);
  	    this.element = 'number';
  	  }

  	  primitive() {
  	    return 'number';
  	  }
  	};
  	return NumberElement_1;
  }

  var BooleanElement_1;
  var hasRequiredBooleanElement;

  function requireBooleanElement () {
  	if (hasRequiredBooleanElement) return BooleanElement_1;
  	hasRequiredBooleanElement = 1;
  	const Element = requireElement();

  	/**
  	 * @class BooleanElement
  	 *
  	 * @param {boolean} content
  	 * @param meta
  	 * @param attributes
  	 */
  	BooleanElement_1 = class BooleanElement extends Element {
  	  constructor(content, meta, attributes) {
  	    super(content, meta, attributes);
  	    this.element = 'boolean';
  	  }

  	  primitive() {
  	    return 'boolean';
  	  }
  	};
  	return BooleanElement_1;
  }

  var ArrayElement_1;
  var hasRequiredArrayElement;

  function requireArrayElement () {
  	if (hasRequiredArrayElement) return ArrayElement_1;
  	hasRequiredArrayElement = 1;
  	const negate = requireNegate();
  	const Element = requireElement();
  	const ArraySlice = requireArraySlice();

  	/**
  	 * @class
  	 *
  	 * @param {Element[]} content
  	 * @param meta
  	 * @param attributes
  	 */
  	class ArrayElement extends Element {
  	  constructor(content, meta, attributes) {
  	    super(content || [], meta, attributes);
  	    this.element = 'array';
  	  }

  	  primitive() {
  	    return 'array';
  	  }

  	  /**
  	   * @returns {Element}
  	   */
  	  get(index) {
  	    return this.content[index];
  	  }

  	  /**
  	   * Helper for returning the value of an item
  	   * This works for both ArrayElement and ObjectElement instances
  	   */
  	  getValue(indexOrKey) {
  	    const item = this.get(indexOrKey);

  	    if (item) {
  	      return item.toValue();
  	    }

  	    return undefined;
  	  }

  	  /**
  	   * @returns {Element}
  	   */
  	  getIndex(index) {
  	    return this.content[index];
  	  }

  	  set(index, value) {
  	    this.content[index] = this.refract(value);
  	    return this;
  	  }

  	  remove(index) {
  	    const removed = this.content.splice(index, 1);

  	    if (removed.length) {
  	      return removed[0];
  	    }

  	    return null;
  	  }

  	  /**
  	   * @param callback - Function to execute for each element
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   */
  	  map(callback, thisArg) {
  	    return this.content.map(callback, thisArg);
  	  }

  	  /**
  	   * Maps and then flattens the results.
  	   * @param callback - Function to execute for each element.
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @returns {array}
  	   */
  	  flatMap(callback, thisArg) {
  	    return this
  	      .map(callback, thisArg)
  	      .reduce((a, b) => a.concat(b), []);
  	  }

  	  /**
  	   * Returns an array containing the truthy results of calling the given transformation with each element of this sequence
  	   * @param transform - A closure that accepts an element of this array as its argument and returns an optional value.
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @memberof ArrayElement.prototype
  	   * @returns An array of the non-undefined results of calling transform with each element of the array
  	   */
  	  compactMap(transform, thisArg) {
  	    const results = [];

  	    this.forEach((element) => {
  	      const result = transform.bind(thisArg)(element);

  	      if (result) {
  	        results.push(result);
  	      }
  	    });

  	    return results;
  	  }

  	  /**
  	   * @param callback - Function to execute for each element
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @returns {ArraySlice}
  	   */
  	  filter(callback, thisArg) {
  	    return new ArraySlice(this.content.filter(callback, thisArg));
  	  }

  	  /**
  	   * @param callback - Function to execute for each element
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @returns {ArraySlice}
  	   */
  	  reject(callback, thisArg) {
  	    return this.filter(negate(callback), thisArg);
  	  }

  	  /**
  	   * This is a reduce function specifically for Minim arrays and objects. It
  	   * allows for returning normal values or Minim instances, so it converts any
  	   * primitives on each step.
  	   */
  	  reduce(callback, initialValue) {
  	    let startIndex;
  	    let memo;

  	    // Allows for defining a starting value of the reduce
  	    if (initialValue !== undefined) {
  	      startIndex = 0;
  	      memo = this.refract(initialValue);
  	    } else {
  	      startIndex = 1;
  	      // Object Element content items are member elements. Because of this,
  	      // the memo should start out as the member value rather than the
  	      // actual member itself.
  	      memo = this.primitive() === 'object' ? this.first.value : this.first;
  	    }

  	    // Sending each function call to the registry allows for passing Minim
  	    // instances through the function return. This means you can return
  	    // primitive values or return Minim instances and reduce will still work.
  	    for (let i = startIndex; i < this.length; i += 1) {
  	      const item = this.content[i];

  	      if (this.primitive() === 'object') {
  	        memo = this.refract(callback(memo, item.value, item.key, item, this));
  	      } else {
  	        memo = this.refract(callback(memo, item, i, this));
  	      }
  	    }

  	    return memo;
  	  }

  	  /**
  	   * @callback forEachCallback
  	   * @param {Element} currentValue
  	   * @param {NumberElement} index
  	   */

  	  /**
  	   * @param {forEachCallback} callback - Function to execute for each element
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @memberof ArrayElement.prototype
  	   */
  	  forEach(callback, thisArg) {
  	    this.content.forEach((item, index) => {
  	      callback.bind(thisArg)(item, this.refract(index));
  	    });
  	  }

  	  /**
  	   * @returns {Element}
  	   */
  	  shift() {
  	    return this.content.shift();
  	  }

  	  /**
  	   * @param value
  	   */
  	  unshift(value) {
  	    this.content.unshift(this.refract(value));
  	  }

  	  /**
  	   * @param value
  	   */
  	  push(value) {
  	    this.content.push(this.refract(value));
  	    return this;
  	  }

  	  /**
  	   * @param value
  	   */
  	  add(value) {
  	    this.push(value);
  	  }

  	  /**
  	   * Recusively search all descendents using a condition function.
  	   * @returns {Element[]}
  	   */
  	  findElements(condition, givenOptions) {
  	    const options = givenOptions || {};
  	    const recursive = !!options.recursive;
  	    const results = options.results === undefined ? [] : options.results;

  	    // The forEach method for Object Elements returns value, key, and member.
  	    // This passes those along to the condition function below.
  	    this.forEach((item, keyOrIndex, member) => {
  	      // We use duck-typing here to support any registered class that
  	      // may contain other elements.
  	      if (recursive && (item.findElements !== undefined)) {
  	        item.findElements(condition, {
  	          results,
  	          recursive,
  	        });
  	      }

  	      if (condition(item, keyOrIndex, member)) {
  	        results.push(item);
  	      }
  	    });

  	    return results;
  	  }

  	  /**
  	   * Recusively search all descendents using a condition function.
  	   * @param condition
  	   * @returns {ArraySlice}
  	   */
  	  find(condition) {
  	    return new ArraySlice(this.findElements(condition, { recursive: true }));
  	  }

  	  /**
  	   * @param {string} element
  	   * @returns {ArraySlice}
  	   */
  	  findByElement(element) {
  	    return this.find(item => item.element === element);
  	  }

  	  /**
  	   * @param {string} className
  	   * @returns {ArraySlice}
  	   * @memberof ArrayElement.prototype
  	   */
  	  findByClass(className) {
  	    return this.find(item => item.classes.includes(className));
  	  }

  	  /**
  	   * Search the tree recursively and find the element with the matching ID
  	   * @param {string} id
  	   * @returns {Element}
  	   * @memberof ArrayElement.prototype
  	   */
  	  getById(id) {
  	    return this.find(item => item.id.toValue() === id).first;
  	  }

  	  /**
  	   * Looks for matching children using deep equality
  	   * @param value
  	   * @returns {boolean}
  	   */
  	  includes(value) {
  	    return this.content.some(element => element.equals(value));
  	  }

  	  /**
  	   * Looks for matching children using deep equality
  	   * @param value
  	   * @returns {boolean}
  	   * @see includes
  	   * @deprecated method was replaced by includes
  	   */
  	  contains(value) {
  	    return this.includes(value);
  	  }

  	  // Fantasy Land

  	  /**
  	   * @returns {ArrayElement} An empty array element
  	   */
  	  empty() {
  	    return new this.constructor([]);
  	  }

  	  ['fantasy-land/empty']() {
  	    return this.empty();
  	  }

  	  /**
  	   * @param {ArrayElement} other
  	   * @returns {ArrayElement}
  	   */
  	  concat(other) {
  	    return new this.constructor(this.content.concat(other.content));
  	  }

  	  ['fantasy-land/concat'](other) {
  	    return this.concat(other);
  	  }

  	  ['fantasy-land/map'](transform) {
  	    return new this.constructor(this.map(transform));
  	  }

  	  ['fantasy-land/chain'](transform) {
  	    return this
  	      .map(element => transform(element), this)
  	      .reduce((a, b) => a.concat(b), this.empty());
  	  }

  	  ['fantasy-land/filter'](callback) {
  	    return new this.constructor(this.content.filter(callback));
  	  }

  	  ['fantasy-land/reduce'](transform, initialValue) {
  	    return this.content.reduce(transform, initialValue);
  	  }

  	  /**
  	   * Returns the length of the collection
  	   * @type number
  	   */
  	  get length() {
  	    return this.content.length;
  	  }

  	  /**
  	   * Returns whether the collection is empty
  	   * @type boolean
  	   */
  	  get isEmpty() {
  	    return this.content.length === 0;
  	  }

  	  /**
  	   * Return the first item in the collection
  	   * @type Element
  	   */
  	  get first() {
  	    return this.getIndex(0);
  	  }

  	  /**
  	   * Return the second item in the collection
  	   * @type Element
  	   */
  	  get second() {
  	    return this.getIndex(1);
  	  }

  	  /**
  	   * Return the last item in the collection
  	   * @type Element
  	   */
  	  get last() {
  	    return this.getIndex(this.length - 1);
  	  }
  	}

  	/**
  	 * @returns {ArrayElement} An empty array element
  	 */
  	ArrayElement.empty = function empty() {
  	  return new this();
  	};

  	ArrayElement['fantasy-land/empty'] = ArrayElement.empty;

  	if (typeof Symbol !== 'undefined') {
  	  ArrayElement.prototype[Symbol.iterator] = function symbol() {
  	    return this.content[Symbol.iterator]();
  	  };
  	}

  	ArrayElement_1 = ArrayElement;
  	return ArrayElement_1;
  }

  var MemberElement_1;
  var hasRequiredMemberElement;

  function requireMemberElement () {
  	if (hasRequiredMemberElement) return MemberElement_1;
  	hasRequiredMemberElement = 1;
  	const KeyValuePair = requireKeyValuePair();
  	const Element = requireElement();

  	/**
  	 * @class MemberElement
  	 *
  	 * @param {Element} key
  	 * @param {Element} value
  	 * @param meta
  	 * @param attributes
  	 */
  	MemberElement_1 = class MemberElement extends Element {
  	  constructor(key, value, meta, attributes) {
  	    super(new KeyValuePair(), meta, attributes);

  	    this.element = 'member';
  	    this.key = key;
  	    this.value = value;
  	  }

  	  /**
  	   * @type Element
  	   */
  	  get key() {
  	    return this.content.key;
  	  }

  	  set key(key) {
  	    this.content.key = this.refract(key);
  	  }

  	  /**
  	   * @type Element
  	   */
  	  get value() {
  	    return this.content.value;
  	  }

  	  set value(value) {
  	    this.content.value = this.refract(value);
  	  }
  	};
  	return MemberElement_1;
  }

  var ObjectSlice_1;
  var hasRequiredObjectSlice;

  function requireObjectSlice () {
  	if (hasRequiredObjectSlice) return ObjectSlice_1;
  	hasRequiredObjectSlice = 1;
  	const negate = requireNegate();
  	const ArraySlice = requireArraySlice();

  	/**
  	 */
  	class ObjectSlice extends ArraySlice {
  	  map(callback, thisArg) {
  	    return this.elements.map(member => callback.bind(thisArg)(member.value, member.key, member));
  	  }

  	  filter(callback, thisArg) {
  	    return new ObjectSlice(this.elements.filter(member => callback.bind(thisArg)(member.value, member.key, member)));
  	  }

  	  reject(callback, thisArg) {
  	    return this.filter(negate(callback.bind(thisArg)));
  	  }

  	  forEach(callback, thisArg) {
  	    return this.elements.forEach((member, index) => { callback.bind(thisArg)(member.value, member.key, member, index); });
  	  }

  	  /**
  	   * @returns {array}
  	   */
  	  keys() {
  	    return this.map((value, key) => key.toValue());
  	  }

  	  /**
  	   * @returns {array}
  	   */
  	  values() {
  	    return this.map(value => value.toValue());
  	  }
  	}

  	ObjectSlice_1 = ObjectSlice;
  	return ObjectSlice_1;
  }

  var ObjectElement_1;
  var hasRequiredObjectElement;

  function requireObjectElement () {
  	if (hasRequiredObjectElement) return ObjectElement_1;
  	hasRequiredObjectElement = 1;
  	const negate = requireNegate();
  	const isObject = requireIsObject();

  	const ArrayElement = requireArrayElement();
  	const MemberElement = requireMemberElement();
  	const ObjectSlice = requireObjectSlice();

  	/**
  	 * @class
  	 *
  	 * @param content
  	 * @param meta
  	 * @param attributes
  	 */
  	class ObjectElement extends ArrayElement {
  	  constructor(content, meta, attributes) {
  	    super(content || [], meta, attributes);
  	    this.element = 'object';
  	  }

  	  primitive() {
  	    return 'object';
  	  }

  	  toValue() {
  	    return this.content.reduce((results, el) => {
  	      results[el.key.toValue()] = el.value ? el.value.toValue() : undefined;
  	      return results;
  	    }, {});
  	  }

  	  /**
  	   * @param key
  	   * @returns {Element}
  	   */
  	  get(name) {
  	    const member = this.getMember(name);

  	    if (member) {
  	      return member.value;
  	    }

  	    return undefined;
  	  }

  	  /**
  	   * @param key
  	   * @returns {MemberElement}
  	   */
  	  getMember(name) {
  	    if (name === undefined) { return undefined; }

  	    return this.content.find(element => element.key.toValue() === name);
  	  }

  	  /**
  	   * @param key
  	   */
  	  remove(name) {
  	    let removed = null;

  	    this.content = this.content.filter((item) => {
  	      if (item.key.toValue() === name) {
  	        removed = item;
  	        return false;
  	      }

  	      return true;
  	    });

  	    return removed;
  	  }

  	  /**
  	   * @param key
  	   * @returns {Element}
  	   */
  	  getKey(name) {
  	    const member = this.getMember(name);

  	    if (member) {
  	      return member.key;
  	    }

  	    return undefined;
  	  }

  	  /**
  	   * Set allows either a key/value pair to be given or an object
  	   * If an object is given, each key is set to its respective value
  	   */
  	  set(keyOrObject, value) {
  	    if (isObject(keyOrObject)) {
  	      Object.keys(keyOrObject).forEach((objectKey) => {
  	        this.set(objectKey, keyOrObject[objectKey]);
  	      });

  	      return this;
  	    }

  	    // Store as key for clarity
  	    const key = keyOrObject;
  	    const member = this.getMember(key);

  	    if (member) {
  	      member.value = value;
  	    } else {
  	      this.content.push(new MemberElement(key, value));
  	    }

  	    return this;
  	  }

  	  /**
  	   */
  	  keys() {
  	    return this.content.map(item => item.key.toValue());
  	  }

  	  /**
  	   */
  	  values() {
  	    return this.content.map(item => item.value.toValue());
  	  }

  	  /**
  	   * @returns {boolean}
  	   */
  	  hasKey(value) {
  	    return this.content.some(member => member.key.equals(value));
  	  }

  	  /**
  	   * @returns {array}
  	   */
  	  items() {
  	    return this.content.map(item => [item.key.toValue(), item.value.toValue()]);
  	  }

  	  /**
  	   * @param callback
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   */
  	  map(callback, thisArg) {
  	    return this.content.map(item => callback.bind(thisArg)(item.value, item.key, item));
  	  }

  	  /**
  	   * Returns an array containing the truthy results of calling the given transformation with each element of this sequence
  	   * @param transform - A closure that accepts the value, key and member element of this object as its argument and returns an optional value.
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   * @returns An array of the non-undefined results of calling transform with each element of the array
  	   */
  	  compactMap(callback, thisArg) {
  	    const results = [];

  	    this.forEach((value, key, member) => {
  	      const result = callback.bind(thisArg)(value, key, member);

  	      if (result) {
  	        results.push(result);
  	      }
  	    });

  	    return results;
  	  }

  	  /**
  	   * @param callback
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   *
  	   * @returns {ObjectSlice}
  	   */
  	  filter(callback, thisArg) {
  	    return new ObjectSlice(this.content).filter(callback, thisArg);
  	  }

  	  /**
  	   * @param callback
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   *
  	   * @returns {ObjectSlice}
  	   *
  	   * @memberof ObjectElement.prototype
  	   */
  	  reject(callback, thisArg) {
  	    return this.filter(negate(callback), thisArg);
  	  }

  	  /**
  	   * @param callback
  	   * @param thisArg - Value to use as this (i.e the reference Object) when executing callback
  	   *
  	   * @memberof ObjectElement.prototype
  	   */
  	  forEach(callback, thisArg) {
  	    return this.content.forEach(item => callback.bind(thisArg)(item.value, item.key, item));
  	  }
  	}

  	ObjectElement_1 = ObjectElement;
  	return ObjectElement_1;
  }

  var LinkElement_1;
  var hasRequiredLinkElement;

  function requireLinkElement () {
  	if (hasRequiredLinkElement) return LinkElement_1;
  	hasRequiredLinkElement = 1;
  	const Element = requireElement();

  	/** Hyperlinking MAY be used to link to other resources, provide links to
  	 * instructions on how to process a given element (by way of a profile or
  	 * other means), and may be used to provide meta data about the element in
  	 * which it's found. The meaning and purpose of the hyperlink is defined by
  	 * the link relation according to RFC 5988.
  	 *
  	 * @class LinkElement
  	 *
  	 * @param content
  	 * @param meta
  	 * @param attributes
  	 */
  	LinkElement_1 = class LinkElement extends Element {
  	  constructor(content, meta, attributes) {
  	    super(content || [], meta, attributes);
  	    this.element = 'link';
  	  }

  	  /**
  	   * The relation identifier for the link, as defined in RFC 5988.
  	   * @type StringElement
  	   */
  	  get relation() {
  	    return this.attributes.get('relation');
  	  }

  	  set relation(relation) {
  	    this.attributes.set('relation', relation);
  	  }

  	  /**
  	   * The URI for the given link.
  	   * @type StringElement
  	   */
  	  get href() {
  	    return this.attributes.get('href');
  	  }

  	  set href(href) {
  	    this.attributes.set('href', href);
  	  }
  	};
  	return LinkElement_1;
  }

  var RefElement_1;
  var hasRequiredRefElement;

  function requireRefElement () {
  	if (hasRequiredRefElement) return RefElement_1;
  	hasRequiredRefElement = 1;
  	const Element = requireElement();

  	/**
  	 * @class RefElement
  	 *
  	 * @param content
  	 * @param meta
  	 * @param attributes
  	 *
  	 * @extends Element
  	 */
  	RefElement_1 = class RefElement extends Element {
  	  constructor(content, meta, attributes) {
  	    super(content || [], meta, attributes);
  	    this.element = 'ref';

  	    if (!this.path) {
  	      this.path = 'element';
  	    }
  	  }

  	  /**
  	   * Path of referenced element to transclude instead of element itself.
  	   * @type StringElement
  	   * @default element
  	   */
  	  get path() {
  	    return this.attributes.get('path');
  	  }

  	  set path(newValue) {
  	    this.attributes.set('path', newValue);
  	  }
  	};
  	return RefElement_1;
  }

  var elements;
  var hasRequiredElements;

  function requireElements () {
  	if (hasRequiredElements) return elements;
  	hasRequiredElements = 1;
  	const Element = requireElement();
  	const NullElement = requireNullElement();
  	const StringElement = requireStringElement();
  	const NumberElement = requireNumberElement();
  	const BooleanElement = requireBooleanElement();
  	const ArrayElement = requireArrayElement();
  	const MemberElement = requireMemberElement();
  	const ObjectElement = requireObjectElement();
  	const LinkElement = requireLinkElement();
  	const RefElement = requireRefElement();

  	const ArraySlice = requireArraySlice();
  	const ObjectSlice = requireObjectSlice();

  	const KeyValuePair = requireKeyValuePair();

  	/**
  	 * Refracts a JSON type to minim elements
  	 * @param value
  	 * @returns {Element}
  	 */
  	function refract(value) {
  	  if (value instanceof Element) {
  	    return value;
  	  }

  	  if (typeof value === 'string') {
  	    return new StringElement(value);
  	  }

  	  if (typeof value === 'number') {
  	    return new NumberElement(value);
  	  }

  	  if (typeof value === 'boolean') {
  	    return new BooleanElement(value);
  	  }

  	  if (value === null) {
  	    return new NullElement();
  	  }

  	  if (Array.isArray(value)) {
  	    return new ArrayElement(value.map(refract));
  	  }

  	  if (typeof value === 'object') {
  	    const element = new ObjectElement(value);
  	    return element;
  	  }

  	  return value;
  	}

  	Element.prototype.ObjectElement = ObjectElement;
  	Element.prototype.RefElement = RefElement;
  	Element.prototype.MemberElement = MemberElement;

  	Element.prototype.refract = refract;
  	ArraySlice.prototype.refract = refract;

  	/**
  	 * Contains all of the element classes, and related structures and methods
  	 * for handling with element instances.
  	 */
  	elements = {
  	  Element,
  	  NullElement,
  	  StringElement,
  	  NumberElement,
  	  BooleanElement,
  	  ArrayElement,
  	  MemberElement,
  	  ObjectElement,
  	  LinkElement,
  	  RefElement,

  	  refract,

  	  ArraySlice,
  	  ObjectSlice,
  	  KeyValuePair,
  	};
  	return elements;
  }

  var Namespace_1;
  var hasRequiredNamespace;

  function requireNamespace () {
  	if (hasRequiredNamespace) return Namespace_1;
  	hasRequiredNamespace = 1;
  	const isNull = requireIsNull();
  	const isString = requireIsString();
  	const isNumber = requireIsNumber();
  	const isBoolean = requireIsBoolean();
  	const isObject = requireIsObject();

  	const JSONSerialiser = requireJSONSerialiser();
  	const elements = requireElements();

  	/**
  	 * @class
  	 *
  	 * A refract element implementation with an extensible namespace, able to
  	 * load other namespaces into it.
  	 *
  	 * The namespace allows you to register your own classes to be instantiated
  	 * when a particular refract element is encountered, and allows you to specify
  	 * which elements get instantiated for existing Javascript objects.
  	 */
  	class Namespace {
  	  constructor(options) {
  	    this.elementMap = {};
  	    this.elementDetection = [];
  	    this.Element = elements.Element;
  	    this.KeyValuePair = elements.KeyValuePair;

  	    if (!options || !options.noDefault) {
  	      this.useDefault();
  	    }

  	    // These provide the defaults for new elements.
  	    this._attributeElementKeys = [];
  	    this._attributeElementArrayKeys = [];
  	  }

  	  /**
  	   * Use a namespace plugin or load a generic plugin.
  	   *
  	   * @param plugin
  	   */
  	  use(plugin) {
  	    if (plugin.namespace) {
  	      plugin.namespace({ base: this });
  	    }
  	    if (plugin.load) {
  	      plugin.load({ base: this });
  	    }
  	    return this;
  	  }

  	  /*
  	   * Use the default namespace. This preloads all the default elements
  	   * into this registry instance.
  	   */
  	  useDefault() {
  	    // Set up classes for default elements
  	    this
  	      .register('null', elements.NullElement)
  	      .register('string', elements.StringElement)
  	      .register('number', elements.NumberElement)
  	      .register('boolean', elements.BooleanElement)
  	      .register('array', elements.ArrayElement)
  	      .register('object', elements.ObjectElement)
  	      .register('member', elements.MemberElement)
  	      .register('ref', elements.RefElement)
  	      .register('link', elements.LinkElement);

  	    // Add instance detection functions to convert existing objects into
  	    // the corresponding refract elements.
  	    this
  	      .detect(isNull, elements.NullElement, false)
  	      .detect(isString, elements.StringElement, false)
  	      .detect(isNumber, elements.NumberElement, false)
  	      .detect(isBoolean, elements.BooleanElement, false)
  	      .detect(Array.isArray, elements.ArrayElement, false)
  	      .detect(isObject, elements.ObjectElement, false);

  	    return this;
  	  }

  	  /**
  	   * Register a new element class for an element.
  	   *
  	   * @param {string} name
  	   * @param elementClass
  	   */
  	  register(name, ElementClass) {
  	    this._elements = undefined;
  	    this.elementMap[name] = ElementClass;
  	    return this;
  	  }

  	  /**
  	   * Unregister a previously registered class for an element.
  	   *
  	   * @param {string} name
  	   */
  	  unregister(name) {
  	    this._elements = undefined;
  	    delete this.elementMap[name];
  	    return this;
  	  }

  	  /*
  	   * Add a new detection function to determine which element
  	   * class to use when converting existing js instances into
  	   * refract element.
  	   */
  	  detect(test, ElementClass, givenPrepend) {
  	    const prepend = givenPrepend === undefined ? true : givenPrepend;

  	    if (prepend) {
  	      this.elementDetection.unshift([test, ElementClass]);
  	    } else {
  	      this.elementDetection.push([test, ElementClass]);
  	    }

  	    return this;
  	  }

  	  /*
  	   * Convert an existing Javascript object into refract element instances, which
  	   * can be further processed or serialized into refract.
  	   * If the item passed in is already refracted, then it is returned
  	   * unmodified.
  	   */
  	  toElement(value) {
  	    if (value instanceof this.Element) { return value; }

  	    let element;

  	    for (let i = 0; i < this.elementDetection.length; i += 1) {
  	      const test = this.elementDetection[i][0];
  	      const ElementClass = this.elementDetection[i][1];

  	      if (test(value)) {
  	        element = new ElementClass(value);
  	        break;
  	      }
  	    }

  	    return element;
  	  }

  	  /*
  	   * Get an element class given an element name.
  	   */
  	  getElementClass(element) {
  	    const ElementClass = this.elementMap[element];

  	    if (ElementClass === undefined) {
  	      // Fall back to the base element. We may not know what
  	      // to do with the `content`, but downstream software
  	      // may know.
  	      return this.Element;
  	    }

  	    return ElementClass;
  	  }

  	  /*
  	   * Convert a refract document into refract element instances.
  	   */
  	  fromRefract(doc) {
  	    return this.serialiser.deserialise(doc);
  	  }

  	  /*
  	   * Convert an element to a Refracted JSON object.
  	   */
  	  toRefract(element) {
  	    return this.serialiser.serialise(element);
  	  }

  	  /*
  	   * Get an object that contains all registered element classes, where
  	   * the key is the PascalCased element name and the value is the class.
  	   */
  	  get elements() {
  	    if (this._elements === undefined) {
  	      this._elements = {
  	        Element: this.Element,
  	      };

  	      Object.keys(this.elementMap).forEach((name) => {
  	        // Currently, all registered element types use a camelCaseName.
  	        // Converting to PascalCase is as simple as upper-casing the first
  	        // letter.
  	        const pascal = name[0].toUpperCase() + name.substr(1);
  	        this._elements[pascal] = this.elementMap[name];
  	      });
  	    }

  	    return this._elements;
  	  }

  	  /**
  	   * Convinience method for getting a JSON Serialiser configured with the
  	   * current namespace
  	   *
  	   * @type JSONSerialiser
  	   * @readonly
  	   *
  	   * @memberof Namespace.prototype
  	   */
  	  get serialiser() {
  	    return new JSONSerialiser(this);
  	  }
  	}

  	JSONSerialiser.prototype.Namespace = Namespace;

  	Namespace_1 = Namespace;
  	return Namespace_1;
  }

  var JSON06Serialiser_1;
  var hasRequiredJSON06Serialiser;

  function requireJSON06Serialiser () {
  	if (hasRequiredJSON06Serialiser) return JSON06Serialiser_1;
  	hasRequiredJSON06Serialiser = 1;
  	const JSONSerialiser = requireJSONSerialiser();

  	JSON06Serialiser_1 = class JSON06Serialiser extends JSONSerialiser {
  	  serialise(element) {
  	    if (!(element instanceof this.namespace.elements.Element)) {
  	      throw new TypeError(`Given element \`${element}\` is not an Element instance`);
  	    }

  	    let variable;
  	    if (element._attributes && element.attributes.get('variable')) {
  	      variable = element.attributes.get('variable');
  	    }

  	    const payload = {
  	      element: element.element,
  	    };

  	    if (element._meta && element._meta.length > 0) {
  	      payload.meta = this.serialiseObject(element.meta);
  	    }

  	    const isEnum = (element.element === 'enum' || element.attributes.keys().indexOf('enumerations') !== -1);

  	    if (isEnum) {
  	      const attributes = this.enumSerialiseAttributes(element);

  	      if (attributes) {
  	        payload.attributes = attributes;
  	      }
  	    } else if (element._attributes && element._attributes.length > 0) {
  	      let { attributes } = element;

  	      // Meta attribute was renamed to metadata
  	      if (attributes.get('metadata')) {
  	        attributes = attributes.clone();
  	        attributes.set('meta', attributes.get('metadata'));
  	        attributes.remove('metadata');
  	      }

  	      if (element.element === 'member' && variable) {
  	        attributes = attributes.clone();
  	        attributes.remove('variable');
  	      }

  	      if (attributes.length > 0) {
  	        payload.attributes = this.serialiseObject(attributes);
  	      }
  	    }

  	    if (isEnum) {
  	      payload.content = this.enumSerialiseContent(element, payload);
  	    } else if (this[`${element.element}SerialiseContent`]) {
  	      payload.content = this[`${element.element}SerialiseContent`](element, payload);
  	    } else if (element.content !== undefined) {
  	      let content;

  	      if (variable && element.content.key) {
  	        content = element.content.clone();
  	        content.key.attributes.set('variable', variable);
  	        content = this.serialiseContent(content);
  	      } else {
  	        content = this.serialiseContent(element.content);
  	      }

  	      if (this.shouldSerialiseContent(element, content)) {
  	        payload.content = content;
  	      }
  	    } else if (this.shouldSerialiseContent(element, element.content) && element instanceof this.namespace.elements.Array) {
  	      payload.content = [];
  	    }

  	    return payload;
  	  }

  	  shouldSerialiseContent(element, content) {
  	    if (element.element === 'parseResult' || element.element === 'httpRequest'
  	        || element.element === 'httpResponse' || element.element === 'category'
  	        || element.element === 'link') {
  	      return true;
  	    }

  	    if (content === undefined) {
  	      return false;
  	    }

  	    if (Array.isArray(content) && content.length === 0) {
  	      return false;
  	    }

  	    return true;
  	  }

  	  refSerialiseContent(element, payload) {
  	    delete payload.attributes;

  	    return {
  	      href: element.toValue(),
  	      path: element.path.toValue(),
  	    };
  	  }

  	  sourceMapSerialiseContent(element) {
  	    return element.toValue();
  	  }

  	  dataStructureSerialiseContent(element) {
  	    return [this.serialiseContent(element.content)];
  	  }

  	  enumSerialiseAttributes(element) {
  	    const attributes = element.attributes.clone();

  	    // Enumerations attribute was is placed inside content (see `enumSerialiseContent` below)
  	    const enumerations = attributes.remove('enumerations') || new this.namespace.elements.Array([]);

  	    // Remove fixed type attribute from samples and default
  	    const defaultValue = attributes.get('default');
  	    let samples = attributes.get('samples') || new this.namespace.elements.Array([]);

  	    if (defaultValue && defaultValue.content) {
  	      if (defaultValue.content.attributes) {
  	        defaultValue.content.attributes.remove('typeAttributes');
  	      }
  	      // Wrap default in array (not sure it is really needed because tests pass without this line)
  	      attributes.set('default', new this.namespace.elements.Array([defaultValue.content]));
  	    }

  	    // Strip typeAttributes from samples, 0.6 doesn't usually contain them in samples
  	    samples.forEach((sample) => {
  	      if (sample.content && sample.content.element) {
  	        sample.content.attributes.remove('typeAttributes');
  	      }
  	    });

  	    // Content -> Samples
  	    if (element.content && enumerations.length !== 0) {
  	      // If we don't have enumerations, content should stay in
  	      // content (enumerations) as per Drafter 3 behaviour.
  	      samples.unshift(element.content);
  	    }

  	    samples = samples.map((sample) => {
  	      if (sample instanceof this.namespace.elements.Array) {
  	        return [sample];
  	      }

  	      return new this.namespace.elements.Array([sample.content]);
  	    });

  	    if (samples.length) {
  	      attributes.set('samples', samples);
  	    }

  	    if (attributes.length > 0) {
  	      return this.serialiseObject(attributes);
  	    }

  	    return undefined;
  	  }

  	  enumSerialiseContent(element) {
  	    // In API Elements < 1.0, the content is the enumerations
  	    // If we don't have an enumerations, use the value (Drafter 3 behaviour)

  	    if (element._attributes) {
  	      const enumerations = element.attributes.get('enumerations');

  	      if (enumerations && enumerations.length > 0) {
  	        return enumerations.content.map((enumeration) => {
  	          const e = enumeration.clone();
  	          e.attributes.remove('typeAttributes');
  	          return this.serialise(e);
  	        });
  	      }
  	    }

  	    if (element.content) {
  	      const value = element.content.clone();
  	      value.attributes.remove('typeAttributes');
  	      return [this.serialise(value)];
  	    }

  	    return [];
  	  }

  	  deserialise(value) {
  	    if (typeof value === 'string') {
  	      return new this.namespace.elements.String(value);
  	    }

  	    if (typeof value === 'number') {
  	      return new this.namespace.elements.Number(value);
  	    }

  	    if (typeof value === 'boolean') {
  	      return new this.namespace.elements.Boolean(value);
  	    }

  	    if (value === null) {
  	      return new this.namespace.elements.Null();
  	    }

  	    if (Array.isArray(value)) {
  	      return new this.namespace.elements.Array(value.map(this.deserialise, this));
  	    }

  	    const ElementClass = this.namespace.getElementClass(value.element);
  	    const element = new ElementClass();

  	    if (element.element !== value.element) {
  	      element.element = value.element;
  	    }

  	    if (value.meta) {
  	      this.deserialiseObject(value.meta, element.meta);
  	    }

  	    if (value.attributes) {
  	      this.deserialiseObject(value.attributes, element.attributes);
  	    }

  	    const content = this.deserialiseContent(value.content);
  	    if (content !== undefined || element.content === null) {
  	      element.content = content;
  	    }

  	    if (element.element === 'enum') {
  	      // Grab enumerations from content
  	      if (element.content) {
  	        element.attributes.set('enumerations', element.content);
  	      }

  	      // Unwrap the sample value (inside double array)
  	      let samples = element.attributes.get('samples');
  	      element.attributes.remove('samples');

  	      if (samples) {
  	        // Re-wrap samples from array of array to array of enum's

  	        const existingSamples = samples;

  	        samples = new this.namespace.elements.Array();
  	        existingSamples.forEach((existingSample) => {
  	          existingSample.forEach((sample) => {
  	            const enumElement = new ElementClass(sample);
  	            enumElement.element = element.element;
  	            samples.push(enumElement);
  	          });
  	        });

  	        const sample = samples.shift();

  	        if (sample) {
  	          element.content = sample.content;
  	        } else {
  	          element.content = undefined;
  	        }

  	        element.attributes.set('samples', samples);
  	      } else {
  	        element.content = undefined;
  	      }

  	      // Unwrap the default value
  	      let defaultValue = element.attributes.get('default');
  	      if (defaultValue && defaultValue.length > 0) {
  	        defaultValue = defaultValue.get(0);
  	        const defaultElement = new ElementClass(defaultValue);
  	        defaultElement.element = element.element;
  	        element.attributes.set('default', defaultElement);
  	      }
  	    } else if (element.element === 'dataStructure' && Array.isArray(element.content)) {
  	      [element.content] = element.content;
  	    } else if (element.element === 'category') {
  	      // "meta" attribute has been renamed to metadata
  	      const metadata = element.attributes.get('meta');

  	      if (metadata) {
  	        element.attributes.set('metadata', metadata);
  	        element.attributes.remove('meta');
  	      }
  	    } else if (element.element === 'member' && element.key && element.key._attributes && element.key._attributes.getValue('variable')) {
  	      element.attributes.set('variable', element.key.attributes.get('variable'));
  	      element.key.attributes.remove('variable');
  	    }

  	    return element;
  	  }

  	  // Private API

  	  serialiseContent(content) {
  	    if (content instanceof this.namespace.elements.Element) {
  	      return this.serialise(content);
  	    }

  	    if (content instanceof this.namespace.KeyValuePair) {
  	      const pair = {
  	        key: this.serialise(content.key),
  	      };

  	      if (content.value) {
  	        pair.value = this.serialise(content.value);
  	      }

  	      return pair;
  	    }

  	    if (content && content.map) {
  	      return content.map(this.serialise, this);
  	    }

  	    return content;
  	  }

  	  deserialiseContent(content) {
  	    if (content) {
  	      if (content.element) {
  	        return this.deserialise(content);
  	      }

  	      if (content.key) {
  	        const pair = new this.namespace.KeyValuePair(this.deserialise(content.key));

  	        if (content.value) {
  	          pair.value = this.deserialise(content.value);
  	        }

  	        return pair;
  	      }

  	      if (content.map) {
  	        return content.map(this.deserialise, this);
  	      }
  	    }

  	    return content;
  	  }

  	  shouldRefract(element) {
  	    if ((element._attributes && element.attributes.keys().length) || (element._meta && element.meta.keys().length)) {
  	      return true;
  	    }

  	    if (element.element === 'enum') {
  	      // enum elements are treated like primitives (array)
  	      return false;
  	    }

  	    if (element.element !== element.primitive() || element.element === 'member') {
  	      return true;
  	    }

  	    return false;
  	  }

  	  convertKeyToRefract(key, item) {
  	    if (this.shouldRefract(item)) {
  	      return this.serialise(item);
  	    }

  	    if (item.element === 'enum') {
  	      return this.serialiseEnum(item);
  	    }

  	    if (item.element === 'array') {
  	      return item.map((subItem) => {
  	        if (this.shouldRefract(subItem) || key === 'default') {
  	          return this.serialise(subItem);
  	        }

  	        if (subItem.element === 'array' || subItem.element === 'object' || subItem.element === 'enum') {
  	          // items for array or enum inside array are always serialised
  	          return subItem.children.map(subSubItem => this.serialise(subSubItem));
  	        }

  	        return subItem.toValue();
  	      });
  	    }

  	    if (item.element === 'object') {
  	      return (item.content || []).map(this.serialise, this);
  	    }

  	    return item.toValue();
  	  }

  	  serialiseEnum(element) {
  	    return element.children.map(item => this.serialise(item));
  	  }

  	  serialiseObject(obj) {
  	    const result = {};

  	    obj.forEach((value, key) => {
  	      if (value) {
  	        const keyValue = key.toValue();
  	        result[keyValue] = this.convertKeyToRefract(keyValue, value);
  	      }
  	    });

  	    return result;
  	  }

  	  deserialiseObject(from, to) {
  	    Object.keys(from).forEach((key) => {
  	      to.set(key, this.deserialise(from[key]));
  	    });
  	  }
  	};
  	return JSON06Serialiser_1;
  }

  var hasRequiredMinim;

  function requireMinim () {
  	if (hasRequiredMinim) return minim;
  	hasRequiredMinim = 1;
  	const Namespace = requireNamespace();
  	const elements = requireElements();

  	// Direct access to the Namespace class
  	minim.Namespace = Namespace;

  	// Special constructor for the Namespace class
  	minim.namespace = function namespace(options) {
  	  return new Namespace(options);
  	};

  	minim.KeyValuePair = requireKeyValuePair();

  	minim.ArraySlice = elements.ArraySlice;
  	minim.ObjectSlice = elements.ObjectSlice;

  	minim.Element = elements.Element;
  	minim.StringElement = elements.StringElement;
  	minim.NumberElement = elements.NumberElement;
  	minim.BooleanElement = elements.BooleanElement;
  	minim.NullElement = elements.NullElement;
  	minim.ArrayElement = elements.ArrayElement;
  	minim.ObjectElement = elements.ObjectElement;
  	minim.MemberElement = elements.MemberElement;
  	minim.RefElement = elements.RefElement;
  	minim.LinkElement = elements.LinkElement;

  	minim.refract = elements.refract;

  	minim.JSONSerialiser = requireJSONSerialiser();
  	minim.JSON06Serialiser = requireJSON06Serialiser();
  	return minim;
  }

  var minimExports = requireMinim();

  /**
   * @public
   */
  class Annotation extends minimExports.StringElement {
    // classes: warning | error

    constructor(content, meta, attributes) {
      super(content, meta, attributes);
      this.element = 'annotation';
    }
    get code() {
      return this.attributes.get('code');
    }
    set code(value) {
      this.attributes.set('code', value);
    }
  }

  /**
   * @public
   */
  class Comment extends minimExports.StringElement {
    constructor(content, meta, attributes) {
      super(content, meta, attributes);
      this.element = 'comment';
    }
  }

  /**
   * @public
   */
  class ParseResult extends minimExports.ArrayElement {
    constructor(content, meta, attributes) {
      super(content, meta, attributes);
      this.element = 'parseResult';
    }
    get api() {
      return this.children.filter(item => item.classes.contains('api')).first;
    }
    get results() {
      return this.children.filter(item => item.classes.contains('result'));
    }
    get result() {
      return this.results.first;
    }
    get annotations() {
      return this.children.filter(item => item.element === 'annotation');
    }
    get warnings() {
      return this.children.filter(item => item.element === 'annotation' && item.classes.contains('warning'));
    }
    get errors() {
      return this.children.filter(item => item.element === 'annotation' && item.classes.contains('error'));
    }
    get isEmpty() {
      return this.children.reject(item => item.element === 'annotation').isEmpty;
    }
    replaceResult(replacement) {
      const {
        result
      } = this;
      if (isUndefined(result)) {
        return false;
      }

      // @ts-ignore
      const searchIndex = this.content.findIndex(e => e === result);
      if (searchIndex === -1) {
        return false;
      }
      this.content[searchIndex] = replacement;
      return true;
    }
  }

  /**
   * @public
   */

  /**
   * @public
   */

  /**
   * @public
   */

  /**
   * @public
   */

  /**
   * @public
   */

  /**
   * @public
   */

  /**
   * @public
   */

  /**
   * @public
   */
  const hasMethod = (name, element) => {
    return typeof element === 'object' && element !== null && name in element && typeof element[name] === 'function';
  };

  /**
   * @public
   */
  const hasBasicElementProps = element => typeof element === 'object' && element != null && '_storedElement' in element && typeof element._storedElement === 'string' &&
  // eslint-disable-line no-underscore-dangle
  '_content' in element;

  /**
   * @public
   */
  const primitiveEq = (val, element) => {
    if (typeof element === 'object' && element !== null && 'primitive' in element) {
      return typeof element.primitive === 'function' && element.primitive() === val;
    }
    return false;
  };

  /**
   * @public
   */
  const hasClass = (cls, element) => {
    return typeof element === 'object' && element !== null && 'classes' in element && (Array.isArray(element.classes) || element.classes instanceof minimExports.ArrayElement) && element.classes.includes(cls);
  };

  /**
   * @public
   */
  const isElementType = (name, element) => typeof element === 'object' && element !== null && 'element' in element && element.element === name;

  /**
   * @public
   */
  const createPredicate = predicateCreator => {
    return predicateCreator({
      hasMethod,
      hasBasicElementProps,
      primitiveEq,
      isElementType,
      hasClass
    });
  };

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    primitiveEq
  }) => {
    return element => element instanceof minimExports.Element || hasBasicElementProps(element) && primitiveEq(undefined, element);
  });

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    primitiveEq
  }) => {
    return element => element instanceof minimExports.StringElement || hasBasicElementProps(element) && primitiveEq('string', element);
  });

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    primitiveEq
  }) => {
    return element => element instanceof minimExports.NumberElement || hasBasicElementProps(element) && primitiveEq('number', element);
  });

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    primitiveEq
  }) => {
    return element => element instanceof minimExports.NullElement || hasBasicElementProps(element) && primitiveEq('null', element);
  });

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    primitiveEq
  }) => {
    return element => element instanceof minimExports.BooleanElement || hasBasicElementProps(element) && primitiveEq('boolean', element);
  });

  /**
   * @public
   */
  const isObjectElement = createPredicate(({
    hasBasicElementProps,
    primitiveEq,
    hasMethod
  }) => {
    return element => element instanceof minimExports.ObjectElement || hasBasicElementProps(element) && primitiveEq('object', element) && hasMethod('keys', element) && hasMethod('values', element) && hasMethod('items', element);
  });

  /**
   * @public
   */
  const isArrayElement = createPredicate(({
    hasBasicElementProps,
    primitiveEq,
    hasMethod
  }) => {
    return element => element instanceof minimExports.ArrayElement && !(element instanceof minimExports.ObjectElement) || hasBasicElementProps(element) && primitiveEq('array', element) && hasMethod('push', element) && hasMethod('unshift', element) && hasMethod('map', element) && hasMethod('reduce', element);
  });

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    isElementType,
    primitiveEq
  }) => {
    return element => element instanceof minimExports.MemberElement || hasBasicElementProps(element) && isElementType('member', element) && primitiveEq(undefined, element);
  });

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    isElementType,
    primitiveEq
  }) => {
    return element => element instanceof minimExports.LinkElement || hasBasicElementProps(element) && isElementType('link', element) && primitiveEq(undefined, element);
  });

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    isElementType,
    primitiveEq
  }) => {
    return element => element instanceof minimExports.RefElement || hasBasicElementProps(element) && isElementType('ref', element) && primitiveEq(undefined, element);
  });

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    isElementType,
    primitiveEq
  }) => {
    return element => element instanceof Annotation || hasBasicElementProps(element) && isElementType('annotation', element) && primitiveEq('array', element);
  });

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    isElementType,
    primitiveEq
  }) => {
    return element => element instanceof Comment || hasBasicElementProps(element) && isElementType('comment', element) && primitiveEq('string', element);
  });

  /**
   * @public
   */
  createPredicate(({
    hasBasicElementProps,
    isElementType,
    primitiveEq
  }) => {
    return element => element instanceof ParseResult || hasBasicElementProps(element) && isElementType('parseResult', element) && primitiveEq('array', element);
  });

  class ApiDOMEvaluationRealm extends EvaluationRealm {
    name = 'apidom';
    isArray(node) {
      return isArrayElement(node);
    }
    isObject(node) {
      return isObjectElement(node);
    }
    sizeOf(node) {
      if (this.isArray(node) || this.isObject(node)) {
        return node.length;
      }
      return 0;
    }
    has(node, referenceToken) {
      if (this.isArray(node)) {
        const index = Number(referenceToken);
        const indexUint32 = index >>> 0;
        if (index !== indexUint32) {
          throw new JSONPointerIndexError(`Invalid array index "${referenceToken}": index must be an unsinged 32-bit integer`, {
            referenceToken,
            currentValue: node,
            realm: this.name
          });
        }
        return indexUint32 < this.sizeOf(node);
      }
      if (this.isObject(node)) {
        const keys = node.keys();
        const uniqueKeys = new Set(keys);
        if (keys.length !== uniqueKeys.size) {
          throw new JSONPointerKeyError(`Object key "${referenceToken}" is not unique — JSON Pointer requires unique member names`, {
            referenceToken,
            currentValue: node,
            realm: this.name
          });
        }
        return node.hasKey(referenceToken);
      }
      return false;
    }
    evaluate(node, referenceToken) {
      if (this.isArray(node)) {
        return node.get(Number(referenceToken));
      }
      return node.get(referenceToken);
    }
  }

  const evaluate = (value, jsonPointer, options = {}) => {
    return evaluate$1(value, jsonPointer, {
      ...options,
      realm: new ApiDOMEvaluationRealm()
    });
  };

  exports.ASTTranslator = ASTTranslator;
  exports.CSTTranslator = CSTTranslator;
  exports.Grammar = grammar$5;
  exports.JSONPointerCompileError = JSONPointerCompileError;
  exports.JSONPointerError = JSONPointerError;
  exports.JSONPointerEvaluateError = JSONPointerEvaluateError;
  exports.JSONPointerIndexError = JSONPointerIndexError;
  exports.JSONPointerKeyError = JSONPointerKeyError;
  exports.JSONPointerParseError = JSONPointerParseError;
  exports.JSONPointerTypeError = JSONPointerTypeError;
  exports.JSONString = jsonString;
  exports.URIFragmentIdentifier = uriFragmentIdentifier;
  exports.XMLTranslator = XMLTranslator;
  exports.compile = compile;
  exports.escape = escape;
  exports.evaluate = evaluate;
  exports.parse = parse;
  exports.testArrayDash = testArrayDash;
  exports.testArrayIndex = testArrayIndex;
  exports.testArrayLocation = testArrayLocation;
  exports.testJSONPointer = testJSONPointer;
  exports.testReferenceToken = testReferenceToken;
  exports.unescape = unescape;

  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

}));
