= 0; --i) {\n parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));\n }\n }\n }\n\n _forceRemove(currentNode);\n return true;\n }\n\n /* Check whether element has a valid namespace */\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n if ((tagName === 'noscript' || tagName === 'noembed') && regExpTest(/<\\/no(script|embed)/i, currentNode.innerHTML)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {\n /* Get the element's text content */\n content = currentNode.textContent;\n content = stringReplace(content, MUSTACHE_EXPR$$1, ' ');\n content = stringReplace(content, ERB_EXPR$$1, ' ');\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });\n currentNode.textContent = content;\n }\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeElements', currentNode, null);\n\n return false;\n };\n\n /**\n * _isValidAttribute\n *\n * @param {string} lcTag Lowercase tag name of containing element.\n * @param {string} lcName Lowercase attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n var _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {\n return false;\n }\n\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$$1, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$$1, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n return false;\n\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) ; else if (!value) ; else {\n return false;\n }\n\n return true;\n };\n\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param {Node} currentNode to sanitize\n */\n var _sanitizeAttributes = function _sanitizeAttributes(currentNode) {\n var attr = void 0;\n var value = void 0;\n var lcName = void 0;\n var l = void 0;\n /* Execute a hook if present */\n _executeHook('beforeSanitizeAttributes', currentNode, null);\n\n var attributes = currentNode.attributes;\n\n /* Check if we have attributes; if not we might have a text node */\n\n if (!attributes) {\n return;\n }\n\n var hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR\n };\n l = attributes.length;\n\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n attr = attributes[l];\n var _attr = attr,\n name = _attr.name,\n namespaceURI = _attr.namespaceURI;\n\n value = stringTrim(attr.value);\n lcName = stringToLowerCase(name);\n\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHook('uponSanitizeAttribute', currentNode, hookEvent);\n value = hookEvent.attrValue;\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n\n /* Remove attribute */\n _removeAttribute(name, currentNode);\n\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n continue;\n }\n\n /* Work around a security issue in jQuery 3.0 */\n if (regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n value = stringReplace(value, MUSTACHE_EXPR$$1, ' ');\n value = stringReplace(value, ERB_EXPR$$1, ' ');\n }\n\n /* Is `value` valid for this attribute? */\n var lcTag = currentNode.nodeName.toLowerCase();\n if (!_isValidAttribute(lcTag, lcName, value)) {\n continue;\n }\n\n /* Handle invalid data-* attribute set by try-catching it */\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n\n arrayPop(DOMPurify.removed);\n } catch (_) {}\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeAttributes', currentNode, null);\n };\n\n /**\n * _sanitizeShadowDOM\n *\n * @param {DocumentFragment} fragment to iterate over recursively\n */\n var _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {\n var shadowNode = void 0;\n var shadowIterator = _createIterator(fragment);\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeShadowDOM', fragment, null);\n\n while (shadowNode = shadowIterator.nextNode()) {\n /* Execute a hook if present */\n _executeHook('uponSanitizeShadowNode', shadowNode, null);\n\n /* Sanitize tags and elements */\n if (_sanitizeElements(shadowNode)) {\n continue;\n }\n\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(shadowNode);\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeShadowDOM', fragment, null);\n };\n\n /**\n * Sanitize\n * Public method providing core sanitation functionality\n *\n * @param {String|Node} dirty string or DOM node\n * @param {Object} configuration object\n */\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty, cfg) {\n var body = void 0;\n var importedNode = void 0;\n var currentNode = void 0;\n var oldNode = void 0;\n var returnNode = void 0;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '';\n }\n\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n // eslint-disable-next-line no-negated-condition\n if (typeof dirty.toString !== 'function') {\n throw typeErrorCreate('toString is not a function');\n } else {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n }\n }\n\n /* Check we can run. Otherwise fall back or ignore */\n if (!DOMPurify.isSupported) {\n if (_typeof(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {\n if (typeof dirty === 'string') {\n return window.toStaticHTML(dirty);\n }\n\n if (_isNode(dirty)) {\n return window.toStaticHTML(dirty.outerHTML);\n }\n }\n\n return dirty;\n }\n\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n\n /* Clean up removed elements */\n DOMPurify.removed = [];\n\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n\n if (IN_PLACE) ; else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;\n }\n\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : emptyHTML;\n }\n }\n\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n\n /* Get node iterator */\n var nodeIterator = _createIterator(IN_PLACE ? dirty : body);\n\n /* Now start iterating over the created document */\n while (currentNode = nodeIterator.nextNode()) {\n /* Fix IE's strange behavior with manipulated textNodes #89 */\n if (currentNode.nodeType === 3 && currentNode === oldNode) {\n continue;\n }\n\n /* Sanitize tags and elements */\n if (_sanitizeElements(currentNode)) {\n continue;\n }\n\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(currentNode);\n\n oldNode = currentNode;\n }\n\n oldNode = null;\n\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n\n if (RETURN_DOM_IMPORT) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n\n return returnNode;\n }\n\n var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$$1, ' ');\n serializedHTML = stringReplace(serializedHTML, ERB_EXPR$$1, ' ');\n }\n\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;\n };\n\n /**\n * Public method to set the configuration once\n * setConfig\n *\n * @param {Object} cfg configuration object\n */\n DOMPurify.setConfig = function (cfg) {\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n\n /**\n * Public method to remove the configuration\n * clearConfig\n *\n */\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n\n /**\n * Public method to check if an attribute value is valid.\n * Uses last set config, if any. Otherwise, uses config defaults.\n * isValidAttribute\n *\n * @param {string} tag Tag name of containing element.\n * @param {string} attr Attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.\n */\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n\n var lcTag = stringToLowerCase(tag);\n var lcName = stringToLowerCase(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n\n /**\n * AddHook\n * Public method to add DOMPurify hooks\n *\n * @param {String} entryPoint entry point for the hook to add\n * @param {Function} hookFunction function to execute\n */\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n\n hooks[entryPoint] = hooks[entryPoint] || [];\n arrayPush(hooks[entryPoint], hookFunction);\n };\n\n /**\n * RemoveHook\n * Public method to remove a DOMPurify hook at a given entryPoint\n * (pops it from the stack of hooks if more are present)\n *\n * @param {String} entryPoint entry point for the hook to remove\n */\n DOMPurify.removeHook = function (entryPoint) {\n if (hooks[entryPoint]) {\n arrayPop(hooks[entryPoint]);\n }\n };\n\n /**\n * RemoveHooks\n * Public method to remove all DOMPurify hooks at a given entryPoint\n *\n * @param {String} entryPoint entry point for the hooks to remove\n */\n DOMPurify.removeHooks = function (entryPoint) {\n if (hooks[entryPoint]) {\n hooks[entryPoint] = [];\n }\n };\n\n /**\n * RemoveAllHooks\n * Public method to remove all DOMPurify hooks\n *\n */\n DOMPurify.removeAllHooks = function () {\n hooks = {};\n };\n\n return DOMPurify;\n }\n\n var purify = createDOMPurify();\n\n return purify;\n\n}));\n//# sourceMappingURL=purify.js.map\n","var Handlebars = require(\"../../../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"\"\n + ((stack1 = container.lambda((depth0 != null ? lookupProperty(depth0,\"barContent\") : depth0), depth0)) != null ? stack1 : \"\")\n + \"\";\n},\"useData\":true});","var Handlebars = require(\"../../../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n return \"|\";\n},\"useData\":true});","var Handlebars = require(\"../../../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"1\":function(container,depth0,helpers,partials,data) {\n var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"\"\n + ((stack1 = container.lambda((depth0 != null ? lookupProperty(depth0,\"chordLineOffset\") : depth0), depth0)) != null ? stack1 : \"\")\n + \"\";\n},\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"\"\n + ((stack1 = lookupProperty(helpers,\"if\").call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? lookupProperty(depth0,\"chordLineOffset\") : depth0),{\"name\":\"if\",\"hash\":{},\"fn\":container.program(1, data, 0),\"inverse\":container.noop,\"data\":data,\"loc\":{\"start\":{\"line\":1,\"column\":26},\"end\":{\"line\":1,\"column\":128}}})) != null ? stack1 : \"\")\n + ((stack1 = container.lambda((depth0 != null ? lookupProperty(depth0,\"chordLine\") : depth0), depth0)) != null ? stack1 : \"\")\n + \"\";\n},\"useData\":true});","var Handlebars = require(\"../../../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"\"\n + container.escapeExpression(container.lambda((depth0 != null ? lookupProperty(depth0,\"chordSymbol\") : depth0), depth0))\n + \"\";\n},\"useData\":true});","var Handlebars = require(\"../../../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n return \" \";\n},\"useData\":true});","var Handlebars = require(\"../../../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var stack1, helper, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"\"\n + ((stack1 = container.lambda((depth0 != null ? lookupProperty(depth0,\"line\") : depth0), depth0)) != null ? stack1 : \"\")\n + \"
\";\n},\"useData\":true});","var Handlebars = require(\"../../../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"\"\n + ((stack1 = container.lambda((depth0 != null ? lookupProperty(depth0,\"lyricLine\") : depth0), depth0)) != null ? stack1 : \"\")\n + \"\";\n},\"useData\":true});","var Handlebars = require(\"../../../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"\"\n + ((stack1 = container.lambda((depth0 != null ? lookupProperty(depth0,\"sectionLabel\") : depth0), depth0)) != null ? stack1 : \"\")\n + \"\";\n},\"useData\":true});","var Handlebars = require(\"../../../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return ((stack1 = container.lambda((depth0 != null ? lookupProperty(depth0,\"song\") : depth0), depth0)) != null ? stack1 : \"\");\n},\"useData\":true});","var Handlebars = require(\"../../../../node_modules/handlebars/runtime.js\");\nfunction __default(obj) { return obj && (obj.__esModule ? obj[\"default\"] : obj); }\nmodule.exports = (Handlebars[\"default\"] || Handlebars).template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"\"\n + ((stack1 = container.lambda((depth0 != null ? lookupProperty(depth0,\"timeSignature\") : depth0), depth0)) != null ? stack1 : \"\")\n + \"\";\n},\"useData\":true});","'use strict';\n\nexports.__esModule = true;\n// istanbul ignore next\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n// istanbul ignore next\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nvar _handlebarsBase = require('./handlebars/base');\n\nvar base = _interopRequireWildcard(_handlebarsBase);\n\n// Each of these augment the Handlebars object. No need to setup here.\n// (This is done to easily share code between commonjs and browse envs)\n\nvar _handlebarsSafeString = require('./handlebars/safe-string');\n\nvar _handlebarsSafeString2 = _interopRequireDefault(_handlebarsSafeString);\n\nvar _handlebarsException = require('./handlebars/exception');\n\nvar _handlebarsException2 = _interopRequireDefault(_handlebarsException);\n\nvar _handlebarsUtils = require('./handlebars/utils');\n\nvar Utils = _interopRequireWildcard(_handlebarsUtils);\n\nvar _handlebarsRuntime = require('./handlebars/runtime');\n\nvar runtime = _interopRequireWildcard(_handlebarsRuntime);\n\nvar _handlebarsNoConflict = require('./handlebars/no-conflict');\n\nvar _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);\n\n// For compatibility and usage outside of module systems, make the Handlebars object a namespace\nfunction create() {\n var hb = new base.HandlebarsEnvironment();\n\n Utils.extend(hb, base);\n hb.SafeString = _handlebarsSafeString2['default'];\n hb.Exception = _handlebarsException2['default'];\n hb.Utils = Utils;\n hb.escapeExpression = Utils.escapeExpression;\n\n hb.VM = runtime;\n hb.template = function (spec) {\n return runtime.template(spec, hb);\n };\n\n return hb;\n}\n\nvar inst = create();\ninst.create = create;\n\n_handlebarsNoConflict2['default'](inst);\n\ninst['default'] = inst;\n\nexports['default'] = inst;\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi9oYW5kbGViYXJzLnJ1bnRpbWUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OEJBQXNCLG1CQUFtQjs7SUFBN0IsSUFBSTs7Ozs7b0NBSU8sMEJBQTBCOzs7O21DQUMzQix3QkFBd0I7Ozs7K0JBQ3ZCLG9CQUFvQjs7SUFBL0IsS0FBSzs7aUNBQ1Esc0JBQXNCOztJQUFuQyxPQUFPOztvQ0FFSSwwQkFBMEI7Ozs7O0FBR2pELFNBQVMsTUFBTSxHQUFHO0FBQ2hCLE1BQUksRUFBRSxHQUFHLElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7O0FBRTFDLE9BQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3ZCLElBQUUsQ0FBQyxVQUFVLG9DQUFhLENBQUM7QUFDM0IsSUFBRSxDQUFDLFNBQVMsbUNBQVksQ0FBQztBQUN6QixJQUFFLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztBQUNqQixJQUFFLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixDQUFDOztBQUU3QyxJQUFFLENBQUMsRUFBRSxHQUFHLE9BQU8sQ0FBQztBQUNoQixJQUFFLENBQUMsUUFBUSxHQUFHLFVBQVMsSUFBSSxFQUFFO0FBQzNCLFdBQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7R0FDbkMsQ0FBQzs7QUFFRixTQUFPLEVBQUUsQ0FBQztDQUNYOztBQUVELElBQUksSUFBSSxHQUFHLE1BQU0sRUFBRSxDQUFDO0FBQ3BCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDOztBQUVyQixrQ0FBVyxJQUFJLENBQUMsQ0FBQzs7QUFFakIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQzs7cUJBRVIsSUFBSSIsImZpbGUiOiJoYW5kbGViYXJzLnJ1bnRpbWUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBiYXNlIGZyb20gJy4vaGFuZGxlYmFycy9iYXNlJztcblxuLy8gRWFjaCBvZiB0aGVzZSBhdWdtZW50IHRoZSBIYW5kbGViYXJzIG9iamVjdC4gTm8gbmVlZCB0byBzZXR1cCBoZXJlLlxuLy8gKFRoaXMgaXMgZG9uZSB0byBlYXNpbHkgc2hhcmUgY29kZSBiZXR3ZWVuIGNvbW1vbmpzIGFuZCBicm93c2UgZW52cylcbmltcG9ydCBTYWZlU3RyaW5nIGZyb20gJy4vaGFuZGxlYmFycy9zYWZlLXN0cmluZyc7XG5pbXBvcnQgRXhjZXB0aW9uIGZyb20gJy4vaGFuZGxlYmFycy9leGNlcHRpb24nO1xuaW1wb3J0ICogYXMgVXRpbHMgZnJvbSAnLi9oYW5kbGViYXJzL3V0aWxzJztcbmltcG9ydCAqIGFzIHJ1bnRpbWUgZnJvbSAnLi9oYW5kbGViYXJzL3J1bnRpbWUnO1xuXG5pbXBvcnQgbm9Db25mbGljdCBmcm9tICcuL2hhbmRsZWJhcnMvbm8tY29uZmxpY3QnO1xuXG4vLyBGb3IgY29tcGF0aWJpbGl0eSBhbmQgdXNhZ2Ugb3V0c2lkZSBvZiBtb2R1bGUgc3lzdGVtcywgbWFrZSB0aGUgSGFuZGxlYmFycyBvYmplY3QgYSBuYW1lc3BhY2VcbmZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgbGV0IGhiID0gbmV3IGJhc2UuSGFuZGxlYmFyc0Vudmlyb25tZW50KCk7XG5cbiAgVXRpbHMuZXh0ZW5kKGhiLCBiYXNlKTtcbiAgaGIuU2FmZVN0cmluZyA9IFNhZmVTdHJpbmc7XG4gIGhiLkV4Y2VwdGlvbiA9IEV4Y2VwdGlvbjtcbiAgaGIuVXRpbHMgPSBVdGlscztcbiAgaGIuZXNjYXBlRXhwcmVzc2lvbiA9IFV0aWxzLmVzY2FwZUV4cHJlc3Npb247XG5cbiAgaGIuVk0gPSBydW50aW1lO1xuICBoYi50ZW1wbGF0ZSA9IGZ1bmN0aW9uKHNwZWMpIHtcbiAgICByZXR1cm4gcnVudGltZS50ZW1wbGF0ZShzcGVjLCBoYik7XG4gIH07XG5cbiAgcmV0dXJuIGhiO1xufVxuXG5sZXQgaW5zdCA9IGNyZWF0ZSgpO1xuaW5zdC5jcmVhdGUgPSBjcmVhdGU7XG5cbm5vQ29uZmxpY3QoaW5zdCk7XG5cbmluc3RbJ2RlZmF1bHQnXSA9IGluc3Q7XG5cbmV4cG9ydCBkZWZhdWx0IGluc3Q7XG4iXX0=\n","'use strict';\n\nexports.__esModule = true;\nexports.HandlebarsEnvironment = HandlebarsEnvironment;\n// istanbul ignore next\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _utils = require('./utils');\n\nvar _exception = require('./exception');\n\nvar _exception2 = _interopRequireDefault(_exception);\n\nvar _helpers = require('./helpers');\n\nvar _decorators = require('./decorators');\n\nvar _logger = require('./logger');\n\nvar _logger2 = _interopRequireDefault(_logger);\n\nvar _internalProtoAccess = require('./internal/proto-access');\n\nvar VERSION = '4.7.7';\nexports.VERSION = VERSION;\nvar COMPILER_REVISION = 8;\nexports.COMPILER_REVISION = COMPILER_REVISION;\nvar LAST_COMPATIBLE_COMPILER_REVISION = 7;\n\nexports.LAST_COMPATIBLE_COMPILER_REVISION = LAST_COMPATIBLE_COMPILER_REVISION;\nvar REVISION_CHANGES = {\n 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it\n 2: '== 1.0.0-rc.3',\n 3: '== 1.0.0-rc.4',\n 4: '== 1.x.x',\n 5: '== 2.0.0-alpha.x',\n 6: '>= 2.0.0-beta.1',\n 7: '>= 4.0.0 <4.3.0',\n 8: '>= 4.3.0'\n};\n\nexports.REVISION_CHANGES = REVISION_CHANGES;\nvar objectType = '[object Object]';\n\nfunction HandlebarsEnvironment(helpers, partials, decorators) {\n this.helpers = helpers || {};\n this.partials = partials || {};\n this.decorators = decorators || {};\n\n _helpers.registerDefaultHelpers(this);\n _decorators.registerDefaultDecorators(this);\n}\n\nHandlebarsEnvironment.prototype = {\n constructor: HandlebarsEnvironment,\n\n logger: _logger2['default'],\n log: _logger2['default'].log,\n\n registerHelper: function registerHelper(name, fn) {\n if (_utils.toString.call(name) === objectType) {\n if (fn) {\n throw new _exception2['default']('Arg not supported with multiple helpers');\n }\n _utils.extend(this.helpers, name);\n } else {\n this.helpers[name] = fn;\n }\n },\n unregisterHelper: function unregisterHelper(name) {\n delete this.helpers[name];\n },\n\n registerPartial: function registerPartial(name, partial) {\n if (_utils.toString.call(name) === objectType) {\n _utils.extend(this.partials, name);\n } else {\n if (typeof partial === 'undefined') {\n throw new _exception2['default']('Attempting to register a partial called \"' + name + '\" as undefined');\n }\n this.partials[name] = partial;\n }\n },\n unregisterPartial: function unregisterPartial(name) {\n delete this.partials[name];\n },\n\n registerDecorator: function registerDecorator(name, fn) {\n if (_utils.toString.call(name) === objectType) {\n if (fn) {\n throw new _exception2['default']('Arg not supported with multiple decorators');\n }\n _utils.extend(this.decorators, name);\n } else {\n this.decorators[name] = fn;\n }\n },\n unregisterDecorator: function unregisterDecorator(name) {\n delete this.decorators[name];\n },\n /**\n * Reset the memory of illegal property accesses that have already been logged.\n * @deprecated should only be used in handlebars test-cases\n */\n resetLoggedPropertyAccesses: function resetLoggedPropertyAccesses() {\n _internalProtoAccess.resetLoggedProperties();\n }\n};\n\nvar log = _logger2['default'].log;\n\nexports.log = log;\nexports.createFrame = _utils.createFrame;\nexports.logger = _logger2['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2Jhc2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7cUJBQThDLFNBQVM7O3lCQUNqQyxhQUFhOzs7O3VCQUNJLFdBQVc7OzBCQUNSLGNBQWM7O3NCQUNyQyxVQUFVOzs7O21DQUNTLHlCQUF5Qjs7QUFFeEQsSUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDOztBQUN4QixJQUFNLGlCQUFpQixHQUFHLENBQUMsQ0FBQzs7QUFDNUIsSUFBTSxpQ0FBaUMsR0FBRyxDQUFDLENBQUM7OztBQUU1QyxJQUFNLGdCQUFnQixHQUFHO0FBQzlCLEdBQUMsRUFBRSxhQUFhO0FBQ2hCLEdBQUMsRUFBRSxlQUFlO0FBQ2xCLEdBQUMsRUFBRSxlQUFlO0FBQ2xCLEdBQUMsRUFBRSxVQUFVO0FBQ2IsR0FBQyxFQUFFLGtCQUFrQjtBQUNyQixHQUFDLEVBQUUsaUJBQWlCO0FBQ3BCLEdBQUMsRUFBRSxpQkFBaUI7QUFDcEIsR0FBQyxFQUFFLFVBQVU7Q0FDZCxDQUFDOzs7QUFFRixJQUFNLFVBQVUsR0FBRyxpQkFBaUIsQ0FBQzs7QUFFOUIsU0FBUyxxQkFBcUIsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRTtBQUNuRSxNQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sSUFBSSxFQUFFLENBQUM7QUFDN0IsTUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLElBQUksRUFBRSxDQUFDO0FBQy9CLE1BQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxJQUFJLEVBQUUsQ0FBQzs7QUFFbkMsa0NBQXVCLElBQUksQ0FBQyxDQUFDO0FBQzdCLHdDQUEwQixJQUFJLENBQUMsQ0FBQztDQUNqQzs7QUFFRCxxQkFBcUIsQ0FBQyxTQUFTLEdBQUc7QUFDaEMsYUFBVyxFQUFFLHFCQUFxQjs7QUFFbEMsUUFBTSxxQkFBUTtBQUNkLEtBQUcsRUFBRSxvQkFBTyxHQUFHOztBQUVmLGdCQUFjLEVBQUUsd0JBQVMsSUFBSSxFQUFFLEVBQUUsRUFBRTtBQUNqQyxRQUFJLGdCQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxVQUFVLEVBQUU7QUFDdEMsVUFBSSxFQUFFLEVBQUU7QUFDTixjQUFNLDJCQUFjLHlDQUF5QyxDQUFDLENBQUM7T0FDaEU7QUFDRCxvQkFBTyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0tBQzVCLE1BQU07QUFDTCxVQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUN6QjtHQUNGO0FBQ0Qsa0JBQWdCLEVBQUUsMEJBQVMsSUFBSSxFQUFFO0FBQy9CLFdBQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztHQUMzQjs7QUFFRCxpQkFBZSxFQUFFLHlCQUFTLElBQUksRUFBRSxPQUFPLEVBQUU7QUFDdkMsUUFBSSxnQkFBUyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssVUFBVSxFQUFFO0FBQ3RDLG9CQUFPLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDN0IsTUFBTTtBQUNMLFVBQUksT0FBTyxPQUFPLEtBQUssV0FBVyxFQUFFO0FBQ2xDLGNBQU0seUVBQ3dDLElBQUksb0JBQ2pELENBQUM7T0FDSDtBQUNELFVBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDO0tBQy9CO0dBQ0Y7QUFDRCxtQkFBaUIsRUFBRSwyQkFBUyxJQUFJLEVBQUU7QUFDaEMsV0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0dBQzVCOztBQUVELG1CQUFpQixFQUFFLDJCQUFTLElBQUksRUFBRSxFQUFFLEVBQUU7QUFDcEMsUUFBSSxnQkFBUyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssVUFBVSxFQUFFO0FBQ3RDLFVBQUksRUFBRSxFQUFFO0FBQ04sY0FBTSwyQkFBYyw0Q0FBNEMsQ0FBQyxDQUFDO09BQ25FO0FBQ0Qsb0JBQU8sSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztLQUMvQixNQUFNO0FBQ0wsVUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7S0FDNUI7R0FDRjtBQUNELHFCQUFtQixFQUFFLDZCQUFTLElBQUksRUFBRTtBQUNsQyxXQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7R0FDOUI7Ozs7O0FBS0QsNkJBQTJCLEVBQUEsdUNBQUc7QUFDNUIsZ0RBQXVCLENBQUM7R0FDekI7Q0FDRixDQUFDOztBQUVLLElBQUksR0FBRyxHQUFHLG9CQUFPLEdBQUcsQ0FBQzs7O1FBRW5CLFdBQVc7UUFBRSxNQUFNIiwiZmlsZSI6ImJhc2UuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVGcmFtZSwgZXh0ZW5kLCB0b1N0cmluZyB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IEV4Y2VwdGlvbiBmcm9tICcuL2V4Y2VwdGlvbic7XG5pbXBvcnQgeyByZWdpc3RlckRlZmF1bHRIZWxwZXJzIH0gZnJvbSAnLi9oZWxwZXJzJztcbmltcG9ydCB7IHJlZ2lzdGVyRGVmYXVsdERlY29yYXRvcnMgfSBmcm9tICcuL2RlY29yYXRvcnMnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgeyByZXNldExvZ2dlZFByb3BlcnRpZXMgfSBmcm9tICcuL2ludGVybmFsL3Byb3RvLWFjY2Vzcyc7XG5cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gJzQuNy43JztcbmV4cG9ydCBjb25zdCBDT01QSUxFUl9SRVZJU0lPTiA9IDg7XG5leHBvcnQgY29uc3QgTEFTVF9DT01QQVRJQkxFX0NPTVBJTEVSX1JFVklTSU9OID0gNztcblxuZXhwb3J0IGNvbnN0IFJFVklTSU9OX0NIQU5HRVMgPSB7XG4gIDE6ICc8PSAxLjAucmMuMicsIC8vIDEuMC5yYy4yIGlzIGFjdHVhbGx5IHJldjIgYnV0IGRvZXNuJ3QgcmVwb3J0IGl0XG4gIDI6ICc9PSAxLjAuMC1yYy4zJyxcbiAgMzogJz09IDEuMC4wLXJjLjQnLFxuICA0OiAnPT0gMS54LngnLFxuICA1OiAnPT0gMi4wLjAtYWxwaGEueCcsXG4gIDY6ICc+PSAyLjAuMC1iZXRhLjEnLFxuICA3OiAnPj0gNC4wLjAgPDQuMy4wJyxcbiAgODogJz49IDQuMy4wJ1xufTtcblxuY29uc3Qgb2JqZWN0VHlwZSA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG5leHBvcnQgZnVuY3Rpb24gSGFuZGxlYmFyc0Vudmlyb25tZW50KGhlbHBlcnMsIHBhcnRpYWxzLCBkZWNvcmF0b3JzKSB7XG4gIHRoaXMuaGVscGVycyA9IGhlbHBlcnMgfHwge307XG4gIHRoaXMucGFydGlhbHMgPSBwYXJ0aWFscyB8fCB7fTtcbiAgdGhpcy5kZWNvcmF0b3JzID0gZGVjb3JhdG9ycyB8fCB7fTtcblxuICByZWdpc3RlckRlZmF1bHRIZWxwZXJzKHRoaXMpO1xuICByZWdpc3RlckRlZmF1bHREZWNvcmF0b3JzKHRoaXMpO1xufVxuXG5IYW5kbGViYXJzRW52aXJvbm1lbnQucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogSGFuZGxlYmFyc0Vudmlyb25tZW50LFxuXG4gIGxvZ2dlcjogbG9nZ2VyLFxuICBsb2c6IGxvZ2dlci5sb2csXG5cbiAgcmVnaXN0ZXJIZWxwZXI6IGZ1bmN0aW9uKG5hbWUsIGZuKSB7XG4gICAgaWYgKHRvU3RyaW5nLmNhbGwobmFtZSkgPT09IG9iamVjdFR5cGUpIHtcbiAgICAgIGlmIChmbikge1xuICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCdBcmcgbm90IHN1cHBvcnRlZCB3aXRoIG11bHRpcGxlIGhlbHBlcnMnKTtcbiAgICAgIH1cbiAgICAgIGV4dGVuZCh0aGlzLmhlbHBlcnMsIG5hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhlbHBlcnNbbmFtZV0gPSBmbjtcbiAgICB9XG4gIH0sXG4gIHVucmVnaXN0ZXJIZWxwZXI6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBkZWxldGUgdGhpcy5oZWxwZXJzW25hbWVdO1xuICB9LFxuXG4gIHJlZ2lzdGVyUGFydGlhbDogZnVuY3Rpb24obmFtZSwgcGFydGlhbCkge1xuICAgIGlmICh0b1N0cmluZy5jYWxsKG5hbWUpID09PSBvYmplY3RUeXBlKSB7XG4gICAgICBleHRlbmQodGhpcy5wYXJ0aWFscywgbmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2YgcGFydGlhbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbihcbiAgICAgICAgICBgQXR0ZW1wdGluZyB0byByZWdpc3RlciBhIHBhcnRpYWwgY2FsbGVkIFwiJHtuYW1lfVwiIGFzIHVuZGVmaW5lZGBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucGFydGlhbHNbbmFtZV0gPSBwYXJ0aWFsO1xuICAgIH1cbiAgfSxcbiAgdW5yZWdpc3RlclBhcnRpYWw6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBkZWxldGUgdGhpcy5wYXJ0aWFsc1tuYW1lXTtcbiAgfSxcblxuICByZWdpc3RlckRlY29yYXRvcjogZnVuY3Rpb24obmFtZSwgZm4pIHtcbiAgICBpZiAodG9TdHJpbmcuY2FsbChuYW1lKSA9PT0gb2JqZWN0VHlwZSkge1xuICAgICAgaWYgKGZuKSB7XG4gICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oJ0FyZyBub3Qgc3VwcG9ydGVkIHdpdGggbXVsdGlwbGUgZGVjb3JhdG9ycycpO1xuICAgICAgfVxuICAgICAgZXh0ZW5kKHRoaXMuZGVjb3JhdG9ycywgbmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGVjb3JhdG9yc1tuYW1lXSA9IGZuO1xuICAgIH1cbiAgfSxcbiAgdW5yZWdpc3RlckRlY29yYXRvcjogZnVuY3Rpb24obmFtZSkge1xuICAgIGRlbGV0ZSB0aGlzLmRlY29yYXRvcnNbbmFtZV07XG4gIH0sXG4gIC8qKlxuICAgKiBSZXNldCB0aGUgbWVtb3J5IG9mIGlsbGVnYWwgcHJvcGVydHkgYWNjZXNzZXMgdGhhdCBoYXZlIGFscmVhZHkgYmVlbiBsb2dnZWQuXG4gICAqIEBkZXByZWNhdGVkIHNob3VsZCBvbmx5IGJlIHVzZWQgaW4gaGFuZGxlYmFycyB0ZXN0LWNhc2VzXG4gICAqL1xuICByZXNldExvZ2dlZFByb3BlcnR5QWNjZXNzZXMoKSB7XG4gICAgcmVzZXRMb2dnZWRQcm9wZXJ0aWVzKCk7XG4gIH1cbn07XG5cbmV4cG9ydCBsZXQgbG9nID0gbG9nZ2VyLmxvZztcblxuZXhwb3J0IHsgY3JlYXRlRnJhbWUsIGxvZ2dlciB9O1xuIl19\n","'use strict';\n\nexports.__esModule = true;\nexports.registerDefaultDecorators = registerDefaultDecorators;\n// istanbul ignore next\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _decoratorsInline = require('./decorators/inline');\n\nvar _decoratorsInline2 = _interopRequireDefault(_decoratorsInline);\n\nfunction registerDefaultDecorators(instance) {\n _decoratorsInline2['default'](instance);\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2RlY29yYXRvcnMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Z0NBQTJCLHFCQUFxQjs7OztBQUV6QyxTQUFTLHlCQUF5QixDQUFDLFFBQVEsRUFBRTtBQUNsRCxnQ0FBZSxRQUFRLENBQUMsQ0FBQztDQUMxQiIsImZpbGUiOiJkZWNvcmF0b3JzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlZ2lzdGVySW5saW5lIGZyb20gJy4vZGVjb3JhdG9ycy9pbmxpbmUnO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJEZWZhdWx0RGVjb3JhdG9ycyhpbnN0YW5jZSkge1xuICByZWdpc3RlcklubGluZShpbnN0YW5jZSk7XG59XG4iXX0=\n","'use strict';\n\nexports.__esModule = true;\n\nvar _utils = require('../utils');\n\nexports['default'] = function (instance) {\n instance.registerDecorator('inline', function (fn, props, container, options) {\n var ret = fn;\n if (!props.partials) {\n props.partials = {};\n ret = function (context, options) {\n // Create a new partials stack frame prior to exec.\n var original = container.partials;\n container.partials = _utils.extend({}, original, props.partials);\n var ret = fn(context, options);\n container.partials = original;\n return ret;\n };\n }\n\n props.partials[options.args[0]] = options.fn;\n\n return ret;\n });\n};\n\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2RlY29yYXRvcnMvaW5saW5lLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7cUJBQXVCLFVBQVU7O3FCQUVsQixVQUFTLFFBQVEsRUFBRTtBQUNoQyxVQUFRLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLFVBQVMsRUFBRSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFO0FBQzNFLFFBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztBQUNiLFFBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFO0FBQ25CLFdBQUssQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO0FBQ3BCLFNBQUcsR0FBRyxVQUFTLE9BQU8sRUFBRSxPQUFPLEVBQUU7O0FBRS9CLFlBQUksUUFBUSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUM7QUFDbEMsaUJBQVMsQ0FBQyxRQUFRLEdBQUcsY0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMxRCxZQUFJLEdBQUcsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQy9CLGlCQUFTLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztBQUM5QixlQUFPLEdBQUcsQ0FBQztPQUNaLENBQUM7S0FDSDs7QUFFRCxTQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDOztBQUU3QyxXQUFPLEdBQUcsQ0FBQztHQUNaLENBQUMsQ0FBQztDQUNKIiwiZmlsZSI6ImlubGluZS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4dGVuZCB9IGZyb20gJy4uL3V0aWxzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oaW5zdGFuY2UpIHtcbiAgaW5zdGFuY2UucmVnaXN0ZXJEZWNvcmF0b3IoJ2lubGluZScsIGZ1bmN0aW9uKGZuLCBwcm9wcywgY29udGFpbmVyLCBvcHRpb25zKSB7XG4gICAgbGV0IHJldCA9IGZuO1xuICAgIGlmICghcHJvcHMucGFydGlhbHMpIHtcbiAgICAgIHByb3BzLnBhcnRpYWxzID0ge307XG4gICAgICByZXQgPSBmdW5jdGlvbihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgIC8vIENyZWF0ZSBhIG5ldyBwYXJ0aWFscyBzdGFjayBmcmFtZSBwcmlvciB0byBleGVjLlxuICAgICAgICBsZXQgb3JpZ2luYWwgPSBjb250YWluZXIucGFydGlhbHM7XG4gICAgICAgIGNvbnRhaW5lci5wYXJ0aWFscyA9IGV4dGVuZCh7fSwgb3JpZ2luYWwsIHByb3BzLnBhcnRpYWxzKTtcbiAgICAgICAgbGV0IHJldCA9IGZuKGNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICBjb250YWluZXIucGFydGlhbHMgPSBvcmlnaW5hbDtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvcHMucGFydGlhbHNbb3B0aW9ucy5hcmdzWzBdXSA9IG9wdGlvbnMuZm47XG5cbiAgICByZXR1cm4gcmV0O1xuICB9KTtcbn1cbiJdfQ==\n","'use strict';\n\nexports.__esModule = true;\nvar errorProps = ['description', 'fileName', 'lineNumber', 'endLineNumber', 'message', 'name', 'number', 'stack'];\n\nfunction Exception(message, node) {\n var loc = node && node.loc,\n line = undefined,\n endLineNumber = undefined,\n column = undefined,\n endColumn = undefined;\n\n if (loc) {\n line = loc.start.line;\n endLineNumber = loc.end.line;\n column = loc.start.column;\n endColumn = loc.end.column;\n\n message += ' - ' + line + ':' + column;\n }\n\n var tmp = Error.prototype.constructor.call(this, message);\n\n // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.\n for (var idx = 0; idx < errorProps.length; idx++) {\n this[errorProps[idx]] = tmp[errorProps[idx]];\n }\n\n /* istanbul ignore else */\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, Exception);\n }\n\n try {\n if (loc) {\n this.lineNumber = line;\n this.endLineNumber = endLineNumber;\n\n // Work around issue under safari where we can't directly set the column value\n /* istanbul ignore next */\n if (Object.defineProperty) {\n Object.defineProperty(this, 'column', {\n value: column,\n enumerable: true\n });\n Object.defineProperty(this, 'endColumn', {\n value: endColumn,\n enumerable: true\n });\n } else {\n this.column = column;\n this.endColumn = endColumn;\n }\n }\n } catch (nop) {\n /* Ignore if the browser is very particular */\n }\n}\n\nException.prototype = new Error();\n\nexports['default'] = Exception;\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2V4Y2VwdGlvbi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxJQUFNLFVBQVUsR0FBRyxDQUNqQixhQUFhLEVBQ2IsVUFBVSxFQUNWLFlBQVksRUFDWixlQUFlLEVBQ2YsU0FBUyxFQUNULE1BQU0sRUFDTixRQUFRLEVBQ1IsT0FBTyxDQUNSLENBQUM7O0FBRUYsU0FBUyxTQUFTLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRTtBQUNoQyxNQUFJLEdBQUcsR0FBRyxJQUFJLElBQUksSUFBSSxDQUFDLEdBQUc7TUFDeEIsSUFBSSxZQUFBO01BQ0osYUFBYSxZQUFBO01BQ2IsTUFBTSxZQUFBO01BQ04sU0FBUyxZQUFBLENBQUM7O0FBRVosTUFBSSxHQUFHLEVBQUU7QUFDUCxRQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7QUFDdEIsaUJBQWEsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQztBQUM3QixVQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7QUFDMUIsYUFBUyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDOztBQUUzQixXQUFPLElBQUksS0FBSyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDO0dBQ3hDOztBQUVELE1BQUksR0FBRyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7OztBQUcxRCxPQUFLLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRTtBQUNoRCxRQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0dBQzlDOzs7QUFHRCxNQUFJLEtBQUssQ0FBQyxpQkFBaUIsRUFBRTtBQUMzQixTQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0dBQzFDOztBQUVELE1BQUk7QUFDRixRQUFJLEdBQUcsRUFBRTtBQUNQLFVBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO0FBQ3ZCLFVBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDOzs7O0FBSW5DLFVBQUksTUFBTSxDQUFDLGNBQWMsRUFBRTtBQUN6QixjQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7QUFDcEMsZUFBSyxFQUFFLE1BQU07QUFDYixvQkFBVSxFQUFFLElBQUk7U0FDakIsQ0FBQyxDQUFDO0FBQ0gsY0FBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFO0FBQ3ZDLGVBQUssRUFBRSxTQUFTO0FBQ2hCLG9CQUFVLEVBQUUsSUFBSTtTQUNqQixDQUFDLENBQUM7T0FDSixNQUFNO0FBQ0wsWUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7QUFDckIsWUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7T0FDNUI7S0FDRjtHQUNGLENBQUMsT0FBTyxHQUFHLEVBQUU7O0dBRWI7Q0FDRjs7QUFFRCxTQUFTLENBQUMsU0FBUyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7O3FCQUVuQixTQUFTIiwiZmlsZSI6ImV4Y2VwdGlvbi5qcyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGVycm9yUHJvcHMgPSBbXG4gICdkZXNjcmlwdGlvbicsXG4gICdmaWxlTmFtZScsXG4gICdsaW5lTnVtYmVyJyxcbiAgJ2VuZExpbmVOdW1iZXInLFxuICAnbWVzc2FnZScsXG4gICduYW1lJyxcbiAgJ251bWJlcicsXG4gICdzdGFjaydcbl07XG5cbmZ1bmN0aW9uIEV4Y2VwdGlvbihtZXNzYWdlLCBub2RlKSB7XG4gIGxldCBsb2MgPSBub2RlICYmIG5vZGUubG9jLFxuICAgIGxpbmUsXG4gICAgZW5kTGluZU51bWJlcixcbiAgICBjb2x1bW4sXG4gICAgZW5kQ29sdW1uO1xuXG4gIGlmIChsb2MpIHtcbiAgICBsaW5lID0gbG9jLnN0YXJ0LmxpbmU7XG4gICAgZW5kTGluZU51bWJlciA9IGxvYy5lbmQubGluZTtcbiAgICBjb2x1bW4gPSBsb2Muc3RhcnQuY29sdW1uO1xuICAgIGVuZENvbHVtbiA9IGxvYy5lbmQuY29sdW1uO1xuXG4gICAgbWVzc2FnZSArPSAnIC0gJyArIGxpbmUgKyAnOicgKyBjb2x1bW47XG4gIH1cblxuICBsZXQgdG1wID0gRXJyb3IucHJvdG90eXBlLmNvbnN0cnVjdG9yLmNhbGwodGhpcywgbWVzc2FnZSk7XG5cbiAgLy8gVW5mb3J0dW5hdGVseSBlcnJvcnMgYXJlIG5vdCBlbnVtZXJhYmxlIGluIENocm9tZSAoYXQgbGVhc3QpLCBzbyBgZm9yIHByb3AgaW4gdG1wYCBkb2Vzbid0IHdvcmsuXG4gIGZvciAobGV0IGlkeCA9IDA7IGlkeCA8IGVycm9yUHJvcHMubGVuZ3RoOyBpZHgrKykge1xuICAgIHRoaXNbZXJyb3JQcm9wc1tpZHhdXSA9IHRtcFtlcnJvclByb3BzW2lkeF1dO1xuICB9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgRXhjZXB0aW9uKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgaWYgKGxvYykge1xuICAgICAgdGhpcy5saW5lTnVtYmVyID0gbGluZTtcbiAgICAgIHRoaXMuZW5kTGluZU51bWJlciA9IGVuZExpbmVOdW1iZXI7XG5cbiAgICAgIC8vIFdvcmsgYXJvdW5kIGlzc3VlIHVuZGVyIHNhZmFyaSB3aGVyZSB3ZSBjYW4ndCBkaXJlY3RseSBzZXQgdGhlIGNvbHVtbiB2YWx1ZVxuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdjb2x1bW4nLCB7XG4gICAgICAgICAgdmFsdWU6IGNvbHVtbixcbiAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2VuZENvbHVtbicsIHtcbiAgICAgICAgICB2YWx1ZTogZW5kQ29sdW1uLFxuICAgICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjtcbiAgICAgICAgdGhpcy5lbmRDb2x1bW4gPSBlbmRDb2x1bW47XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChub3ApIHtcbiAgICAvKiBJZ25vcmUgaWYgdGhlIGJyb3dzZXIgaXMgdmVyeSBwYXJ0aWN1bGFyICovXG4gIH1cbn1cblxuRXhjZXB0aW9uLnByb3RvdHlwZSA9IG5ldyBFcnJvcigpO1xuXG5leHBvcnQgZGVmYXVsdCBFeGNlcHRpb247XG4iXX0=\n","'use strict';\n\nexports.__esModule = true;\nexports.registerDefaultHelpers = registerDefaultHelpers;\nexports.moveHelperToHooks = moveHelperToHooks;\n// istanbul ignore next\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _helpersBlockHelperMissing = require('./helpers/block-helper-missing');\n\nvar _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing);\n\nvar _helpersEach = require('./helpers/each');\n\nvar _helpersEach2 = _interopRequireDefault(_helpersEach);\n\nvar _helpersHelperMissing = require('./helpers/helper-missing');\n\nvar _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing);\n\nvar _helpersIf = require('./helpers/if');\n\nvar _helpersIf2 = _interopRequireDefault(_helpersIf);\n\nvar _helpersLog = require('./helpers/log');\n\nvar _helpersLog2 = _interopRequireDefault(_helpersLog);\n\nvar _helpersLookup = require('./helpers/lookup');\n\nvar _helpersLookup2 = _interopRequireDefault(_helpersLookup);\n\nvar _helpersWith = require('./helpers/with');\n\nvar _helpersWith2 = _interopRequireDefault(_helpersWith);\n\nfunction registerDefaultHelpers(instance) {\n _helpersBlockHelperMissing2['default'](instance);\n _helpersEach2['default'](instance);\n _helpersHelperMissing2['default'](instance);\n _helpersIf2['default'](instance);\n _helpersLog2['default'](instance);\n _helpersLookup2['default'](instance);\n _helpersWith2['default'](instance);\n}\n\nfunction moveHelperToHooks(instance, helperName, keepHelper) {\n if (instance.helpers[helperName]) {\n instance.hooks[helperName] = instance.helpers[helperName];\n if (!keepHelper) {\n delete instance.helpers[helperName];\n }\n }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2hlbHBlcnMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O3lDQUF1QyxnQ0FBZ0M7Ozs7MkJBQzlDLGdCQUFnQjs7OztvQ0FDUCwwQkFBMEI7Ozs7eUJBQ3JDLGNBQWM7Ozs7MEJBQ2IsZUFBZTs7Ozs2QkFDWixrQkFBa0I7Ozs7MkJBQ3BCLGdCQUFnQjs7OztBQUVsQyxTQUFTLHNCQUFzQixDQUFDLFFBQVEsRUFBRTtBQUMvQyx5Q0FBMkIsUUFBUSxDQUFDLENBQUM7QUFDckMsMkJBQWEsUUFBUSxDQUFDLENBQUM7QUFDdkIsb0NBQXNCLFFBQVEsQ0FBQyxDQUFDO0FBQ2hDLHlCQUFXLFFBQVEsQ0FBQyxDQUFDO0FBQ3JCLDBCQUFZLFFBQVEsQ0FBQyxDQUFDO0FBQ3RCLDZCQUFlLFFBQVEsQ0FBQyxDQUFDO0FBQ3pCLDJCQUFhLFFBQVEsQ0FBQyxDQUFDO0NBQ3hCOztBQUVNLFNBQVMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUU7QUFDbEUsTUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFO0FBQ2hDLFlBQVEsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUMxRCxRQUFJLENBQUMsVUFBVSxFQUFFO0FBQ2YsYUFBTyxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0tBQ3JDO0dBQ0Y7Q0FDRiIsImZpbGUiOiJoZWxwZXJzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlZ2lzdGVyQmxvY2tIZWxwZXJNaXNzaW5nIGZyb20gJy4vaGVscGVycy9ibG9jay1oZWxwZXItbWlzc2luZyc7XG5pbXBvcnQgcmVnaXN0ZXJFYWNoIGZyb20gJy4vaGVscGVycy9lYWNoJztcbmltcG9ydCByZWdpc3RlckhlbHBlck1pc3NpbmcgZnJvbSAnLi9oZWxwZXJzL2hlbHBlci1taXNzaW5nJztcbmltcG9ydCByZWdpc3RlcklmIGZyb20gJy4vaGVscGVycy9pZic7XG5pbXBvcnQgcmVnaXN0ZXJMb2cgZnJvbSAnLi9oZWxwZXJzL2xvZyc7XG5pbXBvcnQgcmVnaXN0ZXJMb29rdXAgZnJvbSAnLi9oZWxwZXJzL2xvb2t1cCc7XG5pbXBvcnQgcmVnaXN0ZXJXaXRoIGZyb20gJy4vaGVscGVycy93aXRoJztcblxuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyRGVmYXVsdEhlbHBlcnMoaW5zdGFuY2UpIHtcbiAgcmVnaXN0ZXJCbG9ja0hlbHBlck1pc3NpbmcoaW5zdGFuY2UpO1xuICByZWdpc3RlckVhY2goaW5zdGFuY2UpO1xuICByZWdpc3RlckhlbHBlck1pc3NpbmcoaW5zdGFuY2UpO1xuICByZWdpc3RlcklmKGluc3RhbmNlKTtcbiAgcmVnaXN0ZXJMb2coaW5zdGFuY2UpO1xuICByZWdpc3Rlckxvb2t1cChpbnN0YW5jZSk7XG4gIHJlZ2lzdGVyV2l0aChpbnN0YW5jZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtb3ZlSGVscGVyVG9Ib29rcyhpbnN0YW5jZSwgaGVscGVyTmFtZSwga2VlcEhlbHBlcikge1xuICBpZiAoaW5zdGFuY2UuaGVscGVyc1toZWxwZXJOYW1lXSkge1xuICAgIGluc3RhbmNlLmhvb2tzW2hlbHBlck5hbWVdID0gaW5zdGFuY2UuaGVscGVyc1toZWxwZXJOYW1lXTtcbiAgICBpZiAoIWtlZXBIZWxwZXIpIHtcbiAgICAgIGRlbGV0ZSBpbnN0YW5jZS5oZWxwZXJzW2hlbHBlck5hbWVdO1xuICAgIH1cbiAgfVxufVxuIl19\n","'use strict';\n\nexports.__esModule = true;\n\nvar _utils = require('../utils');\n\nexports['default'] = function (instance) {\n instance.registerHelper('blockHelperMissing', function (context, options) {\n var inverse = options.inverse,\n fn = options.fn;\n\n if (context === true) {\n return fn(this);\n } else if (context === false || context == null) {\n return inverse(this);\n } else if (_utils.isArray(context)) {\n if (context.length > 0) {\n if (options.ids) {\n options.ids = [options.name];\n }\n\n return instance.helpers.each(context, options);\n } else {\n return inverse(this);\n }\n } else {\n if (options.data && options.ids) {\n var data = _utils.createFrame(options.data);\n data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name);\n options = { data: data };\n }\n\n return fn(context, options);\n }\n });\n};\n\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2hlbHBlcnMvYmxvY2staGVscGVyLW1pc3NpbmcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztxQkFBd0QsVUFBVTs7cUJBRW5ELFVBQVMsUUFBUSxFQUFFO0FBQ2hDLFVBQVEsQ0FBQyxjQUFjLENBQUMsb0JBQW9CLEVBQUUsVUFBUyxPQUFPLEVBQUUsT0FBTyxFQUFFO0FBQ3ZFLFFBQUksT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPO1FBQzNCLEVBQUUsR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDOztBQUVsQixRQUFJLE9BQU8sS0FBSyxJQUFJLEVBQUU7QUFDcEIsYUFBTyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDakIsTUFBTSxJQUFJLE9BQU8sS0FBSyxLQUFLLElBQUksT0FBTyxJQUFJLElBQUksRUFBRTtBQUMvQyxhQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztLQUN0QixNQUFNLElBQUksZUFBUSxPQUFPLENBQUMsRUFBRTtBQUMzQixVQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0FBQ3RCLFlBQUksT0FBTyxDQUFDLEdBQUcsRUFBRTtBQUNmLGlCQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQzlCOztBQUVELGVBQU8sUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO09BQ2hELE1BQU07QUFDTCxlQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztPQUN0QjtLQUNGLE1BQU07QUFDTCxVQUFJLE9BQU8sQ0FBQyxJQUFJLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRTtBQUMvQixZQUFJLElBQUksR0FBRyxtQkFBWSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDckMsWUFBSSxDQUFDLFdBQVcsR0FBRyx5QkFDakIsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQ3hCLE9BQU8sQ0FBQyxJQUFJLENBQ2IsQ0FBQztBQUNGLGVBQU8sR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQztPQUMxQjs7QUFFRCxhQUFPLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7S0FDN0I7R0FDRixDQUFDLENBQUM7Q0FDSiIsImZpbGUiOiJibG9jay1oZWxwZXItbWlzc2luZy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGFwcGVuZENvbnRleHRQYXRoLCBjcmVhdGVGcmFtZSwgaXNBcnJheSB9IGZyb20gJy4uL3V0aWxzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oaW5zdGFuY2UpIHtcbiAgaW5zdGFuY2UucmVnaXN0ZXJIZWxwZXIoJ2Jsb2NrSGVscGVyTWlzc2luZycsIGZ1bmN0aW9uKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICBsZXQgaW52ZXJzZSA9IG9wdGlvbnMuaW52ZXJzZSxcbiAgICAgIGZuID0gb3B0aW9ucy5mbjtcblxuICAgIGlmIChjb250ZXh0ID09PSB0cnVlKSB7XG4gICAgICByZXR1cm4gZm4odGhpcyk7XG4gICAgfSBlbHNlIGlmIChjb250ZXh0ID09PSBmYWxzZSB8fCBjb250ZXh0ID09IG51bGwpIHtcbiAgICAgIHJldHVybiBpbnZlcnNlKHRoaXMpO1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheShjb250ZXh0KSkge1xuICAgICAgaWYgKGNvbnRleHQubGVuZ3RoID4gMCkge1xuICAgICAgICBpZiAob3B0aW9ucy5pZHMpIHtcbiAgICAgICAgICBvcHRpb25zLmlkcyA9IFtvcHRpb25zLm5hbWVdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGluc3RhbmNlLmhlbHBlcnMuZWFjaChjb250ZXh0LCBvcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBpbnZlcnNlKHRoaXMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAob3B0aW9ucy5kYXRhICYmIG9wdGlvbnMuaWRzKSB7XG4gICAgICAgIGxldCBkYXRhID0gY3JlYXRlRnJhbWUob3B0aW9ucy5kYXRhKTtcbiAgICAgICAgZGF0YS5jb250ZXh0UGF0aCA9IGFwcGVuZENvbnRleHRQYXRoKFxuICAgICAgICAgIG9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aCxcbiAgICAgICAgICBvcHRpb25zLm5hbWVcbiAgICAgICAgKTtcbiAgICAgICAgb3B0aW9ucyA9IHsgZGF0YTogZGF0YSB9O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZm4oY29udGV4dCwgb3B0aW9ucyk7XG4gICAgfVxuICB9KTtcbn1cbiJdfQ==\n","'use strict';\n\nexports.__esModule = true;\n// istanbul ignore next\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _utils = require('../utils');\n\nvar _exception = require('../exception');\n\nvar _exception2 = _interopRequireDefault(_exception);\n\nexports['default'] = function (instance) {\n instance.registerHelper('each', function (context, options) {\n if (!options) {\n throw new _exception2['default']('Must pass iterator to #each');\n }\n\n var fn = options.fn,\n inverse = options.inverse,\n i = 0,\n ret = '',\n data = undefined,\n contextPath = undefined;\n\n if (options.data && options.ids) {\n contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';\n }\n\n if (_utils.isFunction(context)) {\n context = context.call(this);\n }\n\n if (options.data) {\n data = _utils.createFrame(options.data);\n }\n\n function execIteration(field, index, last) {\n if (data) {\n data.key = field;\n data.index = index;\n data.first = index === 0;\n data.last = !!last;\n\n if (contextPath) {\n data.contextPath = contextPath + field;\n }\n }\n\n ret = ret + fn(context[field], {\n data: data,\n blockParams: _utils.blockParams([context[field], field], [contextPath + field, null])\n });\n }\n\n if (context && typeof context === 'object') {\n if (_utils.isArray(context)) {\n for (var j = context.length; i < j; i++) {\n if (i in context) {\n execIteration(i, i, i === context.length - 1);\n }\n }\n } else if (global.Symbol && context[global.Symbol.iterator]) {\n var newContext = [];\n var iterator = context[global.Symbol.iterator]();\n for (var it = iterator.next(); !it.done; it = iterator.next()) {\n newContext.push(it.value);\n }\n context = newContext;\n for (var j = context.length; i < j; i++) {\n execIteration(i, i, i === context.length - 1);\n }\n } else {\n (function () {\n var priorKey = undefined;\n\n Object.keys(context).forEach(function (key) {\n // We're running the iterations one step out of sync so we can detect\n // the last iteration without have to scan the object twice and create\n // an itermediate keys array.\n if (priorKey !== undefined) {\n execIteration(priorKey, i - 1);\n }\n priorKey = key;\n i++;\n });\n if (priorKey !== undefined) {\n execIteration(priorKey, i - 1, true);\n }\n })();\n }\n }\n\n if (i === 0) {\n ret = inverse(this);\n }\n\n return ret;\n });\n};\n\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2hlbHBlcnMvZWFjaC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O3FCQU1PLFVBQVU7O3lCQUNLLGNBQWM7Ozs7cUJBRXJCLFVBQVMsUUFBUSxFQUFFO0FBQ2hDLFVBQVEsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLFVBQVMsT0FBTyxFQUFFLE9BQU8sRUFBRTtBQUN6RCxRQUFJLENBQUMsT0FBTyxFQUFFO0FBQ1osWUFBTSwyQkFBYyw2QkFBNkIsQ0FBQyxDQUFDO0tBQ3BEOztBQUVELFFBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxFQUFFO1FBQ2pCLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTztRQUN6QixDQUFDLEdBQUcsQ0FBQztRQUNMLEdBQUcsR0FBRyxFQUFFO1FBQ1IsSUFBSSxZQUFBO1FBQ0osV0FBVyxZQUFBLENBQUM7O0FBRWQsUUFBSSxPQUFPLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUU7QUFDL0IsaUJBQVcsR0FDVCx5QkFBa0IsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztLQUNyRTs7QUFFRCxRQUFJLGtCQUFXLE9BQU8sQ0FBQyxFQUFFO0FBQ3ZCLGFBQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQzlCOztBQUVELFFBQUksT0FBTyxDQUFDLElBQUksRUFBRTtBQUNoQixVQUFJLEdBQUcsbUJBQVksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ2xDOztBQUVELGFBQVMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFO0FBQ3pDLFVBQUksSUFBSSxFQUFFO0FBQ1IsWUFBSSxDQUFDLEdBQUcsR0FBRyxLQUFLLENBQUM7QUFDakIsWUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDbkIsWUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLEtBQUssQ0FBQyxDQUFDO0FBQ3pCLFlBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQzs7QUFFbkIsWUFBSSxXQUFXLEVBQUU7QUFDZixjQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsR0FBRyxLQUFLLENBQUM7U0FDeEM7T0FDRjs7QUFFRCxTQUFHLEdBQ0QsR0FBRyxHQUNILEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7QUFDakIsWUFBSSxFQUFFLElBQUk7QUFDVixtQkFBVyxFQUFFLG1CQUNYLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUN2QixDQUFDLFdBQVcsR0FBRyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQzVCO09BQ0YsQ0FBQyxDQUFDO0tBQ047O0FBRUQsUUFBSSxPQUFPLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO0FBQzFDLFVBQUksZUFBUSxPQUFPLENBQUMsRUFBRTtBQUNwQixhQUFLLElBQUksQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUN2QyxjQUFJLENBQUMsSUFBSSxPQUFPLEVBQUU7QUFDaEIseUJBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1dBQy9DO1NBQ0Y7T0FDRixNQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRTtBQUMzRCxZQUFNLFVBQVUsR0FBRyxFQUFFLENBQUM7QUFDdEIsWUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztBQUNuRCxhQUFLLElBQUksRUFBRSxHQUFHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxHQUFHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsRUFBRTtBQUM3RCxvQkFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDM0I7QUFDRCxlQUFPLEdBQUcsVUFBVSxDQUFDO0FBQ3JCLGFBQUssSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ3ZDLHVCQUFhLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztTQUMvQztPQUNGLE1BQU07O0FBQ0wsY0FBSSxRQUFRLFlBQUEsQ0FBQzs7QUFFYixnQkFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQSxHQUFHLEVBQUk7Ozs7QUFJbEMsZ0JBQUksUUFBUSxLQUFLLFNBQVMsRUFBRTtBQUMxQiwyQkFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7YUFDaEM7QUFDRCxvQkFBUSxHQUFHLEdBQUcsQ0FBQztBQUNmLGFBQUMsRUFBRSxDQUFDO1dBQ0wsQ0FBQyxDQUFDO0FBQ0gsY0FBSSxRQUFRLEtBQUssU0FBUyxFQUFFO0FBQzFCLHlCQUFhLENBQUMsUUFBUSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7V0FDdEM7O09BQ0Y7S0FDRjs7QUFFRCxRQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7QUFDWCxTQUFHLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ3JCOztBQUVELFdBQU8sR0FBRyxDQUFDO0dBQ1osQ0FBQyxDQUFDO0NBQ0oiLCJmaWxlIjoiZWFjaC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGFwcGVuZENvbnRleHRQYXRoLFxuICBibG9ja1BhcmFtcyxcbiAgY3JlYXRlRnJhbWUsXG4gIGlzQXJyYXksXG4gIGlzRnVuY3Rpb25cbn0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IEV4Y2VwdGlvbiBmcm9tICcuLi9leGNlcHRpb24nO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihpbnN0YW5jZSkge1xuICBpbnN0YW5jZS5yZWdpc3RlckhlbHBlcignZWFjaCcsIGZ1bmN0aW9uKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oJ011c3QgcGFzcyBpdGVyYXRvciB0byAjZWFjaCcpO1xuICAgIH1cblxuICAgIGxldCBmbiA9IG9wdGlvbnMuZm4sXG4gICAgICBpbnZlcnNlID0gb3B0aW9ucy5pbnZlcnNlLFxuICAgICAgaSA9IDAsXG4gICAgICByZXQgPSAnJyxcbiAgICAgIGRhdGEsXG4gICAgICBjb250ZXh0UGF0aDtcblxuICAgIGlmIChvcHRpb25zLmRhdGEgJiYgb3B0aW9ucy5pZHMpIHtcbiAgICAgIGNvbnRleHRQYXRoID1cbiAgICAgICAgYXBwZW5kQ29udGV4dFBhdGgob3B0aW9ucy5kYXRhLmNvbnRleHRQYXRoLCBvcHRpb25zLmlkc1swXSkgKyAnLic7XG4gICAgfVxuXG4gICAgaWYgKGlzRnVuY3Rpb24oY29udGV4dCkpIHtcbiAgICAgIGNvbnRleHQgPSBjb250ZXh0LmNhbGwodGhpcyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuZGF0YSkge1xuICAgICAgZGF0YSA9IGNyZWF0ZUZyYW1lKG9wdGlvbnMuZGF0YSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXhlY0l0ZXJhdGlvbihmaWVsZCwgaW5kZXgsIGxhc3QpIHtcbiAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgIGRhdGEua2V5ID0gZmllbGQ7XG4gICAgICAgIGRhdGEuaW5kZXggPSBpbmRleDtcbiAgICAgICAgZGF0YS5maXJzdCA9IGluZGV4ID09PSAwO1xuICAgICAgICBkYXRhLmxhc3QgPSAhIWxhc3Q7XG5cbiAgICAgICAgaWYgKGNvbnRleHRQYXRoKSB7XG4gICAgICAgICAgZGF0YS5jb250ZXh0UGF0aCA9IGNvbnRleHRQYXRoICsgZmllbGQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0ID1cbiAgICAgICAgcmV0ICtcbiAgICAgICAgZm4oY29udGV4dFtmaWVsZF0sIHtcbiAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgIGJsb2NrUGFyYW1zOiBibG9ja1BhcmFtcyhcbiAgICAgICAgICAgIFtjb250ZXh0W2ZpZWxkXSwgZmllbGRdLFxuICAgICAgICAgICAgW2NvbnRleHRQYXRoICsgZmllbGQsIG51bGxdXG4gICAgICAgICAgKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCAmJiB0eXBlb2YgY29udGV4dCA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChpc0FycmF5KGNvbnRleHQpKSB7XG4gICAgICAgIGZvciAobGV0IGogPSBjb250ZXh0Lmxlbmd0aDsgaSA8IGo7IGkrKykge1xuICAgICAgICAgIGlmIChpIGluIGNvbnRleHQpIHtcbiAgICAgICAgICAgIGV4ZWNJdGVyYXRpb24oaSwgaSwgaSA9PT0gY29udGV4dC5sZW5ndGggLSAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZ2xvYmFsLlN5bWJvbCAmJiBjb250ZXh0W2dsb2JhbC5TeW1ib2wuaXRlcmF0b3JdKSB7XG4gICAgICAgIGNvbnN0IG5ld0NvbnRleHQgPSBbXTtcbiAgICAgICAgY29uc3QgaXRlcmF0b3IgPSBjb250ZXh0W2dsb2JhbC5TeW1ib2wuaXRlcmF0b3JdKCk7XG4gICAgICAgIGZvciAobGV0IGl0ID0gaXRlcmF0b3IubmV4dCgpOyAhaXQuZG9uZTsgaXQgPSBpdGVyYXRvci5uZXh0KCkpIHtcbiAgICAgICAgICBuZXdDb250ZXh0LnB1c2goaXQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQgPSBuZXdDb250ZXh0O1xuICAgICAgICBmb3IgKGxldCBqID0gY29udGV4dC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcbiAgICAgICAgICBleGVjSXRlcmF0aW9uKGksIGksIGkgPT09IGNvbnRleHQubGVuZ3RoIC0gMSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBwcmlvcktleTtcblxuICAgICAgICBPYmplY3Qua2V5cyhjb250ZXh0KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgLy8gV2UncmUgcnVubmluZyB0aGUgaXRlcmF0aW9ucyBvbmUgc3RlcCBvdXQgb2Ygc3luYyBzbyB3ZSBjYW4gZGV0ZWN0XG4gICAgICAgICAgLy8gdGhlIGxhc3QgaXRlcmF0aW9uIHdpdGhvdXQgaGF2ZSB0byBzY2FuIHRoZSBvYmplY3QgdHdpY2UgYW5kIGNyZWF0ZVxuICAgICAgICAgIC8vIGFuIGl0ZXJtZWRpYXRlIGtleXMgYXJyYXkuXG4gICAgICAgICAgaWYgKHByaW9yS2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGV4ZWNJdGVyYXRpb24ocHJpb3JLZXksIGkgLSAxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcHJpb3JLZXkgPSBrZXk7XG4gICAgICAgICAgaSsrO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHByaW9yS2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBleGVjSXRlcmF0aW9uKHByaW9yS2V5LCBpIC0gMSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgcmV0ID0gaW52ZXJzZSh0aGlzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmV0O1xuICB9KTtcbn1cbiJdfQ==\n","'use strict';\n\nexports.__esModule = true;\n// istanbul ignore next\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _exception = require('../exception');\n\nvar _exception2 = _interopRequireDefault(_exception);\n\nexports['default'] = function (instance) {\n instance.registerHelper('helperMissing', function () /* [args, ]options */{\n if (arguments.length === 1) {\n // A missing field in a {{foo}} construct.\n return undefined;\n } else {\n // Someone is actually trying to call something, blow up.\n throw new _exception2['default']('Missing helper: \"' + arguments[arguments.length - 1].name + '\"');\n }\n });\n};\n\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2hlbHBlcnMvaGVscGVyLW1pc3NpbmcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozt5QkFBc0IsY0FBYzs7OztxQkFFckIsVUFBUyxRQUFRLEVBQUU7QUFDaEMsVUFBUSxDQUFDLGNBQWMsQ0FBQyxlQUFlLEVBQUUsaUNBQWdDO0FBQ3ZFLFFBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7O0FBRTFCLGFBQU8sU0FBUyxDQUFDO0tBQ2xCLE1BQU07O0FBRUwsWUFBTSwyQkFDSixtQkFBbUIsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUNqRSxDQUFDO0tBQ0g7R0FDRixDQUFDLENBQUM7Q0FDSiIsImZpbGUiOiJoZWxwZXItbWlzc2luZy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBFeGNlcHRpb24gZnJvbSAnLi4vZXhjZXB0aW9uJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oaW5zdGFuY2UpIHtcbiAgaW5zdGFuY2UucmVnaXN0ZXJIZWxwZXIoJ2hlbHBlck1pc3NpbmcnLCBmdW5jdGlvbigvKiBbYXJncywgXW9wdGlvbnMgKi8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgLy8gQSBtaXNzaW5nIGZpZWxkIGluIGEge3tmb299fSBjb25zdHJ1Y3QuXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBTb21lb25lIGlzIGFjdHVhbGx5IHRyeWluZyB0byBjYWxsIHNvbWV0aGluZywgYmxvdyB1cC5cbiAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oXG4gICAgICAgICdNaXNzaW5nIGhlbHBlcjogXCInICsgYXJndW1lbnRzW2FyZ3VtZW50cy5sZW5ndGggLSAxXS5uYW1lICsgJ1wiJ1xuICAgICAgKTtcbiAgICB9XG4gIH0pO1xufVxuIl19\n","'use strict';\n\nexports.__esModule = true;\n// istanbul ignore next\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _utils = require('../utils');\n\nvar _exception = require('../exception');\n\nvar _exception2 = _interopRequireDefault(_exception);\n\nexports['default'] = function (instance) {\n instance.registerHelper('if', function (conditional, options) {\n if (arguments.length != 2) {\n throw new _exception2['default']('#if requires exactly one argument');\n }\n if (_utils.isFunction(conditional)) {\n conditional = conditional.call(this);\n }\n\n // Default behavior is to render the positive path if the value is truthy and not empty.\n // The `includeZero` option may be set to treat the condtional as purely not empty based on the\n // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.\n if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) {\n return options.inverse(this);\n } else {\n return options.fn(this);\n }\n });\n\n instance.registerHelper('unless', function (conditional, options) {\n if (arguments.length != 2) {\n throw new _exception2['default']('#unless requires exactly one argument');\n }\n return instance.helpers['if'].call(this, conditional, {\n fn: options.inverse,\n inverse: options.fn,\n hash: options.hash\n });\n });\n};\n\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2hlbHBlcnMvaWYuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7OztxQkFBb0MsVUFBVTs7eUJBQ3hCLGNBQWM7Ozs7cUJBRXJCLFVBQVMsUUFBUSxFQUFFO0FBQ2hDLFVBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLFVBQVMsV0FBVyxFQUFFLE9BQU8sRUFBRTtBQUMzRCxRQUFJLFNBQVMsQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFO0FBQ3pCLFlBQU0sMkJBQWMsbUNBQW1DLENBQUMsQ0FBQztLQUMxRDtBQUNELFFBQUksa0JBQVcsV0FBVyxDQUFDLEVBQUU7QUFDM0IsaUJBQVcsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ3RDOzs7OztBQUtELFFBQUksQUFBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsV0FBVyxJQUFLLGVBQVEsV0FBVyxDQUFDLEVBQUU7QUFDdkUsYUFBTyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQzlCLE1BQU07QUFDTCxhQUFPLE9BQU8sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDekI7R0FDRixDQUFDLENBQUM7O0FBRUgsVUFBUSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsVUFBUyxXQUFXLEVBQUUsT0FBTyxFQUFFO0FBQy9ELFFBQUksU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7QUFDekIsWUFBTSwyQkFBYyx1Q0FBdUMsQ0FBQyxDQUFDO0tBQzlEO0FBQ0QsV0FBTyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFO0FBQ3BELFFBQUUsRUFBRSxPQUFPLENBQUMsT0FBTztBQUNuQixhQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUU7QUFDbkIsVUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO0tBQ25CLENBQUMsQ0FBQztHQUNKLENBQUMsQ0FBQztDQUNKIiwiZmlsZSI6ImlmLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNFbXB0eSwgaXNGdW5jdGlvbiB9IGZyb20gJy4uL3V0aWxzJztcbmltcG9ydCBFeGNlcHRpb24gZnJvbSAnLi4vZXhjZXB0aW9uJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oaW5zdGFuY2UpIHtcbiAgaW5zdGFuY2UucmVnaXN0ZXJIZWxwZXIoJ2lmJywgZnVuY3Rpb24oY29uZGl0aW9uYWwsIG9wdGlvbnMpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCAhPSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCcjaWYgcmVxdWlyZXMgZXhhY3RseSBvbmUgYXJndW1lbnQnKTtcbiAgICB9XG4gICAgaWYgKGlzRnVuY3Rpb24oY29uZGl0aW9uYWwpKSB7XG4gICAgICBjb25kaXRpb25hbCA9IGNvbmRpdGlvbmFsLmNhbGwodGhpcyk7XG4gICAgfVxuXG4gICAgLy8gRGVmYXVsdCBiZWhhdmlvciBpcyB0byByZW5kZXIgdGhlIHBvc2l0aXZlIHBhdGggaWYgdGhlIHZhbHVlIGlzIHRydXRoeSBhbmQgbm90IGVtcHR5LlxuICAgIC8vIFRoZSBgaW5jbHVkZVplcm9gIG9wdGlvbiBtYXkgYmUgc2V0IHRvIHRyZWF0IHRoZSBjb25kdGlvbmFsIGFzIHB1cmVseSBub3QgZW1wdHkgYmFzZWQgb24gdGhlXG4gICAgLy8gYmVoYXZpb3Igb2YgaXNFbXB0eS4gRWZmZWN0aXZlbHkgdGhpcyBkZXRlcm1pbmVzIGlmIDAgaXMgaGFuZGxlZCBieSB0aGUgcG9zaXRpdmUgcGF0aCBvciBuZWdhdGl2ZS5cbiAgICBpZiAoKCFvcHRpb25zLmhhc2guaW5jbHVkZVplcm8gJiYgIWNvbmRpdGlvbmFsKSB8fCBpc0VtcHR5KGNvbmRpdGlvbmFsKSkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuZm4odGhpcyk7XG4gICAgfVxuICB9KTtcblxuICBpbnN0YW5jZS5yZWdpc3RlckhlbHBlcigndW5sZXNzJywgZnVuY3Rpb24oY29uZGl0aW9uYWwsIG9wdGlvbnMpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCAhPSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCcjdW5sZXNzIHJlcXVpcmVzIGV4YWN0bHkgb25lIGFyZ3VtZW50Jyk7XG4gICAgfVxuICAgIHJldHVybiBpbnN0YW5jZS5oZWxwZXJzWydpZiddLmNhbGwodGhpcywgY29uZGl0aW9uYWwsIHtcbiAgICAgIGZuOiBvcHRpb25zLmludmVyc2UsXG4gICAgICBpbnZlcnNlOiBvcHRpb25zLmZuLFxuICAgICAgaGFzaDogb3B0aW9ucy5oYXNoXG4gICAgfSk7XG4gIH0pO1xufVxuIl19\n","'use strict';\n\nexports.__esModule = true;\n\nexports['default'] = function (instance) {\n instance.registerHelper('log', function () /* message, options */{\n var args = [undefined],\n options = arguments[arguments.length - 1];\n for (var i = 0; i < arguments.length - 1; i++) {\n args.push(arguments[i]);\n }\n\n var level = 1;\n if (options.hash.level != null) {\n level = options.hash.level;\n } else if (options.data && options.data.level != null) {\n level = options.data.level;\n }\n args[0] = level;\n\n instance.log.apply(instance, args);\n });\n};\n\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2hlbHBlcnMvbG9nLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7cUJBQWUsVUFBUyxRQUFRLEVBQUU7QUFDaEMsVUFBUSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsa0NBQWlDO0FBQzlELFFBQUksSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDO1FBQ3BCLE9BQU8sR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM1QyxTQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDN0MsVUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUN6Qjs7QUFFRCxRQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7QUFDZCxRQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksRUFBRTtBQUM5QixXQUFLLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7S0FDNUIsTUFBTSxJQUFJLE9BQU8sQ0FBQyxJQUFJLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxFQUFFO0FBQ3JELFdBQUssR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztLQUM1QjtBQUNELFFBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7O0FBRWhCLFlBQVEsQ0FBQyxHQUFHLE1BQUEsQ0FBWixRQUFRLEVBQVEsSUFBSSxDQUFDLENBQUM7R0FDdkIsQ0FBQyxDQUFDO0NBQ0oiLCJmaWxlIjoibG9nLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oaW5zdGFuY2UpIHtcbiAgaW5zdGFuY2UucmVnaXN0ZXJIZWxwZXIoJ2xvZycsIGZ1bmN0aW9uKC8qIG1lc3NhZ2UsIG9wdGlvbnMgKi8pIHtcbiAgICBsZXQgYXJncyA9IFt1bmRlZmluZWRdLFxuICAgICAgb3B0aW9ucyA9IGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgICB9XG5cbiAgICBsZXQgbGV2ZWwgPSAxO1xuICAgIGlmIChvcHRpb25zLmhhc2gubGV2ZWwgIT0gbnVsbCkge1xuICAgICAgbGV2ZWwgPSBvcHRpb25zLmhhc2gubGV2ZWw7XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLmRhdGEgJiYgb3B0aW9ucy5kYXRhLmxldmVsICE9IG51bGwpIHtcbiAgICAgIGxldmVsID0gb3B0aW9ucy5kYXRhLmxldmVsO1xuICAgIH1cbiAgICBhcmdzWzBdID0gbGV2ZWw7XG5cbiAgICBpbnN0YW5jZS5sb2coLi4uYXJncyk7XG4gIH0pO1xufVxuIl19\n","'use strict';\n\nexports.__esModule = true;\n\nexports['default'] = function (instance) {\n instance.registerHelper('lookup', function (obj, field, options) {\n if (!obj) {\n // Note for 5.0: Change to \"obj == null\" in 5.0\n return obj;\n }\n return options.lookupProperty(obj, field);\n });\n};\n\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2hlbHBlcnMvbG9va3VwLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7cUJBQWUsVUFBUyxRQUFRLEVBQUU7QUFDaEMsVUFBUSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsVUFBUyxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtBQUM5RCxRQUFJLENBQUMsR0FBRyxFQUFFOztBQUVSLGFBQU8sR0FBRyxDQUFDO0tBQ1o7QUFDRCxXQUFPLE9BQU8sQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO0dBQzNDLENBQUMsQ0FBQztDQUNKIiwiZmlsZSI6Imxvb2t1cC5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKGluc3RhbmNlKSB7XG4gIGluc3RhbmNlLnJlZ2lzdGVySGVscGVyKCdsb29rdXAnLCBmdW5jdGlvbihvYmosIGZpZWxkLCBvcHRpb25zKSB7XG4gICAgaWYgKCFvYmopIHtcbiAgICAgIC8vIE5vdGUgZm9yIDUuMDogQ2hhbmdlIHRvIFwib2JqID09IG51bGxcIiBpbiA1LjBcbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zLmxvb2t1cFByb3BlcnR5KG9iaiwgZmllbGQpO1xuICB9KTtcbn1cbiJdfQ==\n","'use strict';\n\nexports.__esModule = true;\n// istanbul ignore next\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _utils = require('../utils');\n\nvar _exception = require('../exception');\n\nvar _exception2 = _interopRequireDefault(_exception);\n\nexports['default'] = function (instance) {\n instance.registerHelper('with', function (context, options) {\n if (arguments.length != 2) {\n throw new _exception2['default']('#with requires exactly one argument');\n }\n if (_utils.isFunction(context)) {\n context = context.call(this);\n }\n\n var fn = options.fn;\n\n if (!_utils.isEmpty(context)) {\n var data = options.data;\n if (options.data && options.ids) {\n data = _utils.createFrame(options.data);\n data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]);\n }\n\n return fn(context, {\n data: data,\n blockParams: _utils.blockParams([context], [data && data.contextPath])\n });\n } else {\n return options.inverse(this);\n }\n });\n};\n\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2hlbHBlcnMvd2l0aC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O3FCQU1PLFVBQVU7O3lCQUNLLGNBQWM7Ozs7cUJBRXJCLFVBQVMsUUFBUSxFQUFFO0FBQ2hDLFVBQVEsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLFVBQVMsT0FBTyxFQUFFLE9BQU8sRUFBRTtBQUN6RCxRQUFJLFNBQVMsQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFO0FBQ3pCLFlBQU0sMkJBQWMscUNBQXFDLENBQUMsQ0FBQztLQUM1RDtBQUNELFFBQUksa0JBQVcsT0FBTyxDQUFDLEVBQUU7QUFDdkIsYUFBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDOUI7O0FBRUQsUUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsQ0FBQzs7QUFFcEIsUUFBSSxDQUFDLGVBQVEsT0FBTyxDQUFDLEVBQUU7QUFDckIsVUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztBQUN4QixVQUFJLE9BQU8sQ0FBQyxJQUFJLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRTtBQUMvQixZQUFJLEdBQUcsbUJBQVksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2pDLFlBQUksQ0FBQyxXQUFXLEdBQUcseUJBQ2pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUN4QixPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUNmLENBQUM7T0FDSDs7QUFFRCxhQUFPLEVBQUUsQ0FBQyxPQUFPLEVBQUU7QUFDakIsWUFBSSxFQUFFLElBQUk7QUFDVixtQkFBVyxFQUFFLG1CQUFZLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO09BQ2hFLENBQUMsQ0FBQztLQUNKLE1BQU07QUFDTCxhQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDOUI7R0FDRixDQUFDLENBQUM7Q0FDSiIsImZpbGUiOiJ3aXRoLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgYXBwZW5kQ29udGV4dFBhdGgsXG4gIGJsb2NrUGFyYW1zLFxuICBjcmVhdGVGcmFtZSxcbiAgaXNFbXB0eSxcbiAgaXNGdW5jdGlvblxufSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQgRXhjZXB0aW9uIGZyb20gJy4uL2V4Y2VwdGlvbic7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKGluc3RhbmNlKSB7XG4gIGluc3RhbmNlLnJlZ2lzdGVySGVscGVyKCd3aXRoJywgZnVuY3Rpb24oY29udGV4dCwgb3B0aW9ucykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oJyN3aXRoIHJlcXVpcmVzIGV4YWN0bHkgb25lIGFyZ3VtZW50Jyk7XG4gICAgfVxuICAgIGlmIChpc0Z1bmN0aW9uKGNvbnRleHQpKSB7XG4gICAgICBjb250ZXh0ID0gY29udGV4dC5jYWxsKHRoaXMpO1xuICAgIH1cblxuICAgIGxldCBmbiA9IG9wdGlvbnMuZm47XG5cbiAgICBpZiAoIWlzRW1wdHkoY29udGV4dCkpIHtcbiAgICAgIGxldCBkYXRhID0gb3B0aW9ucy5kYXRhO1xuICAgICAgaWYgKG9wdGlvbnMuZGF0YSAmJiBvcHRpb25zLmlkcykge1xuICAgICAgICBkYXRhID0gY3JlYXRlRnJhbWUob3B0aW9ucy5kYXRhKTtcbiAgICAgICAgZGF0YS5jb250ZXh0UGF0aCA9IGFwcGVuZENvbnRleHRQYXRoKFxuICAgICAgICAgIG9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aCxcbiAgICAgICAgICBvcHRpb25zLmlkc1swXVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZm4oY29udGV4dCwge1xuICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICBibG9ja1BhcmFtczogYmxvY2tQYXJhbXMoW2NvbnRleHRdLCBbZGF0YSAmJiBkYXRhLmNvbnRleHRQYXRoXSlcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgIH1cbiAgfSk7XG59XG4iXX0=\n","'use strict';\n\nexports.__esModule = true;\nexports.createNewLookupObject = createNewLookupObject;\n\nvar _utils = require('../utils');\n\n/**\n * Create a new object with \"null\"-prototype to avoid truthy results on prototype properties.\n * The resulting object can be used with \"object[property]\" to check if a property exists\n * @param {...object} sources a varargs parameter of source objects that will be merged\n * @returns {object}\n */\n\nfunction createNewLookupObject() {\n for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {\n sources[_key] = arguments[_key];\n }\n\n return _utils.extend.apply(undefined, [Object.create(null)].concat(sources));\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2ludGVybmFsL2NyZWF0ZS1uZXctbG9va3VwLW9iamVjdC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztxQkFBdUIsVUFBVTs7Ozs7Ozs7O0FBUTFCLFNBQVMscUJBQXFCLEdBQWE7b0NBQVQsT0FBTztBQUFQLFdBQU87OztBQUM5QyxTQUFPLGdDQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQUssT0FBTyxFQUFDLENBQUM7Q0FDaEQiLCJmaWxlIjoiY3JlYXRlLW5ldy1sb29rdXAtb2JqZWN0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBvYmplY3Qgd2l0aCBcIm51bGxcIi1wcm90b3R5cGUgdG8gYXZvaWQgdHJ1dGh5IHJlc3VsdHMgb24gcHJvdG90eXBlIHByb3BlcnRpZXMuXG4gKiBUaGUgcmVzdWx0aW5nIG9iamVjdCBjYW4gYmUgdXNlZCB3aXRoIFwib2JqZWN0W3Byb3BlcnR5XVwiIHRvIGNoZWNrIGlmIGEgcHJvcGVydHkgZXhpc3RzXG4gKiBAcGFyYW0gey4uLm9iamVjdH0gc291cmNlcyBhIHZhcmFyZ3MgcGFyYW1ldGVyIG9mIHNvdXJjZSBvYmplY3RzIHRoYXQgd2lsbCBiZSBtZXJnZWRcbiAqIEByZXR1cm5zIHtvYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVOZXdMb29rdXBPYmplY3QoLi4uc291cmNlcykge1xuICByZXR1cm4gZXh0ZW5kKE9iamVjdC5jcmVhdGUobnVsbCksIC4uLnNvdXJjZXMpO1xufVxuIl19\n","'use strict';\n\nexports.__esModule = true;\nexports.createProtoAccessControl = createProtoAccessControl;\nexports.resultIsAllowed = resultIsAllowed;\nexports.resetLoggedProperties = resetLoggedProperties;\n// istanbul ignore next\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nvar _createNewLookupObject = require('./create-new-lookup-object');\n\nvar _logger = require('../logger');\n\nvar logger = _interopRequireWildcard(_logger);\n\nvar loggedProperties = Object.create(null);\n\nfunction createProtoAccessControl(runtimeOptions) {\n var defaultMethodWhiteList = Object.create(null);\n defaultMethodWhiteList['constructor'] = false;\n defaultMethodWhiteList['__defineGetter__'] = false;\n defaultMethodWhiteList['__defineSetter__'] = false;\n defaultMethodWhiteList['__lookupGetter__'] = false;\n\n var defaultPropertyWhiteList = Object.create(null);\n // eslint-disable-next-line no-proto\n defaultPropertyWhiteList['__proto__'] = false;\n\n return {\n properties: {\n whitelist: _createNewLookupObject.createNewLookupObject(defaultPropertyWhiteList, runtimeOptions.allowedProtoProperties),\n defaultValue: runtimeOptions.allowProtoPropertiesByDefault\n },\n methods: {\n whitelist: _createNewLookupObject.createNewLookupObject(defaultMethodWhiteList, runtimeOptions.allowedProtoMethods),\n defaultValue: runtimeOptions.allowProtoMethodsByDefault\n }\n };\n}\n\nfunction resultIsAllowed(result, protoAccessControl, propertyName) {\n if (typeof result === 'function') {\n return checkWhiteList(protoAccessControl.methods, propertyName);\n } else {\n return checkWhiteList(protoAccessControl.properties, propertyName);\n }\n}\n\nfunction checkWhiteList(protoAccessControlForType, propertyName) {\n if (protoAccessControlForType.whitelist[propertyName] !== undefined) {\n return protoAccessControlForType.whitelist[propertyName] === true;\n }\n if (protoAccessControlForType.defaultValue !== undefined) {\n return protoAccessControlForType.defaultValue;\n }\n logUnexpecedPropertyAccessOnce(propertyName);\n return false;\n}\n\nfunction logUnexpecedPropertyAccessOnce(propertyName) {\n if (loggedProperties[propertyName] !== true) {\n loggedProperties[propertyName] = true;\n logger.log('error', 'Handlebars: Access has been denied to resolve the property \"' + propertyName + '\" because it is not an \"own property\" of its parent.\\n' + 'You can add a runtime option to disable the check or this warning:\\n' + 'See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details');\n }\n}\n\nfunction resetLoggedProperties() {\n Object.keys(loggedProperties).forEach(function (propertyName) {\n delete loggedProperties[propertyName];\n });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2ludGVybmFsL3Byb3RvLWFjY2Vzcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O3FDQUFzQyw0QkFBNEI7O3NCQUMxQyxXQUFXOztJQUF2QixNQUFNOztBQUVsQixJQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7O0FBRXRDLFNBQVMsd0JBQXdCLENBQUMsY0FBYyxFQUFFO0FBQ3ZELE1BQUksc0JBQXNCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNqRCx3QkFBc0IsQ0FBQyxhQUFhLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDOUMsd0JBQXNCLENBQUMsa0JBQWtCLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDbkQsd0JBQXNCLENBQUMsa0JBQWtCLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDbkQsd0JBQXNCLENBQUMsa0JBQWtCLENBQUMsR0FBRyxLQUFLLENBQUM7O0FBRW5ELE1BQUksd0JBQXdCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQzs7QUFFbkQsMEJBQXdCLENBQUMsV0FBVyxDQUFDLEdBQUcsS0FBSyxDQUFDOztBQUU5QyxTQUFPO0FBQ0wsY0FBVSxFQUFFO0FBQ1YsZUFBUyxFQUFFLDZDQUNULHdCQUF3QixFQUN4QixjQUFjLENBQUMsc0JBQXNCLENBQ3RDO0FBQ0Qsa0JBQVksRUFBRSxjQUFjLENBQUMsNkJBQTZCO0tBQzNEO0FBQ0QsV0FBTyxFQUFFO0FBQ1AsZUFBUyxFQUFFLDZDQUNULHNCQUFzQixFQUN0QixjQUFjLENBQUMsbUJBQW1CLENBQ25DO0FBQ0Qsa0JBQVksRUFBRSxjQUFjLENBQUMsMEJBQTBCO0tBQ3hEO0dBQ0YsQ0FBQztDQUNIOztBQUVNLFNBQVMsZUFBZSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUU7QUFDeEUsTUFBSSxPQUFPLE1BQU0sS0FBSyxVQUFVLEVBQUU7QUFDaEMsV0FBTyxjQUFjLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDO0dBQ2pFLE1BQU07QUFDTCxXQUFPLGNBQWMsQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUM7R0FDcEU7Q0FDRjs7QUFFRCxTQUFTLGNBQWMsQ0FBQyx5QkFBeUIsRUFBRSxZQUFZLEVBQUU7QUFDL0QsTUFBSSx5QkFBeUIsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLEtBQUssU0FBUyxFQUFFO0FBQ25FLFdBQU8seUJBQXlCLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxLQUFLLElBQUksQ0FBQztHQUNuRTtBQUNELE1BQUkseUJBQXlCLENBQUMsWUFBWSxLQUFLLFNBQVMsRUFBRTtBQUN4RCxXQUFPLHlCQUF5QixDQUFDLFlBQVksQ0FBQztHQUMvQztBQUNELGdDQUE4QixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQzdDLFNBQU8sS0FBSyxDQUFDO0NBQ2Q7O0FBRUQsU0FBUyw4QkFBOEIsQ0FBQyxZQUFZLEVBQUU7QUFDcEQsTUFBSSxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsS0FBSyxJQUFJLEVBQUU7QUFDM0Msb0JBQWdCLENBQUMsWUFBWSxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ3RDLFVBQU0sQ0FBQyxHQUFHLENBQ1IsT0FBTyxFQUNQLGlFQUErRCxZQUFZLG9JQUNILG9IQUMyQyxDQUNwSCxDQUFDO0dBQ0g7Q0FDRjs7QUFFTSxTQUFTLHFCQUFxQixHQUFHO0FBQ3RDLFFBQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQSxZQUFZLEVBQUk7QUFDcEQsV0FBTyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztHQUN2QyxDQUFDLENBQUM7Q0FDSiIsImZpbGUiOiJwcm90by1hY2Nlc3MuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVOZXdMb29rdXBPYmplY3QgfSBmcm9tICcuL2NyZWF0ZS1uZXctbG9va3VwLW9iamVjdCc7XG5pbXBvcnQgKiBhcyBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcblxuY29uc3QgbG9nZ2VkUHJvcGVydGllcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQcm90b0FjY2Vzc0NvbnRyb2wocnVudGltZU9wdGlvbnMpIHtcbiAgbGV0IGRlZmF1bHRNZXRob2RXaGl0ZUxpc3QgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBkZWZhdWx0TWV0aG9kV2hpdGVMaXN0Wydjb25zdHJ1Y3RvciddID0gZmFsc2U7XG4gIGRlZmF1bHRNZXRob2RXaGl0ZUxpc3RbJ19fZGVmaW5lR2V0dGVyX18nXSA9IGZhbHNlO1xuICBkZWZhdWx0TWV0aG9kV2hpdGVMaXN0WydfX2RlZmluZVNldHRlcl9fJ10gPSBmYWxzZTtcbiAgZGVmYXVsdE1ldGhvZFdoaXRlTGlzdFsnX19sb29rdXBHZXR0ZXJfXyddID0gZmFsc2U7XG5cbiAgbGV0IGRlZmF1bHRQcm9wZXJ0eVdoaXRlTGlzdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wcm90b1xuICBkZWZhdWx0UHJvcGVydHlXaGl0ZUxpc3RbJ19fcHJvdG9fXyddID0gZmFsc2U7XG5cbiAgcmV0dXJuIHtcbiAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICB3aGl0ZWxpc3Q6IGNyZWF0ZU5ld0xvb2t1cE9iamVjdChcbiAgICAgICAgZGVmYXVsdFByb3BlcnR5V2hpdGVMaXN0LFxuICAgICAgICBydW50aW1lT3B0aW9ucy5hbGxvd2VkUHJvdG9Qcm9wZXJ0aWVzXG4gICAgICApLFxuICAgICAgZGVmYXVsdFZhbHVlOiBydW50aW1lT3B0aW9ucy5hbGxvd1Byb3RvUHJvcGVydGllc0J5RGVmYXVsdFxuICAgIH0sXG4gICAgbWV0aG9kczoge1xuICAgICAgd2hpdGVsaXN0OiBjcmVhdGVOZXdMb29rdXBPYmplY3QoXG4gICAgICAgIGRlZmF1bHRNZXRob2RXaGl0ZUxpc3QsXG4gICAgICAgIHJ1bnRpbWVPcHRpb25zLmFsbG93ZWRQcm90b01ldGhvZHNcbiAgICAgICksXG4gICAgICBkZWZhdWx0VmFsdWU6IHJ1bnRpbWVPcHRpb25zLmFsbG93UHJvdG9NZXRob2RzQnlEZWZhdWx0XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzdWx0SXNBbGxvd2VkKHJlc3VsdCwgcHJvdG9BY2Nlc3NDb250cm9sLCBwcm9wZXJ0eU5hbWUpIHtcbiAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gY2hlY2tXaGl0ZUxpc3QocHJvdG9BY2Nlc3NDb250cm9sLm1ldGhvZHMsIHByb3BlcnR5TmFtZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNoZWNrV2hpdGVMaXN0KHByb3RvQWNjZXNzQ29udHJvbC5wcm9wZXJ0aWVzLCBwcm9wZXJ0eU5hbWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrV2hpdGVMaXN0KHByb3RvQWNjZXNzQ29udHJvbEZvclR5cGUsIHByb3BlcnR5TmFtZSkge1xuICBpZiAocHJvdG9BY2Nlc3NDb250cm9sRm9yVHlwZS53aGl0ZWxpc3RbcHJvcGVydHlOYW1lXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHByb3RvQWNjZXNzQ29udHJvbEZvclR5cGUud2hpdGVsaXN0W3Byb3BlcnR5TmFtZV0gPT09IHRydWU7XG4gIH1cbiAgaWYgKHByb3RvQWNjZXNzQ29udHJvbEZvclR5cGUuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gcHJvdG9BY2Nlc3NDb250cm9sRm9yVHlwZS5kZWZhdWx0VmFsdWU7XG4gIH1cbiAgbG9nVW5leHBlY2VkUHJvcGVydHlBY2Nlc3NPbmNlKHByb3BlcnR5TmFtZSk7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gbG9nVW5leHBlY2VkUHJvcGVydHlBY2Nlc3NPbmNlKHByb3BlcnR5TmFtZSkge1xuICBpZiAobG9nZ2VkUHJvcGVydGllc1twcm9wZXJ0eU5hbWVdICE9PSB0cnVlKSB7XG4gICAgbG9nZ2VkUHJvcGVydGllc1twcm9wZXJ0eU5hbWVdID0gdHJ1ZTtcbiAgICBsb2dnZXIubG9nKFxuICAgICAgJ2Vycm9yJyxcbiAgICAgIGBIYW5kbGViYXJzOiBBY2Nlc3MgaGFzIGJlZW4gZGVuaWVkIHRvIHJlc29sdmUgdGhlIHByb3BlcnR5IFwiJHtwcm9wZXJ0eU5hbWV9XCIgYmVjYXVzZSBpdCBpcyBub3QgYW4gXCJvd24gcHJvcGVydHlcIiBvZiBpdHMgcGFyZW50LlxcbmAgK1xuICAgICAgICBgWW91IGNhbiBhZGQgYSBydW50aW1lIG9wdGlvbiB0byBkaXNhYmxlIHRoZSBjaGVjayBvciB0aGlzIHdhcm5pbmc6XFxuYCArXG4gICAgICAgIGBTZWUgaHR0cHM6Ly9oYW5kbGViYXJzanMuY29tL2FwaS1yZWZlcmVuY2UvcnVudGltZS1vcHRpb25zLmh0bWwjb3B0aW9ucy10by1jb250cm9sLXByb3RvdHlwZS1hY2Nlc3MgZm9yIGRldGFpbHNgXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRMb2dnZWRQcm9wZXJ0aWVzKCkge1xuICBPYmplY3Qua2V5cyhsb2dnZWRQcm9wZXJ0aWVzKS5mb3JFYWNoKHByb3BlcnR5TmFtZSA9PiB7XG4gICAgZGVsZXRlIGxvZ2dlZFByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcbiAgfSk7XG59XG4iXX0=\n","'use strict';\n\nexports.__esModule = true;\nexports.wrapHelper = wrapHelper;\n\nfunction wrapHelper(helper, transformOptionsFn) {\n if (typeof helper !== 'function') {\n // This should not happen, but apparently it does in https://github.com/wycats/handlebars.js/issues/1639\n // We try to make the wrapper least-invasive by not wrapping it, if the helper is not a function.\n return helper;\n }\n var wrapper = function wrapper() /* dynamic arguments */{\n var options = arguments[arguments.length - 1];\n arguments[arguments.length - 1] = transformOptionsFn(options);\n return helper.apply(this, arguments);\n };\n return wrapper;\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2ludGVybmFsL3dyYXBIZWxwZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBTyxTQUFTLFVBQVUsQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLEVBQUU7QUFDckQsTUFBSSxPQUFPLE1BQU0sS0FBSyxVQUFVLEVBQUU7OztBQUdoQyxXQUFPLE1BQU0sQ0FBQztHQUNmO0FBQ0QsTUFBSSxPQUFPLEdBQUcsU0FBVixPQUFPLDBCQUFxQztBQUM5QyxRQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNoRCxhQUFTLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM5RCxXQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0dBQ3RDLENBQUM7QUFDRixTQUFPLE9BQU8sQ0FBQztDQUNoQiIsImZpbGUiOiJ3cmFwSGVscGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGZ1bmN0aW9uIHdyYXBIZWxwZXIoaGVscGVyLCB0cmFuc2Zvcm1PcHRpb25zRm4pIHtcbiAgaWYgKHR5cGVvZiBoZWxwZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBUaGlzIHNob3VsZCBub3QgaGFwcGVuLCBidXQgYXBwYXJlbnRseSBpdCBkb2VzIGluIGh0dHBzOi8vZ2l0aHViLmNvbS93eWNhdHMvaGFuZGxlYmFycy5qcy9pc3N1ZXMvMTYzOVxuICAgIC8vIFdlIHRyeSB0byBtYWtlIHRoZSB3cmFwcGVyIGxlYXN0LWludmFzaXZlIGJ5IG5vdCB3cmFwcGluZyBpdCwgaWYgdGhlIGhlbHBlciBpcyBub3QgYSBmdW5jdGlvbi5cbiAgICByZXR1cm4gaGVscGVyO1xuICB9XG4gIGxldCB3cmFwcGVyID0gZnVuY3Rpb24oLyogZHluYW1pYyBhcmd1bWVudHMgKi8pIHtcbiAgICBjb25zdCBvcHRpb25zID0gYXJndW1lbnRzW2FyZ3VtZW50cy5sZW5ndGggLSAxXTtcbiAgICBhcmd1bWVudHNbYXJndW1lbnRzLmxlbmd0aCAtIDFdID0gdHJhbnNmb3JtT3B0aW9uc0ZuKG9wdGlvbnMpO1xuICAgIHJldHVybiBoZWxwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfTtcbiAgcmV0dXJuIHdyYXBwZXI7XG59XG4iXX0=\n","'use strict';\n\nexports.__esModule = true;\n\nvar _utils = require('./utils');\n\nvar logger = {\n methodMap: ['debug', 'info', 'warn', 'error'],\n level: 'info',\n\n // Maps a given level value to the `methodMap` indexes above.\n lookupLevel: function lookupLevel(level) {\n if (typeof level === 'string') {\n var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase());\n if (levelMap >= 0) {\n level = levelMap;\n } else {\n level = parseInt(level, 10);\n }\n }\n\n return level;\n },\n\n // Can be overridden in the host environment\n log: function log(level) {\n level = logger.lookupLevel(level);\n\n if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) {\n var method = logger.methodMap[level];\n // eslint-disable-next-line no-console\n if (!console[method]) {\n method = 'log';\n }\n\n for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n message[_key - 1] = arguments[_key];\n }\n\n console[method].apply(console, message); // eslint-disable-line no-console\n }\n }\n};\n\nexports['default'] = logger;\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2xvZ2dlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O3FCQUF3QixTQUFTOztBQUVqQyxJQUFJLE1BQU0sR0FBRztBQUNYLFdBQVMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQztBQUM3QyxPQUFLLEVBQUUsTUFBTTs7O0FBR2IsYUFBVyxFQUFFLHFCQUFTLEtBQUssRUFBRTtBQUMzQixRQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtBQUM3QixVQUFJLFFBQVEsR0FBRyxlQUFRLE1BQU0sQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7QUFDOUQsVUFBSSxRQUFRLElBQUksQ0FBQyxFQUFFO0FBQ2pCLGFBQUssR0FBRyxRQUFRLENBQUM7T0FDbEIsTUFBTTtBQUNMLGFBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO09BQzdCO0tBQ0Y7O0FBRUQsV0FBTyxLQUFLLENBQUM7R0FDZDs7O0FBR0QsS0FBRyxFQUFFLGFBQVMsS0FBSyxFQUFjO0FBQy9CLFNBQUssR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDOztBQUVsQyxRQUNFLE9BQU8sT0FBTyxLQUFLLFdBQVcsSUFDOUIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxFQUN6QztBQUNBLFVBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7O0FBRXJDLFVBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7QUFDcEIsY0FBTSxHQUFHLEtBQUssQ0FBQztPQUNoQjs7d0NBWG1CLE9BQU87QUFBUCxlQUFPOzs7QUFZM0IsYUFBTyxDQUFDLE1BQU0sT0FBQyxDQUFmLE9BQU8sRUFBWSxPQUFPLENBQUMsQ0FBQztLQUM3QjtHQUNGO0NBQ0YsQ0FBQzs7cUJBRWEsTUFBTSIsImZpbGUiOiJsb2dnZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmRleE9mIH0gZnJvbSAnLi91dGlscyc7XG5cbmxldCBsb2dnZXIgPSB7XG4gIG1ldGhvZE1hcDogWydkZWJ1ZycsICdpbmZvJywgJ3dhcm4nLCAnZXJyb3InXSxcbiAgbGV2ZWw6ICdpbmZvJyxcblxuICAvLyBNYXBzIGEgZ2l2ZW4gbGV2ZWwgdmFsdWUgdG8gdGhlIGBtZXRob2RNYXBgIGluZGV4ZXMgYWJvdmUuXG4gIGxvb2t1cExldmVsOiBmdW5jdGlvbihsZXZlbCkge1xuICAgIGlmICh0eXBlb2YgbGV2ZWwgPT09ICdzdHJpbmcnKSB7XG4gICAgICBsZXQgbGV2ZWxNYXAgPSBpbmRleE9mKGxvZ2dlci5tZXRob2RNYXAsIGxldmVsLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgaWYgKGxldmVsTWFwID49IDApIHtcbiAgICAgICAgbGV2ZWwgPSBsZXZlbE1hcDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldmVsID0gcGFyc2VJbnQobGV2ZWwsIDEwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbGV2ZWw7XG4gIH0sXG5cbiAgLy8gQ2FuIGJlIG92ZXJyaWRkZW4gaW4gdGhlIGhvc3QgZW52aXJvbm1lbnRcbiAgbG9nOiBmdW5jdGlvbihsZXZlbCwgLi4ubWVzc2FnZSkge1xuICAgIGxldmVsID0gbG9nZ2VyLmxvb2t1cExldmVsKGxldmVsKTtcblxuICAgIGlmIChcbiAgICAgIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgbG9nZ2VyLmxvb2t1cExldmVsKGxvZ2dlci5sZXZlbCkgPD0gbGV2ZWxcbiAgICApIHtcbiAgICAgIGxldCBtZXRob2QgPSBsb2dnZXIubWV0aG9kTWFwW2xldmVsXTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBpZiAoIWNvbnNvbGVbbWV0aG9kXSkge1xuICAgICAgICBtZXRob2QgPSAnbG9nJztcbiAgICAgIH1cbiAgICAgIGNvbnNvbGVbbWV0aG9kXSguLi5tZXNzYWdlKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1jb25zb2xlXG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBsb2dnZXI7XG4iXX0=\n","'use strict';\n\nexports.__esModule = true;\n\nexports['default'] = function (Handlebars) {\n /* istanbul ignore next */\n var root = typeof global !== 'undefined' ? global : window,\n $Handlebars = root.Handlebars;\n /* istanbul ignore next */\n Handlebars.noConflict = function () {\n if (root.Handlebars === Handlebars) {\n root.Handlebars = $Handlebars;\n }\n return Handlebars;\n };\n};\n\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL25vLWNvbmZsaWN0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7cUJBQWUsVUFBUyxVQUFVLEVBQUU7O0FBRWxDLE1BQUksSUFBSSxHQUFHLE9BQU8sTUFBTSxLQUFLLFdBQVcsR0FBRyxNQUFNLEdBQUcsTUFBTTtNQUN4RCxXQUFXLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQzs7QUFFaEMsWUFBVSxDQUFDLFVBQVUsR0FBRyxZQUFXO0FBQ2pDLFFBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxVQUFVLEVBQUU7QUFDbEMsVUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFXLENBQUM7S0FDL0I7QUFDRCxXQUFPLFVBQVUsQ0FBQztHQUNuQixDQUFDO0NBQ0giLCJmaWxlIjoibm8tY29uZmxpY3QuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbihIYW5kbGViYXJzKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGxldCByb290ID0gdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB3aW5kb3csXG4gICAgJEhhbmRsZWJhcnMgPSByb290LkhhbmRsZWJhcnM7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIEhhbmRsZWJhcnMubm9Db25mbGljdCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmIChyb290LkhhbmRsZWJhcnMgPT09IEhhbmRsZWJhcnMpIHtcbiAgICAgIHJvb3QuSGFuZGxlYmFycyA9ICRIYW5kbGViYXJzO1xuICAgIH1cbiAgICByZXR1cm4gSGFuZGxlYmFycztcbiAgfTtcbn1cbiJdfQ==\n","'use strict';\n\nexports.__esModule = true;\nexports.checkRevision = checkRevision;\nexports.template = template;\nexports.wrapProgram = wrapProgram;\nexports.resolvePartial = resolvePartial;\nexports.invokePartial = invokePartial;\nexports.noop = noop;\n// istanbul ignore next\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n// istanbul ignore next\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\nvar _utils = require('./utils');\n\nvar Utils = _interopRequireWildcard(_utils);\n\nvar _exception = require('./exception');\n\nvar _exception2 = _interopRequireDefault(_exception);\n\nvar _base = require('./base');\n\nvar _helpers = require('./helpers');\n\nvar _internalWrapHelper = require('./internal/wrapHelper');\n\nvar _internalProtoAccess = require('./internal/proto-access');\n\nfunction checkRevision(compilerInfo) {\n var compilerRevision = compilerInfo && compilerInfo[0] || 1,\n currentRevision = _base.COMPILER_REVISION;\n\n if (compilerRevision >= _base.LAST_COMPATIBLE_COMPILER_REVISION && compilerRevision <= _base.COMPILER_REVISION) {\n return;\n }\n\n if (compilerRevision < _base.LAST_COMPATIBLE_COMPILER_REVISION) {\n var runtimeVersions = _base.REVISION_CHANGES[currentRevision],\n compilerVersions = _base.REVISION_CHANGES[compilerRevision];\n throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').');\n } else {\n // Use the embedded version info since the runtime doesn't know about this revision yet\n throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').');\n }\n}\n\nfunction template(templateSpec, env) {\n /* istanbul ignore next */\n if (!env) {\n throw new _exception2['default']('No environment passed to template');\n }\n if (!templateSpec || !templateSpec.main) {\n throw new _exception2['default']('Unknown template object: ' + typeof templateSpec);\n }\n\n templateSpec.main.decorator = templateSpec.main_d;\n\n // Note: Using env.VM references rather than local var references throughout this section to allow\n // for external users to override these as pseudo-supported APIs.\n env.VM.checkRevision(templateSpec.compiler);\n\n // backwards compatibility for precompiled templates with compiler-version 7 (<4.3.0)\n var templateWasPrecompiledWithCompilerV7 = templateSpec.compiler && templateSpec.compiler[0] === 7;\n\n function invokePartialWrapper(partial, context, options) {\n if (options.hash) {\n context = Utils.extend({}, context, options.hash);\n if (options.ids) {\n options.ids[0] = true;\n }\n }\n partial = env.VM.resolvePartial.call(this, partial, context, options);\n\n var extendedOptions = Utils.extend({}, options, {\n hooks: this.hooks,\n protoAccessControl: this.protoAccessControl\n });\n\n var result = env.VM.invokePartial.call(this, partial, context, extendedOptions);\n\n if (result == null && env.compile) {\n options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);\n result = options.partials[options.name](context, extendedOptions);\n }\n if (result != null) {\n if (options.indent) {\n var lines = result.split('\\n');\n for (var i = 0, l = lines.length; i < l; i++) {\n if (!lines[i] && i + 1 === l) {\n break;\n }\n\n lines[i] = options.indent + lines[i];\n }\n result = lines.join('\\n');\n }\n return result;\n } else {\n throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');\n }\n }\n\n // Just add water\n var container = {\n strict: function strict(obj, name, loc) {\n if (!obj || !(name in obj)) {\n throw new _exception2['default']('\"' + name + '\" not defined in ' + obj, {\n loc: loc\n });\n }\n return container.lookupProperty(obj, name);\n },\n lookupProperty: function lookupProperty(parent, propertyName) {\n var result = parent[propertyName];\n if (result == null) {\n return result;\n }\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return result;\n }\n\n if (_internalProtoAccess.resultIsAllowed(result, container.protoAccessControl, propertyName)) {\n return result;\n }\n return undefined;\n },\n lookup: function lookup(depths, name) {\n var len = depths.length;\n for (var i = 0; i < len; i++) {\n var result = depths[i] && container.lookupProperty(depths[i], name);\n if (result != null) {\n return depths[i][name];\n }\n }\n },\n lambda: function lambda(current, context) {\n return typeof current === 'function' ? current.call(context) : current;\n },\n\n escapeExpression: Utils.escapeExpression,\n invokePartial: invokePartialWrapper,\n\n fn: function fn(i) {\n var ret = templateSpec[i];\n ret.decorator = templateSpec[i + '_d'];\n return ret;\n },\n\n programs: [],\n program: function program(i, data, declaredBlockParams, blockParams, depths) {\n var programWrapper = this.programs[i],\n fn = this.fn(i);\n if (data || depths || blockParams || declaredBlockParams) {\n programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);\n } else if (!programWrapper) {\n programWrapper = this.programs[i] = wrapProgram(this, i, fn);\n }\n return programWrapper;\n },\n\n data: function data(value, depth) {\n while (value && depth--) {\n value = value._parent;\n }\n return value;\n },\n mergeIfNeeded: function mergeIfNeeded(param, common) {\n var obj = param || common;\n\n if (param && common && param !== common) {\n obj = Utils.extend({}, common, param);\n }\n\n return obj;\n },\n // An empty object to use as replacement for null-contexts\n nullContext: Object.seal({}),\n\n noop: env.VM.noop,\n compilerInfo: templateSpec.compiler\n };\n\n function ret(context) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var data = options.data;\n\n ret._setup(options);\n if (!options.partial && templateSpec.useData) {\n data = initData(context, data);\n }\n var depths = undefined,\n blockParams = templateSpec.useBlockParams ? [] : undefined;\n if (templateSpec.useDepths) {\n if (options.depths) {\n depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths;\n } else {\n depths = [context];\n }\n }\n\n function main(context /*, options*/) {\n return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths);\n }\n\n main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);\n return main(context, options);\n }\n\n ret.isTop = true;\n\n ret._setup = function (options) {\n if (!options.partial) {\n var mergedHelpers = Utils.extend({}, env.helpers, options.helpers);\n wrapHelpersToPassLookupProperty(mergedHelpers, container);\n container.helpers = mergedHelpers;\n\n if (templateSpec.usePartial) {\n // Use mergeIfNeeded here to prevent compiling global partials multiple times\n container.partials = container.mergeIfNeeded(options.partials, env.partials);\n }\n if (templateSpec.usePartial || templateSpec.useDecorators) {\n container.decorators = Utils.extend({}, env.decorators, options.decorators);\n }\n\n container.hooks = {};\n container.protoAccessControl = _internalProtoAccess.createProtoAccessControl(options);\n\n var keepHelperInHelpers = options.allowCallsToHelperMissing || templateWasPrecompiledWithCompilerV7;\n _helpers.moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers);\n _helpers.moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers);\n } else {\n container.protoAccessControl = options.protoAccessControl; // internal option\n container.helpers = options.helpers;\n container.partials = options.partials;\n container.decorators = options.decorators;\n container.hooks = options.hooks;\n }\n };\n\n ret._child = function (i, data, blockParams, depths) {\n if (templateSpec.useBlockParams && !blockParams) {\n throw new _exception2['default']('must pass block params');\n }\n if (templateSpec.useDepths && !depths) {\n throw new _exception2['default']('must pass parent depths');\n }\n\n return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);\n };\n return ret;\n}\n\nfunction wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {\n function prog(context) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n var currentDepths = depths;\n if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) {\n currentDepths = [context].concat(depths);\n }\n\n return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths);\n }\n\n prog = executeDecorators(fn, prog, container, depths, data, blockParams);\n\n prog.program = i;\n prog.depth = depths ? depths.length : 0;\n prog.blockParams = declaredBlockParams || 0;\n return prog;\n}\n\n/**\n * This is currently part of the official API, therefore implementation details should not be changed.\n */\n\nfunction resolvePartial(partial, context, options) {\n if (!partial) {\n if (options.name === '@partial-block') {\n partial = options.data['partial-block'];\n } else {\n partial = options.partials[options.name];\n }\n } else if (!partial.call && !options.name) {\n // This is a dynamic partial that returned a string\n options.name = partial;\n partial = options.partials[partial];\n }\n return partial;\n}\n\nfunction invokePartial(partial, context, options) {\n // Use the current closure context to save the partial-block if this partial\n var currentPartialBlock = options.data && options.data['partial-block'];\n options.partial = true;\n if (options.ids) {\n options.data.contextPath = options.ids[0] || options.data.contextPath;\n }\n\n var partialBlock = undefined;\n if (options.fn && options.fn !== noop) {\n (function () {\n options.data = _base.createFrame(options.data);\n // Wrapper function to get access to currentPartialBlock from the closure\n var fn = options.fn;\n partialBlock = options.data['partial-block'] = function partialBlockWrapper(context) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\n // Restore the partial-block from the closure for the execution of the block\n // i.e. the part inside the block of the partial call.\n options.data = _base.createFrame(options.data);\n options.data['partial-block'] = currentPartialBlock;\n return fn(context, options);\n };\n if (fn.partials) {\n options.partials = Utils.extend({}, options.partials, fn.partials);\n }\n })();\n }\n\n if (partial === undefined && partialBlock) {\n partial = partialBlock;\n }\n\n if (partial === undefined) {\n throw new _exception2['default']('The partial ' + options.name + ' could not be found');\n } else if (partial instanceof Function) {\n return partial(context, options);\n }\n}\n\nfunction noop() {\n return '';\n}\n\nfunction initData(context, data) {\n if (!data || !('root' in data)) {\n data = data ? _base.createFrame(data) : {};\n data.root = context;\n }\n return data;\n}\n\nfunction executeDecorators(fn, prog, container, depths, data, blockParams) {\n if (fn.decorator) {\n var props = {};\n prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths);\n Utils.extend(prog, props);\n }\n return prog;\n}\n\nfunction wrapHelpersToPassLookupProperty(mergedHelpers, container) {\n Object.keys(mergedHelpers).forEach(function (helperName) {\n var helper = mergedHelpers[helperName];\n mergedHelpers[helperName] = passLookupPropertyOption(helper, container);\n });\n}\n\nfunction passLookupPropertyOption(helper, container) {\n var lookupProperty = container.lookupProperty;\n return _internalWrapHelper.wrapHelper(helper, function (options) {\n return Utils.extend({ lookupProperty: lookupProperty }, options);\n });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL3J1bnRpbWUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7cUJBQXVCLFNBQVM7O0lBQXBCLEtBQUs7O3lCQUNLLGFBQWE7Ozs7b0JBTTVCLFFBQVE7O3VCQUNtQixXQUFXOztrQ0FDbEIsdUJBQXVCOzttQ0FJM0MseUJBQXlCOztBQUV6QixTQUFTLGFBQWEsQ0FBQyxZQUFZLEVBQUU7QUFDMUMsTUFBTSxnQkFBZ0IsR0FBRyxBQUFDLFlBQVksSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUssQ0FBQztNQUM3RCxlQUFlLDBCQUFvQixDQUFDOztBQUV0QyxNQUNFLGdCQUFnQiwyQ0FBcUMsSUFDckQsZ0JBQWdCLDJCQUFxQixFQUNyQztBQUNBLFdBQU87R0FDUjs7QUFFRCxNQUFJLGdCQUFnQiwwQ0FBb0MsRUFBRTtBQUN4RCxRQUFNLGVBQWUsR0FBRyx1QkFBaUIsZUFBZSxDQUFDO1FBQ3ZELGdCQUFnQixHQUFHLHVCQUFpQixnQkFBZ0IsQ0FBQyxDQUFDO0FBQ3hELFVBQU0sMkJBQ0oseUZBQXlGLEdBQ3ZGLHFEQUFxRCxHQUNyRCxlQUFlLEdBQ2YsbURBQW1ELEdBQ25ELGdCQUFnQixHQUNoQixJQUFJLENBQ1AsQ0FBQztHQUNILE1BQU07O0FBRUwsVUFBTSwyQkFDSix3RkFBd0YsR0FDdEYsaURBQWlELEdBQ2pELFlBQVksQ0FBQyxDQUFDLENBQUMsR0FDZixJQUFJLENBQ1AsQ0FBQztHQUNIO0NBQ0Y7O0FBRU0sU0FBUyxRQUFRLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRTs7QUFFMUMsTUFBSSxDQUFDLEdBQUcsRUFBRTtBQUNSLFVBQU0sMkJBQWMsbUNBQW1DLENBQUMsQ0FBQztHQUMxRDtBQUNELE1BQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFO0FBQ3ZDLFVBQU0sMkJBQWMsMkJBQTJCLEdBQUcsT0FBTyxZQUFZLENBQUMsQ0FBQztHQUN4RTs7QUFFRCxjQUFZLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDOzs7O0FBSWxELEtBQUcsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQzs7O0FBRzVDLE1BQU0sb0NBQW9DLEdBQ3hDLFlBQVksQ0FBQyxRQUFRLElBQUksWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7O0FBRTFELFdBQVMsb0JBQW9CLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUU7QUFDdkQsUUFBSSxPQUFPLENBQUMsSUFBSSxFQUFFO0FBQ2hCLGFBQU8sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2xELFVBQUksT0FBTyxDQUFDLEdBQUcsRUFBRTtBQUNmLGVBQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO09BQ3ZCO0tBQ0Y7QUFDRCxXQUFPLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDOztBQUV0RSxRQUFJLGVBQWUsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUU7QUFDOUMsV0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0FBQ2pCLHdCQUFrQixFQUFFLElBQUksQ0FBQyxrQkFBa0I7S0FDNUMsQ0FBQyxDQUFDOztBQUVILFFBQUksTUFBTSxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLElBQUksQ0FDcEMsSUFBSSxFQUNKLE9BQU8sRUFDUCxPQUFPLEVBQ1AsZUFBZSxDQUNoQixDQUFDOztBQUVGLFFBQUksTUFBTSxJQUFJLElBQUksSUFBSSxHQUFHLENBQUMsT0FBTyxFQUFFO0FBQ2pDLGFBQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQzFDLE9BQU8sRUFDUCxZQUFZLENBQUMsZUFBZSxFQUM1QixHQUFHLENBQ0osQ0FBQztBQUNGLFlBQU0sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7S0FDbkU7QUFDRCxRQUFJLE1BQU0sSUFBSSxJQUFJLEVBQUU7QUFDbEIsVUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFO0FBQ2xCLFlBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDL0IsYUFBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUM1QyxjQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFO0FBQzVCLGtCQUFNO1dBQ1A7O0FBRUQsZUFBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ3RDO0FBQ0QsY0FBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7T0FDM0I7QUFDRCxhQUFPLE1BQU0sQ0FBQztLQUNmLE1BQU07QUFDTCxZQUFNLDJCQUNKLGNBQWMsR0FDWixPQUFPLENBQUMsSUFBSSxHQUNaLDBEQUEwRCxDQUM3RCxDQUFDO0tBQ0g7R0FDRjs7O0FBR0QsTUFBSSxTQUFTLEdBQUc7QUFDZCxVQUFNLEVBQUUsZ0JBQVMsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUU7QUFDL0IsVUFBSSxDQUFDLEdBQUcsSUFBSSxFQUFFLElBQUksSUFBSSxHQUFHLENBQUEsQUFBQyxFQUFFO0FBQzFCLGNBQU0sMkJBQWMsR0FBRyxHQUFHLElBQUksR0FBRyxtQkFBbUIsR0FBRyxHQUFHLEVBQUU7QUFDMUQsYUFBRyxFQUFFLEdBQUc7U0FDVCxDQUFDLENBQUM7T0FDSjtBQUNELGFBQU8sU0FBUyxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDNUM7QUFDRCxrQkFBYyxFQUFFLHdCQUFTLE1BQU0sRUFBRSxZQUFZLEVBQUU7QUFDN0MsVUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ2xDLFVBQUksTUFBTSxJQUFJLElBQUksRUFBRTtBQUNsQixlQUFPLE1BQU0sQ0FBQztPQUNmO0FBQ0QsVUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxFQUFFO0FBQzlELGVBQU8sTUFBTSxDQUFDO09BQ2Y7O0FBRUQsVUFBSSxxQ0FBZ0IsTUFBTSxFQUFFLFNBQVMsQ0FBQyxrQkFBa0IsRUFBRSxZQUFZLENBQUMsRUFBRTtBQUN2RSxlQUFPLE1BQU0sQ0FBQztPQUNmO0FBQ0QsYUFBTyxTQUFTLENBQUM7S0FDbEI7QUFDRCxVQUFNLEVBQUUsZ0JBQVMsTUFBTSxFQUFFLElBQUksRUFBRTtBQUM3QixVQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0FBQzFCLFdBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDNUIsWUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3BFLFlBQUksTUFBTSxJQUFJLElBQUksRUFBRTtBQUNsQixpQkFBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDeEI7T0FDRjtLQUNGO0FBQ0QsVUFBTSxFQUFFLGdCQUFTLE9BQU8sRUFBRSxPQUFPLEVBQUU7QUFDakMsYUFBTyxPQUFPLE9BQU8sS0FBSyxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxPQUFPLENBQUM7S0FDeEU7O0FBRUQsb0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtBQUN4QyxpQkFBYSxFQUFFLG9CQUFvQjs7QUFFbkMsTUFBRSxFQUFFLFlBQVMsQ0FBQyxFQUFFO0FBQ2QsVUFBSSxHQUFHLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFCLFNBQUcsQ0FBQyxTQUFTLEdBQUcsWUFBWSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUN2QyxhQUFPLEdBQUcsQ0FBQztLQUNaOztBQUVELFlBQVEsRUFBRSxFQUFFO0FBQ1osV0FBTyxFQUFFLGlCQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRTtBQUNuRSxVQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztVQUNuQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixVQUFJLElBQUksSUFBSSxNQUFNLElBQUksV0FBVyxJQUFJLG1CQUFtQixFQUFFO0FBQ3hELHNCQUFjLEdBQUcsV0FBVyxDQUMxQixJQUFJLEVBQ0osQ0FBQyxFQUNELEVBQUUsRUFDRixJQUFJLEVBQ0osbUJBQW1CLEVBQ25CLFdBQVcsRUFDWCxNQUFNLENBQ1AsQ0FBQztPQUNILE1BQU0sSUFBSSxDQUFDLGNBQWMsRUFBRTtBQUMxQixzQkFBYyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7T0FDOUQ7QUFDRCxhQUFPLGNBQWMsQ0FBQztLQUN2Qjs7QUFFRCxRQUFJLEVBQUUsY0FBUyxLQUFLLEVBQUUsS0FBSyxFQUFFO0FBQzNCLGFBQU8sS0FBSyxJQUFJLEtBQUssRUFBRSxFQUFFO0FBQ3ZCLGFBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO09BQ3ZCO0FBQ0QsYUFBTyxLQUFLLENBQUM7S0FDZDtBQUNELGlCQUFhLEVBQUUsdUJBQVMsS0FBSyxFQUFFLE1BQU0sRUFBRTtBQUNyQyxVQUFJLEdBQUcsR0FBRyxLQUFLLElBQUksTUFBTSxDQUFDOztBQUUxQixVQUFJLEtBQUssSUFBSSxNQUFNLElBQUksS0FBSyxLQUFLLE1BQU0sRUFBRTtBQUN2QyxXQUFHLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO09BQ3ZDOztBQUVELGFBQU8sR0FBRyxDQUFDO0tBQ1o7O0FBRUQsZUFBVyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDOztBQUU1QixRQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJO0FBQ2pCLGdCQUFZLEVBQUUsWUFBWSxDQUFDLFFBQVE7R0FDcEMsQ0FBQzs7QUFFRixXQUFTLEdBQUcsQ0FBQyxPQUFPLEVBQWdCO1FBQWQsT0FBTyx5REFBRyxFQUFFOztBQUNoQyxRQUFJLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDOztBQUV4QixPQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BCLFFBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLFlBQVksQ0FBQyxPQUFPLEVBQUU7QUFDNUMsVUFBSSxHQUFHLFFBQVEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDaEM7QUFDRCxRQUFJLE1BQU0sWUFBQTtRQUNSLFdBQVcsR0FBRyxZQUFZLENBQUMsY0FBYyxHQUFHLEVBQUUsR0FBRyxTQUFTLENBQUM7QUFDN0QsUUFBSSxZQUFZLENBQUMsU0FBUyxFQUFFO0FBQzFCLFVBQUksT0FBTyxDQUFDLE1BQU0sRUFBRTtBQUNsQixjQUFNLEdBQ0osT0FBTyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQ3hCLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FDaEMsT0FBTyxDQUFDLE1BQU0sQ0FBQztPQUN0QixNQUFNO0FBQ0wsY0FBTSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7T0FDcEI7S0FDRjs7QUFFRCxhQUFTLElBQUksQ0FBQyxPQUFPLGdCQUFnQjtBQUNuQyxhQUNFLEVBQUUsR0FDRixZQUFZLENBQUMsSUFBSSxDQUNmLFNBQVMsRUFDVCxPQUFPLEVBQ1AsU0FBUyxDQUFDLE9BQU8sRUFDakIsU0FBUyxDQUFDLFFBQVEsRUFDbEIsSUFBSSxFQUNKLFdBQVcsRUFDWCxNQUFNLENBQ1AsQ0FDRDtLQUNIOztBQUVELFFBQUksR0FBRyxpQkFBaUIsQ0FDdEIsWUFBWSxDQUFDLElBQUksRUFDakIsSUFBSSxFQUNKLFNBQVMsRUFDVCxPQUFPLENBQUMsTUFBTSxJQUFJLEVBQUUsRUFDcEIsSUFBSSxFQUNKLFdBQVcsQ0FDWixDQUFDO0FBQ0YsV0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0dBQy9COztBQUVELEtBQUcsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDOztBQUVqQixLQUFHLENBQUMsTUFBTSxHQUFHLFVBQVMsT0FBTyxFQUFFO0FBQzdCLFFBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFO0FBQ3BCLFVBQUksYUFBYSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ25FLHFDQUErQixDQUFDLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUMxRCxlQUFTLENBQUMsT0FBTyxHQUFHLGFBQWEsQ0FBQzs7QUFFbEMsVUFBSSxZQUFZLENBQUMsVUFBVSxFQUFFOztBQUUzQixpQkFBUyxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUMsYUFBYSxDQUMxQyxPQUFPLENBQUMsUUFBUSxFQUNoQixHQUFHLENBQUMsUUFBUSxDQUNiLENBQUM7T0FDSDtBQUNELFVBQUksWUFBWSxDQUFDLFVBQVUsSUFBSSxZQUFZLENBQUMsYUFBYSxFQUFFO0FBQ3pELGlCQUFTLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQ2pDLEVBQUUsRUFDRixHQUFHLENBQUMsVUFBVSxFQUNkLE9BQU8sQ0FBQyxVQUFVLENBQ25CLENBQUM7T0FDSDs7QUFFRCxlQUFTLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztBQUNyQixlQUFTLENBQUMsa0JBQWtCLEdBQUcsOENBQXlCLE9BQU8sQ0FBQyxDQUFDOztBQUVqRSxVQUFJLG1CQUFtQixHQUNyQixPQUFPLENBQUMseUJBQXlCLElBQ2pDLG9DQUFvQyxDQUFDO0FBQ3ZDLGlDQUFrQixTQUFTLEVBQUUsZUFBZSxFQUFFLG1CQUFtQixDQUFDLENBQUM7QUFDbkUsaUNBQWtCLFNBQVMsRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0tBQ3pFLE1BQU07QUFDTCxlQUFTLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0FBQzFELGVBQVMsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztBQUNwQyxlQUFTLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7QUFDdEMsZUFBUyxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDO0FBQzFDLGVBQVMsQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztLQUNqQztHQUNGLENBQUM7O0FBRUYsS0FBRyxDQUFDLE1BQU0sR0FBRyxVQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRTtBQUNsRCxRQUFJLFlBQVksQ0FBQyxjQUFjLElBQUksQ0FBQyxXQUFXLEVBQUU7QUFDL0MsWUFBTSwyQkFBYyx3QkFBd0IsQ0FBQyxDQUFDO0tBQy9DO0FBQ0QsUUFBSSxZQUFZLENBQUMsU0FBUyxJQUFJLENBQUMsTUFBTSxFQUFFO0FBQ3JDLFlBQU0sMkJBQWMseUJBQXlCLENBQUMsQ0FBQztLQUNoRDs7QUFFRCxXQUFPLFdBQVcsQ0FDaEIsU0FBUyxFQUNULENBQUMsRUFDRCxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQ2YsSUFBSSxFQUNKLENBQUMsRUFDRCxXQUFXLEVBQ1gsTUFBTSxDQUNQLENBQUM7R0FDSCxDQUFDO0FBQ0YsU0FBTyxHQUFHLENBQUM7Q0FDWjs7QUFFTSxTQUFTLFdBQVcsQ0FDekIsU0FBUyxFQUNULENBQUMsRUFDRCxFQUFFLEVBQ0YsSUFBSSxFQUNKLG1CQUFtQixFQUNuQixXQUFXLEVBQ1gsTUFBTSxFQUNOO0FBQ0EsV0FBUyxJQUFJLENBQUMsT0FBTyxFQUFnQjtRQUFkLE9BQU8seURBQUcsRUFBRTs7QUFDakMsUUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDO0FBQzNCLFFBQ0UsTUFBTSxJQUNOLE9BQU8sSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQ3BCLEVBQUUsT0FBTyxLQUFLLFNBQVMsQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQSxBQUFDLEVBQzFEO0FBQ0EsbUJBQWEsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztLQUMxQzs7QUFFRCxXQUFPLEVBQUUsQ0FDUCxTQUFTLEVBQ1QsT0FBTyxFQUNQLFNBQVMsQ0FBQyxPQUFPLEVBQ2pCLFNBQVMsQ0FBQyxRQUFRLEVBQ2xCLE9BQU8sQ0FBQyxJQUFJLElBQUksSUFBSSxFQUNwQixXQUFXLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUN4RCxhQUFhLENBQ2QsQ0FBQztHQUNIOztBQUVELE1BQUksR0FBRyxpQkFBaUIsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDOztBQUV6RSxNQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztBQUNqQixNQUFJLENBQUMsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztBQUN4QyxNQUFJLENBQUMsV0FBVyxHQUFHLG1CQUFtQixJQUFJLENBQUMsQ0FBQztBQUM1QyxTQUFPLElBQUksQ0FBQztDQUNiOzs7Ozs7QUFLTSxTQUFTLGNBQWMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRTtBQUN4RCxNQUFJLENBQUMsT0FBTyxFQUFFO0FBQ1osUUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLGdCQUFnQixFQUFFO0FBQ3JDLGFBQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0tBQ3pDLE1BQU07QUFDTCxhQUFPLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDMUM7R0FDRixNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTs7QUFFekMsV0FBTyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7QUFDdkIsV0FBTyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7R0FDckM7QUFDRCxTQUFPLE9BQU8sQ0FBQztDQUNoQjs7QUFFTSxTQUFTLGFBQWEsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRTs7QUFFdkQsTUFBTSxtQkFBbUIsR0FBRyxPQUFPLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDMUUsU0FBTyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7QUFDdkIsTUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFO0FBQ2YsV0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztHQUN2RTs7QUFFRCxNQUFJLFlBQVksWUFBQSxDQUFDO0FBQ2pCLE1BQUksT0FBTyxDQUFDLEVBQUUsSUFBSSxPQUFPLENBQUMsRUFBRSxLQUFLLElBQUksRUFBRTs7QUFDckMsYUFBTyxDQUFDLElBQUksR0FBRyxrQkFBWSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7O0FBRXpDLFVBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUM7QUFDcEIsa0JBQVksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLFNBQVMsbUJBQW1CLENBQ3pFLE9BQU8sRUFFUDtZQURBLE9BQU8seURBQUcsRUFBRTs7OztBQUlaLGVBQU8sQ0FBQyxJQUFJLEdBQUcsa0JBQVksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3pDLGVBQU8sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsbUJBQW1CLENBQUM7QUFDcEQsZUFBTyxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO09BQzdCLENBQUM7QUFDRixVQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7QUFDZixlQUFPLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO09BQ3BFOztHQUNGOztBQUVELE1BQUksT0FBTyxLQUFLLFNBQVMsSUFBSSxZQUFZLEVBQUU7QUFDekMsV0FBTyxHQUFHLFlBQVksQ0FBQztHQUN4Qjs7QUFFRCxNQUFJLE9BQU8sS0FBSyxTQUFTLEVBQUU7QUFDekIsVUFBTSwyQkFBYyxjQUFjLEdBQUcsT0FBTyxDQUFDLElBQUksR0FBRyxxQkFBcUIsQ0FBQyxDQUFDO0dBQzVFLE1BQU0sSUFBSSxPQUFPLFlBQVksUUFBUSxFQUFFO0FBQ3RDLFdBQU8sT0FBTyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztHQUNsQztDQUNGOztBQUVNLFNBQVMsSUFBSSxHQUFHO0FBQ3JCLFNBQU8sRUFBRSxDQUFDO0NBQ1g7O0FBRUQsU0FBUyxRQUFRLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRTtBQUMvQixNQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsTUFBTSxJQUFJLElBQUksQ0FBQSxBQUFDLEVBQUU7QUFDOUIsUUFBSSxHQUFHLElBQUksR0FBRyxrQkFBWSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDckMsUUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7R0FDckI7QUFDRCxTQUFPLElBQUksQ0FBQztDQUNiOztBQUVELFNBQVMsaUJBQWlCLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUU7QUFDekUsTUFBSSxFQUFFLENBQUMsU0FBUyxFQUFFO0FBQ2hCLFFBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztBQUNmLFFBQUksR0FBRyxFQUFFLENBQUMsU0FBUyxDQUNqQixJQUFJLEVBQ0osS0FBSyxFQUNMLFNBQVMsRUFDVCxNQUFNLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUNuQixJQUFJLEVBQ0osV0FBVyxFQUNYLE1BQU0sQ0FDUCxDQUFDO0FBQ0YsU0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7R0FDM0I7QUFDRCxTQUFPLElBQUksQ0FBQztDQUNiOztBQUVELFNBQVMsK0JBQStCLENBQUMsYUFBYSxFQUFFLFNBQVMsRUFBRTtBQUNqRSxRQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFBLFVBQVUsRUFBSTtBQUMvQyxRQUFJLE1BQU0sR0FBRyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDdkMsaUJBQWEsQ0FBQyxVQUFVLENBQUMsR0FBRyx3QkFBd0IsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7R0FDekUsQ0FBQyxDQUFDO0NBQ0o7O0FBRUQsU0FBUyx3QkFBd0IsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFO0FBQ25ELE1BQU0sY0FBYyxHQUFHLFNBQVMsQ0FBQyxjQUFjLENBQUM7QUFDaEQsU0FBTywrQkFBVyxNQUFNLEVBQUUsVUFBQSxPQUFPLEVBQUk7QUFDbkMsV0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsY0FBYyxFQUFkLGNBQWMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0dBQ2xELENBQUMsQ0FBQztDQUNKIiwiZmlsZSI6InJ1bnRpbWUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBVdGlscyBmcm9tICcuL3V0aWxzJztcbmltcG9ydCBFeGNlcHRpb24gZnJvbSAnLi9leGNlcHRpb24nO1xuaW1wb3J0IHtcbiAgQ09NUElMRVJfUkVWSVNJT04sXG4gIGNyZWF0ZUZyYW1lLFxuICBMQVNUX0NPTVBBVElCTEVfQ09NUElMRVJfUkVWSVNJT04sXG4gIFJFVklTSU9OX0NIQU5HRVNcbn0gZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7IG1vdmVIZWxwZXJUb0hvb2tzIH0gZnJvbSAnLi9oZWxwZXJzJztcbmltcG9ydCB7IHdyYXBIZWxwZXIgfSBmcm9tICcuL2ludGVybmFsL3dyYXBIZWxwZXInO1xuaW1wb3J0IHtcbiAgY3JlYXRlUHJvdG9BY2Nlc3NDb250cm9sLFxuICByZXN1bHRJc0FsbG93ZWRcbn0gZnJvbSAnLi9pbnRlcm5hbC9wcm90by1hY2Nlc3MnO1xuXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tSZXZpc2lvbihjb21waWxlckluZm8pIHtcbiAgY29uc3QgY29tcGlsZXJSZXZpc2lvbiA9IChjb21waWxlckluZm8gJiYgY29tcGlsZXJJbmZvWzBdKSB8fCAxLFxuICAgIGN1cnJlbnRSZXZpc2lvbiA9IENPTVBJTEVSX1JFVklTSU9OO1xuXG4gIGlmIChcbiAgICBjb21waWxlclJldmlzaW9uID49IExBU1RfQ09NUEFUSUJMRV9DT01QSUxFUl9SRVZJU0lPTiAmJlxuICAgIGNvbXBpbGVyUmV2aXNpb24gPD0gQ09NUElMRVJfUkVWSVNJT05cbiAgKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGNvbXBpbGVyUmV2aXNpb24gPCBMQVNUX0NPTVBBVElCTEVfQ09NUElMRVJfUkVWSVNJT04pIHtcbiAgICBjb25zdCBydW50aW1lVmVyc2lvbnMgPSBSRVZJU0lPTl9DSEFOR0VTW2N1cnJlbnRSZXZpc2lvbl0sXG4gICAgICBjb21waWxlclZlcnNpb25zID0gUkVWSVNJT05fQ0hBTkdFU1tjb21waWxlclJldmlzaW9uXTtcbiAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKFxuICAgICAgJ1RlbXBsYXRlIHdhcyBwcmVjb21waWxlZCB3aXRoIGFuIG9sZGVyIHZlcnNpb24gb2YgSGFuZGxlYmFycyB0aGFuIHRoZSBjdXJyZW50IHJ1bnRpbWUuICcgK1xuICAgICAgICAnUGxlYXNlIHVwZGF0ZSB5b3VyIHByZWNvbXBpbGVyIHRvIGEgbmV3ZXIgdmVyc2lvbiAoJyArXG4gICAgICAgIHJ1bnRpbWVWZXJzaW9ucyArXG4gICAgICAgICcpIG9yIGRvd25ncmFkZSB5b3VyIHJ1bnRpbWUgdG8gYW4gb2xkZXIgdmVyc2lvbiAoJyArXG4gICAgICAgIGNvbXBpbGVyVmVyc2lvbnMgK1xuICAgICAgICAnKS4nXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBVc2UgdGhlIGVtYmVkZGVkIHZlcnNpb24gaW5mbyBzaW5jZSB0aGUgcnVudGltZSBkb2Vzbid0IGtub3cgYWJvdXQgdGhpcyByZXZpc2lvbiB5ZXRcbiAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKFxuICAgICAgJ1RlbXBsYXRlIHdhcyBwcmVjb21waWxlZCB3aXRoIGEgbmV3ZXIgdmVyc2lvbiBvZiBIYW5kbGViYXJzIHRoYW4gdGhlIGN1cnJlbnQgcnVudGltZS4gJyArXG4gICAgICAgICdQbGVhc2UgdXBkYXRlIHlvdXIgcnVudGltZSB0byBhIG5ld2VyIHZlcnNpb24gKCcgK1xuICAgICAgICBjb21waWxlckluZm9bMV0gK1xuICAgICAgICAnKS4nXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdGVtcGxhdGUodGVtcGxhdGVTcGVjLCBlbnYpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgaWYgKCFlbnYpIHtcbiAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCdObyBlbnZpcm9ubWVudCBwYXNzZWQgdG8gdGVtcGxhdGUnKTtcbiAgfVxuICBpZiAoIXRlbXBsYXRlU3BlYyB8fCAhdGVtcGxhdGVTcGVjLm1haW4pIHtcbiAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCdVbmtub3duIHRlbXBsYXRlIG9iamVjdDogJyArIHR5cGVvZiB0ZW1wbGF0ZVNwZWMpO1xuICB9XG5cbiAgdGVtcGxhdGVTcGVjLm1haW4uZGVjb3JhdG9yID0gdGVtcGxhdGVTcGVjLm1haW5fZDtcblxuICAvLyBOb3RlOiBVc2luZyBlbnYuVk0gcmVmZXJlbmNlcyByYXRoZXIgdGhhbiBsb2NhbCB2YXIgcmVmZXJlbmNlcyB0aHJvdWdob3V0IHRoaXMgc2VjdGlvbiB0byBhbGxvd1xuICAvLyBmb3IgZXh0ZXJuYWwgdXNlcnMgdG8gb3ZlcnJpZGUgdGhlc2UgYXMgcHNldWRvLXN1cHBvcnRlZCBBUElzLlxuICBlbnYuVk0uY2hlY2tSZXZpc2lvbih0ZW1wbGF0ZVNwZWMuY29tcGlsZXIpO1xuXG4gIC8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGZvciBwcmVjb21waWxlZCB0ZW1wbGF0ZXMgd2l0aCBjb21waWxlci12ZXJzaW9uIDcgKDw0LjMuMClcbiAgY29uc3QgdGVtcGxhdGVXYXNQcmVjb21waWxlZFdpdGhDb21waWxlclY3ID1cbiAgICB0ZW1wbGF0ZVNwZWMuY29tcGlsZXIgJiYgdGVtcGxhdGVTcGVjLmNvbXBpbGVyWzBdID09PSA3O1xuXG4gIGZ1bmN0aW9uIGludm9rZVBhcnRpYWxXcmFwcGVyKHBhcnRpYWwsIGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICBpZiAob3B0aW9ucy5oYXNoKSB7XG4gICAgICBjb250ZXh0ID0gVXRpbHMuZXh0ZW5kKHt9LCBjb250ZXh0LCBvcHRpb25zLmhhc2gpO1xuICAgICAgaWYgKG9wdGlvbnMuaWRzKSB7XG4gICAgICAgIG9wdGlvbnMuaWRzWzBdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcGFydGlhbCA9IGVudi5WTS5yZXNvbHZlUGFydGlhbC5jYWxsKHRoaXMsIHBhcnRpYWwsIGNvbnRleHQsIG9wdGlvbnMpO1xuXG4gICAgbGV0IGV4dGVuZGVkT3B0aW9ucyA9IFV0aWxzLmV4dGVuZCh7fSwgb3B0aW9ucywge1xuICAgICAgaG9va3M6IHRoaXMuaG9va3MsXG4gICAgICBwcm90b0FjY2Vzc0NvbnRyb2w6IHRoaXMucHJvdG9BY2Nlc3NDb250cm9sXG4gICAgfSk7XG5cbiAgICBsZXQgcmVzdWx0ID0gZW52LlZNLmludm9rZVBhcnRpYWwuY2FsbChcbiAgICAgIHRoaXMsXG4gICAgICBwYXJ0aWFsLFxuICAgICAgY29udGV4dCxcbiAgICAgIGV4dGVuZGVkT3B0aW9uc1xuICAgICk7XG5cbiAgICBpZiAocmVzdWx0ID09IG51bGwgJiYgZW52LmNvbXBpbGUpIHtcbiAgICAgIG9wdGlvbnMucGFydGlhbHNbb3B0aW9ucy5uYW1lXSA9IGVudi5jb21waWxlKFxuICAgICAgICBwYXJ0aWFsLFxuICAgICAgICB0ZW1wbGF0ZVNwZWMuY29tcGlsZXJPcHRpb25zLFxuICAgICAgICBlbnZcbiAgICAgICk7XG4gICAgICByZXN1bHQgPSBvcHRpb25zLnBhcnRpYWxzW29wdGlvbnMubmFtZV0oY29udGV4dCwgZXh0ZW5kZWRPcHRpb25zKTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7XG4gICAgICBpZiAob3B0aW9ucy5pbmRlbnQpIHtcbiAgICAgICAgbGV0IGxpbmVzID0gcmVzdWx0LnNwbGl0KCdcXG4nKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBsaW5lcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICBpZiAoIWxpbmVzW2ldICYmIGkgKyAxID09PSBsKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsaW5lc1tpXSA9IG9wdGlvbnMuaW5kZW50ICsgbGluZXNbaV07XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0ID0gbGluZXMuam9pbignXFxuJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKFxuICAgICAgICAnVGhlIHBhcnRpYWwgJyArXG4gICAgICAgICAgb3B0aW9ucy5uYW1lICtcbiAgICAgICAgICAnIGNvdWxkIG5vdCBiZSBjb21waWxlZCB3aGVuIHJ1bm5pbmcgaW4gcnVudGltZS1vbmx5IG1vZGUnXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIEp1c3QgYWRkIHdhdGVyXG4gIGxldCBjb250YWluZXIgPSB7XG4gICAgc3RyaWN0OiBmdW5jdGlvbihvYmosIG5hbWUsIGxvYykge1xuICAgICAgaWYgKCFvYmogfHwgIShuYW1lIGluIG9iaikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbignXCInICsgbmFtZSArICdcIiBub3QgZGVmaW5lZCBpbiAnICsgb2JqLCB7XG4gICAgICAgICAgbG9jOiBsb2NcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY29udGFpbmVyLmxvb2t1cFByb3BlcnR5KG9iaiwgbmFtZSk7XG4gICAgfSxcbiAgICBsb29rdXBQcm9wZXJ0eTogZnVuY3Rpb24ocGFyZW50LCBwcm9wZXJ0eU5hbWUpIHtcbiAgICAgIGxldCByZXN1bHQgPSBwYXJlbnRbcHJvcGVydHlOYW1lXTtcbiAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwYXJlbnQsIHByb3BlcnR5TmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3VsdElzQWxsb3dlZChyZXN1bHQsIGNvbnRhaW5lci5wcm90b0FjY2Vzc0NvbnRyb2wsIHByb3BlcnR5TmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfSxcbiAgICBsb29rdXA6IGZ1bmN0aW9uKGRlcHRocywgbmFtZSkge1xuICAgICAgY29uc3QgbGVuID0gZGVwdGhzLmxlbmd0aDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGRlcHRoc1tpXSAmJiBjb250YWluZXIubG9va3VwUHJvcGVydHkoZGVwdGhzW2ldLCBuYW1lKTtcbiAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIGRlcHRoc1tpXVtuYW1lXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgbGFtYmRhOiBmdW5jdGlvbihjdXJyZW50LCBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gdHlwZW9mIGN1cnJlbnQgPT09ICdmdW5jdGlvbicgPyBjdXJyZW50LmNhbGwoY29udGV4dCkgOiBjdXJyZW50O1xuICAgIH0sXG5cbiAgICBlc2NhcGVFeHByZXNzaW9uOiBVdGlscy5lc2NhcGVFeHByZXNzaW9uLFxuICAgIGludm9rZVBhcnRpYWw6IGludm9rZVBhcnRpYWxXcmFwcGVyLFxuXG4gICAgZm46IGZ1bmN0aW9uKGkpIHtcbiAgICAgIGxldCByZXQgPSB0ZW1wbGF0ZVNwZWNbaV07XG4gICAgICByZXQuZGVjb3JhdG9yID0gdGVtcGxhdGVTcGVjW2kgKyAnX2QnXTtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfSxcblxuICAgIHByb2dyYW1zOiBbXSxcbiAgICBwcm9ncmFtOiBmdW5jdGlvbihpLCBkYXRhLCBkZWNsYXJlZEJsb2NrUGFyYW1zLCBibG9ja1BhcmFtcywgZGVwdGhzKSB7XG4gICAgICBsZXQgcHJvZ3JhbVdyYXBwZXIgPSB0aGlzLnByb2dyYW1zW2ldLFxuICAgICAgICBmbiA9IHRoaXMuZm4oaSk7XG4gICAgICBpZiAoZGF0YSB8fCBkZXB0aHMgfHwgYmxvY2tQYXJhbXMgfHwgZGVjbGFyZWRCbG9ja1BhcmFtcykge1xuICAgICAgICBwcm9ncmFtV3JhcHBlciA9IHdyYXBQcm9ncmFtKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgaSxcbiAgICAgICAgICBmbixcbiAgICAgICAgICBkYXRhLFxuICAgICAgICAgIGRlY2xhcmVkQmxvY2tQYXJhbXMsXG4gICAgICAgICAgYmxvY2tQYXJhbXMsXG4gICAgICAgICAgZGVwdGhzXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKCFwcm9ncmFtV3JhcHBlcikge1xuICAgICAgICBwcm9ncmFtV3JhcHBlciA9IHRoaXMucHJvZ3JhbXNbaV0gPSB3cmFwUHJvZ3JhbSh0aGlzLCBpLCBmbik7XG4gICAgICB9XG4gICAgICByZXR1cm4gcHJvZ3JhbVdyYXBwZXI7XG4gICAgfSxcblxuICAgIGRhdGE6IGZ1bmN0aW9uKHZhbHVlLCBkZXB0aCkge1xuICAgICAgd2hpbGUgKHZhbHVlICYmIGRlcHRoLS0pIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5fcGFyZW50O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gICAgbWVyZ2VJZk5lZWRlZDogZnVuY3Rpb24ocGFyYW0sIGNvbW1vbikge1xuICAgICAgbGV0IG9iaiA9IHBhcmFtIHx8IGNvbW1vbjtcblxuICAgICAgaWYgKHBhcmFtICYmIGNvbW1vbiAmJiBwYXJhbSAhPT0gY29tbW9uKSB7XG4gICAgICAgIG9iaiA9IFV0aWxzLmV4dGVuZCh7fSwgY29tbW9uLCBwYXJhbSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvYmo7XG4gICAgfSxcbiAgICAvLyBBbiBlbXB0eSBvYmplY3QgdG8gdXNlIGFzIHJlcGxhY2VtZW50IGZvciBudWxsLWNvbnRleHRzXG4gICAgbnVsbENvbnRleHQ6IE9iamVjdC5zZWFsKHt9KSxcblxuICAgIG5vb3A6IGVudi5WTS5ub29wLFxuICAgIGNvbXBpbGVySW5mbzogdGVtcGxhdGVTcGVjLmNvbXBpbGVyXG4gIH07XG5cbiAgZnVuY3Rpb24gcmV0KGNvbnRleHQsIG9wdGlvbnMgPSB7fSkge1xuICAgIGxldCBkYXRhID0gb3B0aW9ucy5kYXRhO1xuXG4gICAgcmV0Ll9zZXR1cChvcHRpb25zKTtcbiAgICBpZiAoIW9wdGlvbnMucGFydGlhbCAmJiB0ZW1wbGF0ZVNwZWMudXNlRGF0YSkge1xuICAgICAgZGF0YSA9IGluaXREYXRhKGNvbnRleHQsIGRhdGEpO1xuICAgIH1cbiAgICBsZXQgZGVwdGhzLFxuICAgICAgYmxvY2tQYXJhbXMgPSB0ZW1wbGF0ZVNwZWMudXNlQmxvY2tQYXJhbXMgPyBbXSA6IHVuZGVmaW5lZDtcbiAgICBpZiAodGVtcGxhdGVTcGVjLnVzZURlcHRocykge1xuICAgICAgaWYgKG9wdGlvbnMuZGVwdGhzKSB7XG4gICAgICAgIGRlcHRocyA9XG4gICAgICAgICAgY29udGV4dCAhPSBvcHRpb25zLmRlcHRoc1swXVxuICAgICAgICAgICAgPyBbY29udGV4dF0uY29uY2F0KG9wdGlvbnMuZGVwdGhzKVxuICAgICAgICAgICAgOiBvcHRpb25zLmRlcHRocztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlcHRocyA9IFtjb250ZXh0XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWluKGNvbnRleHQgLyosIG9wdGlvbnMqLykge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgJycgK1xuICAgICAgICB0ZW1wbGF0ZVNwZWMubWFpbihcbiAgICAgICAgICBjb250YWluZXIsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBjb250YWluZXIuaGVscGVycyxcbiAgICAgICAgICBjb250YWluZXIucGFydGlhbHMsXG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBibG9ja1BhcmFtcyxcbiAgICAgICAgICBkZXB0aHNcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBtYWluID0gZXhlY3V0ZURlY29yYXRvcnMoXG4gICAgICB0ZW1wbGF0ZVNwZWMubWFpbixcbiAgICAgIG1haW4sXG4gICAgICBjb250YWluZXIsXG4gICAgICBvcHRpb25zLmRlcHRocyB8fCBbXSxcbiAgICAgIGRhdGEsXG4gICAgICBibG9ja1BhcmFtc1xuICAgICk7XG4gICAgcmV0dXJuIG1haW4oY29udGV4dCwgb3B0aW9ucyk7XG4gIH1cblxuICByZXQuaXNUb3AgPSB0cnVlO1xuXG4gIHJldC5fc2V0dXAgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zLnBhcnRpYWwpIHtcbiAgICAgIGxldCBtZXJnZWRIZWxwZXJzID0gVXRpbHMuZXh0ZW5kKHt9LCBlbnYuaGVscGVycywgb3B0aW9ucy5oZWxwZXJzKTtcbiAgICAgIHdyYXBIZWxwZXJzVG9QYXNzTG9va3VwUHJvcGVydHkobWVyZ2VkSGVscGVycywgY29udGFpbmVyKTtcbiAgICAgIGNvbnRhaW5lci5oZWxwZXJzID0gbWVyZ2VkSGVscGVycztcblxuICAgICAgaWYgKHRlbXBsYXRlU3BlYy51c2VQYXJ0aWFsKSB7XG4gICAgICAgIC8vIFVzZSBtZXJnZUlmTmVlZGVkIGhlcmUgdG8gcHJldmVudCBjb21waWxpbmcgZ2xvYmFsIHBhcnRpYWxzIG11bHRpcGxlIHRpbWVzXG4gICAgICAgIGNvbnRhaW5lci5wYXJ0aWFscyA9IGNvbnRhaW5lci5tZXJnZUlmTmVlZGVkKFxuICAgICAgICAgIG9wdGlvbnMucGFydGlhbHMsXG4gICAgICAgICAgZW52LnBhcnRpYWxzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAodGVtcGxhdGVTcGVjLnVzZVBhcnRpYWwgfHwgdGVtcGxhdGVTcGVjLnVzZURlY29yYXRvcnMpIHtcbiAgICAgICAgY29udGFpbmVyLmRlY29yYXRvcnMgPSBVdGlscy5leHRlbmQoXG4gICAgICAgICAge30sXG4gICAgICAgICAgZW52LmRlY29yYXRvcnMsXG4gICAgICAgICAgb3B0aW9ucy5kZWNvcmF0b3JzXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRhaW5lci5ob29rcyA9IHt9O1xuICAgICAgY29udGFpbmVyLnByb3RvQWNjZXNzQ29udHJvbCA9IGNyZWF0ZVByb3RvQWNjZXNzQ29udHJvbChvcHRpb25zKTtcblxuICAgICAgbGV0IGtlZXBIZWxwZXJJbkhlbHBlcnMgPVxuICAgICAgICBvcHRpb25zLmFsbG93Q2FsbHNUb0hlbHBlck1pc3NpbmcgfHxcbiAgICAgICAgdGVtcGxhdGVXYXNQcmVjb21waWxlZFdpdGhDb21waWxlclY3O1xuICAgICAgbW92ZUhlbHBlclRvSG9va3MoY29udGFpbmVyLCAnaGVscGVyTWlzc2luZycsIGtlZXBIZWxwZXJJbkhlbHBlcnMpO1xuICAgICAgbW92ZUhlbHBlclRvSG9va3MoY29udGFpbmVyLCAnYmxvY2tIZWxwZXJNaXNzaW5nJywga2VlcEhlbHBlckluSGVscGVycyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRhaW5lci5wcm90b0FjY2Vzc0NvbnRyb2wgPSBvcHRpb25zLnByb3RvQWNjZXNzQ29udHJvbDsgLy8gaW50ZXJuYWwgb3B0aW9uXG4gICAgICBjb250YWluZXIuaGVscGVycyA9IG9wdGlvbnMuaGVscGVycztcbiAgICAgIGNvbnRhaW5lci5wYXJ0aWFscyA9IG9wdGlvbnMucGFydGlhbHM7XG4gICAgICBjb250YWluZXIuZGVjb3JhdG9ycyA9IG9wdGlvbnMuZGVjb3JhdG9ycztcbiAgICAgIGNvbnRhaW5lci5ob29rcyA9IG9wdGlvbnMuaG9va3M7XG4gICAgfVxuICB9O1xuXG4gIHJldC5fY2hpbGQgPSBmdW5jdGlvbihpLCBkYXRhLCBibG9ja1BhcmFtcywgZGVwdGhzKSB7XG4gICAgaWYgKHRlbXBsYXRlU3BlYy51c2VCbG9ja1BhcmFtcyAmJiAhYmxvY2tQYXJhbXMpIHtcbiAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oJ211c3QgcGFzcyBibG9jayBwYXJhbXMnKTtcbiAgICB9XG4gICAgaWYgKHRlbXBsYXRlU3BlYy51c2VEZXB0aHMgJiYgIWRlcHRocykge1xuICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbignbXVzdCBwYXNzIHBhcmVudCBkZXB0aHMnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gd3JhcFByb2dyYW0oXG4gICAgICBjb250YWluZXIsXG4gICAgICBpLFxuICAgICAgdGVtcGxhdGVTcGVjW2ldLFxuICAgICAgZGF0YSxcbiAgICAgIDAsXG4gICAgICBibG9ja1BhcmFtcyxcbiAgICAgIGRlcHRoc1xuICAgICk7XG4gIH07XG4gIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3cmFwUHJvZ3JhbShcbiAgY29udGFpbmVyLFxuICBpLFxuICBmbixcbiAgZGF0YSxcbiAgZGVjbGFyZWRCbG9ja1BhcmFtcyxcbiAgYmxvY2tQYXJhbXMsXG4gIGRlcHRoc1xuKSB7XG4gIGZ1bmN0aW9uIHByb2coY29udGV4dCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgbGV0IGN1cnJlbnREZXB0aHMgPSBkZXB0aHM7XG4gICAgaWYgKFxuICAgICAgZGVwdGhzICYmXG4gICAgICBjb250ZXh0ICE9IGRlcHRoc1swXSAmJlxuICAgICAgIShjb250ZXh0ID09PSBjb250YWluZXIubnVsbENvbnRleHQgJiYgZGVwdGhzWzBdID09PSBudWxsKVxuICAgICkge1xuICAgICAgY3VycmVudERlcHRocyA9IFtjb250ZXh0XS5jb25jYXQoZGVwdGhzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZm4oXG4gICAgICBjb250YWluZXIsXG4gICAgICBjb250ZXh0LFxuICAgICAgY29udGFpbmVyLmhlbHBlcnMsXG4gICAgICBjb250YWluZXIucGFydGlhbHMsXG4gICAgICBvcHRpb25zLmRhdGEgfHwgZGF0YSxcbiAgICAgIGJsb2NrUGFyYW1zICYmIFtvcHRpb25zLmJsb2NrUGFyYW1zXS5jb25jYXQoYmxvY2tQYXJhbXMpLFxuICAgICAgY3VycmVudERlcHRoc1xuICAgICk7XG4gIH1cblxuICBwcm9nID0gZXhlY3V0ZURlY29yYXRvcnMoZm4sIHByb2csIGNvbnRhaW5lciwgZGVwdGhzLCBkYXRhLCBibG9ja1BhcmFtcyk7XG5cbiAgcHJvZy5wcm9ncmFtID0gaTtcbiAgcHJvZy5kZXB0aCA9IGRlcHRocyA/IGRlcHRocy5sZW5ndGggOiAwO1xuICBwcm9nLmJsb2NrUGFyYW1zID0gZGVjbGFyZWRCbG9ja1BhcmFtcyB8fCAwO1xuICByZXR1cm4gcHJvZztcbn1cblxuLyoqXG4gKiBUaGlzIGlzIGN1cnJlbnRseSBwYXJ0IG9mIHRoZSBvZmZpY2lhbCBBUEksIHRoZXJlZm9yZSBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIHNob3VsZCBub3QgYmUgY2hhbmdlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVQYXJ0aWFsKHBhcnRpYWwsIGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgaWYgKCFwYXJ0aWFsKSB7XG4gICAgaWYgKG9wdGlvbnMubmFtZSA9PT0gJ0BwYXJ0aWFsLWJsb2NrJykge1xuICAgICAgcGFydGlhbCA9IG9wdGlvbnMuZGF0YVsncGFydGlhbC1ibG9jayddO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJ0aWFsID0gb3B0aW9ucy5wYXJ0aWFsc1tvcHRpb25zLm5hbWVdO1xuICAgIH1cbiAgfSBlbHNlIGlmICghcGFydGlhbC5jYWxsICYmICFvcHRpb25zLm5hbWUpIHtcbiAgICAvLyBUaGlzIGlzIGEgZHluYW1pYyBwYXJ0aWFsIHRoYXQgcmV0dXJuZWQgYSBzdHJpbmdcbiAgICBvcHRpb25zLm5hbWUgPSBwYXJ0aWFsO1xuICAgIHBhcnRpYWwgPSBvcHRpb25zLnBhcnRpYWxzW3BhcnRpYWxdO1xuICB9XG4gIHJldHVybiBwYXJ0aWFsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW52b2tlUGFydGlhbChwYXJ0aWFsLCBjb250ZXh0LCBvcHRpb25zKSB7XG4gIC8vIFVzZSB0aGUgY3VycmVudCBjbG9zdXJlIGNvbnRleHQgdG8gc2F2ZSB0aGUgcGFydGlhbC1ibG9jayBpZiB0aGlzIHBhcnRpYWxcbiAgY29uc3QgY3VycmVudFBhcnRpYWxCbG9jayA9IG9wdGlvbnMuZGF0YSAmJiBvcHRpb25zLmRhdGFbJ3BhcnRpYWwtYmxvY2snXTtcbiAgb3B0aW9ucy5wYXJ0aWFsID0gdHJ1ZTtcbiAgaWYgKG9wdGlvbnMuaWRzKSB7XG4gICAgb3B0aW9ucy5kYXRhLmNvbnRleHRQYXRoID0gb3B0aW9ucy5pZHNbMF0gfHwgb3B0aW9ucy5kYXRhLmNvbnRleHRQYXRoO1xuICB9XG5cbiAgbGV0IHBhcnRpYWxCbG9jaztcbiAgaWYgKG9wdGlvbnMuZm4gJiYgb3B0aW9ucy5mbiAhPT0gbm9vcCkge1xuICAgIG9wdGlvbnMuZGF0YSA9IGNyZWF0ZUZyYW1lKG9wdGlvbnMuZGF0YSk7XG4gICAgLy8gV3JhcHBlciBmdW5jdGlvbiB0byBnZXQgYWNjZXNzIHRvIGN1cnJlbnRQYXJ0aWFsQmxvY2sgZnJvbSB0aGUgY2xvc3VyZVxuICAgIGxldCBmbiA9IG9wdGlvbnMuZm47XG4gICAgcGFydGlhbEJsb2NrID0gb3B0aW9ucy5kYXRhWydwYXJ0aWFsLWJsb2NrJ10gPSBmdW5jdGlvbiBwYXJ0aWFsQmxvY2tXcmFwcGVyKFxuICAgICAgY29udGV4dCxcbiAgICAgIG9wdGlvbnMgPSB7fVxuICAgICkge1xuICAgICAgLy8gUmVzdG9yZSB0aGUgcGFydGlhbC1ibG9jayBmcm9tIHRoZSBjbG9zdXJlIGZvciB0aGUgZXhlY3V0aW9uIG9mIHRoZSBibG9ja1xuICAgICAgLy8gaS5lLiB0aGUgcGFydCBpbnNpZGUgdGhlIGJsb2NrIG9mIHRoZSBwYXJ0aWFsIGNhbGwuXG4gICAgICBvcHRpb25zLmRhdGEgPSBjcmVhdGVGcmFtZShvcHRpb25zLmRhdGEpO1xuICAgICAgb3B0aW9ucy5kYXRhWydwYXJ0aWFsLWJsb2NrJ10gPSBjdXJyZW50UGFydGlhbEJsb2NrO1xuICAgICAgcmV0dXJuIGZuKGNvbnRleHQsIG9wdGlvbnMpO1xuICAgIH07XG4gICAgaWYgKGZuLnBhcnRpYWxzKSB7XG4gICAgICBvcHRpb25zLnBhcnRpYWxzID0gVXRpbHMuZXh0ZW5kKHt9LCBvcHRpb25zLnBhcnRpYWxzLCBmbi5wYXJ0aWFscyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHBhcnRpYWwgPT09IHVuZGVmaW5lZCAmJiBwYXJ0aWFsQmxvY2spIHtcbiAgICBwYXJ0aWFsID0gcGFydGlhbEJsb2NrO1xuICB9XG5cbiAgaWYgKHBhcnRpYWwgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFeGNlcHRpb24oJ1RoZSBwYXJ0aWFsICcgKyBvcHRpb25zLm5hbWUgKyAnIGNvdWxkIG5vdCBiZSBmb3VuZCcpO1xuICB9IGVsc2UgaWYgKHBhcnRpYWwgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgIHJldHVybiBwYXJ0aWFsKGNvbnRleHQsIG9wdGlvbnMpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub29wKCkge1xuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIGluaXREYXRhKGNvbnRleHQsIGRhdGEpIHtcbiAgaWYgKCFkYXRhIHx8ICEoJ3Jvb3QnIGluIGRhdGEpKSB7XG4gICAgZGF0YSA9IGRhdGEgPyBjcmVhdGVGcmFtZShkYXRhKSA6IHt9O1xuICAgIGRhdGEucm9vdCA9IGNvbnRleHQ7XG4gIH1cbiAgcmV0dXJuIGRhdGE7XG59XG5cbmZ1bmN0aW9uIGV4ZWN1dGVEZWNvcmF0b3JzKGZuLCBwcm9nLCBjb250YWluZXIsIGRlcHRocywgZGF0YSwgYmxvY2tQYXJhbXMpIHtcbiAgaWYgKGZuLmRlY29yYXRvcikge1xuICAgIGxldCBwcm9wcyA9IHt9O1xuICAgIHByb2cgPSBmbi5kZWNvcmF0b3IoXG4gICAgICBwcm9nLFxuICAgICAgcHJvcHMsXG4gICAgICBjb250YWluZXIsXG4gICAgICBkZXB0aHMgJiYgZGVwdGhzWzBdLFxuICAgICAgZGF0YSxcbiAgICAgIGJsb2NrUGFyYW1zLFxuICAgICAgZGVwdGhzXG4gICAgKTtcbiAgICBVdGlscy5leHRlbmQocHJvZywgcHJvcHMpO1xuICB9XG4gIHJldHVybiBwcm9nO1xufVxuXG5mdW5jdGlvbiB3cmFwSGVscGVyc1RvUGFzc0xvb2t1cFByb3BlcnR5KG1lcmdlZEhlbHBlcnMsIGNvbnRhaW5lcikge1xuICBPYmplY3Qua2V5cyhtZXJnZWRIZWxwZXJzKS5mb3JFYWNoKGhlbHBlck5hbWUgPT4ge1xuICAgIGxldCBoZWxwZXIgPSBtZXJnZWRIZWxwZXJzW2hlbHBlck5hbWVdO1xuICAgIG1lcmdlZEhlbHBlcnNbaGVscGVyTmFtZV0gPSBwYXNzTG9va3VwUHJvcGVydHlPcHRpb24oaGVscGVyLCBjb250YWluZXIpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcGFzc0xvb2t1cFByb3BlcnR5T3B0aW9uKGhlbHBlciwgY29udGFpbmVyKSB7XG4gIGNvbnN0IGxvb2t1cFByb3BlcnR5ID0gY29udGFpbmVyLmxvb2t1cFByb3BlcnR5O1xuICByZXR1cm4gd3JhcEhlbHBlcihoZWxwZXIsIG9wdGlvbnMgPT4ge1xuICAgIHJldHVybiBVdGlscy5leHRlbmQoeyBsb29rdXBQcm9wZXJ0eSB9LCBvcHRpb25zKTtcbiAgfSk7XG59XG4iXX0=\n","// Build out our basic SafeString type\n'use strict';\n\nexports.__esModule = true;\nfunction SafeString(string) {\n this.string = string;\n}\n\nSafeString.prototype.toString = SafeString.prototype.toHTML = function () {\n return '' + this.string;\n};\n\nexports['default'] = SafeString;\nmodule.exports = exports['default'];\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL3NhZmUtc3RyaW5nLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFDQSxTQUFTLFVBQVUsQ0FBQyxNQUFNLEVBQUU7QUFDMUIsTUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7Q0FDdEI7O0FBRUQsVUFBVSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsWUFBVztBQUN2RSxTQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0NBQ3pCLENBQUM7O3FCQUVhLFVBQVUiLCJmaWxlIjoic2FmZS1zdHJpbmcuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBCdWlsZCBvdXQgb3VyIGJhc2ljIFNhZmVTdHJpbmcgdHlwZVxuZnVuY3Rpb24gU2FmZVN0cmluZyhzdHJpbmcpIHtcbiAgdGhpcy5zdHJpbmcgPSBzdHJpbmc7XG59XG5cblNhZmVTdHJpbmcucHJvdG90eXBlLnRvU3RyaW5nID0gU2FmZVN0cmluZy5wcm90b3R5cGUudG9IVE1MID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAnJyArIHRoaXMuc3RyaW5nO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgU2FmZVN0cmluZztcbiJdfQ==\n","'use strict';\n\nexports.__esModule = true;\nexports.extend = extend;\nexports.indexOf = indexOf;\nexports.escapeExpression = escapeExpression;\nexports.isEmpty = isEmpty;\nexports.createFrame = createFrame;\nexports.blockParams = blockParams;\nexports.appendContextPath = appendContextPath;\nvar escape = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n '`': '`',\n '=': '='\n};\n\nvar badChars = /[&<>\"'`=]/g,\n possible = /[&<>\"'`=]/;\n\nfunction escapeChar(chr) {\n return escape[chr];\n}\n\nfunction extend(obj /* , ...source */) {\n for (var i = 1; i < arguments.length; i++) {\n for (var key in arguments[i]) {\n if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {\n obj[key] = arguments[i][key];\n }\n }\n }\n\n return obj;\n}\n\nvar toString = Object.prototype.toString;\n\nexports.toString = toString;\n// Sourced from lodash\n// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt\n/* eslint-disable func-style */\nvar isFunction = function isFunction(value) {\n return typeof value === 'function';\n};\n// fallback for older versions of Chrome and Safari\n/* istanbul ignore next */\nif (isFunction(/x/)) {\n exports.isFunction = isFunction = function (value) {\n return typeof value === 'function' && toString.call(value) === '[object Function]';\n };\n}\nexports.isFunction = isFunction;\n\n/* eslint-enable func-style */\n\n/* istanbul ignore next */\nvar isArray = Array.isArray || function (value) {\n return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;\n};\n\nexports.isArray = isArray;\n// Older IE versions do not directly support indexOf so we must implement our own, sadly.\n\nfunction indexOf(array, value) {\n for (var i = 0, len = array.length; i < len; i++) {\n if (array[i] === value) {\n return i;\n }\n }\n return -1;\n}\n\nfunction escapeExpression(string) {\n if (typeof string !== 'string') {\n // don't escape SafeStrings, since they're already safe\n if (string && string.toHTML) {\n return string.toHTML();\n } else if (string == null) {\n return '';\n } else if (!string) {\n return string + '';\n }\n\n // Force a string conversion as this will be done by the append regardless and\n // the regex test will do this transparently behind the scenes, causing issues if\n // an object's to string has escaped characters in it.\n string = '' + string;\n }\n\n if (!possible.test(string)) {\n return string;\n }\n return string.replace(badChars, escapeChar);\n}\n\nfunction isEmpty(value) {\n if (!value && value !== 0) {\n return true;\n } else if (isArray(value) && value.length === 0) {\n return true;\n } else {\n return false;\n }\n}\n\nfunction createFrame(object) {\n var frame = extend({}, object);\n frame._parent = object;\n return frame;\n}\n\nfunction blockParams(params, ids) {\n params.path = ids;\n return params;\n}\n\nfunction appendContextPath(contextPath, id) {\n return (contextPath ? contextPath + '.' : '') + id;\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL3V0aWxzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSxJQUFNLE1BQU0sR0FBRztBQUNiLEtBQUcsRUFBRSxPQUFPO0FBQ1osS0FBRyxFQUFFLE1BQU07QUFDWCxLQUFHLEVBQUUsTUFBTTtBQUNYLEtBQUcsRUFBRSxRQUFRO0FBQ2IsS0FBRyxFQUFFLFFBQVE7QUFDYixLQUFHLEVBQUUsUUFBUTtBQUNiLEtBQUcsRUFBRSxRQUFRO0NBQ2QsQ0FBQzs7QUFFRixJQUFNLFFBQVEsR0FBRyxZQUFZO0lBQzNCLFFBQVEsR0FBRyxXQUFXLENBQUM7O0FBRXpCLFNBQVMsVUFBVSxDQUFDLEdBQUcsRUFBRTtBQUN2QixTQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztDQUNwQjs7QUFFTSxTQUFTLE1BQU0sQ0FBQyxHQUFHLG9CQUFvQjtBQUM1QyxPQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUN6QyxTQUFLLElBQUksR0FBRyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUM1QixVQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUU7QUFDM0QsV0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztPQUM5QjtLQUNGO0dBQ0Y7O0FBRUQsU0FBTyxHQUFHLENBQUM7Q0FDWjs7QUFFTSxJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQzs7Ozs7O0FBS2hELElBQUksVUFBVSxHQUFHLG9CQUFTLEtBQUssRUFBRTtBQUMvQixTQUFPLE9BQU8sS0FBSyxLQUFLLFVBQVUsQ0FBQztDQUNwQyxDQUFDOzs7QUFHRixJQUFJLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRTtBQUNuQixVQU9PLFVBQVUsR0FQakIsVUFBVSxHQUFHLFVBQVMsS0FBSyxFQUFFO0FBQzNCLFdBQ0UsT0FBTyxLQUFLLEtBQUssVUFBVSxJQUMzQixRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLG1CQUFtQixDQUM1QztHQUNILENBQUM7Q0FDSDtRQUNRLFVBQVUsR0FBVixVQUFVOzs7OztBQUlaLElBQU0sT0FBTyxHQUNsQixLQUFLLENBQUMsT0FBTyxJQUNiLFVBQVMsS0FBSyxFQUFFO0FBQ2QsU0FBTyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxHQUNyQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLGdCQUFnQixHQUN6QyxLQUFLLENBQUM7Q0FDWCxDQUFDOzs7OztBQUdHLFNBQVMsT0FBTyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUU7QUFDcEMsT0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUNoRCxRQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLEVBQUU7QUFDdEIsYUFBTyxDQUFDLENBQUM7S0FDVjtHQUNGO0FBQ0QsU0FBTyxDQUFDLENBQUMsQ0FBQztDQUNYOztBQUVNLFNBQVMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFO0FBQ3ZDLE1BQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFOztBQUU5QixRQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFO0FBQzNCLGFBQU8sTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO0tBQ3hCLE1BQU0sSUFBSSxNQUFNLElBQUksSUFBSSxFQUFFO0FBQ3pCLGFBQU8sRUFBRSxDQUFDO0tBQ1gsTUFBTSxJQUFJLENBQUMsTUFBTSxFQUFFO0FBQ2xCLGFBQU8sTUFBTSxHQUFHLEVBQUUsQ0FBQztLQUNwQjs7Ozs7QUFLRCxVQUFNLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQztHQUN0Qjs7QUFFRCxNQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRTtBQUMxQixXQUFPLE1BQU0sQ0FBQztHQUNmO0FBQ0QsU0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztDQUM3Qzs7QUFFTSxTQUFTLE9BQU8sQ0FBQyxLQUFLLEVBQUU7QUFDN0IsTUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFO0FBQ3pCLFdBQU8sSUFBSSxDQUFDO0dBQ2IsTUFBTSxJQUFJLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtBQUMvQyxXQUFPLElBQUksQ0FBQztHQUNiLE1BQU07QUFDTCxXQUFPLEtBQUssQ0FBQztHQUNkO0NBQ0Y7O0FBRU0sU0FBUyxXQUFXLENBQUMsTUFBTSxFQUFFO0FBQ2xDLE1BQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDL0IsT0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7QUFDdkIsU0FBTyxLQUFLLENBQUM7Q0FDZDs7QUFFTSxTQUFTLFdBQVcsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFO0FBQ3ZDLFFBQU0sQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO0FBQ2xCLFNBQU8sTUFBTSxDQUFDO0NBQ2Y7O0FBRU0sU0FBUyxpQkFBaUIsQ0FBQyxXQUFXLEVBQUUsRUFBRSxFQUFFO0FBQ2pELFNBQU8sQ0FBQyxXQUFXLEdBQUcsV0FBVyxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUEsR0FBSSxFQUFFLENBQUM7Q0FDcEQiLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBlc2NhcGUgPSB7XG4gICcmJzogJyZhbXA7JyxcbiAgJzwnOiAnJmx0OycsXG4gICc+JzogJyZndDsnLFxuICAnXCInOiAnJnF1b3Q7JyxcbiAgXCInXCI6ICcmI3gyNzsnLFxuICAnYCc6ICcmI3g2MDsnLFxuICAnPSc6ICcmI3gzRDsnXG59O1xuXG5jb25zdCBiYWRDaGFycyA9IC9bJjw+XCInYD1dL2csXG4gIHBvc3NpYmxlID0gL1smPD5cIidgPV0vO1xuXG5mdW5jdGlvbiBlc2NhcGVDaGFyKGNocikge1xuICByZXR1cm4gZXNjYXBlW2Nocl07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRlbmQob2JqIC8qICwgLi4uc291cmNlICovKSB7XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQga2V5IGluIGFyZ3VtZW50c1tpXSkge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChhcmd1bWVudHNbaV0sIGtleSkpIHtcbiAgICAgICAgb2JqW2tleV0gPSBhcmd1bWVudHNbaV1ba2V5XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gb2JqO1xufVxuXG5leHBvcnQgbGV0IHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLy8gU291cmNlZCBmcm9tIGxvZGFzaFxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2Jlc3RpZWpzL2xvZGFzaC9ibG9iL21hc3Rlci9MSUNFTlNFLnR4dFxuLyogZXNsaW50LWRpc2FibGUgZnVuYy1zdHlsZSAqL1xubGV0IGlzRnVuY3Rpb24gPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nO1xufTtcbi8vIGZhbGxiYWNrIGZvciBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaVxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmlmIChpc0Z1bmN0aW9uKC94LykpIHtcbiAgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgdG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSdcbiAgICApO1xuICB9O1xufVxuZXhwb3J0IHsgaXNGdW5jdGlvbiB9O1xuLyogZXNsaW50LWVuYWJsZSBmdW5jLXN0eWxlICovXG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5leHBvcnQgY29uc3QgaXNBcnJheSA9XG4gIEFycmF5LmlzQXJyYXkgfHxcbiAgZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0J1xuICAgICAgPyB0b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgQXJyYXldJ1xuICAgICAgOiBmYWxzZTtcbiAgfTtcblxuLy8gT2xkZXIgSUUgdmVyc2lvbnMgZG8gbm90IGRpcmVjdGx5IHN1cHBvcnQgaW5kZXhPZiBzbyB3ZSBtdXN0IGltcGxlbWVudCBvdXIgb3duLCBzYWRseS5cbmV4cG9ydCBmdW5jdGlvbiBpbmRleE9mKGFycmF5LCB2YWx1ZSkge1xuICBmb3IgKGxldCBpID0gMCwgbGVuID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoYXJyYXlbaV0gPT09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gaTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlRXhwcmVzc2lvbihzdHJpbmcpIHtcbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgLy8gZG9uJ3QgZXNjYXBlIFNhZmVTdHJpbmdzLCBzaW5jZSB0aGV5J3JlIGFscmVhZHkgc2FmZVxuICAgIGlmIChzdHJpbmcgJiYgc3RyaW5nLnRvSFRNTCkge1xuICAgICAgcmV0dXJuIHN0cmluZy50b0hUTUwoKTtcbiAgICB9IGVsc2UgaWYgKHN0cmluZyA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSBlbHNlIGlmICghc3RyaW5nKSB7XG4gICAgICByZXR1cm4gc3RyaW5nICsgJyc7XG4gICAgfVxuXG4gICAgLy8gRm9yY2UgYSBzdHJpbmcgY29udmVyc2lvbiBhcyB0aGlzIHdpbGwgYmUgZG9uZSBieSB0aGUgYXBwZW5kIHJlZ2FyZGxlc3MgYW5kXG4gICAgLy8gdGhlIHJlZ2V4IHRlc3Qgd2lsbCBkbyB0aGlzIHRyYW5zcGFyZW50bHkgYmVoaW5kIHRoZSBzY2VuZXMsIGNhdXNpbmcgaXNzdWVzIGlmXG4gICAgLy8gYW4gb2JqZWN0J3MgdG8gc3RyaW5nIGhhcyBlc2NhcGVkIGNoYXJhY3RlcnMgaW4gaXQuXG4gICAgc3RyaW5nID0gJycgKyBzdHJpbmc7XG4gIH1cblxuICBpZiAoIXBvc3NpYmxlLnRlc3Qoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmc7XG4gIH1cbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKGJhZENoYXJzLCBlc2NhcGVDaGFyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHkodmFsdWUpIHtcbiAgaWYgKCF2YWx1ZSAmJiB2YWx1ZSAhPT0gMCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRnJhbWUob2JqZWN0KSB7XG4gIGxldCBmcmFtZSA9IGV4dGVuZCh7fSwgb2JqZWN0KTtcbiAgZnJhbWUuX3BhcmVudCA9IG9iamVjdDtcbiAgcmV0dXJuIGZyYW1lO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYmxvY2tQYXJhbXMocGFyYW1zLCBpZHMpIHtcbiAgcGFyYW1zLnBhdGggPSBpZHM7XG4gIHJldHVybiBwYXJhbXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBlbmRDb250ZXh0UGF0aChjb250ZXh0UGF0aCwgaWQpIHtcbiAgcmV0dXJuIChjb250ZXh0UGF0aCA/IGNvbnRleHRQYXRoICsgJy4nIDogJycpICsgaWQ7XG59XG4iXX0=\n","// Create a simple path alias to allow browserify to resolve\n// the runtime on a supported path.\nmodule.exports = require('./dist/cjs/handlebars.runtime')['default'];\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nmodule.exports = DataView;\n","var hashClear = require('./_hashClear'),\n hashDelete = require('./_hashDelete'),\n hashGet = require('./_hashGet'),\n hashHas = require('./_hashHas'),\n hashSet = require('./_hashSet');\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nmodule.exports = Hash;\n","var listCacheClear = require('./_listCacheClear'),\n listCacheDelete = require('./_listCacheDelete'),\n listCacheGet = require('./_listCacheGet'),\n listCacheHas = require('./_listCacheHas'),\n listCacheSet = require('./_listCacheSet');\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nmodule.exports = ListCache;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nmodule.exports = Map;\n","var mapCacheClear = require('./_mapCacheClear'),\n mapCacheDelete = require('./_mapCacheDelete'),\n mapCacheGet = require('./_mapCacheGet'),\n mapCacheHas = require('./_mapCacheHas'),\n mapCacheSet = require('./_mapCacheSet');\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nmodule.exports = MapCache;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nmodule.exports = Promise;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nmodule.exports = Set;\n","var MapCache = require('./_MapCache'),\n setCacheAdd = require('./_setCacheAdd'),\n setCacheHas = require('./_setCacheHas');\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nmodule.exports = SetCache;\n","var ListCache = require('./_ListCache'),\n stackClear = require('./_stackClear'),\n stackDelete = require('./_stackDelete'),\n stackGet = require('./_stackGet'),\n stackHas = require('./_stackHas'),\n stackSet = require('./_stackSet');\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nmodule.exports = Stack;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nmodule.exports = Uint8Array;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nmodule.exports = WeakMap;\n","/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\nmodule.exports = arrayEach;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nmodule.exports = arrayFilter;\n","var baseTimes = require('./_baseTimes'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isIndex = require('./_isIndex'),\n isTypedArray = require('./isTypedArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = arrayLikeKeys;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nmodule.exports = arrayMap;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nmodule.exports = arrayPush;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nmodule.exports = arraySome;\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignValue;\n","var eq = require('./eq');\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nmodule.exports = assocIndexOf;\n","var copyObject = require('./_copyObject'),\n keys = require('./keys');\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n}\n\nmodule.exports = baseAssign;\n","var copyObject = require('./_copyObject'),\n keysIn = require('./keysIn');\n\n/**\n * The base implementation of `_.assignIn` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssignIn(object, source) {\n return object && copyObject(source, keysIn(source), object);\n}\n\nmodule.exports = baseAssignIn;\n","var defineProperty = require('./_defineProperty');\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nmodule.exports = baseAssignValue;\n","var Stack = require('./_Stack'),\n arrayEach = require('./_arrayEach'),\n assignValue = require('./_assignValue'),\n baseAssign = require('./_baseAssign'),\n baseAssignIn = require('./_baseAssignIn'),\n cloneBuffer = require('./_cloneBuffer'),\n copyArray = require('./_copyArray'),\n copySymbols = require('./_copySymbols'),\n copySymbolsIn = require('./_copySymbolsIn'),\n getAllKeys = require('./_getAllKeys'),\n getAllKeysIn = require('./_getAllKeysIn'),\n getTag = require('./_getTag'),\n initCloneArray = require('./_initCloneArray'),\n initCloneByTag = require('./_initCloneByTag'),\n initCloneObject = require('./_initCloneObject'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isMap = require('./isMap'),\n isObject = require('./isObject'),\n isSet = require('./isSet'),\n keys = require('./keys'),\n keysIn = require('./keysIn');\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Deep clone\n * 2 - Flatten inherited properties\n * 4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, bitmask, customizer, key, object, stack) {\n var result,\n isDeep = bitmask & CLONE_DEEP_FLAG,\n isFlat = bitmask & CLONE_FLAT_FLAG,\n isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n result = (isFlat || isFunc) ? {} : initCloneObject(value);\n if (!isDeep) {\n return isFlat\n ? copySymbolsIn(value, baseAssignIn(result, value))\n : copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (isSet(value)) {\n value.forEach(function(subValue) {\n result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n });\n } else if (isMap(value)) {\n value.forEach(function(subValue, key) {\n result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n }\n\n var keysFunc = isFull\n ? (isFlat ? getAllKeysIn : getAllKeys)\n : (isFlat ? keysIn : keys);\n\n var props = isArr ? undefined : keysFunc(value);\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n return result;\n}\n\nmodule.exports = baseClone;\n","var isObject = require('./isObject');\n\n/** Built-in value references. */\nvar objectCreate = Object.create;\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n function object() {}\n return function(proto) {\n if (!isObject(proto)) {\n return {};\n }\n if (objectCreate) {\n return objectCreate(proto);\n }\n object.prototype = proto;\n var result = new object;\n object.prototype = undefined;\n return result;\n };\n}());\n\nmodule.exports = baseCreate;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nmodule.exports = baseFindIndex;\n","var castPath = require('./_castPath'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nmodule.exports = baseGet;\n","var arrayPush = require('./_arrayPush'),\n isArray = require('./isArray');\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nmodule.exports = baseGetAllKeys;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nmodule.exports = baseHasIn;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nmodule.exports = baseIsArguments;\n","var baseIsEqualDeep = require('./_baseIsEqualDeep'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nmodule.exports = baseIsEqual;\n","var Stack = require('./_Stack'),\n equalArrays = require('./_equalArrays'),\n equalByTag = require('./_equalByTag'),\n equalObjects = require('./_equalObjects'),\n getTag = require('./_getTag'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isTypedArray = require('./isTypedArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nmodule.exports = baseIsEqualDeep;\n","var getTag = require('./_getTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]';\n\n/**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\nfunction baseIsMap(value) {\n return isObjectLike(value) && getTag(value) == mapTag;\n}\n\nmodule.exports = baseIsMap;\n","var Stack = require('./_Stack'),\n baseIsEqual = require('./_baseIsEqual');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n}\n\nmodule.exports = baseIsMatch;\n","var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","var getTag = require('./_getTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar setTag = '[object Set]';\n\n/**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\nfunction baseIsSet(value) {\n return isObjectLike(value) && getTag(value) == setTag;\n}\n\nmodule.exports = baseIsSet;\n","var baseGetTag = require('./_baseGetTag'),\n isLength = require('./isLength'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nmodule.exports = baseIsTypedArray;\n","var baseMatches = require('./_baseMatches'),\n baseMatchesProperty = require('./_baseMatchesProperty'),\n identity = require('./identity'),\n isArray = require('./isArray'),\n property = require('./property');\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nmodule.exports = baseIteratee;\n","var isPrototype = require('./_isPrototype'),\n nativeKeys = require('./_nativeKeys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeys;\n","var isObject = require('./isObject'),\n isPrototype = require('./_isPrototype'),\n nativeKeysIn = require('./_nativeKeysIn');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeysIn;\n","var baseIsMatch = require('./_baseIsMatch'),\n getMatchData = require('./_getMatchData'),\n matchesStrictComparable = require('./_matchesStrictComparable');\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n}\n\nmodule.exports = baseMatches;\n","var baseIsEqual = require('./_baseIsEqual'),\n get = require('./get'),\n hasIn = require('./hasIn'),\n isKey = require('./_isKey'),\n isStrictComparable = require('./_isStrictComparable'),\n matchesStrictComparable = require('./_matchesStrictComparable'),\n toKey = require('./_toKey');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n}\n\nmodule.exports = baseMatchesProperty;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nmodule.exports = baseProperty;\n","var baseGet = require('./_baseGet');\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n}\n\nmodule.exports = basePropertyDeep;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nmodule.exports = baseTimes;\n","var Symbol = require('./_Symbol'),\n arrayMap = require('./_arrayMap'),\n isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = baseToString;\n","var trimmedEndIndex = require('./_trimmedEndIndex');\n\n/** Used to match leading whitespace. */\nvar reTrimStart = /^\\s+/;\n\n/**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\nfunction baseTrim(string) {\n return string\n ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n}\n\nmodule.exports = baseTrim;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nmodule.exports = baseUnary;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nmodule.exports = cacheHas;\n","var isArray = require('./isArray'),\n isKey = require('./_isKey'),\n stringToPath = require('./_stringToPath'),\n toString = require('./toString');\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nmodule.exports = castPath;\n","var Uint8Array = require('./_Uint8Array');\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\nmodule.exports = cloneArrayBuffer;\n","var root = require('./_root');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n}\n\nmodule.exports = cloneBuffer;\n","var cloneArrayBuffer = require('./_cloneArrayBuffer');\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\nmodule.exports = cloneDataView;\n","/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\nmodule.exports = cloneRegExp;\n","var Symbol = require('./_Symbol');\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\nmodule.exports = cloneSymbol;\n","var cloneArrayBuffer = require('./_cloneArrayBuffer');\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nmodule.exports = cloneTypedArray;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nmodule.exports = copyArray;\n","var assignValue = require('./_assignValue'),\n baseAssignValue = require('./_baseAssignValue');\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n}\n\nmodule.exports = copyObject;\n","var copyObject = require('./_copyObject'),\n getSymbols = require('./_getSymbols');\n\n/**\n * Copies own symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n}\n\nmodule.exports = copySymbols;\n","var copyObject = require('./_copyObject'),\n getSymbolsIn = require('./_getSymbolsIn');\n\n/**\n * Copies own and inherited symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbolsIn(source, object) {\n return copyObject(source, getSymbolsIn(source), object);\n}\n\nmodule.exports = copySymbolsIn;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","var SetCache = require('./_SetCache'),\n arraySome = require('./_arraySome'),\n cacheHas = require('./_cacheHas');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Check that cyclic values are equal.\n var arrStacked = stack.get(array);\n var othStacked = stack.get(other);\n if (arrStacked && othStacked) {\n return arrStacked == other && othStacked == array;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalArrays;\n","var Symbol = require('./_Symbol'),\n Uint8Array = require('./_Uint8Array'),\n eq = require('./eq'),\n equalArrays = require('./_equalArrays'),\n mapToArray = require('./_mapToArray'),\n setToArray = require('./_setToArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nmodule.exports = equalByTag;\n","var getAllKeys = require('./_getAllKeys');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Check that cyclic values are equal.\n var objStacked = stack.get(object);\n var othStacked = stack.get(other);\n if (objStacked && othStacked) {\n return objStacked == other && othStacked == object;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalObjects;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var baseGetAllKeys = require('./_baseGetAllKeys'),\n getSymbols = require('./_getSymbols'),\n keys = require('./keys');\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nmodule.exports = getAllKeys;\n","var baseGetAllKeys = require('./_baseGetAllKeys'),\n getSymbolsIn = require('./_getSymbolsIn'),\n keysIn = require('./keysIn');\n\n/**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeysIn(object) {\n return baseGetAllKeys(object, keysIn, getSymbolsIn);\n}\n\nmodule.exports = getAllKeysIn;\n","var isKeyable = require('./_isKeyable');\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nmodule.exports = getMapData;\n","var isStrictComparable = require('./_isStrictComparable'),\n keys = require('./keys');\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n}\n\nmodule.exports = getMatchData;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var overArg = require('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","var arrayFilter = require('./_arrayFilter'),\n stubArray = require('./stubArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nmodule.exports = getSymbols;\n","var arrayPush = require('./_arrayPush'),\n getPrototype = require('./_getPrototype'),\n getSymbols = require('./_getSymbols'),\n stubArray = require('./stubArray');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n var result = [];\n while (object) {\n arrayPush(result, getSymbols(object));\n object = getPrototype(object);\n }\n return result;\n};\n\nmodule.exports = getSymbolsIn;\n","var DataView = require('./_DataView'),\n Map = require('./_Map'),\n Promise = require('./_Promise'),\n Set = require('./_Set'),\n WeakMap = require('./_WeakMap'),\n baseGetTag = require('./_baseGetTag'),\n toSource = require('./_toSource');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nmodule.exports = getTag;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","var castPath = require('./_castPath'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isIndex = require('./_isIndex'),\n isLength = require('./isLength'),\n toKey = require('./_toKey');\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n}\n\nmodule.exports = hasPath;\n","var nativeCreate = require('./_nativeCreate');\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nmodule.exports = hashClear;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = hashDelete;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nmodule.exports = hashGet;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nmodule.exports = hashHas;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nmodule.exports = hashSet;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = new array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\nmodule.exports = initCloneArray;\n","var cloneArrayBuffer = require('./_cloneArrayBuffer'),\n cloneDataView = require('./_cloneDataView'),\n cloneRegExp = require('./_cloneRegExp'),\n cloneSymbol = require('./_cloneSymbol'),\n cloneTypedArray = require('./_cloneTypedArray');\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return new Ctor;\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return new Ctor;\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\nmodule.exports = initCloneByTag;\n","var baseCreate = require('./_baseCreate'),\n getPrototype = require('./_getPrototype'),\n isPrototype = require('./_isPrototype');\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\nmodule.exports = initCloneObject;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nmodule.exports = isIndex;\n","var isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nmodule.exports = isKey;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nmodule.exports = isKeyable;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nmodule.exports = isPrototype;\n","var isObject = require('./isObject');\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n return value === value && !isObject(value);\n}\n\nmodule.exports = isStrictComparable;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nmodule.exports = listCacheClear;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nmodule.exports = listCacheDelete;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nmodule.exports = listCacheGet;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nmodule.exports = listCacheHas;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nmodule.exports = listCacheSet;\n","var Hash = require('./_Hash'),\n ListCache = require('./_ListCache'),\n Map = require('./_Map');\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nmodule.exports = mapCacheClear;\n","var getMapData = require('./_getMapData');\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = mapCacheDelete;\n","var getMapData = require('./_getMapData');\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nmodule.exports = mapCacheGet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nmodule.exports = mapCacheHas;\n","var getMapData = require('./_getMapData');\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nmodule.exports = mapCacheSet;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nmodule.exports = mapToArray;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nmodule.exports = matchesStrictComparable;\n","var memoize = require('./memoize');\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nmodule.exports = memoizeCapped;\n","var getNative = require('./_getNative');\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nmodule.exports = nativeCreate;\n","var overArg = require('./_overArg');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nmodule.exports = nativeKeys;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = nativeKeysIn;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\nmodule.exports = nodeUtil;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nmodule.exports = overArg;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nmodule.exports = setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nmodule.exports = setCacheHas;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nmodule.exports = setToArray;\n","var ListCache = require('./_ListCache');\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\nmodule.exports = stackClear;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nmodule.exports = stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nmodule.exports = stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nmodule.exports = stackHas;\n","var ListCache = require('./_ListCache'),\n Map = require('./_Map'),\n MapCache = require('./_MapCache');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\nmodule.exports = stackSet;\n","var memoizeCapped = require('./_memoizeCapped');\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nmodule.exports = stringToPath;\n","var isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = toKey;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n","/** Used to match a single whitespace character. */\nvar reWhitespace = /\\s/;\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\nfunction trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n}\n\nmodule.exports = trimmedEndIndex;\n","var baseClone = require('./_baseClone');\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\nfunction cloneDeep(value) {\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);\n}\n\nmodule.exports = cloneDeep;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nmodule.exports = eq;\n","var baseFindIndex = require('./_baseFindIndex'),\n baseIteratee = require('./_baseIteratee'),\n toInteger = require('./toInteger');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * This method is like `_.find` except that it returns the index of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `_.matches` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\nfunction findIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseFindIndex(array, baseIteratee(predicate, 3), index);\n}\n\nmodule.exports = findIndex;\n","var baseGet = require('./_baseGet');\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nmodule.exports = get;\n","var baseHasIn = require('./_baseHasIn'),\n hasPath = require('./_hasPath');\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n}\n\nmodule.exports = hasIn;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nmodule.exports = identity;\n","var baseIsArguments = require('./_baseIsArguments'),\n isObjectLike = require('./isObjectLike');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\nmodule.exports = isArguments;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nmodule.exports = isArray;\n","var isFunction = require('./isFunction'),\n isLength = require('./isLength');\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nmodule.exports = isArrayLike;\n","var root = require('./_root'),\n stubFalse = require('./stubFalse');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nmodule.exports = isBuffer;\n","var baseIsEqual = require('./_baseIsEqual');\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\nfunction isEqual(value, other) {\n return baseIsEqual(value, other);\n}\n\nmodule.exports = isEqual;\n","var root = require('./_root');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsFinite = root.isFinite;\n\n/**\n * Checks if `value` is a finite primitive number.\n *\n * **Note:** This method is based on\n * [`Number.isFinite`](https://mdn.io/Number/isFinite).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.\n * @example\n *\n * _.isFinite(3);\n * // => true\n *\n * _.isFinite(Number.MIN_VALUE);\n * // => true\n *\n * _.isFinite(Infinity);\n * // => false\n *\n * _.isFinite('3');\n * // => false\n */\nfunction isFinite(value) {\n return typeof value == 'number' && nativeIsFinite(value);\n}\n\nmodule.exports = isFinite;\n","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nmodule.exports = isLength;\n","var baseIsMap = require('./_baseIsMap'),\n baseUnary = require('./_baseUnary'),\n nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsMap = nodeUtil && nodeUtil.isMap;\n\n/**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\nvar isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\nmodule.exports = isMap;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","var baseIsSet = require('./_baseIsSet'),\n baseUnary = require('./_baseUnary'),\n nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsSet = nodeUtil && nodeUtil.isSet;\n\n/**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\nvar isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\nmodule.exports = isSet;\n","var baseGetTag = require('./_baseGetTag'),\n isArray = require('./isArray'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar stringTag = '[object String]';\n\n/**\n * Checks if `value` is classified as a `String` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a string, else `false`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\nfunction isString(value) {\n return typeof value == 'string' ||\n (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);\n}\n\nmodule.exports = isString;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var baseIsTypedArray = require('./_baseIsTypedArray'),\n baseUnary = require('./_baseUnary'),\n nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nmodule.exports = isTypedArray;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeys = require('./_baseKeys'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nmodule.exports = keys;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeysIn = require('./_baseKeysIn'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nmodule.exports = keysIn;\n","var MapCache = require('./_MapCache');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nmodule.exports = memoize;\n","var baseProperty = require('./_baseProperty'),\n basePropertyDeep = require('./_basePropertyDeep'),\n isKey = require('./_isKey'),\n toKey = require('./_toKey');\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n * { 'a': { 'b': 2 } },\n * { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nmodule.exports = property;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nmodule.exports = stubArray;\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = stubFalse;\n","var toNumber = require('./toNumber');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n MAX_INTEGER = 1.7976931348623157e+308;\n\n/**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n}\n\nmodule.exports = toFinite;\n","var toFinite = require('./toFinite');\n\n/**\n * Converts `value` to an integer.\n *\n * **Note:** This method is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\nmodule.exports = toInteger;\n","var baseTrim = require('./_baseTrim'),\n isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","var baseToString = require('./_baseToString');\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nmodule.exports = toString;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = (module) => {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","import domPurify from 'dompurify';\n\nexport default function escapeHTML(unescaped) {\n\treturn domPurify.sanitize(unescaped);\n}\n","import domPurify from 'dompurify';\n\nexport default function stripTags(html) {\n\treturn domPurify.sanitize(html, {\n\t\tALLOWED_TAGS: ['#text'],\n\t\tKEEP_CONTENT: true,\n\t});\n}\n","/**\n * @enum {String}\n * @readonly\n */\nexport default {\n\tCHORD: 'chord',\n\tCHORD_LINE_REPEATER: 'chordLineRepeater',\n\tEMPTY_LINE: 'emptyLine',\n\tLYRIC: 'lyric',\n\tSECTION_LABEL: 'sectionLabel',\n\tTIME_SIGNATURE: 'timeSignature',\n};\n","const allowedTimeSignatures = [\n\t'2/2',\n\t'3/2',\n\t'2/4',\n\t'3/4',\n\t'4/4',\n\t'5/4',\n\t'3/8',\n\t'6/8',\n\t'9/8',\n\t'12/8',\n];\n\nexport default function isTimeSignatureString(string) {\n\treturn allowedTimeSignatures.includes(string);\n}\n","export default {\n\tbarRepeat: '/',\n\tchordBeatCount: '\\\\.',\n\tchordLineRepeat: '/',\n\tnoChord: 'NC',\n\tnoLyrics: 'NL',\n\tsectionLabel: '#',\n\tchordPositionMarker: '_',\n};\n","import syntax from '../syntax';\n\nconst sectionLabelRegexp = new RegExp(\n\t'^' + syntax.sectionLabel + '[a-zA-Z]+( x[2-9])?$'\n);\n\nexport default function isSectionLabel(string) {\n\tconst found = string.trim().match(sectionLabelRegexp);\n\treturn found !== null;\n}\n","export default function clearSpaces(string) {\n\treturn string.replace(/\\t+/g, ' ').replace(/ +/g, ' ').trim();\n}\n","import { chordParserFactory } from 'chord-symbol';\n\nexport default function isChord(potentialChord) {\n\tconst parseChord = chordParserFactory();\n\tconst parsed = parseChord(potentialChord);\n\treturn !parsed.error;\n}\n","import clearSpaces from '../helper/clearSpaces';\n\nimport syntax from '../syntax';\nimport isChord from './isChord';\n\nconst chordBeatCountSymbols = new RegExp(syntax.chordBeatCount + '*$', 'g');\nconst barRepeatSymbols = new RegExp('^' + syntax.barRepeat + '+$');\n\nexport default function isChordLine(line = '') {\n\treturn clearSpaces(line)\n\t\t.split(' ')\n\t\t.every((potentialChordToken, index) => {\n\t\t\tconst withoutBeatCount = potentialChordToken.replace(\n\t\t\t\tchordBeatCountSymbols,\n\t\t\t\t''\n\t\t\t);\n\t\t\treturn (\n\t\t\t\tisChord(withoutBeatCount) ||\n\t\t\t\t(potentialChordToken.match(barRepeatSymbols) && index > 0) ||\n\t\t\t\twithoutBeatCount === syntax.noChord\n\t\t\t);\n\t\t});\n}\n","import syntax from '../syntax';\nimport clearSpaces from '../helper/clearSpaces';\n\nexport default function isChordLineRepeater(string) {\n\treturn clearSpaces(string) === syntax.chordLineRepeat;\n}\n","import clearSpaces from '../helper/clearSpaces';\n\nexport default function isEmptyLine(string) {\n\treturn clearSpaces(string) === '';\n}\n","import isTimeSignatureString from './matchers/isTimeSignatureString';\n\n/**\n * @typedef {Object} TimeSignature\n * @type {Object}\n * @property {String} string - original string\n * @property {Number} count - upper part of time signature\n * @property {Number} value - lower part of time signature\n * @property {Number} beatCount - number of beats per bar\n */\n\n/**\n * @param {String} string\n * @returns {TimeSignature}\n */\nexport default function parseTimeSignature(string) {\n\tif (!isTimeSignatureString(string)) {\n\t\tthrow new TypeError(\n\t\t\t'Expected time signature string, received: ' + string\n\t\t);\n\t}\n\n\tconst array = string.split('/');\n\n\tconst count = Number.parseInt(array[0], 10);\n\tconst value = Number.parseInt(array[1], 10);\n\n\tlet beatCount = count;\n\n\tif (value === 2) {\n\t\tbeatCount = count * 2;\n\t} else if (value === 8) {\n\t\tbeatCount = count / 3;\n\t}\n\n\treturn {\n\t\tstring,\n\t\tcount,\n\t\tvalue,\n\t\tbeatCount,\n\t};\n}\n","import { chordParserFactory } from 'chord-symbol';\n\n/**\n * @param chordString\n * @returns {Chord}\n */\nexport default function parseChordWrapper(chordString) {\n\tconst parseChord = chordParserFactory();\n\treturn parseChord(chordString);\n}\n","import _isString from 'lodash/isString';\nimport _isFinite from 'lodash/isFinite';\n\nexport default class IncorrectBeatCountException extends Error {\n\tconstructor({ string, duration, currentBeatCount, beatCount } = {}) {\n\t\tif (!string || !_isString(string)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'IncorrectBeatCountException cannot be created without chord string, received: ' +\n\t\t\t\t\tstring\n\t\t\t);\n\t\t}\n\t\tif (!duration || !_isFinite(duration)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'IncorrectBeatCountException cannot be created without chord duration, received: ' +\n\t\t\t\t\tduration\n\t\t\t);\n\t\t}\n\t\tif (!currentBeatCount || !_isFinite(currentBeatCount)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'IncorrectBeatCountException cannot be created without currentBeatCount, received: ' +\n\t\t\t\t\tcurrentBeatCount\n\t\t\t);\n\t\t}\n\t\tif (!beatCount || !_isFinite(beatCount)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'IncorrectBeatCountException cannot be created without beatCount, received: ' +\n\t\t\t\t\tbeatCount\n\t\t\t);\n\t\t}\n\n\t\tsuper();\n\n\t\tthis.name = 'IncorrectBeatCountException';\n\t\tthis.string = string;\n\t\tthis.duration = duration;\n\t\tthis.currentBeatCount = currentBeatCount;\n\t\tthis.beatCount = beatCount;\n\t}\n}\n","import _isString from 'lodash/isString';\n\nexport default class InvalidChordRepetitionException extends Error {\n\tconstructor({ string } = {}) {\n\t\tif (!string || !_isString(string)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'InvalidChordRepetitionException cannot be created without chord string, received: ' +\n\t\t\t\t\tstring\n\t\t\t);\n\t\t}\n\n\t\tsuper();\n\n\t\tthis.name = 'InvalidChordRepetitionException';\n\t\tthis.string = string;\n\t}\n}\n","import _isEqual from 'lodash/isEqual';\nimport _cloneDeep from 'lodash/cloneDeep';\n\nimport syntax from './syntax';\nimport clearSpaces from './helper/clearSpaces';\n\nimport parseChord from './parseChord';\nimport parseTimeSignature from './parseTimeSignature';\n\nimport IncorrectBeatCountException from './exceptions/IncorrectBeatCountException';\nimport InvalidChordRepetitionException from './exceptions/InvalidChordRepetitionException';\n\nconst chordBeatCountSymbols = new RegExp(syntax.chordBeatCount, 'g');\nconst barRepeatSymbols = new RegExp('^' + syntax.barRepeat + '+$');\nconst defaultTimeSignature = parseTimeSignature('4/4');\n\n/**\n * @typedef {Object} ChordLine\n * @type {Object}\n * @property {Number} chordCount - number of chords in the line\n * @property {Bar[]} allBars\n */\n\n/**\n * @typedef {Object} Bar\n * @type {Object}\n * @property {TimeSignature} timeSignature\n * @property {ChordLineChord[]} allChords\n */\n\n/**\n * @typedef {Object} ChordLineChord\n * @type {Object}\n * @property {String} string - original chord string\n * @property {ChordDef|String} model - parsed chord or \"NC\" if \"no chord\" symbol\n * @property {Number} duration - number of beats the chord lasts\n * @property {Number} beat - beat on which the chord starts\n */\n\n/**\n * @param {String} chordLine\n * @param {TimeSignature} timeSignature\n * @returns {ChordLine}\n */\nexport default function parseChordLine(\n\tchordLine,\n\t{ timeSignature = defaultTimeSignature } = {}\n) {\n\tconst { beatCount } = timeSignature;\n\n\tconst allBars = [];\n\tconst emptyBar = { allChords: [] };\n\n\tlet bar = _cloneDeep(emptyBar);\n\tlet chord = {};\n\tlet tokenWithoutBeatCount;\n\tlet currentBeatCount = 0;\n\tlet chordCount = 0;\n\tlet previousBar;\n\n\tconst allTokens = clearSpaces(chordLine).split(' ');\n\tallTokens.forEach((token, tokenIndex) => {\n\t\tif (token.match(barRepeatSymbols)) {\n\t\t\tif (previousBar) {\n\t\t\t\tfor (let i = 0; i < token.length; i++) {\n\t\t\t\t\tallBars.push(_cloneDeep(previousBar));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'A chord line cannot start with the barRepeat symbol'\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\ttokenWithoutBeatCount = token.replace(chordBeatCountSymbols, '');\n\t\t\tchord = {\n\t\t\t\tstring: token,\n\t\t\t\tduration: getChordDuration(token, beatCount),\n\t\t\t\tmodel: isNoChordSymbol(tokenWithoutBeatCount)\n\t\t\t\t\t? syntax.noChord\n\t\t\t\t\t: parseChord(tokenWithoutBeatCount),\n\t\t\t\tbeat: currentBeatCount + 1,\n\t\t\t};\n\t\t\tcurrentBeatCount += chord.duration;\n\n\t\t\tcheckInvalidChordRepetition(bar, chord);\n\n\t\t\tbar.allChords.push(chord);\n\t\t\tchordCount++;\n\n\t\t\tif (shouldChangeBar(currentBeatCount, beatCount)) {\n\t\t\t\tbar.timeSignature = timeSignature;\n\t\t\t\tconst barClone = _cloneDeep(bar);\n\n\t\t\t\tallBars.push(barClone);\n\t\t\t\tpreviousBar = barClone;\n\n\t\t\t\tbar = _cloneDeep(emptyBar);\n\t\t\t\tcurrentBeatCount = 0;\n\t\t\t} else {\n\t\t\t\tcheckInvalidBeatCount(\n\t\t\t\t\tchord,\n\t\t\t\t\tcurrentBeatCount,\n\t\t\t\t\tbeatCount,\n\t\t\t\t\tallTokens.length === tokenIndex + 1\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t});\n\n\treturn {\n\t\tchordCount,\n\t\tallBars,\n\t};\n}\n\nfunction isNoChordSymbol(token) {\n\treturn token === syntax.noChord;\n}\n\nfunction getChordDuration(token, beatCount) {\n\treturn (token.match(chordBeatCountSymbols) || []).length || beatCount;\n}\n\nfunction checkInvalidChordRepetition(bar, currentChord) {\n\tif (bar.allChords.length > 0) {\n\t\tconst previousChord = bar.allChords[bar.allChords.length - 1];\n\t\tif (_isEqual(previousChord.model, currentChord.model)) {\n\t\t\tthrow new InvalidChordRepetitionException({\n\t\t\t\tstring: currentChord.string,\n\t\t\t});\n\t\t}\n\t}\n}\n\nfunction shouldChangeBar(currentBeatCount, beatCount) {\n\treturn currentBeatCount === beatCount;\n}\n\nfunction checkInvalidBeatCount(chord, currentBeatCount, beatCount, isLast) {\n\tif (hasInvalidBeatCount(currentBeatCount, beatCount, isLast)) {\n\t\tthrow new IncorrectBeatCountException({\n\t\t\tmessage: '',\n\t\t\tstring: chord.string,\n\t\t\tduration: chord.duration,\n\t\t\tcurrentBeatCount,\n\t\t\tbeatCount,\n\t\t});\n\t}\n}\nfunction hasInvalidBeatCount(currentBeatCount, barBeatCount, isLast) {\n\treturn (\n\t\thasTooManyBeats(currentBeatCount, barBeatCount) ||\n\t\thasTooFewBeats(currentBeatCount, barBeatCount, isLast)\n\t);\n}\nfunction hasTooManyBeats(currentBeatCount, barBeatCount) {\n\treturn currentBeatCount > barBeatCount;\n}\nfunction hasTooFewBeats(currentBeatCount, barBeatCount, isLast) {\n\treturn isLast && currentBeatCount < barBeatCount;\n}\n","import isSectionLabel from './matchers/isSectionLabel';\n\n/**\n * @typedef {Object} SectionLabel\n * @type {Object}\n * @property {String} string - original string\n * @property {String} label - label of the section\n * @property {Number} repeatTimes - number of times the section should be repeated\n */\n\n/**\n * @param {String} string\n * @returns {SectionLabel}\n */\nexport default function parseSectionLabel(string) {\n\tif (!isSectionLabel(string)) {\n\t\tthrow new TypeError(\n\t\t\t'Expected section identifier string, received: ' + string\n\t\t);\n\t}\n\n\tconst [labelSrc, repeatSrc] = string.trim().split(' ');\n\n\treturn {\n\t\tstring,\n\t\tlabel: labelSrc.substring(1),\n\t\trepeatTimes: repeatSrc ? Number.parseInt(repeatSrc.substring(1)) : 0,\n\t};\n}\n","import syntax from './syntax';\n\n/**\n * @typedef {Object} LyricLine\n * @type {Object}\n * @property {String} lyrics\n * @property {Number[]} chordPositions\n */\n\n/**\n * @param {String} string\n * @returns {LyricLine}\n */\nexport default function parseLyricLine(string) {\n\tconst regexp = new RegExp(syntax.chordPositionMarker, 'g');\n\tconst stringWithoutPositionMarkers = string.replace(regexp, '');\n\n\tconst chordPositions = [];\n\tlet tmpString = string;\n\tlet position;\n\n\twhile ((position = tmpString.indexOf(syntax.chordPositionMarker)) !== -1) {\n\t\tif (!chordPositions.includes(position)) {\n\t\t\tchordPositions.push(position);\n\t\t}\n\t\ttmpString = tmpString.replace(syntax.chordPositionMarker, '');\n\t}\n\treturn {\n\t\tlyrics: stringWithoutPositionMarkers,\n\t\tchordPositions,\n\t};\n}\n","import _cloneDeep from 'lodash/cloneDeep';\n\nimport lineTypes from '../lineTypes';\n\n/**\n * @param {SongLine[]} allLines\n * @param {Function} fn - to execute on each chord\n * @returns {SongLine[]}\n */\nexport function forEachChordInSong(allLines, fn) {\n\tconst newLines = _cloneDeep(allLines);\n\n\tnewLines.forEach((line) => {\n\t\tif (line.type === lineTypes.CHORD) {\n\t\t\tline.model.allBars.forEach((bar) => {\n\t\t\t\tbar.allChords.forEach((chord) => {\n\t\t\t\t\tfn(chord);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t});\n\treturn newLines;\n}\n\n/**\n * @param {ChordLine} chordLine\n * @param {Function} fn - to execute on each chord\n * @returns {ChordLine}\n */\nexport function forEachChordInChordLine(chordLine, fn) {\n\tconst newChordLine = _cloneDeep(chordLine);\n\n\tnewChordLine.allBars.forEach((bar, barIndex) => {\n\t\tbar.allChords.forEach((chord, chordIndex) => {\n\t\t\tfn(chord, chordIndex, barIndex);\n\t\t});\n\t});\n\n\treturn newChordLine;\n}\n\n/**\n * @param {SongLine[]} allLines\n * @param {String} label - the label to select\n * @param {Number} n - the index of the section to select\n * @returns {SongLine[]} all lines of the requested section\n */\nexport function getNthOfLabel(allLines, label, n) {\n\tconst selected = [];\n\tconst typesCount = {};\n\n\tlet enableSelect = false;\n\tlet currentLabel = '';\n\n\tallLines.forEach((line) => {\n\t\tif (line.type === lineTypes.SECTION_LABEL) {\n\t\t\tcurrentLabel = line.model.label;\n\n\t\t\tif (!typesCount[currentLabel]) {\n\t\t\t\ttypesCount[currentLabel] = 1;\n\t\t\t} else {\n\t\t\t\ttypesCount[currentLabel]++;\n\t\t\t}\n\n\t\t\tenableSelect = line.id === label + n;\n\t\t} else if (enableSelect) {\n\t\t\tselected.push(line);\n\t\t}\n\t});\n\treturn selected;\n}\n","/*eslint-disable max-lines-per-function */\nimport _cloneDeep from 'lodash/cloneDeep';\nimport lineTypes from './lineTypes';\n\nimport isTimeSignature from './matchers/isTimeSignatureString';\nimport isSectionLabel from './matchers/isSectionLabel';\nimport isChordLine from './matchers/isChordLine';\nimport isChordLineRepeater from './matchers/isChordLineRepeater';\nimport isEmptyLine from './matchers/isEmptyLine';\n\nimport parseTimeSignature from './parseTimeSignature';\nimport parseChordLine from './parseChordLine';\nimport parseSectionLabel from './parseSectionLabel';\nimport parseLyricLine from './parseLyricLine';\n\nimport { getNthOfLabel } from './helper/songs';\n\nconst defaultTimeSignature = '4/4';\n\n/**\n * @typedef {Object} SongLine\n * @type {Object}\n * @property {String} string - original line in source file\n * @property {String} type - chord|lyric|timeSignature|sectionLabel...\n * @property {Boolean} [isFromSectionRepeat] - line created by a section repeat directive (x3...)\n * @property {Boolean} [isFromAutoRepeatChords] - line created by auto repeats of chords from a section to another\n */\n\n/**\n * @typedef {SongLine} SongChordLine\n * @type {Object}\n * @property {ChordLine} model\n * @property {Boolean} [isFromChordLineRepeater] - line created by the chordLine repeat symbol\n */\n\n/**\n * @typedef {SongLine} SongTimeSignatureLine\n * @type {Object}\n * @property {TimeSignature} model\n */\n\n/**\n * @typedef {SongLine} SongLyricLine\n * @type {Object}\n * @property {LyricLine} model\n */\n\n/**\n * @typedef {SongLine} SongSectionLabelLine\n * @type {Object}\n * @property {SectionLabel} model\n * @property {Number} index - index of the section for a given label (#v, #v x2, #v => 1, 2, 3, 4)\n * @property {Number} indexWithoutRepeats - idem, but not taking repeats into account (#v, #v x2, #v => 1, 2, 3)\n * @property {String} id\n */\n\nexport default function songLinesFactory() {\n\tconst allLines = [];\n\tconst sectionsStats = {};\n\n\tlet currentTimeSignature = parseTimeSignature(defaultTimeSignature);\n\tlet currentSectionLabel;\n\tlet currentSectionStats;\n\n\tlet previousChordLine;\n\tlet previousSectionLabelLine;\n\n\tlet blueprint = [];\n\tlet blueprintIndex = 0;\n\tlet blueprintLine = '';\n\n\tlet isRepeatingChords = false;\n\tlet shouldRepeatSection = false;\n\n\t/**\n\t * @returns {SongTimeSignatureLine}\n\t */\n\tfunction getTimeSignatureLine(string) {\n\t\tcurrentTimeSignature = parseTimeSignature(string);\n\n\t\treturn {\n\t\t\tstring,\n\t\t\ttype: lineTypes.TIME_SIGNATURE,\n\t\t\tmodel: currentTimeSignature,\n\t\t};\n\t}\n\n\t/**\n\t * @returns {SongSectionLabelLine}\n\t */\n\tfunction getSectionLabelLine(string) {\n\t\tcurrentSectionLabel = parseSectionLabel(string);\n\n\t\tincreaseSectionStats(currentSectionLabel.label);\n\t\tcurrentSectionStats = getSectionCount(currentSectionLabel.label);\n\n\t\tconst line = {\n\t\t\tstring,\n\t\t\ttype: lineTypes.SECTION_LABEL,\n\t\t\tmodel: currentSectionLabel,\n\t\t\tindex: currentSectionStats.count,\n\t\t\tindexWithoutRepeats: currentSectionStats.withoutRepeats,\n\t\t\tid: currentSectionLabel.label + currentSectionStats.count,\n\t\t};\n\n\t\tshouldRepeatSection = currentSectionLabel.repeatTimes > 0;\n\t\tpreviousSectionLabelLine = _cloneDeep(line);\n\n\t\tif (!isFirstOfLabel(currentSectionLabel, allLines)) {\n\t\t\tblueprint = getNthOfLabel(allLines, currentSectionLabel.label, 1);\n\t\t\tblueprintIndex = 0;\n\t\t\tisRepeatingChords = true;\n\t\t} else {\n\t\t\tisRepeatingChords = false;\n\t\t}\n\t\treturn line;\n\t}\n\n\t/**\n\t * @returns {SongLyricLine}\n\t */\n\tfunction getEmptyLine(string) {\n\t\treturn {\n\t\t\tstring,\n\t\t\ttype: lineTypes.EMPTY_LINE,\n\t\t};\n\t}\n\n\t/**\n\t * @returns {SongChordLine|SongLyricLine}\n\t */\n\tfunction getChordLine(string) {\n\t\tlet line;\n\t\ttry {\n\t\t\tconst model = parseChordLine(string, {\n\t\t\t\ttimeSignature: currentTimeSignature,\n\t\t\t});\n\t\t\tline = {\n\t\t\t\tstring,\n\t\t\t\ttype: lineTypes.CHORD,\n\t\t\t\tmodel,\n\t\t\t};\n\t\t\tpreviousChordLine = line;\n\t\t} catch (e) {\n\t\t\tline = getLyricLine(string);\n\t\t}\n\t\treturn line;\n\t}\n\n\t/**\n\t * @returns {SongChordLine|SongLyricLine}\n\t */\n\tfunction getPreviousChordLine(string) {\n\t\tif (previousChordLine) {\n\t\t\treturn {\n\t\t\t\t..._cloneDeep(previousChordLine),\n\t\t\t\tisFromChordLineRepeater: true,\n\t\t\t};\n\t\t}\n\t\treturn getLyricLine(string);\n\t}\n\n\t/**\n\t * @returns {SongLyricLine}\n\t */\n\tfunction getLyricLine(string) {\n\t\treturn {\n\t\t\tstring,\n\t\t\ttype: lineTypes.LYRIC,\n\t\t\tmodel: parseLyricLine(string),\n\t\t};\n\t}\n\n\tfunction increaseSectionStats(label, isRepeated = false) {\n\t\tif (!sectionsStats[label]) {\n\t\t\tsectionsStats[label] = {\n\t\t\t\tcount: 1,\n\t\t\t\twithoutRepeats: 1,\n\t\t\t};\n\t\t} else {\n\t\t\tsectionsStats[label].count++;\n\t\t\tif (!isRepeated) {\n\t\t\t\tsectionsStats[label].withoutRepeats++;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction getSectionCount(label) {\n\t\treturn sectionsStats[label];\n\t}\n\n\tfunction repeatLinesFromBlueprint(line) {\n\t\tif (isRepeatingChords && line.type !== lineTypes.SECTION_LABEL) {\n\t\t\tblueprintLine = blueprint[blueprintIndex];\n\t\t\tlet repeatedLine;\n\n\t\t\twhile (shouldRepeatLineFromBlueprint(blueprintLine, line)) {\n\t\t\t\tif (blueprintLine.type === lineTypes.CHORD) {\n\t\t\t\t\tpreviousChordLine = _cloneDeep(blueprintLine);\n\t\t\t\t}\n\t\t\t\trepeatedLine = {\n\t\t\t\t\t..._cloneDeep(blueprintLine),\n\t\t\t\t\tisFromAutoRepeatChords: true,\n\t\t\t\t};\n\t\t\t\tallLines.push(repeatedLine);\n\t\t\t\tblueprintIndex++;\n\t\t\t\tblueprintLine = blueprint[blueprintIndex];\n\t\t\t}\n\t\t\tblueprintIndex++;\n\t\t}\n\t}\n\n\tfunction repeatSection(lineIndex, allSrcLines) {\n\t\tif (\n\t\t\tshouldRepeatSection &&\n\t\t\tisLastLineOfSection(lineIndex, allSrcLines)\n\t\t) {\n\t\t\tconst toRepeat = getNthOfLabel(\n\t\t\t\tallLines,\n\t\t\t\tcurrentSectionLabel.label,\n\t\t\t\tcurrentSectionStats.count\n\t\t\t).map((line) => ({\n\t\t\t\t..._cloneDeep(line),\n\t\t\t\tisFromSectionRepeat: true,\n\t\t\t}));\n\t\t\tlet sectionLabelLine;\n\n\t\t\tfor (let i = 1; i < currentSectionLabel.repeatTimes; i++) {\n\t\t\t\tincreaseSectionStats(currentSectionLabel.label, true);\n\t\t\t\tcurrentSectionStats = getSectionCount(\n\t\t\t\t\tcurrentSectionLabel.label\n\t\t\t\t);\n\n\t\t\t\tsectionLabelLine = {\n\t\t\t\t\t..._cloneDeep(previousSectionLabelLine),\n\t\t\t\t\tindex: currentSectionStats.count,\n\t\t\t\t\tindexWithoutRepeats: currentSectionStats.withoutRepeats,\n\t\t\t\t\tid: currentSectionLabel.label + currentSectionStats.count,\n\t\t\t\t\tisFromSectionRepeat: true,\n\t\t\t\t};\n\t\t\t\tallLines.push(sectionLabelLine);\n\t\t\t\tallLines.push(..._cloneDeep(toRepeat));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\taddLine(lineSrc, lineIndex, allSrcLines) {\n\t\t\tlet line;\n\t\t\tif (isTimeSignature(lineSrc)) {\n\t\t\t\tline = getTimeSignatureLine(lineSrc);\n\t\t\t} else if (isSectionLabel(lineSrc)) {\n\t\t\t\tline = getSectionLabelLine(lineSrc);\n\t\t\t} else if (isChordLine(lineSrc)) {\n\t\t\t\tline = getChordLine(lineSrc);\n\t\t\t} else if (isChordLineRepeater(lineSrc)) {\n\t\t\t\tline = getPreviousChordLine(lineSrc);\n\t\t\t} else if (isEmptyLine(lineSrc)) {\n\t\t\t\tline = getEmptyLine(lineSrc);\n\t\t\t} else {\n\t\t\t\tline = getLyricLine(lineSrc);\n\t\t\t}\n\n\t\t\trepeatLinesFromBlueprint(line);\n\n\t\t\tallLines.push(line);\n\n\t\t\trepeatSection(lineIndex, allSrcLines);\n\t\t},\n\n\t\t/**\n\t\t * returns {SongLine[]}\n\t\t */\n\t\tasArray() {\n\t\t\treturn _cloneDeep(allLines);\n\t\t},\n\t};\n}\n\nfunction isFirstOfLabel(currentLabel, allLines) {\n\treturn allLines.every(\n\t\t(line) =>\n\t\t\tline.type === lineTypes.SECTION_LABEL &&\n\t\t\tline.model.label !== currentLabel.label\n\t);\n}\n\nfunction shouldRepeatLineFromBlueprint(blueprintLine, currentLine) {\n\treturn (\n\t\tblueprintLine &&\n\t\tblueprintLine.type !== lineTypes.LYRIC &&\n\t\tblueprintLine.type !== lineTypes.EMPTY_LINE &&\n\t\tblueprintLine.type !== currentLine.type &&\n\t\tcurrentLine.type !== lineTypes.EMPTY_LINE\n\t);\n}\n\nfunction isLastLineOfSection(lineIndex, allSrcLines) {\n\tconst nextLine = allSrcLines[lineIndex + 1];\n\treturn typeof nextLine === 'undefined' || isSectionLabel(nextLine);\n}\n","import _findIndex from 'lodash/findIndex';\nimport _isEqual from 'lodash/isEqual';\nimport _cloneDeep from 'lodash/cloneDeep';\n\nimport { forEachChordInSong } from './helper/songs';\n\n/**\n * @param {SongLine[]} allLines\n * @returns {SongChord[]}\n */\nexport default function getAllChordsInSong(allLines) {\n\tconst allChords = [];\n\tlet i;\n\n\tforEachChordInSong(allLines, (chord) => {\n\t\ti = _findIndex(allChords, (o) => _isEqual(o.model, chord.model));\n\n\t\tif (i === -1) {\n\t\t\tallChords.push({\n\t\t\t\tmodel: _cloneDeep(chord.model),\n\t\t\t\toccurrences: 1,\n\t\t\t});\n\t\t} else {\n\t\t\tallChords[i].occurrences++;\n\t\t}\n\t});\n\n\treturn allChords;\n}\n","import _isArray from 'lodash/isArray';\n\nimport escapeHTML from '../core/dom/escapeHTML';\nimport stripTags from '../core/dom/stripTags';\n\nimport songLinesFactory from './songLinesFactory';\n\nimport getAllChordsInSong from './getAllChordsInSong';\n\n/**\n * @typedef {Object} Song\n * @type {Object}\n * @property {SongLine[]} allLines\n * @property {SongChord[]} allChords\n */\n\n/**\n * @typedef {Object} SongChord\n * @type {Object}\n * @property {ChordDef} model\n * @property {number} occurrences - number of times the chord appears in the song\n */\n\n/**\n * @param {string|array} songSrc\n * @returns {Song}\n */\nexport default function parseSong(songSrc) {\n\tconst songArray = !_isArray(songSrc) ? songSrc.split('\\n') : songSrc;\n\n\tconst songLines = songLinesFactory();\n\n\t/**\n\t * @type {SongLine[]}\n\t */\n\tsongArray.map(escapeHTML).map(stripTags).forEach(songLines.addLine);\n\n\tconst allLines = songLines.asArray();\n\tconst allChords = getAllChordsInSong(allLines);\n\n\treturn {\n\t\tallLines,\n\t\tallChords,\n\t};\n}\n","import lineTypes from '../../../parser/lineTypes';\n\n/**\n * @param {SongLine[]} allLines\n * @returns {Array}\n */\nexport default function getMaxBeatsWidth(allLines) {\n\tconst maxBeatsWidth = [];\n\n\tallLines\n\t\t.filter((line) => line.type === lineTypes.CHORD)\n\t\t.forEach((line) => {\n\t\t\tline.model.allBars.forEach((bar, barIndex) => {\n\t\t\t\tif (!maxBeatsWidth[barIndex]) {\n\t\t\t\t\tmaxBeatsWidth[barIndex] = {};\n\n\t\t\t\t\tfor (let i = 1; i <= bar.timeSignature.beatCount; i++) {\n\t\t\t\t\t\tmaxBeatsWidth[barIndex][i] = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbar.allChords.forEach((chord) => {\n\t\t\t\t\tmaxBeatsWidth[barIndex][chord.beat] = Math.max(\n\t\t\t\t\t\tmaxBeatsWidth[barIndex][chord.beat],\n\t\t\t\t\t\tchord.symbol.length\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\treturn maxBeatsWidth;\n}\n","import _cloneDeep from 'lodash/cloneDeep';\n\nconst defaultSpacesAfter = 2;\n\nconst allMasks = {\n\t0: {\n\t\t'': [],\n\t},\n\n\t2: {\n\t\t2: [3], // 'A '\n\t\t11: [3, 2], // 'A B ',\n\t},\n\n\t3: {\n\t\t3: [3], // 'A '\n\t\t12: [2, 4], // 'A B '\n\t\t21: [6, 0], // 'A C'\n\t\t111: [2, 2, 0], // 'A B C'\n\t},\n\n\t4: {\n\t\t4: [3], // 'A ',\n\t\t13: [1, 4], // 'A B ',\n\t\t22: [3, 2], // 'A B ',\n\t\t31: [5, 0], // 'A B',\n\t\t112: [1, 1, 3], // 'A B C ',\n\t\t121: [1, 4, 0], // 'A B C',\n\t\t211: [4, 1, 0], // 'A B C',\n\t\t1111: [2, 2, 2, 0], // 'A B C D',\n\t},\n};\n\n/**\n * @param {ChordLine} chordLineInput\n */\nexport default function space(chordLineInput) {\n\tconst chordLine = _cloneDeep(chordLineInput);\n\n\tlet beatCount = 0;\n\tlet chordCount = 0;\n\tlet chordPattern = '';\n\tlet chordSpaces = [];\n\n\tchordLine.allBars.forEach((bar) => {\n\t\tbeatCount = 0;\n\t\tchordPattern = '';\n\t\tchordSpaces = [];\n\t\tchordCount = bar.allChords.length;\n\n\t\tbar.allChords.forEach((chord) => {\n\t\t\tchordPattern += chord.duration.toString();\n\t\t\tbeatCount += chord.duration;\n\t\t});\n\n\t\tif (allMasks[beatCount] && allMasks[beatCount][chordPattern]) {\n\t\t\tchordSpaces = allMasks[beatCount][chordPattern];\n\t\t}\n\n\t\tfor (let i = 0; i < chordCount; i++) {\n\t\t\tbar.allChords[i].spacesAfter =\n\t\t\t\ttypeof chordSpaces[i] !== 'undefined'\n\t\t\t\t\t? chordSpaces[i]\n\t\t\t\t\t: defaultSpacesAfter;\n\t\t}\n\t});\n\n\treturn chordLine;\n}\n","import _cloneDeep from 'lodash/cloneDeep';\n\nconst spacesAfterDefault = 2;\nconst emptyBeatSpaces = 1;\n\nexport default function space(chordLineInput, maxBeatsWidth) {\n\tconst chordLine = _cloneDeep(chordLineInput);\n\n\tlet beatMaxWidth;\n\n\tchordLine.allBars.forEach((bar, barIndex) => {\n\t\tbar.allChords.forEach((chord) => {\n\t\t\tchord.spacesWithin =\n\t\t\t\tmaxBeatsWidth[barIndex][chord.beat] - chord.symbol.length;\n\t\t\tchord.spacesAfter = 0;\n\n\t\t\tif (chord.beat !== bar.timeSignature.beatCount) {\n\t\t\t\tchord.spacesAfter = spacesAfterDefault;\n\n\t\t\t\tfor (\n\t\t\t\t\tlet i = chord.beat + 1;\n\t\t\t\t\ti < chord.beat + chord.duration;\n\t\t\t\t\ti++\n\t\t\t\t) {\n\t\t\t\t\tbeatMaxWidth = maxBeatsWidth[barIndex][i];\n\n\t\t\t\t\tchord.spacesAfter += beatMaxWidth\n\t\t\t\t\t\t? beatMaxWidth\n\t\t\t\t\t\t: emptyBeatSpaces;\n\n\t\t\t\t\tif (i !== bar.timeSignature.beatCount && beatMaxWidth) {\n\t\t\t\t\t\tchord.spacesAfter += spacesAfterDefault;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n\n\treturn chordLine;\n}\n","export default {\n\tlyricsSpacer: ' ',\n\tchordLineOffsetSpacer: ' ',\n\tbarSeparator: '|',\n};\n","import _cloneDeep from 'lodash/cloneDeep';\nimport { forEachChordInChordLine } from '../../../parser/helper/songs';\n\nimport symbols from '../../symbols';\n\nconst chordSpaceAfterDefault = 1;\n\n/**\n * @param {ChordLine} chordLineInput\n * @param {LyricLine} lyricsLineInput\n * @returns {Object}\n */\nexport default function space(chordLineInput, lyricsLineInput) {\n\tconst chordLine = _cloneDeep(chordLineInput);\n\tconst lyricsLine = _cloneDeep(lyricsLineInput);\n\n\tif (hasNoPositionMarkers(lyricsLine)) {\n\t\treturn {\n\t\t\tchordLine,\n\t\t\tlyricsLine,\n\t\t};\n\t}\n\n\tconst tokenizedLyrics = lyricsLine.chordPositions.map(\n\t\t(position, i, allPositions) => {\n\t\t\treturn lyricsLine.lyrics.substring(position, allPositions[i + 1]);\n\t\t}\n\t);\n\tlet spacedLyricsLine = '';\n\n\tlet chordToken;\n\tlet lyricToken;\n\tlet currentBarIndex = 0;\n\n\tconst spacedChordLine = forEachChordInChordLine(\n\t\tchordLine,\n\t\t(chord, chordIndex, barIndex) => {\n\t\t\tlyricToken = tokenizedLyrics.shift();\n\n\t\t\tif (lyricToken) {\n\t\t\t\tchordToken = chord.symbol;\n\t\t\t\tif (isFirstChord(barIndex, chordIndex)) {\n\t\t\t\t\tchordToken = symbols.barSeparator + chordToken;\n\t\t\t\t} else if (isNewBar(currentBarIndex, barIndex)) {\n\t\t\t\t\tchordToken = symbols.barSeparator + chordToken;\n\t\t\t\t\tcurrentBarIndex = barIndex;\n\t\t\t\t}\n\n\t\t\t\tif (startsWithSpace(lyricToken)) {\n\t\t\t\t\tlyricToken =\n\t\t\t\t\t\tsymbols.lyricsSpacer.repeat(chordToken.length) +\n\t\t\t\t\t\tlyricToken;\n\t\t\t\t}\n\n\t\t\t\tif (lyricToken.length - chordToken.length > 0) {\n\t\t\t\t\tchord.spacesAfter = lyricToken.length - chordToken.length;\n\t\t\t\t} else {\n\t\t\t\t\tchord.spacesAfter = chordSpaceAfterDefault;\n\t\t\t\t\tconst lyricsSpaceAfter =\n\t\t\t\t\t\tchordToken.length -\n\t\t\t\t\t\tlyricToken.length +\n\t\t\t\t\t\tchordSpaceAfterDefault;\n\t\t\t\t\tlyricToken += symbols.lyricsSpacer.repeat(lyricsSpaceAfter);\n\t\t\t\t}\n\t\t\t\tspacedLyricsLine += lyricToken;\n\t\t\t} else {\n\t\t\t\tchord.spacesAfter = chordSpaceAfterDefault;\n\t\t\t}\n\t\t\tchord.spacesWithin = 0;\n\t\t}\n\t);\n\n\tif (shouldOffsetChordLine(lyricsLine)) {\n\t\tconst chordLineOffset = lyricsLine.chordPositions[0];\n\t\tspacedChordLine.offset = chordLineOffset;\n\t\tspacedLyricsLine =\n\t\t\tlyricsLine.lyrics.substring(0, chordLineOffset) + spacedLyricsLine;\n\t}\n\n\tif (tokenizedLyrics.length) {\n\t\tspacedLyricsLine += tokenizedLyrics.join('');\n\t}\n\tlyricsLine.lyrics = trimEnd(spacedLyricsLine);\n\n\treturn {\n\t\tchordLine: spacedChordLine,\n\t\tlyricsLine,\n\t};\n}\n\nconst hasNoPositionMarkers = (lyricsLine) =>\n\tlyricsLine.chordPositions.length === 0;\n\nconst shouldOffsetChordLine = (lyricsLine) => lyricsLine.chordPositions[0] > 0;\n\nconst isFirstChord = (barIndex, chordIndex) =>\n\tbarIndex === 0 && chordIndex === 0;\n\nconst isNewBar = (currentBarIndex, barIndex) => currentBarIndex !== barIndex;\n\n// source: https://github.com/es-shims/String.prototype.trimEnd/blob/main/implementation.js\nconst trimEnd = (str) => {\n\tconst endWhitespace =\n\t\t// eslint-disable-next-line max-len,no-control-regex\n\t\t/[\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF]*$/;\n\treturn str.replace(endWhitespace, '');\n};\n\nconst startsWithSpace = (str) => str.indexOf(' ') === 0;\n","import chordSymbolTpl from './tpl/chordSymbol.hbs';\n\n/**\n * @param {String} chordSymbol\n * @returns {String} rendered html\n */\nexport default function renderChordSymbol(chordSymbol) {\n\treturn chordSymbolTpl({ chordSymbol });\n}\n","import _isFinite from 'lodash/isFinite';\n\nimport renderChord from './renderChordSymbol';\nimport barContentTpl from './tpl/barContent.hbs';\n\nconst space = ' ';\n\nconst defaultSpacesWithin = 0;\nconst defaultSpacesAfter = 2;\n\n/**\n * @param {Bar} bar\n * @returns {String} rendered html\n */\nexport default function renderBarContent(bar) {\n\tlet spacesWithin = 0;\n\tlet spacesAfter = 0;\n\n\tconst barContent = bar.allChords.reduce((rendering, chord) => {\n\t\tspacesWithin = _isFinite(chord.spacesWithin)\n\t\t\t? chord.spacesWithin\n\t\t\t: defaultSpacesWithin;\n\t\tspacesAfter = _isFinite(chord.spacesAfter)\n\t\t\t? chord.spacesAfter\n\t\t\t: defaultSpacesAfter;\n\n\t\trendering +=\n\t\t\trenderChord(chord.symbol) +\n\t\t\tspace.repeat(spacesWithin) +\n\t\t\tspace.repeat(spacesAfter);\n\n\t\treturn rendering;\n\t}, '');\n\n\treturn barContentTpl({ barContent });\n}\n","import chordLineTpl from './tpl/chordLine.hbs';\n\nimport renderBarContent from './renderBarContent';\nimport barSeparatorTpl from './tpl/barSeparator.hbs';\nimport symbols from '../symbols';\n\n/**\n * @param {ChordLine} chordLineModel\n * @returns {String} rendered html\n */\nexport default function renderChordLine(chordLineModel) {\n\tconst allBarsRendered = chordLineModel.allBars.map((bar) =>\n\t\trenderBarContent(bar)\n\t);\n\n\tconst barSeparator = barSeparatorTpl();\n\n\tconst chordLine =\n\t\tbarSeparator + allBarsRendered.join(barSeparator) + barSeparator;\n\n\tconst chordLineOffset = symbols.chordLineOffsetSpacer.repeat(\n\t\tchordLineModel.offset || 0\n\t);\n\n\treturn chordLineTpl({ chordLineOffset, chordLine });\n}\n","import emptyLineTpl from './tpl/emptyLine.hbs';\n\n/**\n * @returns {String} rendered html\n */\nexport default function render() {\n\treturn emptyLineTpl();\n}\n","import lineTpl from './tpl/line.hbs';\n\n/**\n * @param {string} line\n * @param {Boolean} isFromSectionRepeat\n * @param {Boolean} isFromAutoRepeatChords\n * @param {Boolean} isFromChordLineRepeater\n * @returns {String} rendered html\n */\nexport default function render(\n\tline,\n\t{\n\t\tisFromSectionRepeat = false,\n\t\tisFromAutoRepeatChords = false,\n\t\tisFromChordLineRepeater = false,\n\t} = {}\n) {\n\tconst lineClasses = ['cmLine'];\n\tif (isFromSectionRepeat) {\n\t\tlineClasses.push('cmLine--isFromSectionRepeat');\n\t}\n\tif (isFromAutoRepeatChords) {\n\t\tlineClasses.push('cmLine--isFromAutoRepeatChords');\n\t}\n\tif (isFromChordLineRepeater) {\n\t\tlineClasses.push('cmLine--isFromChordLineRepeater');\n\t}\n\n\treturn lineTpl({\n\t\tline,\n\t\tlineClasses: lineClasses.join(' '),\n\t});\n}\n","import sectionLabelTpl from './tpl/sectionLabel.hbs';\n\nconst labelsMapping = {\n\ta: 'adlib',\n\tb: 'bridge',\n\tc: 'chorus',\n\ti: 'intro',\n\to: 'outro',\n\tp: 'pre-chorus',\n\ts: 'solo',\n\tu: 'interlude',\n\tv: 'verse',\n};\n\n/**\n * @param {SongSectionLabelLine} sectionLabelLine\n * @param {Boolean} expandSectionRepeats\n * @param {Object} sectionsStats - key = section label, value = section count in song\n * @returns {String} rendered html\n */\nexport default function renderSectionLabel(\n\tsectionLabelLine,\n\t{ expandSectionRepeats = true, sectionsStats = {} } = {}\n) {\n\tconst { model, index, indexWithoutRepeats } = sectionLabelLine;\n\tconst labelRaw = labelsMapping[model.label]\n\t\t? labelsMapping[model.label]\n\t\t: model.label;\n\n\tlet rendered = labelRaw[0].toUpperCase() + labelRaw.substring(1);\n\n\tif (sectionsStats[model.label] > 1) {\n\t\trendered += ' ';\n\t\trendered += expandSectionRepeats ? index : indexWithoutRepeats;\n\t}\n\n\tif (!expandSectionRepeats && model.repeatTimes) {\n\t\trendered += ' x' + model.repeatTimes;\n\t}\n\n\treturn sectionLabelTpl({ sectionLabel: rendered });\n}\n","import lyricLineTpl from './tpl/lyricLine.hbs';\n\n/**\n * @param {SongLyricLine} lyricLine\n * @returns {String} rendered html\n */\nexport default function render(lyricLine) {\n\treturn lyricLineTpl({ lyricLine: lyricLine.model.lyrics });\n}\n","import timeSignatureTpl from './tpl/timeSignature.hbs';\n\n/**\n * @param {SongTimeSignatureLine} timeSignatureLine\n * @returns {String} rendered html\n */\nexport default function render(timeSignatureLine) {\n\treturn timeSignatureTpl({ timeSignature: timeSignatureLine.string });\n}\n","import syntax from '../../parser/syntax';\nimport { chordRendererFactory } from 'chord-symbol';\n\nconst noChordSymbol = 'NC';\nconst defaultRenderChord = chordRendererFactory();\n\n/**\n * @param {Chord|String} model\n * @param {Function} renderChord\n * @returns {string}\n */\nexport default function (model, renderChord = defaultRenderChord) {\n\treturn model === syntax.noChord ? noChordSymbol : renderChord(model);\n}\n","import lineTypes from '../../parser/lineTypes';\n\n/**\n * Returns the number of usage of each section label\n *\n * @param {SongSectionLabelLine[]} allLines\n * @returns {Object} key = label, value = number of usage\n */\nexport default function getSectionsStats(allLines) {\n\tconst stats = {};\n\n\tallLines\n\t\t.filter((line) => line.type === lineTypes.SECTION_LABEL)\n\t\t.forEach((line) => {\n\t\t\tif (!stats[line.model.label]) {\n\t\t\t\tstats[line.model.label] = 1;\n\t\t\t} else {\n\t\t\t\tstats[line.model.label]++;\n\t\t\t}\n\t\t});\n\n\treturn stats;\n}\n","import syntax from '../../parser/syntax';\n\n/**\n * Returns the most used accidental of a song.\n *\n * @param {SongChord[]} allChords\n * @returns {('flat'|'sharp')}\n */\nexport default function getMainAccidental(allChords) {\n\tlet rootNote = '';\n\tlet flatCount = 0;\n\tlet sharpCount = 0;\n\n\tallChords\n\t\t.filter((chord) => chord.model !== syntax.noChord)\n\t\t.forEach((chord) => {\n\t\t\trootNote = chord.model.formatted.rootNote;\n\n\t\t\tif (rootNote.length === 2) {\n\t\t\t\tlet accidental = rootNote[1];\n\n\t\t\t\tif (accidental === 'b') {\n\t\t\t\t\tflatCount += chord.occurrences;\n\t\t\t\t} else {\n\t\t\t\t\tsharpCount += chord.occurrences;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\treturn flatCount > sharpCount ? 'flat' : 'sharp';\n}\n","import getMaxBeatsWidth from '../spacers/chord/getMaxBeatsWidth';\n\nimport simpleChordSpacer from '../spacers/chord/simple';\nimport alignedChordSpacer from '../spacers/chord/aligned';\nimport chordLyricsSpacer from '../spacers/chord/chordLyrics';\n\nimport { forEachChordInSong } from '../../parser/helper/songs';\n\nimport renderChordLineModel from './renderChordLine';\nimport renderEmptyLine from './renderEmptyLine';\nimport renderLine from './renderLine';\nimport renderSectionLabel from './renderSectionLabel';\nimport renderLyricLine from './renderLyricLine';\nimport renderTimeSignature from './renderTimeSignature';\n\nimport songTpl from './tpl/song.hbs';\nimport getChordSymbol from '../helpers/getChordSymbol';\nimport getSectionsStats from '../helpers/getSectionsStats';\nimport getMainAccidental from '../helpers/getMainAccidental';\n\nimport { chordRendererFactory } from 'chord-symbol';\n\nimport lineTypes from '../../parser/lineTypes';\n\n/**\n * @param {Song} parsedSong\n * @param {Boolean} alignBars\n * @param {Boolean} alignChordsWithLyrics\n * @param {Number} transposeValue\n * @param {('auto'|'flat'|'sharp')} accidentalsType\n * @param {Boolean} harmonizeAccidentals\n * @param {Boolean} expandSectionRepeats\n * @param {Boolean} autoRepeatChords\n * @param {Boolean|('max'|'core')} simplifyChords\n * @param {Boolean} useShortNamings\n * @returns {String} rendered HTML\n */\nexport default function renderSong(\n\tparsedSong,\n\t{\n\t\talignBars = false,\n\t\talignChordsWithLyrics = true,\n\t\ttransposeValue = 0,\n\t\taccidentalsType = 'auto',\n\t\tharmonizeAccidentals = true,\n\t\texpandSectionRepeats = true,\n\t\tautoRepeatChords = true,\n\t\tsimplifyChords = 'none',\n\t\tuseShortNamings = true,\n\t} = {}\n) {\n\tlet { allLines, allChords } = parsedSong;\n\n\tconst accidental =\n\t\taccidentalsType === 'auto'\n\t\t\t? getMainAccidental(allChords)\n\t\t\t: accidentalsType;\n\n\tconst renderChord = chordRendererFactory({\n\t\tsimplify: simplifyChords,\n\t\tuseShortNamings,\n\t\ttransposeValue,\n\t\tharmonizeAccidentals,\n\t\tuseFlats: accidental === 'flat',\n\t});\n\n\tallLines = forEachChordInSong(allLines, (chord) => {\n\t\tchord.symbol = getChordSymbol(chord.model, renderChord);\n\t});\n\n\tconst sectionsStats = getSectionsStats(allLines);\n\tconst maxBeatsWidth = getMaxBeatsWidth(allLines);\n\n\tlet shouldSkipRepeatedSectionLine = false;\n\n\tconst song = allLines\n\t\t.filter(shouldRenderLine)\n\t\t.map((line, lineIndex, allFilteredLines) => {\n\t\t\tlet rendered;\n\n\t\t\tif (line.type === lineTypes.CHORD) {\n\t\t\t\tlet spaced = alignBars\n\t\t\t\t\t? alignedChordSpacer(line.model, maxBeatsWidth)\n\t\t\t\t\t: simpleChordSpacer(line.model);\n\n\t\t\t\tconst nextLine = allFilteredLines[lineIndex + 1];\n\t\t\t\tif (shouldAlignChords(alignChordsWithLyrics, nextLine)) {\n\t\t\t\t\tconst { chordLine, lyricsLine } = chordLyricsSpacer(\n\t\t\t\t\t\tspaced,\n\t\t\t\t\t\tnextLine.model\n\t\t\t\t\t);\n\t\t\t\t\tallFilteredLines[lineIndex + 1].model = lyricsLine;\n\t\t\t\t\tspaced = chordLine;\n\t\t\t\t}\n\n\t\t\t\trendered = renderChordLineModel(spaced);\n\t\t\t} else if (line.type === lineTypes.EMPTY_LINE) {\n\t\t\t\trendered = renderEmptyLine();\n\t\t\t} else if (line.type === lineTypes.SECTION_LABEL) {\n\t\t\t\trendered = renderSectionLabel(line, {\n\t\t\t\t\tsectionsStats,\n\t\t\t\t\texpandSectionRepeats,\n\t\t\t\t});\n\t\t\t} else if (line.type === lineTypes.TIME_SIGNATURE) {\n\t\t\t\trendered = renderTimeSignature(line);\n\t\t\t} else {\n\t\t\t\trendered = renderLyricLine(line);\n\t\t\t}\n\t\t\treturn renderLine(rendered, {\n\t\t\t\tisFromSectionRepeat: line.isFromSectionRepeat,\n\t\t\t\tisFromAutoRepeatChords: line.isFromAutoRepeatChords,\n\t\t\t\tisFromChordLineRepeater: line.isFromChordLineRepeater,\n\t\t\t});\n\t\t})\n\t\t.filter(Boolean)\n\t\t.join('\\n');\n\n\tfunction shouldRenderLine(line) {\n\t\tif (line.type === lineTypes.SECTION_LABEL) {\n\t\t\tshouldSkipRepeatedSectionLine =\n\t\t\t\tline.isFromSectionRepeat === true && !expandSectionRepeats;\n\t\t}\n\t\tconst shouldSkipAutoRepeatChordLine =\n\t\t\tline.isFromAutoRepeatChords && !autoRepeatChords;\n\n\t\treturn !shouldSkipRepeatedSectionLine && !shouldSkipAutoRepeatChordLine;\n\t}\n\n\treturn songTpl({ song });\n}\n\nfunction shouldAlignChords(alignChordsWithLyrics, nextLine) {\n\treturn (\n\t\talignChordsWithLyrics && nextLine && nextLine.type === lineTypes.LYRIC\n\t);\n}\n","import parseSong from './parser/parseSong';\nimport renderSong from './renderer/components/renderSong';\n\nexport { parseSong, renderSong };\n"],"names":["domPurify","escapeHTML","unescaped","sanitize","stripTags","html","ALLOWED_TAGS","KEEP_CONTENT","CHORD","CHORD_LINE_REPEATER","EMPTY_LINE","LYRIC","SECTION_LABEL","TIME_SIGNATURE","allowedTimeSignatures","isTimeSignatureString","string","includes","barRepeat","chordBeatCount","chordLineRepeat","noChord","noLyrics","sectionLabel","chordPositionMarker","syntax","sectionLabelRegexp","RegExp","isSectionLabel","found","trim","match","clearSpaces","replace","chordParserFactory","isChord","potentialChord","parseChord","parsed","error","chordBeatCountSymbols","barRepeatSymbols","isChordLine","line","split","every","potentialChordToken","index","withoutBeatCount","isChordLineRepeater","isEmptyLine","parseTimeSignature","TypeError","array","count","Number","parseInt","value","beatCount","parseChordWrapper","chordString","_isString","_isFinite","IncorrectBeatCountException","duration","currentBeatCount","name","Error","InvalidChordRepetitionException","_isEqual","_cloneDeep","defaultTimeSignature","parseChordLine","chordLine","timeSignature","allBars","emptyBar","allChords","bar","chord","tokenWithoutBeatCount","chordCount","previousBar","allTokens","forEach","token","tokenIndex","i","length","push","getChordDuration","model","isNoChordSymbol","beat","checkInvalidChordRepetition","shouldChangeBar","barClone","checkInvalidBeatCount","currentChord","previousChord","isLast","hasInvalidBeatCount","message","barBeatCount","hasTooManyBeats","hasTooFewBeats","parseSectionLabel","labelSrc","repeatSrc","label","substring","repeatTimes","parseLyricLine","regexp","stringWithoutPositionMarkers","chordPositions","tmpString","position","indexOf","lyrics","lineTypes","forEachChordInSong","allLines","fn","newLines","type","forEachChordInChordLine","newChordLine","barIndex","chordIndex","getNthOfLabel","n","selected","typesCount","enableSelect","currentLabel","id","isTimeSignature","songLinesFactory","sectionsStats","currentTimeSignature","currentSectionLabel","currentSectionStats","previousChordLine","previousSectionLabelLine","blueprint","blueprintIndex","blueprintLine","isRepeatingChords","shouldRepeatSection","getTimeSignatureLine","getSectionLabelLine","increaseSectionStats","getSectionCount","indexWithoutRepeats","withoutRepeats","isFirstOfLabel","getEmptyLine","getChordLine","e","getLyricLine","getPreviousChordLine","isFromChordLineRepeater","isRepeated","repeatLinesFromBlueprint","repeatedLine","shouldRepeatLineFromBlueprint","isFromAutoRepeatChords","repeatSection","lineIndex","allSrcLines","isLastLineOfSection","toRepeat","map","isFromSectionRepeat","sectionLabelLine","addLine","lineSrc","asArray","currentLine","nextLine","_findIndex","getAllChordsInSong","o","occurrences","_isArray","parseSong","songSrc","songArray","songLines","getMaxBeatsWidth","maxBeatsWidth","filter","Math","max","symbol","defaultSpacesAfter","allMasks","space","chordLineInput","chordPattern","chordSpaces","toString","spacesAfter","spacesAfterDefault","emptyBeatSpaces","beatMaxWidth","spacesWithin","lyricsSpacer","chordLineOffsetSpacer","barSeparator","symbols","chordSpaceAfterDefault","lyricsLineInput","lyricsLine","hasNoPositionMarkers","tokenizedLyrics","allPositions","spacedLyricsLine","chordToken","lyricToken","currentBarIndex","spacedChordLine","shift","isFirstChord","isNewBar","startsWithSpace","repeat","lyricsSpaceAfter","shouldOffsetChordLine","chordLineOffset","offset","join","trimEnd","str","endWhitespace","chordSymbolTpl","renderChordSymbol","chordSymbol","renderChord","barContentTpl","defaultSpacesWithin","renderBarContent","barContent","reduce","rendering","chordLineTpl","barSeparatorTpl","renderChordLine","chordLineModel","allBarsRendered","emptyLineTpl","render","lineTpl","lineClasses","sectionLabelTpl","labelsMapping","a","b","c","p","s","u","v","renderSectionLabel","expandSectionRepeats","labelRaw","rendered","toUpperCase","lyricLineTpl","lyricLine","timeSignatureTpl","timeSignatureLine","chordRendererFactory","noChordSymbol","defaultRenderChord","getSectionsStats","stats","getMainAccidental","rootNote","flatCount","sharpCount","formatted","accidental","simpleChordSpacer","alignedChordSpacer","chordLyricsSpacer","renderChordLineModel","renderEmptyLine","renderLine","renderLyricLine","renderTimeSignature","songTpl","getChordSymbol","renderSong","parsedSong","alignBars","alignChordsWithLyrics","transposeValue","accidentalsType","harmonizeAccidentals","autoRepeatChords","simplifyChords","useShortNamings","simplify","useFlats","shouldSkipRepeatedSectionLine","song","shouldRenderLine","allFilteredLines","spaced","shouldAlignChords","Boolean","shouldSkipAutoRepeatChordLine"],"sourceRoot":""}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 1aca5314..75fd84c0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,9 +5,9 @@
"requires": true,
"dependencies": {
"@babel/cli": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.14.5.tgz",
- "integrity": "sha512-poegjhRvXHWO0EAsnYajwYZuqcz7gyfxwfaecUESxDujrqOivf3zrjFbub8IJkrqEaz3fvJWh001EzxBub54fg==",
+ "version": "7.14.8",
+ "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.14.8.tgz",
+ "integrity": "sha512-lcy6Lymft9Rpfqmrqdd4oTDdUx9ZwaAhAfywVrHG4771Pa6PPT0danJ1kDHBXYqh4HHSmIdA+nlmfxfxSDPtBg==",
"dev": true,
"requires": {
"@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.2",
@@ -39,26 +39,26 @@
}
},
"@babel/compat-data": {
- "version": "7.14.7",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz",
- "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz",
+ "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==",
"dev": true
},
"@babel/core": {
- "version": "7.14.6",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz",
- "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz",
+ "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.14.5",
- "@babel/generator": "^7.14.5",
- "@babel/helper-compilation-targets": "^7.14.5",
- "@babel/helper-module-transforms": "^7.14.5",
- "@babel/helpers": "^7.14.6",
- "@babel/parser": "^7.14.6",
+ "@babel/generator": "^7.15.0",
+ "@babel/helper-compilation-targets": "^7.15.0",
+ "@babel/helper-module-transforms": "^7.15.0",
+ "@babel/helpers": "^7.14.8",
+ "@babel/parser": "^7.15.0",
"@babel/template": "^7.14.5",
- "@babel/traverse": "^7.14.5",
- "@babel/types": "^7.14.5",
+ "@babel/traverse": "^7.15.0",
+ "@babel/types": "^7.15.0",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -97,12 +97,12 @@
}
},
"@babel/generator": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
- "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz",
+ "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==",
"dev": true,
"requires": {
- "@babel/types": "^7.14.5",
+ "@babel/types": "^7.15.0",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
},
@@ -135,12 +135,12 @@
}
},
"@babel/helper-compilation-targets": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz",
- "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz",
+ "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==",
"dev": true,
"requires": {
- "@babel/compat-data": "^7.14.5",
+ "@babel/compat-data": "^7.15.0",
"@babel/helper-validator-option": "^7.14.5",
"browserslist": "^4.16.6",
"semver": "^6.3.0"
@@ -155,16 +155,16 @@
}
},
"@babel/helper-create-class-features-plugin": {
- "version": "7.14.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz",
- "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.0.tgz",
+ "integrity": "sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.14.5",
"@babel/helper-function-name": "^7.14.5",
- "@babel/helper-member-expression-to-functions": "^7.14.5",
+ "@babel/helper-member-expression-to-functions": "^7.15.0",
"@babel/helper-optimise-call-expression": "^7.14.5",
- "@babel/helper-replace-supers": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.15.0",
"@babel/helper-split-export-declaration": "^7.14.5"
}
},
@@ -256,12 +256,12 @@
}
},
"@babel/helper-member-expression-to-functions": {
- "version": "7.14.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz",
- "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz",
+ "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==",
"dev": true,
"requires": {
- "@babel/types": "^7.14.5"
+ "@babel/types": "^7.15.0"
}
},
"@babel/helper-module-imports": {
@@ -274,19 +274,27 @@
}
},
"@babel/helper-module-transforms": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz",
- "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz",
+ "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.14.5",
- "@babel/helper-replace-supers": "^7.14.5",
- "@babel/helper-simple-access": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.15.0",
+ "@babel/helper-simple-access": "^7.14.8",
"@babel/helper-split-export-declaration": "^7.14.5",
- "@babel/helper-validator-identifier": "^7.14.5",
+ "@babel/helper-validator-identifier": "^7.14.9",
"@babel/template": "^7.14.5",
- "@babel/traverse": "^7.14.5",
- "@babel/types": "^7.14.5"
+ "@babel/traverse": "^7.15.0",
+ "@babel/types": "^7.15.0"
+ },
+ "dependencies": {
+ "@babel/helper-validator-identifier": {
+ "version": "7.14.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz",
+ "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==",
+ "dev": true
+ }
}
},
"@babel/helper-optimise-call-expression": {
@@ -316,24 +324,24 @@
}
},
"@babel/helper-replace-supers": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz",
- "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz",
+ "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==",
"dev": true,
"requires": {
- "@babel/helper-member-expression-to-functions": "^7.14.5",
+ "@babel/helper-member-expression-to-functions": "^7.15.0",
"@babel/helper-optimise-call-expression": "^7.14.5",
- "@babel/traverse": "^7.14.5",
- "@babel/types": "^7.14.5"
+ "@babel/traverse": "^7.15.0",
+ "@babel/types": "^7.15.0"
}
},
"@babel/helper-simple-access": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz",
- "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==",
+ "version": "7.14.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz",
+ "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==",
"dev": true,
"requires": {
- "@babel/types": "^7.14.5"
+ "@babel/types": "^7.14.8"
}
},
"@babel/helper-skip-transparent-expression-wrappers": {
@@ -379,14 +387,14 @@
}
},
"@babel/helpers": {
- "version": "7.14.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz",
- "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.3.tgz",
+ "integrity": "sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==",
"dev": true,
"requires": {
"@babel/template": "^7.14.5",
- "@babel/traverse": "^7.14.5",
- "@babel/types": "^7.14.5"
+ "@babel/traverse": "^7.15.0",
+ "@babel/types": "^7.15.0"
}
},
"@babel/highlight": {
@@ -401,9 +409,9 @@
}
},
"@babel/parser": {
- "version": "7.14.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
- "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz",
+ "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==",
"dev": true
},
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
@@ -418,9 +426,9 @@
}
},
"@babel/plugin-proposal-async-generator-functions": {
- "version": "7.14.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz",
- "integrity": "sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q==",
+ "version": "7.14.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.9.tgz",
+ "integrity": "sha512-d1lnh+ZnKrFKwtTYdw320+sQWCTwgkB9fmUhNXRADA4akR6wLjaruSGnIEUjpt9HCOwTr4ynFTKu19b7rFRpmw==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.14.5",
@@ -758,18 +766,18 @@
}
},
"@babel/plugin-transform-block-scoping": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz",
- "integrity": "sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz",
+ "integrity": "sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-classes": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz",
- "integrity": "sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA==",
+ "version": "7.14.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.9.tgz",
+ "integrity": "sha512-NfZpTcxU3foGWbl4wxmZ35mTsYJy8oQocbeIMoDAGGFarAmSQlL+LWMkDx/tj6pNotpbX3rltIA4dprgAPOq5A==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.14.5",
@@ -877,14 +885,14 @@
}
},
"@babel/plugin-transform-modules-commonjs": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz",
- "integrity": "sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.0.tgz",
+ "integrity": "sha512-3H/R9s8cXcOGE8kgMlmjYYC9nqr5ELiPkJn4q0mypBrjhYQoc+5/Maq69vV4xRPWnkzZuwJPf5rArxpB/35Cig==",
"dev": true,
"requires": {
- "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helper-module-transforms": "^7.15.0",
"@babel/helper-plugin-utils": "^7.14.5",
- "@babel/helper-simple-access": "^7.14.5",
+ "@babel/helper-simple-access": "^7.14.8",
"babel-plugin-dynamic-import-node": "^2.3.3"
}
},
@@ -912,9 +920,9 @@
}
},
"@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.14.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz",
- "integrity": "sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg==",
+ "version": "7.14.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz",
+ "integrity": "sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==",
"dev": true,
"requires": {
"@babel/helper-create-regexp-features-plugin": "^7.14.5"
@@ -1041,17 +1049,17 @@
}
},
"@babel/preset-env": {
- "version": "7.14.7",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.7.tgz",
- "integrity": "sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.0.tgz",
+ "integrity": "sha512-FhEpCNFCcWW3iZLg0L2NPE9UerdtsCR6ZcsGHUX6Om6kbCQeL5QZDqFDmeNHC6/fy6UH3jEge7K4qG5uC9In0Q==",
"dev": true,
"requires": {
- "@babel/compat-data": "^7.14.7",
- "@babel/helper-compilation-targets": "^7.14.5",
+ "@babel/compat-data": "^7.15.0",
+ "@babel/helper-compilation-targets": "^7.15.0",
"@babel/helper-plugin-utils": "^7.14.5",
"@babel/helper-validator-option": "^7.14.5",
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.14.5",
- "@babel/plugin-proposal-async-generator-functions": "^7.14.7",
+ "@babel/plugin-proposal-async-generator-functions": "^7.14.9",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-class-static-block": "^7.14.5",
"@babel/plugin-proposal-dynamic-import": "^7.14.5",
@@ -1084,7 +1092,7 @@
"@babel/plugin-transform-async-to-generator": "^7.14.5",
"@babel/plugin-transform-block-scoped-functions": "^7.14.5",
"@babel/plugin-transform-block-scoping": "^7.14.5",
- "@babel/plugin-transform-classes": "^7.14.5",
+ "@babel/plugin-transform-classes": "^7.14.9",
"@babel/plugin-transform-computed-properties": "^7.14.5",
"@babel/plugin-transform-destructuring": "^7.14.7",
"@babel/plugin-transform-dotall-regex": "^7.14.5",
@@ -1095,10 +1103,10 @@
"@babel/plugin-transform-literals": "^7.14.5",
"@babel/plugin-transform-member-expression-literals": "^7.14.5",
"@babel/plugin-transform-modules-amd": "^7.14.5",
- "@babel/plugin-transform-modules-commonjs": "^7.14.5",
+ "@babel/plugin-transform-modules-commonjs": "^7.15.0",
"@babel/plugin-transform-modules-systemjs": "^7.14.5",
"@babel/plugin-transform-modules-umd": "^7.14.5",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.7",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.9",
"@babel/plugin-transform-new-target": "^7.14.5",
"@babel/plugin-transform-object-super": "^7.14.5",
"@babel/plugin-transform-parameters": "^7.14.5",
@@ -1113,11 +1121,11 @@
"@babel/plugin-transform-unicode-escapes": "^7.14.5",
"@babel/plugin-transform-unicode-regex": "^7.14.5",
"@babel/preset-modules": "^0.1.4",
- "@babel/types": "^7.14.5",
+ "@babel/types": "^7.15.0",
"babel-plugin-polyfill-corejs2": "^0.2.2",
"babel-plugin-polyfill-corejs3": "^0.2.2",
"babel-plugin-polyfill-regenerator": "^0.2.2",
- "core-js-compat": "^3.15.0",
+ "core-js-compat": "^3.16.0",
"semver": "^6.3.0"
},
"dependencies": {
@@ -1143,9 +1151,9 @@
}
},
"@babel/runtime": {
- "version": "7.14.6",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz",
- "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"dev": true,
"requires": {
"regenerator-runtime": "^0.13.4"
@@ -1163,18 +1171,18 @@
}
},
"@babel/traverse": {
- "version": "7.14.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
- "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz",
+ "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.14.5",
- "@babel/generator": "^7.14.5",
+ "@babel/generator": "^7.15.0",
"@babel/helper-function-name": "^7.14.5",
"@babel/helper-hoist-variables": "^7.14.5",
"@babel/helper-split-export-declaration": "^7.14.5",
- "@babel/parser": "^7.14.7",
- "@babel/types": "^7.14.5",
+ "@babel/parser": "^7.15.0",
+ "@babel/types": "^7.15.0",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
@@ -1197,13 +1205,21 @@
}
},
"@babel/types": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
- "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz",
+ "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.5",
+ "@babel/helper-validator-identifier": "^7.14.9",
"to-fast-properties": "^2.0.0"
+ },
+ "dependencies": {
+ "@babel/helper-validator-identifier": {
+ "version": "7.14.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz",
+ "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==",
+ "dev": true
+ }
}
},
"@bcoe/v8-coverage": {
@@ -1219,9 +1235,9 @@
"dev": true
},
"@eslint/eslintrc": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz",
- "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==",
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
+ "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
@@ -1245,9 +1261,9 @@
}
},
"globals": {
- "version": "13.9.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz",
- "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==",
+ "version": "13.11.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz",
+ "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
@@ -1341,12 +1357,6 @@
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
- },
- "resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true
}
}
},
@@ -1357,16 +1367,16 @@
"dev": true
},
"@jest/console": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.6.tgz",
- "integrity": "sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.1.0.tgz",
+ "integrity": "sha512-+Vl+xmLwAXLNlqT61gmHEixeRbS4L8MUzAjtpBCOPWH+izNI/dR16IeXjkXJdRtIVWVSf9DO1gdp67B1XorZhQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"@types/node": "*",
"chalk": "^4.0.0",
- "jest-message-util": "^27.0.6",
- "jest-util": "^27.0.6",
+ "jest-message-util": "^27.1.0",
+ "jest-util": "^27.1.0",
"slash": "^3.0.0"
},
"dependencies": {
@@ -1380,9 +1390,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -1428,35 +1438,35 @@
}
},
"@jest/core": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.0.6.tgz",
- "integrity": "sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.1.0.tgz",
+ "integrity": "sha512-3l9qmoknrlCFKfGdrmiQiPne+pUR4ALhKwFTYyOeKw6egfDwJkO21RJ1xf41rN8ZNFLg5W+w6+P4fUqq4EMRWA==",
"dev": true,
"requires": {
- "@jest/console": "^27.0.6",
- "@jest/reporters": "^27.0.6",
- "@jest/test-result": "^27.0.6",
- "@jest/transform": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/console": "^27.1.0",
+ "@jest/reporters": "^27.1.0",
+ "@jest/test-result": "^27.1.0",
+ "@jest/transform": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
"emittery": "^0.8.1",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
- "jest-changed-files": "^27.0.6",
- "jest-config": "^27.0.6",
- "jest-haste-map": "^27.0.6",
- "jest-message-util": "^27.0.6",
+ "jest-changed-files": "^27.1.0",
+ "jest-config": "^27.1.0",
+ "jest-haste-map": "^27.1.0",
+ "jest-message-util": "^27.1.0",
"jest-regex-util": "^27.0.6",
- "jest-resolve": "^27.0.6",
- "jest-resolve-dependencies": "^27.0.6",
- "jest-runner": "^27.0.6",
- "jest-runtime": "^27.0.6",
- "jest-snapshot": "^27.0.6",
- "jest-util": "^27.0.6",
- "jest-validate": "^27.0.6",
- "jest-watcher": "^27.0.6",
+ "jest-resolve": "^27.1.0",
+ "jest-resolve-dependencies": "^27.1.0",
+ "jest-runner": "^27.1.0",
+ "jest-runtime": "^27.1.0",
+ "jest-snapshot": "^27.1.0",
+ "jest-util": "^27.1.0",
+ "jest-validate": "^27.1.0",
+ "jest-watcher": "^27.1.0",
"micromatch": "^4.0.4",
"p-each-series": "^2.1.0",
"rimraf": "^3.0.0",
@@ -1483,9 +1493,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -1565,53 +1575,53 @@
}
},
"@jest/environment": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.6.tgz",
- "integrity": "sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.1.0.tgz",
+ "integrity": "sha512-wRp50aAMY2w1U2jP1G32d6FUVBNYqmk8WaGkiIEisU48qyDV0WPtw3IBLnl7orBeggveommAkuijY+RzVnNDOQ==",
"dev": true,
"requires": {
- "@jest/fake-timers": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/fake-timers": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/node": "*",
- "jest-mock": "^27.0.6"
+ "jest-mock": "^27.1.0"
}
},
"@jest/fake-timers": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.6.tgz",
- "integrity": "sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.1.0.tgz",
+ "integrity": "sha512-22Zyn8il8DzpS+30jJNVbTlm7vAtnfy1aYvNeOEHloMlGy1PCYLHa4PWlSws0hvNsMM5bON6GISjkLoQUV3oMA==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"@sinonjs/fake-timers": "^7.0.2",
"@types/node": "*",
- "jest-message-util": "^27.0.6",
- "jest-mock": "^27.0.6",
- "jest-util": "^27.0.6"
+ "jest-message-util": "^27.1.0",
+ "jest-mock": "^27.1.0",
+ "jest-util": "^27.1.0"
}
},
"@jest/globals": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.6.tgz",
- "integrity": "sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.1.0.tgz",
+ "integrity": "sha512-73vLV4aNHAlAgjk0/QcSIzzCZSqVIPbmFROJJv9D3QUR7BI4f517gVdJpSrCHxuRH3VZFhe0yGG/tmttlMll9g==",
"dev": true,
"requires": {
- "@jest/environment": "^27.0.6",
- "@jest/types": "^27.0.6",
- "expect": "^27.0.6"
+ "@jest/environment": "^27.1.0",
+ "@jest/types": "^27.1.0",
+ "expect": "^27.1.0"
}
},
"@jest/reporters": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.0.6.tgz",
- "integrity": "sha512-TIkBt09Cb2gptji3yJXb3EE+eVltW6BjO7frO7NEfjI9vSIYoISi5R3aI3KpEDXlB1xwB+97NXIqz84qYeYsfA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.1.0.tgz",
+ "integrity": "sha512-5T/zlPkN2HnK3Sboeg64L5eC8iiaZueLpttdktWTJsvALEtP2YMkC5BQxwjRWQACG9SwDmz+XjjkoxXUDMDgdw==",
"dev": true,
"requires": {
"@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^27.0.6",
- "@jest/test-result": "^27.0.6",
- "@jest/transform": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/console": "^27.1.0",
+ "@jest/test-result": "^27.1.0",
+ "@jest/transform": "^27.1.0",
+ "@jest/types": "^27.1.0",
"chalk": "^4.0.0",
"collect-v8-coverage": "^1.0.0",
"exit": "^0.1.2",
@@ -1622,10 +1632,10 @@
"istanbul-lib-report": "^3.0.0",
"istanbul-lib-source-maps": "^4.0.0",
"istanbul-reports": "^3.0.2",
- "jest-haste-map": "^27.0.6",
- "jest-resolve": "^27.0.6",
- "jest-util": "^27.0.6",
- "jest-worker": "^27.0.6",
+ "jest-haste-map": "^27.1.0",
+ "jest-resolve": "^27.1.0",
+ "jest-util": "^27.1.0",
+ "jest-worker": "^27.1.0",
"slash": "^3.0.0",
"source-map": "^0.6.0",
"string-length": "^4.0.1",
@@ -1643,9 +1653,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -1702,45 +1712,45 @@
}
},
"@jest/test-result": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.6.tgz",
- "integrity": "sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.1.0.tgz",
+ "integrity": "sha512-Aoz00gpDL528ODLghat3QSy6UBTD5EmmpjrhZZMK/v1Q2/rRRqTGnFxHuEkrD4z/Py96ZdOHxIWkkCKRpmnE1A==",
"dev": true,
"requires": {
- "@jest/console": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/console": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/istanbul-lib-coverage": "^2.0.0",
"collect-v8-coverage": "^1.0.0"
}
},
"@jest/test-sequencer": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz",
- "integrity": "sha512-bISzNIApazYOlTHDum9PwW22NOyDa6VI31n6JucpjTVM0jD6JDgqEZ9+yn575nDdPF0+4csYDxNNW13NvFQGZA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.1.0.tgz",
+ "integrity": "sha512-lnCWawDr6Z1DAAK9l25o3AjmKGgcutq1iIbp+hC10s/HxnB8ZkUsYq1FzjOoxxZ5hW+1+AthBtvS4x9yno3V1A==",
"dev": true,
"requires": {
- "@jest/test-result": "^27.0.6",
+ "@jest/test-result": "^27.1.0",
"graceful-fs": "^4.2.4",
- "jest-haste-map": "^27.0.6",
- "jest-runtime": "^27.0.6"
+ "jest-haste-map": "^27.1.0",
+ "jest-runtime": "^27.1.0"
}
},
"@jest/transform": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.6.tgz",
- "integrity": "sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.1.0.tgz",
+ "integrity": "sha512-ZRGCA2ZEVJ00ubrhkTG87kyLbN6n55g1Ilq0X9nJb5bX3MhMp3O6M7KG+LvYu+nZRqG5cXsQnJEdZbdpTAV8pQ==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"babel-plugin-istanbul": "^6.0.0",
"chalk": "^4.0.0",
"convert-source-map": "^1.4.0",
"fast-json-stable-stringify": "^2.0.0",
"graceful-fs": "^4.2.4",
- "jest-haste-map": "^27.0.6",
+ "jest-haste-map": "^27.1.0",
"jest-regex-util": "^27.0.6",
- "jest-util": "^27.0.6",
+ "jest-util": "^27.1.0",
"micromatch": "^4.0.4",
"pirates": "^4.0.1",
"slash": "^3.0.0",
@@ -1767,9 +1777,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -1849,9 +1859,9 @@
}
},
"@jest/types": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
- "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.1.0.tgz",
+ "integrity": "sha512-pRP5cLIzN7I7Vp6mHKRSaZD7YpBTK7hawx5si8trMKqk4+WOdK8NEKOTO2G8PKWD1HbKMVckVB6/XHh/olhf2g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -1871,9 +1881,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -1949,9 +1959,9 @@
"dev": true
},
"@nodelib/fs.walk": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz",
- "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==",
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dev": true,
"requires": {
"@nodelib/fs.scandir": "2.1.5",
@@ -1983,9 +1993,9 @@
}
},
"@size-limit/file": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@size-limit/file/-/file-5.0.1.tgz",
- "integrity": "sha512-BgbGFdFwijuR6tZRlmUoN3UzOIN+dt+28hzsYKjTl1LOn4zUJjTWgTCye11Qygj5L6+MkDZOA1ppEm4ZfjPgmQ==",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@size-limit/file/-/file-5.0.3.tgz",
+ "integrity": "sha512-tkxf5ntFdlZ1xHQAw4fYd+gIkH85S2D3Wb94upJhtOfPHwDsQoQycDFGQRwTgei07Eq5vA8Jj5f2mu/tAdoaXw==",
"dev": true,
"requires": {
"semver": "7.3.5"
@@ -2003,28 +2013,28 @@
}
},
"@size-limit/preset-small-lib": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@size-limit/preset-small-lib/-/preset-small-lib-5.0.1.tgz",
- "integrity": "sha512-pscQMfUIiTQQ1VzsjNt+O70tr6NPVSK5UThdzWpAxikUF04ABQandQvhAFrOymGjx4CKcLva6ZGPibZ6uKL9RQ==",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@size-limit/preset-small-lib/-/preset-small-lib-5.0.3.tgz",
+ "integrity": "sha512-kQHU5s+DYHG2RIB8Bjm7qoxLpAt/HCr3zYS7d/1SUa1LTP44oxe3DaxBvs69Qg4+VplEh5LfEOOzzNZk3Tx4Ow==",
"dev": true,
"requires": {
- "@size-limit/file": "5.0.1",
- "@size-limit/webpack": "5.0.1"
+ "@size-limit/file": "5.0.3",
+ "@size-limit/webpack": "5.0.3"
}
},
"@size-limit/webpack": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@size-limit/webpack/-/webpack-5.0.1.tgz",
- "integrity": "sha512-dG/H0GRc4P5Dc3KRjaQBq7EfGiOqGDw/eTBdkzvd2VnELl7DFcgoC1hULu9Y0XL50Ha+dGQ1AtNKWsZ3dacH/Q==",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@size-limit/webpack/-/webpack-5.0.3.tgz",
+ "integrity": "sha512-G8UutozNS3jfG2AyKdeHsYeYJ0jXBfHdzzhVUi1zuv6B+HvCDExE0cnbnIAhLyGNp1uTY/miOHLyCKQsxold/g==",
"dev": true,
"requires": {
"css-loader": "^5.2.6",
"escape-string-regexp": "^4.0.0",
"file-loader": "^6.2.0",
"mkdirp": "^1.0.4",
- "nanoid": "^3.1.23",
+ "nanoid": "^3.1.25",
"optimize-css-assets-webpack-plugin": "^6.0.1",
- "pnp-webpack-plugin": "^1.6.4",
+ "pnp-webpack-plugin": "^1.7.0",
"style-loader": "^2.0.0",
"webpack": "^4.44.1",
"webpack-bundle-analyzer": "^4.4.2"
@@ -2124,9 +2134,9 @@
"dev": true
},
"@types/babel__core": {
- "version": "7.1.14",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz",
- "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==",
+ "version": "7.1.15",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz",
+ "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==",
"dev": true,
"requires": {
"@babel/parser": "^7.1.0",
@@ -2137,18 +2147,18 @@
}
},
"@types/babel__generator": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz",
- "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz",
+ "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0"
}
},
"@types/babel__template": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz",
- "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+ "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
"dev": true,
"requires": {
"@babel/parser": "^7.1.0",
@@ -2156,18 +2166,18 @@
}
},
"@types/babel__traverse": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.0.tgz",
- "integrity": "sha512-IilJZ1hJBUZwMOVDNTdflOOLzJB/ZtljYVa7k3gEZN/jqIJIPkWHC6dvbX+DD2CwZDHB9wAKzZPzzqMIkW37/w==",
+ "version": "7.14.2",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz",
+ "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==",
"dev": true,
"requires": {
"@babel/types": "^7.3.0"
}
},
"@types/eslint": {
- "version": "7.2.13",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.13.tgz",
- "integrity": "sha512-LKmQCWAlnVHvvXq4oasNUMTJJb2GwSyTY8+1C7OH5ILR8mPLaljv1jxL1bXW3xB3jFbQxTKxJAvI8PyjB09aBg==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.0.tgz",
+ "integrity": "sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A==",
"dev": true,
"requires": {
"@types/estree": "*",
@@ -2175,9 +2185,9 @@
}
},
"@types/eslint-scope": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz",
- "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==",
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz",
+ "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==",
"dev": true,
"requires": {
"@types/eslint": "*",
@@ -2185,9 +2195,9 @@
}
},
"@types/estree": {
- "version": "0.0.48",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz",
- "integrity": "sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==",
+ "version": "0.0.50",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
+ "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
"dev": true
},
"@types/glob": {
@@ -2269,16 +2279,10 @@
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
"dev": true
},
- "@types/parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
- "dev": true
- },
"@types/prettier": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.1.tgz",
- "integrity": "sha512-NVkb4p4YjI8E3O6+1m8I+8JlMpFZwfSbPGdaw0wXuyPRTEz0SLKwBUWNSO7Maoi8tQMPC8JLZNWkrcKPI7/sLA==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz",
+ "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==",
"dev": true
},
"@types/source-list-map": {
@@ -2422,26 +2426,26 @@
}
},
"@webassemblyjs/helper-numbers": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz",
- "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
+ "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
"dev": true,
"requires": {
- "@webassemblyjs/floating-point-hex-parser": "1.11.0",
- "@webassemblyjs/helper-api-error": "1.11.0",
+ "@webassemblyjs/floating-point-hex-parser": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
"@xtuc/long": "4.2.2"
},
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz",
- "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
+ "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
"dev": true
},
"@webassemblyjs/helper-api-error": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz",
- "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
+ "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
"dev": true
}
}
@@ -2584,9 +2588,9 @@
}
},
"@webpack-cli/serve": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.1.tgz",
- "integrity": "sha512-4vSVUiOPJLmr45S8rMGy7WDvpWxfFxfP/Qx/cxZFCfvoypTYpPPL1X8VIZMe0WTA+Jr7blUxwUSEZNkjoMTgSw==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.2.tgz",
+ "integrity": "sha512-vgJ5OLWadI8aKjDlOH3rb+dYyPd2GTZuQC/Tihjct6F9GpXGZINo3Y/IVuZVTM1eDQB+/AOsjPUWH/WySDaXvw==",
"dev": true
},
"@xtuc/ieee754": {
@@ -2643,10 +2647,16 @@
}
}
},
+ "acorn-import-assertions": {
+ "version": "1.7.6",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz",
+ "integrity": "sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==",
+ "dev": true
+ },
"acorn-jsx": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
- "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true
},
"acorn-walk": {
@@ -2990,13 +3000,13 @@
"dev": true
},
"babel-jest": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.6.tgz",
- "integrity": "sha512-iTJyYLNc4wRofASmofpOc5NK9QunwMk+TLFgGXsTFS8uEqmd8wdI7sga0FPe2oVH3b5Agt/EAK1QjPEuKL8VfA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.1.0.tgz",
+ "integrity": "sha512-6NrdqzaYemALGCuR97QkC/FkFIEBWP5pw5TMJoUHZTVXyOgocujp6A0JE2V6gE0HtqAAv6VKU/nI+OCR1Z4gHA==",
"dev": true,
"requires": {
- "@jest/transform": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/transform": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/babel__core": "^7.1.14",
"babel-plugin-istanbul": "^6.0.0",
"babel-preset-jest": "^27.0.6",
@@ -3015,9 +3025,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -3230,9 +3240,9 @@
}
},
"babel-plugin-polyfill-corejs3": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz",
- "integrity": "sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g==",
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.4.tgz",
+ "integrity": "sha512-z3HnJE5TY/j4EFEa/qpQMSbcUJZ5JQi+3UFjXzn6pQCmIKc5Ug5j98SuYyH+m4xQnvKlMDIW4plLfgyVnd0IcQ==",
"dev": true,
"requires": {
"@babel/helper-define-polyfill-provider": "^0.2.2",
@@ -3539,16 +3549,16 @@
}
},
"browserslist": {
- "version": "4.16.6",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
- "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+ "version": "4.16.8",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz",
+ "integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==",
"dev": true,
"requires": {
- "caniuse-lite": "^1.0.30001219",
- "colorette": "^1.2.2",
- "electron-to-chromium": "^1.3.723",
+ "caniuse-lite": "^1.0.30001251",
+ "colorette": "^1.3.0",
+ "electron-to-chromium": "^1.3.811",
"escalade": "^3.1.1",
- "node-releases": "^1.1.71"
+ "node-releases": "^1.1.75"
}
},
"bser": {
@@ -3572,9 +3582,9 @@
}
},
"buffer-from": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
"buffer-xor": {
@@ -3716,9 +3726,9 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001242",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001242.tgz",
- "integrity": "sha512-KvNuZ/duufelMB3w2xtf9gEWCSxJwUgoxOx5b6ScLXC4kPc9xsczUVCPrQU26j5kOsHM4pSUL54tAZt5THQKug==",
+ "version": "1.0.30001252",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001252.tgz",
+ "integrity": "sha512-I56jhWDGMtdILQORdusxBOH+Nl/KgQSdDmpJezYddnAkVOmnoU8zwjTV9xAjMIYxr0iPreEAVylCGcmHCjfaOw==",
"dev": true
},
"caseless": {
@@ -3873,9 +3883,9 @@
}
},
"cjs-module-lexer": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz",
- "integrity": "sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
+ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
"dev": true
},
"class-utils": {
@@ -3986,15 +3996,15 @@
"dev": true
},
"colord": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/colord/-/colord-2.1.0.tgz",
- "integrity": "sha512-H5sDP9XDk2uP+x/xSGkgB9SEFc1bojdI5DMKU0jmSXQtml2GIe48dj1DcSS0e53QQAHn+JKqUXbGeGX24xWD7w==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/colord/-/colord-2.7.0.tgz",
+ "integrity": "sha512-pZJBqsHz+pYyw3zpX6ZRXWoCHM1/cvFikY9TV8G3zcejCaKE0lhankoj8iScyrrePA8C7yJ5FStfA9zbcOnw7Q==",
"dev": true
},
"colorette": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
- "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz",
+ "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
"colors": {
@@ -4116,17 +4126,17 @@
"dev": true
},
"core-js": {
- "version": "3.15.2",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz",
- "integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q=="
+ "version": "3.16.4",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.4.tgz",
+ "integrity": "sha512-Tq4GVE6XCjE+hcyW6hPy0ofN3hwtLudz5ZRdrlCnsnD/xkm/PWQRudzYHiKgZKUcefV6Q57fhDHjZHJP5dpfSg=="
},
"core-js-compat": {
- "version": "3.15.2",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.2.tgz",
- "integrity": "sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==",
+ "version": "3.16.4",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.16.4.tgz",
+ "integrity": "sha512-IzCSomxRdahCYb6G3HiN6pl3JCiM0NMunRcNa1pIeC7g17Vd6Ue3AT9anQiENPIm/svThUVer1pIbLMDERIsFw==",
"dev": true,
"requires": {
- "browserslist": "^4.16.6",
+ "browserslist": "^4.16.8",
"semver": "7.0.0"
},
"dependencies": {
@@ -4144,19 +4154,6 @@
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
- "cosmiconfig": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
- "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
- "dev": true,
- "requires": {
- "@types/parse-json": "^4.0.0",
- "import-fresh": "^3.2.1",
- "parse-json": "^5.0.0",
- "path-type": "^4.0.0",
- "yaml": "^1.10.0"
- }
- },
"create-ecdh": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
@@ -4239,18 +4236,18 @@
"dev": true
},
"css-declaration-sorter": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz",
- "integrity": "sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw==",
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.1.1.tgz",
+ "integrity": "sha512-BZ1aOuif2Sb7tQYY1GeCjG7F++8ggnwUkH5Ictw0mrdpqpEd+zWmcPdstnH2TItlb74FqR0DrVEieon221T/1Q==",
"dev": true,
"requires": {
"timsort": "^0.3.0"
}
},
"css-loader": {
- "version": "5.2.6",
- "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.6.tgz",
- "integrity": "sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w==",
+ "version": "5.2.7",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz",
+ "integrity": "sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==",
"dev": true,
"requires": {
"icss-utils": "^5.1.0",
@@ -4312,20 +4309,21 @@
"dev": true
},
"cssnano": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.6.tgz",
- "integrity": "sha512-NiaLH/7yqGksFGsFNvSRe2IV/qmEBAeDE64dYeD8OBrgp6lE8YoMeQJMtsv5ijo6MPyhuoOvFhI94reahBRDkw==",
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.8.tgz",
+ "integrity": "sha512-Lda7geZU0Yu+RZi2SGpjYuQz4HI4/1Y+BhdD0jL7NXAQ5larCzVn+PUGuZbDMYz904AXXCOgO5L1teSvgu7aFg==",
"dev": true,
"requires": {
- "cosmiconfig": "^7.0.0",
- "cssnano-preset-default": "^5.1.3",
- "is-resolvable": "^1.1.0"
+ "cssnano-preset-default": "^5.1.4",
+ "is-resolvable": "^1.1.0",
+ "lilconfig": "^2.0.3",
+ "yaml": "^1.10.2"
}
},
"cssnano-preset-default": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.3.tgz",
- "integrity": "sha512-qo9tX+t4yAAZ/yagVV3b+QBKeLklQbmgR3wI7mccrDcR+bEk9iHgZN1E7doX68y9ThznLya3RDmR+nc7l6/2WQ==",
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.4.tgz",
+ "integrity": "sha512-sPpQNDQBI3R/QsYxQvfB4mXeEcWuw0wGtKtmS5eg8wudyStYMgKOQT39G07EbW1LB56AOYrinRS9f0ig4Y3MhQ==",
"dev": true,
"requires": {
"css-declaration-sorter": "^6.0.3",
@@ -4340,7 +4338,7 @@
"postcss-merge-longhand": "^5.0.2",
"postcss-merge-rules": "^5.0.2",
"postcss-minify-font-values": "^5.0.1",
- "postcss-minify-gradients": "^5.0.1",
+ "postcss-minify-gradients": "^5.0.2",
"postcss-minify-params": "^5.0.1",
"postcss-minify-selectors": "^5.1.0",
"postcss-normalize-charset": "^5.0.1",
@@ -4622,6 +4620,14 @@
"dev": true,
"requires": {
"path-type": "^4.0.0"
+ },
+ "dependencies": {
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true
+ }
}
},
"doctrine": {
@@ -4674,23 +4680,23 @@
}
},
"domhandler": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz",
- "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==",
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz",
+ "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==",
"dev": true,
"requires": {
"domelementtype": "^2.2.0"
}
},
"dompurify": {
- "version": "2.2.9",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.2.9.tgz",
- "integrity": "sha512-+9MqacuigMIZ+1+EwoEltogyWGFTJZWU3258Rupxs+2CGs4H914G9er6pZbsme/bvb5L67o2rade9n21e4RW/w=="
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.1.tgz",
+ "integrity": "sha512-xGWt+NHAQS+4tpgbOAI08yxW0Pr256Gu/FNE2frZVTbgrBUn8M7tz7/ktS/LZ2MHeGqz6topj0/xY+y8R5FBFw=="
},
"domutils": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz",
- "integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==",
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"dev": true,
"requires": {
"dom-serializer": "^1.0.1",
@@ -4727,9 +4733,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.766",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.766.tgz",
- "integrity": "sha512-u2quJ862q9reRKh/je3GXis3w38+RoXH1J9N3XjtsS6NzmUAosNsyZgUVFZPN/ZlJ3v6T0rTyZR3q/J5c6Sy5w==",
+ "version": "1.3.822",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.822.tgz",
+ "integrity": "sha512-k7jG5oYYHxF4jx6PcqwHX3JVME/OjzolqOZiIogi9xtsfsmTjTdie4x88OakYFPEa8euciTgCCzvVNwvmjHb1Q==",
"dev": true
},
"elliptic": {
@@ -4851,9 +4857,9 @@
}
},
"es-abstract": {
- "version": "1.18.3",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
- "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
+ "version": "1.18.5",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz",
+ "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
@@ -4862,11 +4868,12 @@
"get-intrinsic": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.2",
+ "internal-slot": "^1.0.3",
"is-callable": "^1.2.3",
"is-negative-zero": "^2.0.1",
"is-regex": "^1.1.3",
"is-string": "^1.0.6",
- "object-inspect": "^1.10.3",
+ "object-inspect": "^1.11.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.2",
"string.prototype.trimend": "^1.0.4",
@@ -4875,9 +4882,9 @@
}
},
"es-module-lexer": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.6.0.tgz",
- "integrity": "sha512-f8kcHX1ArhllUtb/wVSyvygoKCznIjnxhLxy7TCvIiMdT7fL4ZDTIKaadMe6eLvOXg6Wk02UeoFgUoZ2EKZZUA==",
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz",
+ "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==",
"dev": true
},
"es-to-primitive": {
@@ -4964,13 +4971,13 @@
}
},
"eslint": {
- "version": "7.30.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz",
- "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==",
+ "version": "7.32.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
+ "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
"dev": true,
"requires": {
"@babel/code-frame": "7.12.11",
- "@eslint/eslintrc": "^0.4.2",
+ "@eslint/eslintrc": "^0.4.3",
"@humanwhocodes/config-array": "^0.5.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
@@ -5030,9 +5037,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -5054,17 +5061,6 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
- "cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
- "dev": true,
- "requires": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- }
- },
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
@@ -5091,9 +5087,9 @@
}
},
"globals": {
- "version": "13.9.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz",
- "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==",
+ "version": "13.11.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz",
+ "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
@@ -5111,12 +5107,6 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
- "path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true
- },
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
@@ -5126,21 +5116,6 @@
"lru-cache": "^6.0.0"
}
},
- "shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "requires": {
- "shebang-regex": "^3.0.0"
- }
- },
- "shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true
- },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -5149,32 +5124,40 @@
"requires": {
"has-flag": "^4.0.0"
}
- },
- "which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "requires": {
- "isexe": "^2.0.0"
- }
}
}
},
"eslint-import-resolver-node": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz",
- "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==",
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz",
+ "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==",
"dev": true,
"requires": {
- "debug": "^2.6.9",
- "resolve": "^1.13.1"
+ "debug": "^3.2.7",
+ "resolve": "^1.20.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ }
}
},
"eslint-module-utils": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz",
- "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==",
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz",
+ "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==",
"dev": true,
"requires": {
"debug": "^3.2.7",
@@ -5251,26 +5234,26 @@
}
},
"eslint-plugin-import": {
- "version": "2.23.4",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz",
- "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==",
+ "version": "2.24.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz",
+ "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==",
"dev": true,
"requires": {
"array-includes": "^3.1.3",
"array.prototype.flat": "^1.2.4",
"debug": "^2.6.9",
"doctrine": "^2.1.0",
- "eslint-import-resolver-node": "^0.3.4",
- "eslint-module-utils": "^2.6.1",
+ "eslint-import-resolver-node": "^0.3.6",
+ "eslint-module-utils": "^2.6.2",
"find-up": "^2.0.0",
"has": "^1.0.3",
- "is-core-module": "^2.4.0",
+ "is-core-module": "^2.6.0",
"minimatch": "^3.0.4",
- "object.values": "^1.1.3",
+ "object.values": "^1.1.4",
"pkg-up": "^2.0.0",
"read-pkg-up": "^3.0.0",
"resolve": "^1.20.0",
- "tsconfig-paths": "^3.9.0"
+ "tsconfig-paths": "^3.11.0"
},
"dependencies": {
"doctrine": {
@@ -5291,6 +5274,15 @@
"locate-path": "^2.0.0"
}
},
+ "is-core-module": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz",
+ "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
"locate-path": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
@@ -5518,16 +5510,16 @@
}
},
"expect": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz",
- "integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-27.1.0.tgz",
+ "integrity": "sha512-9kJngV5hOJgkFil4F/uXm3hVBubUK2nERVfvqNNwxxuW8ZOUwSTTSysgfzckYtv/LBzj/LJXbiAF7okHCXgdug==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"ansi-styles": "^5.0.0",
"jest-get-type": "^27.0.6",
- "jest-matcher-utils": "^27.0.6",
- "jest-message-util": "^27.0.6",
+ "jest-matcher-utils": "^27.1.0",
+ "jest-message-util": "^27.1.0",
"jest-regex-util": "^27.0.6"
},
"dependencies": {
@@ -5644,9 +5636,9 @@
"dev": true
},
"fast-glob": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.6.tgz",
- "integrity": "sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==",
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz",
+ "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==",
"dev": true,
"requires": {
"@nodelib/fs.stat": "^2.0.2",
@@ -5726,9 +5718,9 @@
"dev": true
},
"fastq": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz",
- "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==",
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz",
+ "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==",
"dev": true,
"requires": {
"reusify": "^1.0.4"
@@ -5829,9 +5821,9 @@
}
},
"flatted": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz",
- "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz",
+ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
"dev": true
},
"flush-write-stream": {
@@ -6290,6 +6282,15 @@
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
"dev": true
},
+ "has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
"has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
@@ -6368,12 +6369,6 @@
"minimalistic-assert": "^1.0.1"
}
},
- "hex-color-regex": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
- "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
- "dev": true
- },
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -6391,18 +6386,6 @@
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
"dev": true
},
- "hsl-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz",
- "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=",
- "dev": true
- },
- "hsla-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz",
- "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
- "dev": true
- },
"html-encoding-sniffer": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
@@ -6537,6 +6520,14 @@
"requires": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
+ },
+ "dependencies": {
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ }
}
},
"import-local": {
@@ -6628,6 +6619,17 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
+ "internal-slot": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+ "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ }
+ },
"interpret": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
@@ -6667,10 +6669,13 @@
"dev": true
},
"is-bigint": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz",
- "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==",
- "dev": true
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "requires": {
+ "has-bigints": "^1.0.1"
+ }
},
"is-binary-path": {
"version": "1.0.1",
@@ -6683,12 +6688,13 @@
}
},
"is-boolean-object": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz",
- "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
"dev": true,
"requires": {
- "call-bind": "^1.0.2"
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
}
},
"is-buffer": {
@@ -6698,9 +6704,9 @@
"dev": true
},
"is-callable": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
- "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
+ "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
"dev": true
},
"is-ci": {
@@ -6712,28 +6718,6 @@
"ci-info": "^3.1.1"
}
},
- "is-color-stop": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz",
- "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=",
- "dev": true,
- "requires": {
- "css-color-names": "^0.0.4",
- "hex-color-regex": "^1.1.0",
- "hsl-regex": "^1.0.0",
- "hsla-regex": "^1.0.0",
- "rgb-regex": "^1.0.1",
- "rgba-regex": "^1.0.0"
- },
- "dependencies": {
- "css-color-names": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
- "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
- "dev": true
- }
- }
- },
"is-core-module": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
@@ -6764,10 +6748,13 @@
}
},
"is-date-object": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz",
- "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==",
- "dev": true
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
},
"is-descriptor": {
"version": "0.1.6",
@@ -6848,10 +6835,13 @@
}
},
"is-number-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz",
- "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==",
- "dev": true
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
+ "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
},
"is-path-cwd": {
"version": "2.2.0",
@@ -6899,13 +6889,13 @@
"dev": true
},
"is-regex": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
- "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
- "has-symbols": "^1.0.2"
+ "has-tostringtag": "^1.0.0"
}
},
"is-resolvable": {
@@ -6915,16 +6905,19 @@
"dev": true
},
"is-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
- "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true
},
"is-string": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
- "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
- "dev": true
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
},
"is-symbol": {
"version": "1.0.4",
@@ -7085,14 +7078,14 @@
}
},
"jest": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest/-/jest-27.0.6.tgz",
- "integrity": "sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-27.1.0.tgz",
+ "integrity": "sha512-pSQDVwRSwb109Ss13lcMtdfS9r8/w2Zz8+mTUA9VORD66GflCdl8nUFCqM96geOD2EBwWCNURrNAfQsLIDNBdg==",
"dev": true,
"requires": {
- "@jest/core": "^27.0.6",
+ "@jest/core": "^27.1.0",
"import-local": "^3.0.2",
- "jest-cli": "^27.0.6"
+ "jest-cli": "^27.1.0"
},
"dependencies": {
"ansi-styles": {
@@ -7105,9 +7098,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -7136,21 +7129,21 @@
"dev": true
},
"jest-cli": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.0.6.tgz",
- "integrity": "sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.1.0.tgz",
+ "integrity": "sha512-h6zPUOUu+6oLDrXz0yOWY2YXvBLk8gQinx4HbZ7SF4V3HzasQf+ncoIbKENUMwXyf54/6dBkYXvXJos+gOHYZw==",
"dev": true,
"requires": {
- "@jest/core": "^27.0.6",
- "@jest/test-result": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/core": "^27.1.0",
+ "@jest/test-result": "^27.1.0",
+ "@jest/types": "^27.1.0",
"chalk": "^4.0.0",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
"import-local": "^3.0.2",
- "jest-config": "^27.0.6",
- "jest-util": "^27.0.6",
- "jest-validate": "^27.0.6",
+ "jest-config": "^27.1.0",
+ "jest-util": "^27.1.0",
+ "jest-validate": "^27.1.0",
"prompts": "^2.0.1",
"yargs": "^16.0.3"
}
@@ -7167,38 +7160,38 @@
}
},
"jest-changed-files": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.0.6.tgz",
- "integrity": "sha512-BuL/ZDauaq5dumYh5y20sn4IISnf1P9A0TDswTxUi84ORGtVa86ApuBHqICL0vepqAnZiY6a7xeSPWv2/yy4eA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.1.0.tgz",
+ "integrity": "sha512-eRcb13TfQw0xiV2E98EmiEgs9a5uaBIqJChyl0G7jR9fCIvGjXovnDS6Zbku3joij4tXYcSK4SE1AXqOlUxjWg==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"execa": "^5.0.0",
"throat": "^6.0.1"
}
},
"jest-circus": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.0.6.tgz",
- "integrity": "sha512-OJlsz6BBeX9qR+7O9lXefWoc2m9ZqcZ5Ohlzz0pTEAG4xMiZUJoacY8f4YDHxgk0oKYxj277AfOk9w6hZYvi1Q==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.1.0.tgz",
+ "integrity": "sha512-6FWtHs3nZyZlMBhRf1wvAC5CirnflbGJAY1xssSAnERLiiXQRH+wY2ptBVtXjX4gz4AA2EwRV57b038LmifRbA==",
"dev": true,
"requires": {
- "@jest/environment": "^27.0.6",
- "@jest/test-result": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/environment": "^27.1.0",
+ "@jest/test-result": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/node": "*",
"chalk": "^4.0.0",
"co": "^4.6.0",
"dedent": "^0.7.0",
- "expect": "^27.0.6",
+ "expect": "^27.1.0",
"is-generator-fn": "^2.0.0",
- "jest-each": "^27.0.6",
- "jest-matcher-utils": "^27.0.6",
- "jest-message-util": "^27.0.6",
- "jest-runtime": "^27.0.6",
- "jest-snapshot": "^27.0.6",
- "jest-util": "^27.0.6",
- "pretty-format": "^27.0.6",
+ "jest-each": "^27.1.0",
+ "jest-matcher-utils": "^27.1.0",
+ "jest-message-util": "^27.1.0",
+ "jest-runtime": "^27.1.0",
+ "jest-snapshot": "^27.1.0",
+ "jest-util": "^27.1.0",
+ "pretty-format": "^27.1.0",
"slash": "^3.0.0",
"stack-utils": "^2.0.3",
"throat": "^6.0.1"
@@ -7214,9 +7207,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -7262,32 +7255,32 @@
}
},
"jest-config": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.6.tgz",
- "integrity": "sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.1.0.tgz",
+ "integrity": "sha512-GMo7f76vMYUA3b3xOdlcKeKQhKcBIgurjERO2hojo0eLkKPGcw7fyIoanH+m6KOP2bLad+fGnF8aWOJYxzNPeg==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/test-sequencer": "^27.0.6",
- "@jest/types": "^27.0.6",
- "babel-jest": "^27.0.6",
+ "@jest/test-sequencer": "^27.1.0",
+ "@jest/types": "^27.1.0",
+ "babel-jest": "^27.1.0",
"chalk": "^4.0.0",
"deepmerge": "^4.2.2",
"glob": "^7.1.1",
"graceful-fs": "^4.2.4",
"is-ci": "^3.0.0",
- "jest-circus": "^27.0.6",
- "jest-environment-jsdom": "^27.0.6",
- "jest-environment-node": "^27.0.6",
+ "jest-circus": "^27.1.0",
+ "jest-environment-jsdom": "^27.1.0",
+ "jest-environment-node": "^27.1.0",
"jest-get-type": "^27.0.6",
- "jest-jasmine2": "^27.0.6",
+ "jest-jasmine2": "^27.1.0",
"jest-regex-util": "^27.0.6",
- "jest-resolve": "^27.0.6",
- "jest-runner": "^27.0.6",
- "jest-util": "^27.0.6",
- "jest-validate": "^27.0.6",
+ "jest-resolve": "^27.1.0",
+ "jest-runner": "^27.1.0",
+ "jest-util": "^27.1.0",
+ "jest-validate": "^27.1.0",
"micromatch": "^4.0.4",
- "pretty-format": "^27.0.6"
+ "pretty-format": "^27.1.0"
},
"dependencies": {
"ansi-styles": {
@@ -7309,9 +7302,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -7385,15 +7378,15 @@
}
},
"jest-diff": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz",
- "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.1.0.tgz",
+ "integrity": "sha512-rjfopEYl58g/SZTsQFmspBODvMSytL16I+cirnScWTLkQVXYVZfxm78DFfdIIXc05RCYuGjxJqrdyG4PIFzcJg==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
"diff-sequences": "^27.0.6",
"jest-get-type": "^27.0.6",
- "pretty-format": "^27.0.6"
+ "pretty-format": "^27.1.0"
},
"dependencies": {
"ansi-styles": {
@@ -7406,9 +7399,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -7457,16 +7450,16 @@
}
},
"jest-each": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.6.tgz",
- "integrity": "sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.1.0.tgz",
+ "integrity": "sha512-K/cNvQlmDqQMRHF8CaQ0XPzCfjP5HMJc2bIJglrIqI9fjwpNqITle63IWE+wq4p+3v+iBgh7Wq0IdGpLx5xjDg==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"chalk": "^4.0.0",
"jest-get-type": "^27.0.6",
- "jest-util": "^27.0.6",
- "pretty-format": "^27.0.6"
+ "jest-util": "^27.1.0",
+ "pretty-format": "^27.1.0"
},
"dependencies": {
"ansi-styles": {
@@ -7479,9 +7472,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -7521,32 +7514,32 @@
}
},
"jest-environment-jsdom": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.6.tgz",
- "integrity": "sha512-FvetXg7lnXL9+78H+xUAsra3IeZRTiegA3An01cWeXBspKXUhAwMM9ycIJ4yBaR0L7HkoMPaZsozCLHh4T8fuw==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.1.0.tgz",
+ "integrity": "sha512-JbwOcOxh/HOtsj56ljeXQCUJr3ivnaIlM45F5NBezFLVYdT91N5UofB1ux2B1CATsQiudcHdgTaeuqGXJqjJYQ==",
"dev": true,
"requires": {
- "@jest/environment": "^27.0.6",
- "@jest/fake-timers": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/environment": "^27.1.0",
+ "@jest/fake-timers": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/node": "*",
- "jest-mock": "^27.0.6",
- "jest-util": "^27.0.6",
+ "jest-mock": "^27.1.0",
+ "jest-util": "^27.1.0",
"jsdom": "^16.6.0"
}
},
"jest-environment-node": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.0.6.tgz",
- "integrity": "sha512-+Vi6yLrPg/qC81jfXx3IBlVnDTI6kmRr08iVa2hFCWmJt4zha0XW7ucQltCAPhSR0FEKEoJ3i+W4E6T0s9is0w==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.1.0.tgz",
+ "integrity": "sha512-JIyJ8H3wVyM4YCXp7njbjs0dIT87yhGlrXCXhDKNIg1OjurXr6X38yocnnbXvvNyqVTqSI4M9l+YfPKueqL1lw==",
"dev": true,
"requires": {
- "@jest/environment": "^27.0.6",
- "@jest/fake-timers": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/environment": "^27.1.0",
+ "@jest/fake-timers": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/node": "*",
- "jest-mock": "^27.0.6",
- "jest-util": "^27.0.6"
+ "jest-mock": "^27.1.0",
+ "jest-util": "^27.1.0"
}
},
"jest-get-type": {
@@ -7562,12 +7555,12 @@
"dev": true
},
"jest-haste-map": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.6.tgz",
- "integrity": "sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.1.0.tgz",
+ "integrity": "sha512-7mz6LopSe+eA6cTFMf10OfLLqRoIPvmMyz5/OnSXnHO7hB0aDP1iIeLWCXzAcYU5eIJVpHr12Bk9yyq2fTW9vg==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"@types/graceful-fs": "^4.1.2",
"@types/node": "*",
"anymatch": "^3.0.3",
@@ -7576,8 +7569,8 @@
"graceful-fs": "^4.2.4",
"jest-regex-util": "^27.0.6",
"jest-serializer": "^27.0.6",
- "jest-util": "^27.0.6",
- "jest-worker": "^27.0.6",
+ "jest-util": "^27.1.0",
+ "jest-worker": "^27.1.0",
"micromatch": "^4.0.4",
"walker": "^1.0.7"
},
@@ -7638,28 +7631,28 @@
}
},
"jest-jasmine2": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.0.6.tgz",
- "integrity": "sha512-cjpH2sBy+t6dvCeKBsHpW41mjHzXgsavaFMp+VWRf0eR4EW8xASk1acqmljFtK2DgyIECMv2yCdY41r2l1+4iA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.1.0.tgz",
+ "integrity": "sha512-Z/NIt0wBDg3przOW2FCWtYjMn3Ip68t0SL60agD/e67jlhTyV3PIF8IzT9ecwqFbeuUSO2OT8WeJgHcalDGFzQ==",
"dev": true,
"requires": {
"@babel/traverse": "^7.1.0",
- "@jest/environment": "^27.0.6",
+ "@jest/environment": "^27.1.0",
"@jest/source-map": "^27.0.6",
- "@jest/test-result": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/test-result": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/node": "*",
"chalk": "^4.0.0",
"co": "^4.6.0",
- "expect": "^27.0.6",
+ "expect": "^27.1.0",
"is-generator-fn": "^2.0.0",
- "jest-each": "^27.0.6",
- "jest-matcher-utils": "^27.0.6",
- "jest-message-util": "^27.0.6",
- "jest-runtime": "^27.0.6",
- "jest-snapshot": "^27.0.6",
- "jest-util": "^27.0.6",
- "pretty-format": "^27.0.6",
+ "jest-each": "^27.1.0",
+ "jest-matcher-utils": "^27.1.0",
+ "jest-message-util": "^27.1.0",
+ "jest-runtime": "^27.1.0",
+ "jest-snapshot": "^27.1.0",
+ "jest-util": "^27.1.0",
+ "pretty-format": "^27.1.0",
"throat": "^6.0.1"
},
"dependencies": {
@@ -7673,9 +7666,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -7715,25 +7708,25 @@
}
},
"jest-leak-detector": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.6.tgz",
- "integrity": "sha512-2/d6n2wlH5zEcdctX4zdbgX8oM61tb67PQt4Xh8JFAIy6LRKUnX528HulkaG6nD5qDl5vRV1NXejCe1XRCH5gQ==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.1.0.tgz",
+ "integrity": "sha512-oHvSkz1E80VyeTKBvZNnw576qU+cVqRXUD3/wKXh1zpaki47Qty2xeHg2HKie9Hqcd2l4XwircgNOWb/NiGqdA==",
"dev": true,
"requires": {
"jest-get-type": "^27.0.6",
- "pretty-format": "^27.0.6"
+ "pretty-format": "^27.1.0"
}
},
"jest-matcher-utils": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz",
- "integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.1.0.tgz",
+ "integrity": "sha512-VmAudus2P6Yt/JVBRdTPFhUzlIN8DYJd+et5Rd9QDsO/Z82Z4iwGjo43U8Z+PTiz8CBvKvlb6Fh3oKy39hykkQ==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
- "jest-diff": "^27.0.6",
+ "jest-diff": "^27.1.0",
"jest-get-type": "^27.0.6",
- "pretty-format": "^27.0.6"
+ "pretty-format": "^27.1.0"
},
"dependencies": {
"ansi-styles": {
@@ -7746,9 +7739,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -7788,18 +7781,18 @@
}
},
"jest-message-util": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz",
- "integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.1.0.tgz",
+ "integrity": "sha512-Eck8NFnJ5Sg36R9XguD65cf2D5+McC+NF5GIdEninoabcuoOfWrID5qJhufq5FB0DRKoiyxB61hS7MKoMD0trQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"@types/stack-utils": "^2.0.0",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
"micromatch": "^4.0.4",
- "pretty-format": "^27.0.6",
+ "pretty-format": "^27.1.0",
"slash": "^3.0.0",
"stack-utils": "^2.0.3"
},
@@ -7823,9 +7816,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -7905,12 +7898,12 @@
}
},
"jest-mock": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.6.tgz",
- "integrity": "sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.1.0.tgz",
+ "integrity": "sha512-iT3/Yhu7DwAg/0HvvLCqLvrTKTRMyJlrrfJYWzuLSf9RCAxBoIXN3HoymZxMnYsC3eD8ewGbUa9jUknwBenx2w==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"@types/node": "*"
}
},
@@ -7927,18 +7920,19 @@
"dev": true
},
"jest-resolve": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.6.tgz",
- "integrity": "sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.1.0.tgz",
+ "integrity": "sha512-TXvzrLyPg0vLOwcWX38ZGYeEztSEmW+cQQKqc4HKDUwun31wsBXwotRlUz4/AYU/Fq4GhbMd/ileIWZEtcdmIA==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"chalk": "^4.0.0",
"escalade": "^3.1.1",
"graceful-fs": "^4.2.4",
+ "jest-haste-map": "^27.1.0",
"jest-pnp-resolver": "^1.2.2",
- "jest-util": "^27.0.6",
- "jest-validate": "^27.0.6",
+ "jest-util": "^27.1.0",
+ "jest-validate": "^27.1.0",
"resolve": "^1.20.0",
"slash": "^3.0.0"
},
@@ -7953,9 +7947,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -8001,42 +7995,42 @@
}
},
"jest-resolve-dependencies": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.6.tgz",
- "integrity": "sha512-mg9x9DS3BPAREWKCAoyg3QucCr0n6S8HEEsqRCKSPjPcu9HzRILzhdzY3imsLoZWeosEbJZz6TKasveczzpJZA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.1.0.tgz",
+ "integrity": "sha512-Kq5XuDAELuBnrERrjFYEzu/A+i2W7l9HnPWqZEeKGEQ7m1R+6ndMbdXCVCx29Se1qwLZLgvoXwinB3SPIaitMQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"jest-regex-util": "^27.0.6",
- "jest-snapshot": "^27.0.6"
+ "jest-snapshot": "^27.1.0"
}
},
"jest-runner": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.0.6.tgz",
- "integrity": "sha512-W3Bz5qAgaSChuivLn+nKOgjqNxM7O/9JOJoKDCqThPIg2sH/d4A/lzyiaFgnb9V1/w29Le11NpzTJSzga1vyYQ==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.1.0.tgz",
+ "integrity": "sha512-ZWPKr9M5w5gDplz1KsJ6iRmQaDT/yyAFLf18fKbb/+BLWsR1sCNC2wMT0H7pP3gDcBz0qZ6aJraSYUNAGSJGaw==",
"dev": true,
"requires": {
- "@jest/console": "^27.0.6",
- "@jest/environment": "^27.0.6",
- "@jest/test-result": "^27.0.6",
- "@jest/transform": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/console": "^27.1.0",
+ "@jest/environment": "^27.1.0",
+ "@jest/test-result": "^27.1.0",
+ "@jest/transform": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/node": "*",
"chalk": "^4.0.0",
"emittery": "^0.8.1",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
"jest-docblock": "^27.0.6",
- "jest-environment-jsdom": "^27.0.6",
- "jest-environment-node": "^27.0.6",
- "jest-haste-map": "^27.0.6",
- "jest-leak-detector": "^27.0.6",
- "jest-message-util": "^27.0.6",
- "jest-resolve": "^27.0.6",
- "jest-runtime": "^27.0.6",
- "jest-util": "^27.0.6",
- "jest-worker": "^27.0.6",
+ "jest-environment-jsdom": "^27.1.0",
+ "jest-environment-node": "^27.1.0",
+ "jest-haste-map": "^27.1.0",
+ "jest-leak-detector": "^27.1.0",
+ "jest-message-util": "^27.1.0",
+ "jest-resolve": "^27.1.0",
+ "jest-runtime": "^27.1.0",
+ "jest-util": "^27.1.0",
+ "jest-worker": "^27.1.0",
"source-map-support": "^0.5.6",
"throat": "^6.0.1"
},
@@ -8051,9 +8045,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -8093,34 +8087,35 @@
}
},
"jest-runtime": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.6.tgz",
- "integrity": "sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.1.0.tgz",
+ "integrity": "sha512-okiR2cpGjY0RkWmUGGado6ETpFOi9oG3yV0CioYdoktkVxy5Hv0WRLWnJFuArSYS8cHMCNcceUUMGiIfgxCO9A==",
"dev": true,
"requires": {
- "@jest/console": "^27.0.6",
- "@jest/environment": "^27.0.6",
- "@jest/fake-timers": "^27.0.6",
- "@jest/globals": "^27.0.6",
+ "@jest/console": "^27.1.0",
+ "@jest/environment": "^27.1.0",
+ "@jest/fake-timers": "^27.1.0",
+ "@jest/globals": "^27.1.0",
"@jest/source-map": "^27.0.6",
- "@jest/test-result": "^27.0.6",
- "@jest/transform": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/test-result": "^27.1.0",
+ "@jest/transform": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/yargs": "^16.0.0",
"chalk": "^4.0.0",
"cjs-module-lexer": "^1.0.0",
"collect-v8-coverage": "^1.0.0",
+ "execa": "^5.0.0",
"exit": "^0.1.2",
"glob": "^7.1.3",
"graceful-fs": "^4.2.4",
- "jest-haste-map": "^27.0.6",
- "jest-message-util": "^27.0.6",
- "jest-mock": "^27.0.6",
+ "jest-haste-map": "^27.1.0",
+ "jest-message-util": "^27.1.0",
+ "jest-mock": "^27.1.0",
"jest-regex-util": "^27.0.6",
- "jest-resolve": "^27.0.6",
- "jest-snapshot": "^27.0.6",
- "jest-util": "^27.0.6",
- "jest-validate": "^27.0.6",
+ "jest-resolve": "^27.1.0",
+ "jest-snapshot": "^27.1.0",
+ "jest-util": "^27.1.0",
+ "jest-validate": "^27.1.0",
"slash": "^3.0.0",
"strip-bom": "^4.0.0",
"yargs": "^16.0.3"
@@ -8136,9 +8131,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -8200,9 +8195,9 @@
}
},
"jest-snapshot": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.6.tgz",
- "integrity": "sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.1.0.tgz",
+ "integrity": "sha512-eaeUBoEjuuRwmiRI51oTldUsKOohB1F6fPqWKKILuDi/CStxzp2IWekVUXbuHHoz5ik33ioJhshiHpgPFbYgcA==",
"dev": true,
"requires": {
"@babel/core": "^7.7.2",
@@ -8211,23 +8206,23 @@
"@babel/plugin-syntax-typescript": "^7.7.2",
"@babel/traverse": "^7.7.2",
"@babel/types": "^7.0.0",
- "@jest/transform": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/transform": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/babel__traverse": "^7.0.4",
"@types/prettier": "^2.1.5",
"babel-preset-current-node-syntax": "^1.0.0",
"chalk": "^4.0.0",
- "expect": "^27.0.6",
+ "expect": "^27.1.0",
"graceful-fs": "^4.2.4",
- "jest-diff": "^27.0.6",
+ "jest-diff": "^27.1.0",
"jest-get-type": "^27.0.6",
- "jest-haste-map": "^27.0.6",
- "jest-matcher-utils": "^27.0.6",
- "jest-message-util": "^27.0.6",
- "jest-resolve": "^27.0.6",
- "jest-util": "^27.0.6",
+ "jest-haste-map": "^27.1.0",
+ "jest-matcher-utils": "^27.1.0",
+ "jest-message-util": "^27.1.0",
+ "jest-resolve": "^27.1.0",
+ "jest-util": "^27.1.0",
"natural-compare": "^1.4.0",
- "pretty-format": "^27.0.6",
+ "pretty-format": "^27.1.0",
"semver": "^7.3.2"
},
"dependencies": {
@@ -8241,9 +8236,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -8292,12 +8287,12 @@
}
},
"jest-util": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz",
- "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.1.0.tgz",
+ "integrity": "sha512-edSLD2OneYDKC6gZM1yc+wY/877s/fuJNoM1k3sOEpzFyeptSmke3SLnk1dDHk9CgTA+58mnfx3ew3J11Kes/w==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"@types/node": "*",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
@@ -8315,9 +8310,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -8357,17 +8352,17 @@
}
},
"jest-validate": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.6.tgz",
- "integrity": "sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.1.0.tgz",
+ "integrity": "sha512-QiJ+4XuSuMsfPi9zvdO//IrSRSlG6ybJhOpuqYSsuuaABaNT84h0IoD6vvQhThBOKT+DIKvl5sTM0l6is9+SRA==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"camelcase": "^6.2.0",
"chalk": "^4.0.0",
"jest-get-type": "^27.0.6",
"leven": "^3.1.0",
- "pretty-format": "^27.0.6"
+ "pretty-format": "^27.1.0"
},
"dependencies": {
"ansi-styles": {
@@ -8386,9 +8381,9 @@
"dev": true
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -8428,17 +8423,17 @@
}
},
"jest-watcher": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.6.tgz",
- "integrity": "sha512-/jIoKBhAP00/iMGnTwUBLgvxkn7vsOweDrOTSPzc7X9uOyUtJIDthQBTI1EXz90bdkrxorUZVhJwiB69gcHtYQ==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.1.0.tgz",
+ "integrity": "sha512-ivaWTrA46aHWdgPDgPypSHiNQjyKnLBpUIHeBaGg11U+pDzZpkffGlcB1l1a014phmG0mHgkOHtOgiqJQM6yKQ==",
"dev": true,
"requires": {
- "@jest/test-result": "^27.0.6",
- "@jest/types": "^27.0.6",
+ "@jest/test-result": "^27.1.0",
+ "@jest/types": "^27.1.0",
"@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
- "jest-util": "^27.0.6",
+ "jest-util": "^27.1.0",
"string-length": "^4.0.1"
},
"dependencies": {
@@ -8452,9 +8447,9 @@
}
},
"chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -8494,9 +8489,9 @@
}
},
"jest-worker": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz",
- "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.1.0.tgz",
+ "integrity": "sha512-mO4PHb2QWLn9yRXGp7rkvXLAYuxwhq1ZYUo0LoDhg8wqvv4QizP1ZWEJOeolgbEgAWZLIEU0wsku8J+lGWfBhg==",
"dev": true,
"requires": {
"@types/node": "*",
@@ -8550,9 +8545,9 @@
"dev": true
},
"jsdom": {
- "version": "16.6.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz",
- "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==",
+ "version": "16.7.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
+ "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==",
"dev": true,
"requires": {
"abab": "^2.0.5",
@@ -8580,7 +8575,7 @@
"whatwg-encoding": "^1.0.5",
"whatwg-mimetype": "^2.3.0",
"whatwg-url": "^8.5.0",
- "ws": "^7.4.5",
+ "ws": "^7.4.6",
"xml-name-validator": "^3.0.0"
},
"dependencies": {
@@ -9053,9 +9048,9 @@
"dev": true
},
"mico-spinner": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/mico-spinner/-/mico-spinner-1.1.1.tgz",
- "integrity": "sha512-b9F3Qx9l6fO141+FbR9hqRUJ15p4bGVsqgXiO/noxxXZmN+hYZVCuWd4LEubadrVkw0eIYAJDXWo0ZYGoLrmfg==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/mico-spinner/-/mico-spinner-1.2.2.tgz",
+ "integrity": "sha512-jIsOIIk5xa+TmZJU2mPVTEk1AC7aKnrj8UJR58cTiK8msNWYvPuQxPx0ojNbtVOut/TjTgGkVLrEt1jsrceYfA==",
"dev": true,
"requires": {
"colorette": "^1.2.2"
@@ -9134,12 +9129,31 @@
"dev": true
},
"mini-css-extract-plugin": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.0.0.tgz",
- "integrity": "sha512-LzJaninAMkfVAUDldZ4lUidAeS8GD0w8tSUbZLscYXWmdTOjYuEoiIhwKvwHX6+42D2cRAl35pA9DHtvAv71JQ==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.2.0.tgz",
+ "integrity": "sha512-91HeVHbq7PUJ4TwOuMTlFWfVWrLqf3SF0PlEDPV+wtgsfxrMebN9LLzflyQqdKLp4/H3PexRB1WLKsCqpWKkxQ==",
"dev": true,
"requires": {
- "schema-utils": "^3.0.0"
+ "schema-utils": "^3.1.0"
+ },
+ "dependencies": {
+ "@types/json-schema": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
+ "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ }
}
},
"minimalistic-assert": {
@@ -9290,9 +9304,9 @@
"dev": true
},
"nanoid": {
- "version": "3.1.23",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
- "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
+ "version": "3.1.25",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz",
+ "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==",
"dev": true
},
"nanomatch": {
@@ -9406,9 +9420,9 @@
"dev": true
},
"node-releases": {
- "version": "1.1.73",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
- "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==",
+ "version": "1.1.75",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz",
+ "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==",
"dev": true
},
"node-sass": {
@@ -9595,9 +9609,9 @@
}
},
"object-inspect": {
- "version": "1.10.3",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
- "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
+ "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
"dev": true
},
"object-keys": {
@@ -9845,10 +9859,21 @@
"dev": true
},
"path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "dev": true
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
},
"pbkdf2": {
"version": "3.1.2",
@@ -9969,9 +9994,9 @@
}
},
"pnp-webpack-plugin": {
- "version": "1.6.4",
- "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz",
- "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==",
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz",
+ "integrity": "sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==",
"dev": true,
"requires": {
"ts-pnp": "^1.1.6"
@@ -9984,9 +10009,9 @@
"dev": true
},
"postcss": {
- "version": "8.3.5",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz",
- "integrity": "sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==",
+ "version": "8.3.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.6.tgz",
+ "integrity": "sha512-wG1cc/JhRgdqB6WHEuyLTedf3KIRuD0hG6ldkFEZNCjRxiC+3i6kkWUUbiJQayP28iwG35cEmAbe98585BYV0A==",
"dev": true,
"requires": {
"colorette": "^1.2.2",
@@ -10083,13 +10108,13 @@
}
},
"postcss-minify-gradients": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.1.tgz",
- "integrity": "sha512-odOwBFAIn2wIv+XYRpoN2hUV3pPQlgbJ10XeXPq8UY2N+9ZG42xu45lTn/g9zZ+d70NKSQD6EOi6UiCMu3FN7g==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.2.tgz",
+ "integrity": "sha512-7Do9JP+wqSD6Prittitt2zDLrfzP9pqKs2EcLX7HJYxsxCOwrrcLt4x/ctQTsiOw+/8HYotAoqNkrzItL19SdQ==",
"dev": true,
"requires": {
+ "colord": "^2.6",
"cssnano-utils": "^2.0.1",
- "is-color-stop": "^1.1.0",
"postcss-value-parser": "^4.1.0"
}
},
@@ -10308,13 +10333,19 @@
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
+ "prettier": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
+ "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
+ "dev": true
+ },
"pretty-format": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
- "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
+ "version": "27.1.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.1.0.tgz",
+ "integrity": "sha512-4aGaud3w3rxAO6OXmK3fwBFQ0bctIOG3/if+jYEFGNGIs0EvuidQm3bZ9mlP2/t9epLNC/12czabfy7TZNSwVA==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.6",
+ "@jest/types": "^27.1.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
@@ -10509,23 +10540,6 @@
"load-json-file": "^4.0.0",
"normalize-package-data": "^2.3.2",
"path-type": "^3.0.0"
- },
- "dependencies": {
- "path-type": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
- "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
- "dev": true,
- "requires": {
- "pify": "^3.0.0"
- }
- },
- "pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
- "dev": true
- }
}
},
"read-pkg-up": {
@@ -10610,9 +10624,9 @@
}
},
"rechoir": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz",
- "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==",
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz",
+ "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==",
"dev": true,
"requires": {
"resolve": "^1.9.0"
@@ -10644,9 +10658,9 @@
}
},
"regenerator-runtime": {
- "version": "0.13.7",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
- "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
+ "version": "0.13.9",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
+ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
"dev": true
},
"regenerator-transform": {
@@ -10816,20 +10830,12 @@
"dev": true,
"requires": {
"resolve-from": "^5.0.0"
- },
- "dependencies": {
- "resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true
- }
}
},
"resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true
},
"resolve-url": {
@@ -10850,18 +10856,6 @@
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true
},
- "rgb-regex": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
- "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=",
- "dev": true
- },
- "rgba-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz",
- "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=",
- "dev": true
- },
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -10921,9 +10915,9 @@
"dev": true
},
"sass": {
- "version": "1.35.1",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.35.1.tgz",
- "integrity": "sha512-oCisuQJstxMcacOPmxLNiLlj4cUyN2+8xJnG7VanRoh2GOLr9RqkvI4AxA4a6LHVg/rsu+PmxXeGhrdSF9jCiQ==",
+ "version": "1.38.2",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.38.2.tgz",
+ "integrity": "sha512-Bz1fG6qiyF0FX6m/I+VxtdVKz1Dfmg/e9kfDy2PhWOkq3T384q2KxwIfP0fXpeI+EyyETdOauH+cRHQDFASllA==",
"dev": true,
"requires": {
"chokidar": ">=3.0.0 <4.0.0"
@@ -11166,6 +11160,17 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
+ "side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ }
+ },
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
@@ -11190,18 +11195,18 @@
"dev": true
},
"size-limit": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/size-limit/-/size-limit-5.0.1.tgz",
- "integrity": "sha512-FZwVay5fCdatHoZU1lGyvVK3KrI4puMKbU1UoLLhEaMjQBxPuovuF+eJIDzmJN+xZRk3thuG7yS77DhuWF4fEQ==",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/size-limit/-/size-limit-5.0.3.tgz",
+ "integrity": "sha512-522c33FTs09sDCN3SUjtxF3Jg361O8Xm1Rh9MUuGGVwY7XGvroE/vL20+//qGltUprGzYQONBbzy9TTdOJWgbw==",
"dev": true,
"requires": {
"bytes-iec": "^3.1.1",
"chokidar": "^3.5.2",
"ci-job-number": "^1.2.2",
- "colorette": "^1.2.2",
+ "colorette": "^1.3.0",
"globby": "^11.0.4",
"lilconfig": "^2.0.3",
- "mico-spinner": "^1.1.1"
+ "mico-spinner": "^1.2.2"
},
"dependencies": {
"array-union": {
@@ -11780,74 +11785,25 @@
}
},
"svgo": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.1.tgz",
- "integrity": "sha512-riDDIQgXpEnn0BEl9Gvhh1LNLIyiusSpt64IR8upJu7MwxnzetmF/Y57pXQD2NMX2lVyMRzXt5f2M5rO4wG7Dw==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.5.0.tgz",
+ "integrity": "sha512-FSdBOOo271VyF/qZnOn1PgwCdt1v4Dx0Sey+U1jgqm1vqRYjPGdip0RGrFW6ItwtkBB8rHgHk26dlVr0uCs82Q==",
"dev": true,
"requires": {
"@trysound/sax": "0.1.1",
- "chalk": "^4.1.0",
- "commander": "^7.1.0",
+ "colorette": "^1.3.0",
+ "commander": "^7.2.0",
"css-select": "^4.1.3",
- "css-tree": "^1.1.2",
+ "css-tree": "^1.1.3",
"csso": "^4.2.0",
"stable": "^0.1.8"
},
"dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
- "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
"commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
"dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
}
}
},
@@ -11872,9 +11828,9 @@
},
"dependencies": {
"ajv": {
- "version": "8.6.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz",
- "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==",
+ "version": "8.6.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz",
+ "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
@@ -11898,9 +11854,9 @@
"dev": true
},
"tar": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
- "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
+ "version": "6.1.11",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
+ "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"dev": true,
"requires": {
"chownr": "^2.0.0",
@@ -12139,9 +12095,9 @@
"dev": true
},
"tsconfig-paths": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
- "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==",
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz",
+ "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==",
"dev": true,
"requires": {
"@types/json5": "^0.0.29",
@@ -12592,21 +12548,22 @@
"dev": true
},
"webpack": {
- "version": "5.42.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.42.0.tgz",
- "integrity": "sha512-Ln8HL0F831t1x/yPB/qZEUVmZM4w9BnHZ1EQD/sAUHv8m22hthoPniWTXEzFMh/Sf84mhrahut22TX5KxWGuyQ==",
+ "version": "5.51.1",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.51.1.tgz",
+ "integrity": "sha512-xsn3lwqEKoFvqn4JQggPSRxE4dhsRcysWTqYABAZlmavcoTmwlOb9b1N36Inbt/eIispSkuHa80/FJkDTPos1A==",
"dev": true,
"requires": {
"@types/eslint-scope": "^3.7.0",
- "@types/estree": "^0.0.48",
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/wasm-edit": "1.11.0",
- "@webassemblyjs/wasm-parser": "1.11.0",
+ "@types/estree": "^0.0.50",
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/wasm-edit": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
"acorn": "^8.4.1",
+ "acorn-import-assertions": "^1.7.6",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.8.0",
- "es-module-lexer": "^0.6.0",
+ "es-module-lexer": "^0.7.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
@@ -12615,139 +12572,145 @@
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
- "schema-utils": "^3.0.0",
+ "schema-utils": "^3.1.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.1.3",
"watchpack": "^2.2.0",
- "webpack-sources": "^2.3.0"
+ "webpack-sources": "^3.2.0"
},
"dependencies": {
+ "@types/json-schema": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
+ "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
+ "dev": true
+ },
"@webassemblyjs/ast": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz",
- "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
+ "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
"dev": true,
"requires": {
- "@webassemblyjs/helper-numbers": "1.11.0",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.0"
+ "@webassemblyjs/helper-numbers": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
}
},
"@webassemblyjs/helper-api-error": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz",
- "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
+ "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
"dev": true
},
"@webassemblyjs/helper-buffer": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz",
- "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
+ "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
"dev": true
},
"@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz",
- "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
+ "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
"dev": true
},
"@webassemblyjs/helper-wasm-section": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz",
- "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
+ "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/helper-buffer": "1.11.0",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
- "@webassemblyjs/wasm-gen": "1.11.0"
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1"
}
},
"@webassemblyjs/ieee754": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz",
- "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
+ "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
"dev": true,
"requires": {
"@xtuc/ieee754": "^1.2.0"
}
},
"@webassemblyjs/leb128": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz",
- "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
+ "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
"dev": true,
"requires": {
"@xtuc/long": "4.2.2"
}
},
"@webassemblyjs/utf8": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz",
- "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
+ "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
"dev": true
},
"@webassemblyjs/wasm-edit": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz",
- "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
+ "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/helper-buffer": "1.11.0",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
- "@webassemblyjs/helper-wasm-section": "1.11.0",
- "@webassemblyjs/wasm-gen": "1.11.0",
- "@webassemblyjs/wasm-opt": "1.11.0",
- "@webassemblyjs/wasm-parser": "1.11.0",
- "@webassemblyjs/wast-printer": "1.11.0"
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/helper-wasm-section": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-opt": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "@webassemblyjs/wast-printer": "1.11.1"
}
},
"@webassemblyjs/wasm-gen": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz",
- "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
+ "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
- "@webassemblyjs/ieee754": "1.11.0",
- "@webassemblyjs/leb128": "1.11.0",
- "@webassemblyjs/utf8": "1.11.0"
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
}
},
"@webassemblyjs/wasm-opt": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz",
- "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
+ "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/helper-buffer": "1.11.0",
- "@webassemblyjs/wasm-gen": "1.11.0",
- "@webassemblyjs/wasm-parser": "1.11.0"
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1"
}
},
"@webassemblyjs/wasm-parser": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz",
- "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
+ "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/helper-api-error": "1.11.0",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
- "@webassemblyjs/ieee754": "1.11.0",
- "@webassemblyjs/leb128": "1.11.0",
- "@webassemblyjs/utf8": "1.11.0"
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
}
},
"@webassemblyjs/wast-printer": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz",
- "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
+ "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.0",
+ "@webassemblyjs/ast": "1.11.1",
"@xtuc/long": "4.2.2"
}
},
@@ -12783,23 +12746,6 @@
"estraverse": "^4.1.1"
}
},
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "jest-worker": {
- "version": "27.0.6",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz",
- "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==",
- "dev": true,
- "requires": {
- "@types/node": "*",
- "merge-stream": "^2.0.0",
- "supports-color": "^8.0.0"
- }
- },
"loader-runner": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
@@ -12815,6 +12761,17 @@
"yocto-queue": "^0.1.0"
}
},
+ "schema-utils": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ },
"serialize-javascript": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
@@ -12824,15 +12781,6 @@
"randombytes": "^2.1.0"
}
},
- "supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
"tapable": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz",
@@ -12840,9 +12788,9 @@
"dev": true
},
"terser": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz",
- "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.2.tgz",
+ "integrity": "sha512-0Omye+RD4X7X69O0eql3lC4Heh/5iLj3ggxR/B5ketZLOtLiOqukUgjw3q4PDnNQbsrkKr3UMypqStQG3XKRvw==",
"dev": true,
"requires": {
"commander": "^2.20.0",
@@ -12883,14 +12831,10 @@
}
},
"webpack-sources": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz",
- "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==",
- "dev": true,
- "requires": {
- "source-list-map": "^2.0.1",
- "source-map": "^0.6.1"
- }
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.0.tgz",
+ "integrity": "sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw==",
+ "dev": true
}
}
},
@@ -12975,15 +12919,15 @@
}
},
"webpack-cli": {
- "version": "4.7.2",
- "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.2.tgz",
- "integrity": "sha512-mEoLmnmOIZQNiRl0ebnjzQ74Hk0iKS5SiEEnpq3dRezoyR3yPaeQZCMCe+db4524pj1Pd5ghZXjT41KLzIhSLw==",
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.8.0.tgz",
+ "integrity": "sha512-+iBSWsX16uVna5aAYN6/wjhJy1q/GKk4KjKvfg90/6hykCTSgozbfz5iRgDTSJt/LgSbYxdBX3KBHeobIs+ZEw==",
"dev": true,
"requires": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/configtest": "^1.0.4",
"@webpack-cli/info": "^1.3.0",
- "@webpack-cli/serve": "^1.5.1",
+ "@webpack-cli/serve": "^1.5.2",
"colorette": "^1.2.1",
"commander": "^7.0.0",
"execa": "^5.0.0",
@@ -13000,91 +12944,6 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
"dev": true
- },
- "cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
- "dev": true,
- "requires": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- }
- },
- "execa": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
- "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
- "dev": true,
- "requires": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^6.0.0",
- "human-signals": "^2.1.0",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.1",
- "onetime": "^5.1.2",
- "signal-exit": "^3.0.3",
- "strip-final-newline": "^2.0.0"
- }
- },
- "get-stream": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
- "dev": true
- },
- "human-signals": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
- "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
- "dev": true
- },
- "is-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
- "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
- "dev": true
- },
- "npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "dev": true,
- "requires": {
- "path-key": "^3.0.0"
- }
- },
- "path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true
- },
- "shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "requires": {
- "shebang-regex": "^3.0.0"
- }
- },
- "shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true
- },
- "which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "requires": {
- "isexe": "^2.0.0"
- }
}
}
},
diff --git a/package.json b/package.json
index fd357388..efddb348 100644
--- a/package.json
+++ b/package.json
@@ -18,41 +18,42 @@
},
"homepage": "https://github.com/no-chris/chord-mark#readme",
"devDependencies": {
- "@babel/cli": "^7.14.3",
- "@babel/core": "^7.14.3",
- "@babel/preset-env": "^7.14.2",
- "@size-limit/preset-small-lib": "^5.0.1",
- "babel-jest": "^27.0.6",
+ "@babel/cli": "^7.14.8",
+ "@babel/core": "^7.15.0",
+ "@babel/preset-env": "^7.15.0",
+ "@size-limit/preset-small-lib": "^5.0.3",
+ "babel-jest": "^27.1.0",
"babel-loader": "^8.2.2",
"clean-webpack-plugin": "^3.0.0",
- "css-loader": "^5.0.1",
- "eslint": "^7.26.0",
- "eslint-plugin-import": "^2.23.4",
+ "eslint": "^7.32.0",
+ "eslint-plugin-import": "^2.24.2",
"eslint-plugin-no-unsanitized": "^3.1.4",
"generate-changelog": "^1.8.0",
"handlebars-loader": "^1.7.1",
- "jest": "^27.0.6",
+ "jest": "^27.1.0",
"jest-handlebars": "^1.0.1",
- "mini-css-extract-plugin": "^2.0.0",
+ "mini-css-extract-plugin": "^2.2.0",
"node-sass": "^6.0.1",
+ "prettier": "^2.3.2",
"raw-loader": "^4.0.2",
- "sass": "^1.32.13",
+ "sass": "^1.38.2",
"sass-loader": "^12.1.0",
- "size-limit": "^5.0.1",
+ "size-limit": "^5.0.3",
"sloc": "^0.2.1",
- "webpack": "^5.37.0",
+ "webpack": "^5.51.1",
"webpack-bundle-analyzer": "^4.4.2",
- "webpack-cli": "^4.7.0"
+ "webpack-cli": "^4.8.0"
},
"dependencies": {
"chord-symbol": "^2.1.0",
- "core-js": "^3.15.2",
- "dompurify": "^2.2.6",
+ "core-js": "^3.16.4",
+ "dompurify": "^2.3.1",
"handlebars": "^4.7.7",
"lodash": "^4.17.21",
"tiny-emitter": "^2.1.0"
},
"scripts": {
+ "format": "prettier --write \"**/*.{js,jsx,json,ts,md}\"",
"lint": "eslint src tests",
"test": "jest",
"bundle-js": "webpack",
@@ -70,7 +71,7 @@
{
"path": "./lib/chord-mark.js",
"webpack": false,
- "limit": "190 KB"
+ "limit": "195 KB"
}
],
"files": [
diff --git a/src/core/addEventEmitter.js b/src/core/addEventEmitter.js
index 29fb174f..d0a4a1e7 100644
--- a/src/core/addEventEmitter.js
+++ b/src/core/addEventEmitter.js
@@ -18,7 +18,7 @@ export default function addEventEmitter(object) {
emit(eventName, ...args) {
this._emitter.emit(eventName, ...args);
- }
+ },
};
return Object.assign(object, eventEmitter);
diff --git a/src/core/dom/htmlToElement.js b/src/core/dom/htmlToElement.js
index a54c54d8..104299e2 100644
--- a/src/core/dom/htmlToElement.js
+++ b/src/core/dom/htmlToElement.js
@@ -2,6 +2,6 @@ import domPurify from 'dompurify';
export default function htmlToElement(html) {
return domPurify.sanitize(html, {
- RETURN_DOM_FRAGMENT: true
+ RETURN_DOM_FRAGMENT: true,
}).firstChild;
}
diff --git a/src/parser/exceptions/IncorrectBeatCountException.js b/src/parser/exceptions/IncorrectBeatCountException.js
index af883d0f..3dad2277 100644
--- a/src/parser/exceptions/IncorrectBeatCountException.js
+++ b/src/parser/exceptions/IncorrectBeatCountException.js
@@ -2,25 +2,30 @@ import _isString from 'lodash/isString';
import _isFinite from 'lodash/isFinite';
export default class IncorrectBeatCountException extends Error {
- constructor(
- {
- string,
- duration,
- currentBeatCount,
- beatCount
- } = {}
- ) {
+ constructor({ string, duration, currentBeatCount, beatCount } = {}) {
if (!string || !_isString(string)) {
- throw new TypeError('IncorrectBeatCountException cannot be created without chord string, received: ' + string);
+ throw new TypeError(
+ 'IncorrectBeatCountException cannot be created without chord string, received: ' +
+ string
+ );
}
if (!duration || !_isFinite(duration)) {
- throw new TypeError('IncorrectBeatCountException cannot be created without chord duration, received: ' + duration);
+ throw new TypeError(
+ 'IncorrectBeatCountException cannot be created without chord duration, received: ' +
+ duration
+ );
}
if (!currentBeatCount || !_isFinite(currentBeatCount)) {
- throw new TypeError('IncorrectBeatCountException cannot be created without currentBeatCount, received: ' + currentBeatCount);
+ throw new TypeError(
+ 'IncorrectBeatCountException cannot be created without currentBeatCount, received: ' +
+ currentBeatCount
+ );
}
if (!beatCount || !_isFinite(beatCount)) {
- throw new TypeError('IncorrectBeatCountException cannot be created without beatCount, received: ' + beatCount);
+ throw new TypeError(
+ 'IncorrectBeatCountException cannot be created without beatCount, received: ' +
+ beatCount
+ );
}
super();
@@ -32,4 +37,3 @@ export default class IncorrectBeatCountException extends Error {
this.beatCount = beatCount;
}
}
-
diff --git a/src/parser/exceptions/InvalidChordRepetitionException.js b/src/parser/exceptions/InvalidChordRepetitionException.js
index 282873b3..346b69a0 100644
--- a/src/parser/exceptions/InvalidChordRepetitionException.js
+++ b/src/parser/exceptions/InvalidChordRepetitionException.js
@@ -1,13 +1,12 @@
import _isString from 'lodash/isString';
export default class InvalidChordRepetitionException extends Error {
- constructor(
- {
- string,
- } = {}
- ) {
+ constructor({ string } = {}) {
if (!string || !_isString(string)) {
- throw new TypeError('InvalidChordRepetitionException cannot be created without chord string, received: ' + string);
+ throw new TypeError(
+ 'InvalidChordRepetitionException cannot be created without chord string, received: ' +
+ string
+ );
}
super();
@@ -16,4 +15,3 @@ export default class InvalidChordRepetitionException extends Error {
this.string = string;
}
}
-
diff --git a/src/parser/getAllChordsInSong.js b/src/parser/getAllChordsInSong.js
index c9f1afa2..3ef0cbf8 100644
--- a/src/parser/getAllChordsInSong.js
+++ b/src/parser/getAllChordsInSong.js
@@ -12,13 +12,13 @@ export default function getAllChordsInSong(allLines) {
const allChords = [];
let i;
- forEachChordInSong(allLines, chord => {
- i = _findIndex(allChords, o => _isEqual(o.model, chord.model));
+ forEachChordInSong(allLines, (chord) => {
+ i = _findIndex(allChords, (o) => _isEqual(o.model, chord.model));
if (i === -1) {
allChords.push({
model: _cloneDeep(chord.model),
- occurrences: 1
+ occurrences: 1,
});
} else {
allChords[i].occurrences++;
diff --git a/src/parser/helper/clearSpaces.js b/src/parser/helper/clearSpaces.js
index df850eaa..56238891 100644
--- a/src/parser/helper/clearSpaces.js
+++ b/src/parser/helper/clearSpaces.js
@@ -1,6 +1,3 @@
export default function clearSpaces(string) {
- return string
- .replace(/\t+/g, ' ')
- .replace(/ +/g, ' ')
- .trim();
-}
\ No newline at end of file
+ return string.replace(/\t+/g, ' ').replace(/ +/g, ' ').trim();
+}
diff --git a/src/parser/helper/songs.js b/src/parser/helper/songs.js
index 9dd9bd8c..f069268d 100644
--- a/src/parser/helper/songs.js
+++ b/src/parser/helper/songs.js
@@ -10,10 +10,10 @@ import lineTypes from '../lineTypes';
export function forEachChordInSong(allLines, fn) {
const newLines = _cloneDeep(allLines);
- newLines.forEach(line => {
+ newLines.forEach((line) => {
if (line.type === lineTypes.CHORD) {
- line.model.allBars.forEach(bar => {
- bar.allChords.forEach(chord => {
+ line.model.allBars.forEach((bar) => {
+ bar.allChords.forEach((chord) => {
fn(chord);
});
});
@@ -22,7 +22,6 @@ export function forEachChordInSong(allLines, fn) {
return newLines;
}
-
/**
* @param {ChordLine} chordLine
* @param {Function} fn - to execute on each chord
@@ -31,16 +30,15 @@ export function forEachChordInSong(allLines, fn) {
export function forEachChordInChordLine(chordLine, fn) {
const newChordLine = _cloneDeep(chordLine);
- newChordLine.allBars.forEach(bar => {
- bar.allChords.forEach(chord => {
- fn(chord);
+ newChordLine.allBars.forEach((bar, barIndex) => {
+ bar.allChords.forEach((chord, chordIndex) => {
+ fn(chord, chordIndex, barIndex);
});
});
return newChordLine;
}
-
/**
* @param {SongLine[]} allLines
* @param {String} label - the label to select
@@ -54,18 +52,17 @@ export function getNthOfLabel(allLines, label, n) {
let enableSelect = false;
let currentLabel = '';
- allLines.forEach(line => {
+ allLines.forEach((line) => {
if (line.type === lineTypes.SECTION_LABEL) {
currentLabel = line.model.label;
- if (! typesCount[currentLabel]) {
+ if (!typesCount[currentLabel]) {
typesCount[currentLabel] = 1;
} else {
typesCount[currentLabel]++;
}
- enableSelect = (line.id === (label + n));
-
+ enableSelect = line.id === label + n;
} else if (enableSelect) {
selected.push(line);
}
diff --git a/src/parser/lineTypes.js b/src/parser/lineTypes.js
index 425c8cc6..047c72e1 100644
--- a/src/parser/lineTypes.js
+++ b/src/parser/lineTypes.js
@@ -6,7 +6,7 @@ export default {
CHORD: 'chord',
CHORD_LINE_REPEATER: 'chordLineRepeater',
EMPTY_LINE: 'emptyLine',
+ LYRIC: 'lyric',
SECTION_LABEL: 'sectionLabel',
- TEXT: 'text',
TIME_SIGNATURE: 'timeSignature',
};
diff --git a/src/parser/matchers/isChord.js b/src/parser/matchers/isChord.js
index e02a7d6c..089a34fa 100644
--- a/src/parser/matchers/isChord.js
+++ b/src/parser/matchers/isChord.js
@@ -1,7 +1,7 @@
-import { chordParserFactory } from 'chord-symbol';
+import { chordParserFactory } from 'chord-symbol';
export default function isChord(potentialChord) {
const parseChord = chordParserFactory();
const parsed = parseChord(potentialChord);
- return !(parsed.error);
+ return !parsed.error;
}
diff --git a/src/parser/matchers/isChordLine.js b/src/parser/matchers/isChordLine.js
index b6451def..c952b2ef 100644
--- a/src/parser/matchers/isChordLine.js
+++ b/src/parser/matchers/isChordLine.js
@@ -10,9 +10,14 @@ export default function isChordLine(line = '') {
return clearSpaces(line)
.split(' ')
.every((potentialChordToken, index) => {
- const withoutBeatCount = potentialChordToken.replace(chordBeatCountSymbols, '');
- return isChord(withoutBeatCount)
- || (potentialChordToken.match(barRepeatSymbols) && index > 0)
- || (withoutBeatCount === syntax.noChord);
+ const withoutBeatCount = potentialChordToken.replace(
+ chordBeatCountSymbols,
+ ''
+ );
+ return (
+ isChord(withoutBeatCount) ||
+ (potentialChordToken.match(barRepeatSymbols) && index > 0) ||
+ withoutBeatCount === syntax.noChord
+ );
});
}
diff --git a/src/parser/matchers/isChordLineRepeater.js b/src/parser/matchers/isChordLineRepeater.js
index 462effdb..f453b2c9 100644
--- a/src/parser/matchers/isChordLineRepeater.js
+++ b/src/parser/matchers/isChordLineRepeater.js
@@ -2,5 +2,5 @@ import syntax from '../syntax';
import clearSpaces from '../helper/clearSpaces';
export default function isChordLineRepeater(string) {
- return (clearSpaces(string) === syntax.chordLineRepeat);
+ return clearSpaces(string) === syntax.chordLineRepeat;
}
diff --git a/src/parser/matchers/isEmptyLine.js b/src/parser/matchers/isEmptyLine.js
index 556d4bac..24acad10 100644
--- a/src/parser/matchers/isEmptyLine.js
+++ b/src/parser/matchers/isEmptyLine.js
@@ -1,5 +1,5 @@
import clearSpaces from '../helper/clearSpaces';
export default function isEmptyLine(string) {
- return (clearSpaces(string) === '');
+ return clearSpaces(string) === '';
}
diff --git a/src/parser/matchers/isSectionLabel.js b/src/parser/matchers/isSectionLabel.js
index ba603c29..c517ecde 100644
--- a/src/parser/matchers/isSectionLabel.js
+++ b/src/parser/matchers/isSectionLabel.js
@@ -1,10 +1,10 @@
import syntax from '../syntax';
-const sectionLabelRegexp = new RegExp('^' + syntax.sectionLabel + '[a-zA-Z]+( x[2-9])?$');
+const sectionLabelRegexp = new RegExp(
+ '^' + syntax.sectionLabel + '[a-zA-Z]+( x[2-9])?$'
+);
export default function isSectionLabel(string) {
- const found = string
- .trim()
- .match(sectionLabelRegexp);
- return (found !== null);
+ const found = string.trim().match(sectionLabelRegexp);
+ return found !== null;
}
diff --git a/src/parser/matchers/isTimeSignatureString.js b/src/parser/matchers/isTimeSignatureString.js
index 19a3afe1..e4a7171b 100644
--- a/src/parser/matchers/isTimeSignatureString.js
+++ b/src/parser/matchers/isTimeSignatureString.js
@@ -1,7 +1,14 @@
const allowedTimeSignatures = [
- '2/2', '3/2',
- '2/4', '3/4', '4/4', '5/4',
- '3/8', '6/8', '9/8', '12/8'
+ '2/2',
+ '3/2',
+ '2/4',
+ '3/4',
+ '4/4',
+ '5/4',
+ '3/8',
+ '6/8',
+ '9/8',
+ '12/8',
];
export default function isTimeSignatureString(string) {
diff --git a/src/parser/parseChordLine.js b/src/parser/parseChordLine.js
index f4ae527e..fd9b131c 100644
--- a/src/parser/parseChordLine.js
+++ b/src/parser/parseChordLine.js
@@ -44,9 +44,7 @@ const defaultTimeSignature = parseTimeSignature('4/4');
*/
export default function parseChordLine(
chordLine,
- {
- timeSignature = defaultTimeSignature
- } = {}
+ { timeSignature = defaultTimeSignature } = {}
) {
const { beatCount } = timeSignature;
@@ -64,19 +62,22 @@ export default function parseChordLine(
allTokens.forEach((token, tokenIndex) => {
if (token.match(barRepeatSymbols)) {
if (previousBar) {
- for(let i = 0; i < token.length; i++) {
+ for (let i = 0; i < token.length; i++) {
allBars.push(_cloneDeep(previousBar));
}
} else {
- throw new Error('A chord line cannot start with the barRepeat symbol');
+ throw new Error(
+ 'A chord line cannot start with the barRepeat symbol'
+ );
}
-
} else {
tokenWithoutBeatCount = token.replace(chordBeatCountSymbols, '');
chord = {
string: token,
duration: getChordDuration(token, beatCount),
- model: isNoChordSymbol(tokenWithoutBeatCount) ? syntax.noChord : parseChord(tokenWithoutBeatCount),
+ model: isNoChordSymbol(tokenWithoutBeatCount)
+ ? syntax.noChord
+ : parseChord(tokenWithoutBeatCount),
beat: currentBeatCount + 1,
};
currentBeatCount += chord.duration;
@@ -95,25 +96,29 @@ export default function parseChordLine(
bar = _cloneDeep(emptyBar);
currentBeatCount = 0;
-
} else {
- checkInvalidBeatCount(chord, currentBeatCount, beatCount, (allTokens.length === (tokenIndex + 1)));
+ checkInvalidBeatCount(
+ chord,
+ currentBeatCount,
+ beatCount,
+ allTokens.length === tokenIndex + 1
+ );
}
}
});
return {
chordCount,
- allBars
+ allBars,
};
}
function isNoChordSymbol(token) {
- return (token === syntax.noChord);
+ return token === syntax.noChord;
}
function getChordDuration(token, beatCount) {
- return ((token.match(chordBeatCountSymbols) || []).length) || beatCount;
+ return (token.match(chordBeatCountSymbols) || []).length || beatCount;
}
function checkInvalidChordRepetition(bar, currentChord) {
@@ -143,8 +148,10 @@ function checkInvalidBeatCount(chord, currentBeatCount, beatCount, isLast) {
}
}
function hasInvalidBeatCount(currentBeatCount, barBeatCount, isLast) {
- return hasTooManyBeats(currentBeatCount, barBeatCount)
- || hasTooFewBeats(currentBeatCount, barBeatCount, isLast);
+ return (
+ hasTooManyBeats(currentBeatCount, barBeatCount) ||
+ hasTooFewBeats(currentBeatCount, barBeatCount, isLast)
+ );
}
function hasTooManyBeats(currentBeatCount, barBeatCount) {
return currentBeatCount > barBeatCount;
diff --git a/src/parser/parseLyricLine.js b/src/parser/parseLyricLine.js
new file mode 100644
index 00000000..8dc871de
--- /dev/null
+++ b/src/parser/parseLyricLine.js
@@ -0,0 +1,32 @@
+import syntax from './syntax';
+
+/**
+ * @typedef {Object} LyricLine
+ * @type {Object}
+ * @property {String} lyrics
+ * @property {Number[]} chordPositions
+ */
+
+/**
+ * @param {String} string
+ * @returns {LyricLine}
+ */
+export default function parseLyricLine(string) {
+ const regexp = new RegExp(syntax.chordPositionMarker, 'g');
+ const stringWithoutPositionMarkers = string.replace(regexp, '');
+
+ const chordPositions = [];
+ let tmpString = string;
+ let position;
+
+ while ((position = tmpString.indexOf(syntax.chordPositionMarker)) !== -1) {
+ if (!chordPositions.includes(position)) {
+ chordPositions.push(position);
+ }
+ tmpString = tmpString.replace(syntax.chordPositionMarker, '');
+ }
+ return {
+ lyrics: stringWithoutPositionMarkers,
+ chordPositions,
+ };
+}
diff --git a/src/parser/parseSectionLabel.js b/src/parser/parseSectionLabel.js
index 4c0ef85d..c8452570 100644
--- a/src/parser/parseSectionLabel.js
+++ b/src/parser/parseSectionLabel.js
@@ -14,15 +14,16 @@ import isSectionLabel from './matchers/isSectionLabel';
*/
export default function parseSectionLabel(string) {
if (!isSectionLabel(string)) {
- throw new TypeError('Expected section identifier string, received: ' + string);
+ throw new TypeError(
+ 'Expected section identifier string, received: ' + string
+ );
}
- const [ labelSrc, repeatSrc ] = string.trim().split(' ');
+ const [labelSrc, repeatSrc] = string.trim().split(' ');
return {
string,
label: labelSrc.substring(1),
- repeatTimes: (repeatSrc) ? Number.parseInt(repeatSrc.substring(1)) : 0
+ repeatTimes: repeatSrc ? Number.parseInt(repeatSrc.substring(1)) : 0,
};
}
-
diff --git a/src/parser/parseSong.js b/src/parser/parseSong.js
index cf11d074..88101a79 100644
--- a/src/parser/parseSong.js
+++ b/src/parser/parseSong.js
@@ -26,23 +26,20 @@ import getAllChordsInSong from './getAllChordsInSong';
* @returns {Song}
*/
export default function parseSong(songSrc) {
- const songArray = (!_isArray(songSrc)) ? songSrc.split('\n') : songSrc;
+ const songArray = !_isArray(songSrc) ? songSrc.split('\n') : songSrc;
const songLines = songLinesFactory();
/**
* @type {SongLine[]}
*/
- songArray
- .map(escapeHTML)
- .map(stripTags)
- .forEach(songLines.addLine);
+ songArray.map(escapeHTML).map(stripTags).forEach(songLines.addLine);
const allLines = songLines.asArray();
const allChords = getAllChordsInSong(allLines);
return {
allLines,
- allChords
+ allChords,
};
}
diff --git a/src/parser/parseTimeSignature.js b/src/parser/parseTimeSignature.js
index 33ec5cfd..376289d8 100644
--- a/src/parser/parseTimeSignature.js
+++ b/src/parser/parseTimeSignature.js
@@ -15,7 +15,9 @@ import isTimeSignatureString from './matchers/isTimeSignatureString';
*/
export default function parseTimeSignature(string) {
if (!isTimeSignatureString(string)) {
- throw new TypeError('Expected time signature string, received: ' + string);
+ throw new TypeError(
+ 'Expected time signature string, received: ' + string
+ );
}
const array = string.split('/');
@@ -27,7 +29,6 @@ export default function parseTimeSignature(string) {
if (value === 2) {
beatCount = count * 2;
-
} else if (value === 8) {
beatCount = count / 3;
}
@@ -39,4 +40,3 @@ export default function parseTimeSignature(string) {
beatCount,
};
}
-
diff --git a/src/parser/songLinesFactory.js b/src/parser/songLinesFactory.js
index 28251f4d..df07178c 100644
--- a/src/parser/songLinesFactory.js
+++ b/src/parser/songLinesFactory.js
@@ -11,6 +11,7 @@ import isEmptyLine from './matchers/isEmptyLine';
import parseTimeSignature from './parseTimeSignature';
import parseChordLine from './parseChordLine';
import parseSectionLabel from './parseSectionLabel';
+import parseLyricLine from './parseLyricLine';
import { getNthOfLabel } from './helper/songs';
@@ -20,7 +21,7 @@ const defaultTimeSignature = '4/4';
* @typedef {Object} SongLine
* @type {Object}
* @property {String} string - original line in source file
- * @property {String} type - chord|text|timeSignature|sectionLabel...
+ * @property {String} type - chord|lyric|timeSignature|sectionLabel...
* @property {Boolean} [isFromSectionRepeat] - line created by a section repeat directive (x3...)
* @property {Boolean} [isFromAutoRepeatChords] - line created by auto repeats of chords from a section to another
*/
@@ -39,8 +40,9 @@ const defaultTimeSignature = '4/4';
*/
/**
- * @typedef {SongLine} SongTextLine
+ * @typedef {SongLine} SongLyricLine
* @type {Object}
+ * @property {LyricLine} model
*/
/**
@@ -101,7 +103,7 @@ export default function songLinesFactory() {
id: currentSectionLabel.label + currentSectionStats.count,
};
- shouldRepeatSection = (currentSectionLabel.repeatTimes > 0);
+ shouldRepeatSection = currentSectionLabel.repeatTimes > 0;
previousSectionLabelLine = _cloneDeep(line);
if (!isFirstOfLabel(currentSectionLabel, allLines)) {
@@ -115,7 +117,7 @@ export default function songLinesFactory() {
}
/**
- * @returns {SongTextLine}
+ * @returns {SongLyricLine}
*/
function getEmptyLine(string) {
return {
@@ -125,48 +127,50 @@ export default function songLinesFactory() {
}
/**
- * @returns {SongChordLine|SongTextLine}
+ * @returns {SongChordLine|SongLyricLine}
*/
function getChordLine(string) {
let line;
try {
- const model = parseChordLine(string, { timeSignature: currentTimeSignature });
+ const model = parseChordLine(string, {
+ timeSignature: currentTimeSignature,
+ });
line = {
string,
type: lineTypes.CHORD,
model,
};
previousChordLine = line;
-
} catch (e) {
- line = getTextLine(string);
+ line = getLyricLine(string);
}
return line;
}
/**
- * @returns {SongChordLine|SongTextLine}
+ * @returns {SongChordLine|SongLyricLine}
*/
function getPreviousChordLine(string) {
if (previousChordLine) {
return {
..._cloneDeep(previousChordLine),
- isFromChordLineRepeater: true
+ isFromChordLineRepeater: true,
};
}
- return getTextLine(string);
+ return getLyricLine(string);
}
/**
- * @returns {SongTextLine}
+ * @returns {SongLyricLine}
*/
- function getTextLine(string) {
+ function getLyricLine(string) {
return {
string,
- type: lineTypes.TEXT,
+ type: lineTypes.LYRIC,
+ model: parseLyricLine(string),
};
}
-
+
function increaseSectionStats(label, isRepeated = false) {
if (!sectionsStats[label]) {
sectionsStats[label] = {
@@ -207,17 +211,25 @@ export default function songLinesFactory() {
}
function repeatSection(lineIndex, allSrcLines) {
- if (shouldRepeatSection && isLastLineOfSection(lineIndex, allSrcLines)) {
- const toRepeat = getNthOfLabel(allLines, currentSectionLabel.label, currentSectionStats.count)
- .map(line => ({
- ..._cloneDeep(line),
- isFromSectionRepeat: true
- }));
+ if (
+ shouldRepeatSection &&
+ isLastLineOfSection(lineIndex, allSrcLines)
+ ) {
+ const toRepeat = getNthOfLabel(
+ allLines,
+ currentSectionLabel.label,
+ currentSectionStats.count
+ ).map((line) => ({
+ ..._cloneDeep(line),
+ isFromSectionRepeat: true,
+ }));
let sectionLabelLine;
for (let i = 1; i < currentSectionLabel.repeatTimes; i++) {
increaseSectionStats(currentSectionLabel.label, true);
- currentSectionStats = getSectionCount(currentSectionLabel.label);
+ currentSectionStats = getSectionCount(
+ currentSectionLabel.label
+ );
sectionLabelLine = {
..._cloneDeep(previousSectionLabelLine),
@@ -237,21 +249,16 @@ export default function songLinesFactory() {
let line;
if (isTimeSignature(lineSrc)) {
line = getTimeSignatureLine(lineSrc);
-
} else if (isSectionLabel(lineSrc)) {
line = getSectionLabelLine(lineSrc);
-
} else if (isChordLine(lineSrc)) {
line = getChordLine(lineSrc);
-
} else if (isChordLineRepeater(lineSrc)) {
line = getPreviousChordLine(lineSrc);
-
} else if (isEmptyLine(lineSrc)) {
line = getEmptyLine(lineSrc);
-
} else {
- line = getTextLine(lineSrc);
+ line = getLyricLine(lineSrc);
}
repeatLinesFromBlueprint(line);
@@ -259,7 +266,6 @@ export default function songLinesFactory() {
allLines.push(line);
repeatSection(lineIndex, allSrcLines);
-
},
/**
@@ -267,22 +273,26 @@ export default function songLinesFactory() {
*/
asArray() {
return _cloneDeep(allLines);
- }
+ },
};
}
function isFirstOfLabel(currentLabel, allLines) {
- return allLines.every(line =>
- (line.type === lineTypes.SECTION_LABEL && line.model.label !== currentLabel.label)
+ return allLines.every(
+ (line) =>
+ line.type === lineTypes.SECTION_LABEL &&
+ line.model.label !== currentLabel.label
);
}
function shouldRepeatLineFromBlueprint(blueprintLine, currentLine) {
- return blueprintLine
- && blueprintLine.type !== lineTypes.TEXT
- && blueprintLine.type !== lineTypes.EMPTY_LINE
- && blueprintLine.type !== currentLine.type
- && currentLine.type !== lineTypes.EMPTY_LINE;
+ return (
+ blueprintLine &&
+ blueprintLine.type !== lineTypes.LYRIC &&
+ blueprintLine.type !== lineTypes.EMPTY_LINE &&
+ blueprintLine.type !== currentLine.type &&
+ currentLine.type !== lineTypes.EMPTY_LINE
+ );
}
function isLastLineOfSection(lineIndex, allSrcLines) {
diff --git a/src/parser/syntax.js b/src/parser/syntax.js
index 2c8a2e48..bd62478e 100644
--- a/src/parser/syntax.js
+++ b/src/parser/syntax.js
@@ -5,4 +5,5 @@ export default {
noChord: 'NC',
noLyrics: 'NL',
sectionLabel: '#',
+ chordPositionMarker: '_',
};
diff --git a/src/renderer/components/renderBarContent.js b/src/renderer/components/renderBarContent.js
index 3ba3d1d4..cab95705 100644
--- a/src/renderer/components/renderBarContent.js
+++ b/src/renderer/components/renderBarContent.js
@@ -17,8 +17,12 @@ export default function renderBarContent(bar) {
let spacesAfter = 0;
const barContent = bar.allChords.reduce((rendering, chord) => {
- spacesWithin = _isFinite(chord.spacesWithin) ? chord.spacesWithin : defaultSpacesWithin;
- spacesAfter = _isFinite(chord.spacesAfter) ? chord.spacesAfter : defaultSpacesAfter;
+ spacesWithin = _isFinite(chord.spacesWithin)
+ ? chord.spacesWithin
+ : defaultSpacesWithin;
+ spacesAfter = _isFinite(chord.spacesAfter)
+ ? chord.spacesAfter
+ : defaultSpacesAfter;
rendering +=
renderChord(chord.symbol) +
diff --git a/src/renderer/components/renderChordLine.js b/src/renderer/components/renderChordLine.js
index 7dbd2b31..08972ecc 100644
--- a/src/renderer/components/renderChordLine.js
+++ b/src/renderer/components/renderChordLine.js
@@ -2,20 +2,25 @@ import chordLineTpl from './tpl/chordLine.hbs';
import renderBarContent from './renderBarContent';
import barSeparatorTpl from './tpl/barSeparator.hbs';
+import symbols from '../symbols';
/**
* @param {ChordLine} chordLineModel
* @returns {String} rendered html
*/
export default function renderChordLine(chordLineModel) {
- const allBarsRendered = chordLineModel.allBars
- .map(bar => renderBarContent(bar));
+ const allBarsRendered = chordLineModel.allBars.map((bar) =>
+ renderBarContent(bar)
+ );
const barSeparator = barSeparatorTpl();
- const chordLine = barSeparator +
- allBarsRendered.join(barSeparator) +
- barSeparator;
+ const chordLine =
+ barSeparator + allBarsRendered.join(barSeparator) + barSeparator;
- return chordLineTpl({ chordLine });
+ const chordLineOffset = symbols.chordLineOffsetSpacer.repeat(
+ chordLineModel.offset || 0
+ );
+
+ return chordLineTpl({ chordLineOffset, chordLine });
}
diff --git a/src/renderer/components/renderChordSymbol.js b/src/renderer/components/renderChordSymbol.js
index 197ad28b..de261641 100644
--- a/src/renderer/components/renderChordSymbol.js
+++ b/src/renderer/components/renderChordSymbol.js
@@ -4,6 +4,6 @@ import chordSymbolTpl from './tpl/chordSymbol.hbs';
* @param {String} chordSymbol
* @returns {String} rendered html
*/
-export default function renderChordSymbol (chordSymbol) {
+export default function renderChordSymbol(chordSymbol) {
return chordSymbolTpl({ chordSymbol });
}
diff --git a/src/renderer/components/renderLine.js b/src/renderer/components/renderLine.js
index e0dc4b00..b125ea55 100644
--- a/src/renderer/components/renderLine.js
+++ b/src/renderer/components/renderLine.js
@@ -7,11 +7,14 @@ import lineTpl from './tpl/line.hbs';
* @param {Boolean} isFromChordLineRepeater
* @returns {String} rendered html
*/
-export default function render(line, {
- isFromSectionRepeat = false,
- isFromAutoRepeatChords = false,
- isFromChordLineRepeater = false,
-} = {}) {
+export default function render(
+ line,
+ {
+ isFromSectionRepeat = false,
+ isFromAutoRepeatChords = false,
+ isFromChordLineRepeater = false,
+ } = {}
+) {
const lineClasses = ['cmLine'];
if (isFromSectionRepeat) {
lineClasses.push('cmLine--isFromSectionRepeat');
diff --git a/src/renderer/components/renderLyricLine.js b/src/renderer/components/renderLyricLine.js
new file mode 100644
index 00000000..361d9193
--- /dev/null
+++ b/src/renderer/components/renderLyricLine.js
@@ -0,0 +1,9 @@
+import lyricLineTpl from './tpl/lyricLine.hbs';
+
+/**
+ * @param {SongLyricLine} lyricLine
+ * @returns {String} rendered html
+ */
+export default function render(lyricLine) {
+ return lyricLineTpl({ lyricLine: lyricLine.model.lyrics });
+}
diff --git a/src/renderer/components/renderSectionLabel.js b/src/renderer/components/renderSectionLabel.js
index 8a8fab7c..669f0fa7 100644
--- a/src/renderer/components/renderSectionLabel.js
+++ b/src/renderer/components/renderSectionLabel.js
@@ -12,28 +12,26 @@ const labelsMapping = {
v: 'verse',
};
-
/**
* @param {SongSectionLabelLine} sectionLabelLine
* @param {Boolean} expandSectionRepeats
* @param {Object} sectionsStats - key = section label, value = section count in song
* @returns {String} rendered html
*/
-export default function renderSectionLabel(sectionLabelLine, {
- expandSectionRepeats = true,
- sectionsStats = {},
-} = {}) {
+export default function renderSectionLabel(
+ sectionLabelLine,
+ { expandSectionRepeats = true, sectionsStats = {} } = {}
+) {
const { model, index, indexWithoutRepeats } = sectionLabelLine;
const labelRaw = labelsMapping[model.label]
? labelsMapping[model.label]
: model.label;
-
let rendered = labelRaw[0].toUpperCase() + labelRaw.substring(1);
if (sectionsStats[model.label] > 1) {
rendered += ' ';
- rendered += (expandSectionRepeats) ? index : indexWithoutRepeats;
+ rendered += expandSectionRepeats ? index : indexWithoutRepeats;
}
if (!expandSectionRepeats && model.repeatTimes) {
diff --git a/src/renderer/components/renderSong.js b/src/renderer/components/renderSong.js
index 6a27e715..8ed03004 100644
--- a/src/renderer/components/renderSong.js
+++ b/src/renderer/components/renderSong.js
@@ -2,14 +2,15 @@ import getMaxBeatsWidth from '../spacers/chord/getMaxBeatsWidth';
import simpleChordSpacer from '../spacers/chord/simple';
import alignedChordSpacer from '../spacers/chord/aligned';
+import chordLyricsSpacer from '../spacers/chord/chordLyrics';
import { forEachChordInSong } from '../../parser/helper/songs';
-import renderChordLine from './renderChordLine';
+import renderChordLineModel from './renderChordLine';
import renderEmptyLine from './renderEmptyLine';
import renderLine from './renderLine';
import renderSectionLabel from './renderSectionLabel';
-import renderTextLine from './renderTextLine';
+import renderLyricLine from './renderLyricLine';
import renderTimeSignature from './renderTimeSignature';
import songTpl from './tpl/song.hbs';
@@ -24,6 +25,7 @@ import lineTypes from '../../parser/lineTypes';
/**
* @param {Song} parsedSong
* @param {Boolean} alignBars
+ * @param {Boolean} alignChordsWithLyrics
* @param {Number} transposeValue
* @param {('auto'|'flat'|'sharp')} accidentalsType
* @param {Boolean} harmonizeAccidentals
@@ -33,29 +35,33 @@ import lineTypes from '../../parser/lineTypes';
* @param {Boolean} useShortNamings
* @returns {String} rendered HTML
*/
-export default function renderSong(parsedSong, {
- alignBars = false,
- transposeValue = 0,
- accidentalsType = 'auto',
- harmonizeAccidentals = true,
- expandSectionRepeats = true,
- autoRepeatChords = true,
- simplifyChords = 'none',
- useShortNamings = true,
-} = {}) {
-
+export default function renderSong(
+ parsedSong,
+ {
+ alignBars = false,
+ alignChordsWithLyrics = true,
+ transposeValue = 0,
+ accidentalsType = 'auto',
+ harmonizeAccidentals = true,
+ expandSectionRepeats = true,
+ autoRepeatChords = true,
+ simplifyChords = 'none',
+ useShortNamings = true,
+ } = {}
+) {
let { allLines, allChords } = parsedSong;
- const accidental = (accidentalsType === 'auto')
- ? getMainAccidental(allChords)
- : accidentalsType;
+ const accidental =
+ accidentalsType === 'auto'
+ ? getMainAccidental(allChords)
+ : accidentalsType;
const renderChord = chordRendererFactory({
simplify: simplifyChords,
useShortNamings,
transposeValue,
harmonizeAccidentals,
- useFlats: (accidental === 'flat'),
+ useFlats: accidental === 'flat',
});
allLines = forEachChordInSong(allLines, (chord) => {
@@ -69,28 +75,36 @@ export default function renderSong(parsedSong, {
const song = allLines
.filter(shouldRenderLine)
- .map(line => {
+ .map((line, lineIndex, allFilteredLines) => {
let rendered;
if (line.type === lineTypes.CHORD) {
- // todo: move this in renderChordLine
- const spaced = (alignBars)
+ let spaced = alignBars
? alignedChordSpacer(line.model, maxBeatsWidth)
: simpleChordSpacer(line.model);
- rendered = renderChordLine(spaced);
-
+ const nextLine = allFilteredLines[lineIndex + 1];
+ if (shouldAlignChords(alignChordsWithLyrics, nextLine)) {
+ const { chordLine, lyricsLine } = chordLyricsSpacer(
+ spaced,
+ nextLine.model
+ );
+ allFilteredLines[lineIndex + 1].model = lyricsLine;
+ spaced = chordLine;
+ }
+
+ rendered = renderChordLineModel(spaced);
} else if (line.type === lineTypes.EMPTY_LINE) {
rendered = renderEmptyLine();
-
} else if (line.type === lineTypes.SECTION_LABEL) {
- rendered = renderSectionLabel(line, { sectionsStats, expandSectionRepeats });
-
+ rendered = renderSectionLabel(line, {
+ sectionsStats,
+ expandSectionRepeats,
+ });
} else if (line.type === lineTypes.TIME_SIGNATURE) {
rendered = renderTimeSignature(line);
-
} else {
- rendered = renderTextLine(line);
+ rendered = renderLyricLine(line);
}
return renderLine(rendered, {
isFromSectionRepeat: line.isFromSectionRepeat,
@@ -101,12 +115,13 @@ export default function renderSong(parsedSong, {
.filter(Boolean)
.join('\n');
-
function shouldRenderLine(line) {
if (line.type === lineTypes.SECTION_LABEL) {
- shouldSkipRepeatedSectionLine = (line.isFromSectionRepeat === true && !expandSectionRepeats);
+ shouldSkipRepeatedSectionLine =
+ line.isFromSectionRepeat === true && !expandSectionRepeats;
}
- const shouldSkipAutoRepeatChordLine = (line.isFromAutoRepeatChords && !autoRepeatChords);
+ const shouldSkipAutoRepeatChordLine =
+ line.isFromAutoRepeatChords && !autoRepeatChords;
return !shouldSkipRepeatedSectionLine && !shouldSkipAutoRepeatChordLine;
}
@@ -114,4 +129,8 @@ export default function renderSong(parsedSong, {
return songTpl({ song });
}
-
+function shouldAlignChords(alignChordsWithLyrics, nextLine) {
+ return (
+ alignChordsWithLyrics && nextLine && nextLine.type === lineTypes.LYRIC
+ );
+}
diff --git a/src/renderer/components/renderTextLine.js b/src/renderer/components/renderTextLine.js
deleted file mode 100644
index 34f40a12..00000000
--- a/src/renderer/components/renderTextLine.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import textLineTpl from './tpl/textLine.hbs';
-
-/**
- * @param {SongTextLine} textLine
- * @returns {String} rendered html
- */
-export default function render(textLine) {
- return textLineTpl({ textLine: textLine.string });
-}
diff --git a/src/renderer/components/tpl/chordLine.hbs b/src/renderer/components/tpl/chordLine.hbs
index 0c4c6573..3ade09d1 100644
--- a/src/renderer/components/tpl/chordLine.hbs
+++ b/src/renderer/components/tpl/chordLine.hbs
@@ -1 +1 @@
-{{{ this.chordLine }}}
\ No newline at end of file
+{{#if this.chordLineOffset}}{{{ this.chordLineOffset }}}{{/if}}{{{ this.chordLine }}}
\ No newline at end of file
diff --git a/src/renderer/components/tpl/lyricLine.hbs b/src/renderer/components/tpl/lyricLine.hbs
new file mode 100644
index 00000000..570ec8af
--- /dev/null
+++ b/src/renderer/components/tpl/lyricLine.hbs
@@ -0,0 +1 @@
+{{{ this.lyricLine }}}
\ No newline at end of file
diff --git a/src/renderer/components/tpl/textLine.hbs b/src/renderer/components/tpl/textLine.hbs
deleted file mode 100644
index d72afa24..00000000
--- a/src/renderer/components/tpl/textLine.hbs
+++ /dev/null
@@ -1 +0,0 @@
-{{{ this.textLine }}}
\ No newline at end of file
diff --git a/src/renderer/helpers/getChordSymbol.js b/src/renderer/helpers/getChordSymbol.js
index de89d5c4..4ec4ae18 100644
--- a/src/renderer/helpers/getChordSymbol.js
+++ b/src/renderer/helpers/getChordSymbol.js
@@ -9,6 +9,6 @@ const defaultRenderChord = chordRendererFactory();
* @param {Function} renderChord
* @returns {string}
*/
-export default function(model, renderChord = defaultRenderChord) {
- return (model === syntax.noChord) ? noChordSymbol : renderChord(model);
+export default function (model, renderChord = defaultRenderChord) {
+ return model === syntax.noChord ? noChordSymbol : renderChord(model);
}
diff --git a/src/renderer/helpers/getMainAccidental.js b/src/renderer/helpers/getMainAccidental.js
index fb3add3e..03e87598 100644
--- a/src/renderer/helpers/getMainAccidental.js
+++ b/src/renderer/helpers/getMainAccidental.js
@@ -12,8 +12,8 @@ export default function getMainAccidental(allChords) {
let sharpCount = 0;
allChords
- .filter(chord => (chord.model !== syntax.noChord))
- .forEach(chord => {
+ .filter((chord) => chord.model !== syntax.noChord)
+ .forEach((chord) => {
rootNote = chord.model.formatted.rootNote;
if (rootNote.length === 2) {
@@ -27,5 +27,5 @@ export default function getMainAccidental(allChords) {
}
});
- return (flatCount > sharpCount) ? 'flat' : 'sharp';
+ return flatCount > sharpCount ? 'flat' : 'sharp';
}
diff --git a/src/renderer/helpers/getSectionsStats.js b/src/renderer/helpers/getSectionsStats.js
index 05e9ab89..8c877d50 100644
--- a/src/renderer/helpers/getSectionsStats.js
+++ b/src/renderer/helpers/getSectionsStats.js
@@ -10,11 +10,10 @@ export default function getSectionsStats(allLines) {
const stats = {};
allLines
- .filter(line => line.type === lineTypes.SECTION_LABEL)
- .forEach(line => {
+ .filter((line) => line.type === lineTypes.SECTION_LABEL)
+ .forEach((line) => {
if (!stats[line.model.label]) {
stats[line.model.label] = 1;
-
} else {
stats[line.model.label]++;
}
diff --git a/src/renderer/spacers/chord/aligned.js b/src/renderer/spacers/chord/aligned.js
index eb09d4b9..5b68016e 100644
--- a/src/renderer/spacers/chord/aligned.js
+++ b/src/renderer/spacers/chord/aligned.js
@@ -9,17 +9,22 @@ export default function space(chordLineInput, maxBeatsWidth) {
let beatMaxWidth;
chordLine.allBars.forEach((bar, barIndex) => {
- bar.allChords.forEach(chord => {
- chord.spacesWithin = maxBeatsWidth[barIndex][chord.beat] - chord.symbol.length;
+ bar.allChords.forEach((chord) => {
+ chord.spacesWithin =
+ maxBeatsWidth[barIndex][chord.beat] - chord.symbol.length;
chord.spacesAfter = 0;
if (chord.beat !== bar.timeSignature.beatCount) {
chord.spacesAfter = spacesAfterDefault;
- for (let i = (chord.beat + 1); i < (chord.beat + chord.duration); i++) {
+ for (
+ let i = chord.beat + 1;
+ i < chord.beat + chord.duration;
+ i++
+ ) {
beatMaxWidth = maxBeatsWidth[barIndex][i];
- chord.spacesAfter += (beatMaxWidth)
+ chord.spacesAfter += beatMaxWidth
? beatMaxWidth
: emptyBeatSpaces;
diff --git a/src/renderer/spacers/chord/chordLyrics.js b/src/renderer/spacers/chord/chordLyrics.js
new file mode 100644
index 00000000..79f2c15a
--- /dev/null
+++ b/src/renderer/spacers/chord/chordLyrics.js
@@ -0,0 +1,109 @@
+import _cloneDeep from 'lodash/cloneDeep';
+import { forEachChordInChordLine } from '../../../parser/helper/songs';
+
+import symbols from '../../symbols';
+
+const chordSpaceAfterDefault = 1;
+
+/**
+ * @param {ChordLine} chordLineInput
+ * @param {LyricLine} lyricsLineInput
+ * @returns {Object}
+ */
+export default function space(chordLineInput, lyricsLineInput) {
+ const chordLine = _cloneDeep(chordLineInput);
+ const lyricsLine = _cloneDeep(lyricsLineInput);
+
+ if (hasNoPositionMarkers(lyricsLine)) {
+ return {
+ chordLine,
+ lyricsLine,
+ };
+ }
+
+ const tokenizedLyrics = lyricsLine.chordPositions.map(
+ (position, i, allPositions) => {
+ return lyricsLine.lyrics.substring(position, allPositions[i + 1]);
+ }
+ );
+ let spacedLyricsLine = '';
+
+ let chordToken;
+ let lyricToken;
+ let currentBarIndex = 0;
+
+ const spacedChordLine = forEachChordInChordLine(
+ chordLine,
+ (chord, chordIndex, barIndex) => {
+ lyricToken = tokenizedLyrics.shift();
+
+ if (lyricToken) {
+ chordToken = chord.symbol;
+ if (isFirstChord(barIndex, chordIndex)) {
+ chordToken = symbols.barSeparator + chordToken;
+ } else if (isNewBar(currentBarIndex, barIndex)) {
+ chordToken = symbols.barSeparator + chordToken;
+ currentBarIndex = barIndex;
+ }
+
+ if (startsWithSpace(lyricToken)) {
+ lyricToken =
+ symbols.lyricsSpacer.repeat(chordToken.length) +
+ lyricToken;
+ }
+
+ if (lyricToken.length - chordToken.length > 0) {
+ chord.spacesAfter = lyricToken.length - chordToken.length;
+ } else {
+ chord.spacesAfter = chordSpaceAfterDefault;
+ const lyricsSpaceAfter =
+ chordToken.length -
+ lyricToken.length +
+ chordSpaceAfterDefault;
+ lyricToken += symbols.lyricsSpacer.repeat(lyricsSpaceAfter);
+ }
+ spacedLyricsLine += lyricToken;
+ } else {
+ chord.spacesAfter = chordSpaceAfterDefault;
+ }
+ chord.spacesWithin = 0;
+ }
+ );
+
+ if (shouldOffsetChordLine(lyricsLine)) {
+ const chordLineOffset = lyricsLine.chordPositions[0];
+ spacedChordLine.offset = chordLineOffset;
+ spacedLyricsLine =
+ lyricsLine.lyrics.substring(0, chordLineOffset) + spacedLyricsLine;
+ }
+
+ if (tokenizedLyrics.length) {
+ spacedLyricsLine += tokenizedLyrics.join('');
+ }
+ lyricsLine.lyrics = trimEnd(spacedLyricsLine);
+
+ return {
+ chordLine: spacedChordLine,
+ lyricsLine,
+ };
+}
+
+const hasNoPositionMarkers = (lyricsLine) =>
+ lyricsLine.chordPositions.length === 0;
+
+const shouldOffsetChordLine = (lyricsLine) => lyricsLine.chordPositions[0] > 0;
+
+const isFirstChord = (barIndex, chordIndex) =>
+ barIndex === 0 && chordIndex === 0;
+
+const isNewBar = (currentBarIndex, barIndex) => currentBarIndex !== barIndex;
+
+// source: https://github.com/es-shims/String.prototype.trimEnd/blob/main/implementation.js
+const trimEnd = (str) => {
+ const endWhitespace =
+ // eslint-disable-next-line max-len,no-control-regex
+ /[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]*$/;
+ return str.replace(endWhitespace, '');
+};
+
+const startsWithSpace = (str) => str.indexOf(' ') === 0;
diff --git a/src/renderer/spacers/chord/getMaxBeatsWidth.js b/src/renderer/spacers/chord/getMaxBeatsWidth.js
index 60b52ed7..7160e22c 100644
--- a/src/renderer/spacers/chord/getMaxBeatsWidth.js
+++ b/src/renderer/spacers/chord/getMaxBeatsWidth.js
@@ -8,8 +8,8 @@ export default function getMaxBeatsWidth(allLines) {
const maxBeatsWidth = [];
allLines
- .filter(line => line.type === lineTypes.CHORD)
- .forEach(line => {
+ .filter((line) => line.type === lineTypes.CHORD)
+ .forEach((line) => {
line.model.allBars.forEach((bar, barIndex) => {
if (!maxBeatsWidth[barIndex]) {
maxBeatsWidth[barIndex] = {};
@@ -18,7 +18,7 @@ export default function getMaxBeatsWidth(allLines) {
maxBeatsWidth[barIndex][i] = 0;
}
}
- bar.allChords.forEach(chord => {
+ bar.allChords.forEach((chord) => {
maxBeatsWidth[barIndex][chord.beat] = Math.max(
maxBeatsWidth[barIndex][chord.beat],
chord.symbol.length
diff --git a/src/renderer/spacers/chord/simple.js b/src/renderer/spacers/chord/simple.js
index 246704c2..f079a5db 100644
--- a/src/renderer/spacers/chord/simple.js
+++ b/src/renderer/spacers/chord/simple.js
@@ -4,30 +4,30 @@ const defaultSpacesAfter = 2;
const allMasks = {
0: {
- '': []
+ '': [],
},
2: {
- '2': [3], // 'A '
- '11': [3, 2], // 'A B ',
+ 2: [3], // 'A '
+ 11: [3, 2], // 'A B ',
},
3: {
- '3': [3], // 'A '
- '12': [2, 4], // 'A B '
- '21': [6, 0], // 'A C'
- '111': [2, 2, 0], // 'A B C'
+ 3: [3], // 'A '
+ 12: [2, 4], // 'A B '
+ 21: [6, 0], // 'A C'
+ 111: [2, 2, 0], // 'A B C'
},
4: {
- '4': [3], // 'A ',
- '13': [1, 4], // 'A B ',
- '22': [3, 2], // 'A B ',
- '31': [5, 0], // 'A B',
- '112': [1, 1, 3], // 'A B C ',
- '121': [1, 4, 0], // 'A B C',
- '211': [4, 1, 0], // 'A B C',
- '1111': [2, 2, 2, 0], // 'A B C D',
+ 4: [3], // 'A ',
+ 13: [1, 4], // 'A B ',
+ 22: [3, 2], // 'A B ',
+ 31: [5, 0], // 'A B',
+ 112: [1, 1, 3], // 'A B C ',
+ 121: [1, 4, 0], // 'A B C',
+ 211: [4, 1, 0], // 'A B C',
+ 1111: [2, 2, 2, 0], // 'A B C D',
},
};
@@ -42,13 +42,13 @@ export default function space(chordLineInput) {
let chordPattern = '';
let chordSpaces = [];
- chordLine.allBars.forEach(bar => {
+ chordLine.allBars.forEach((bar) => {
beatCount = 0;
chordPattern = '';
chordSpaces = [];
chordCount = bar.allChords.length;
- bar.allChords.forEach(chord => {
+ bar.allChords.forEach((chord) => {
chordPattern += chord.duration.toString();
beatCount += chord.duration;
});
@@ -58,9 +58,10 @@ export default function space(chordLineInput) {
}
for (let i = 0; i < chordCount; i++) {
- bar.allChords[i].spacesAfter = (typeof(chordSpaces[i]) !== 'undefined')
- ? chordSpaces[i]
- : defaultSpacesAfter;
+ bar.allChords[i].spacesAfter =
+ typeof chordSpaces[i] !== 'undefined'
+ ? chordSpaces[i]
+ : defaultSpacesAfter;
}
});
diff --git a/src/renderer/symbols.js b/src/renderer/symbols.js
new file mode 100644
index 00000000..f580c55f
--- /dev/null
+++ b/src/renderer/symbols.js
@@ -0,0 +1,5 @@
+export default {
+ lyricsSpacer: ' ',
+ chordLineOffsetSpacer: ' ',
+ barSeparator: '|',
+};
diff --git a/tests/.eslintrc.js b/tests/.eslintrc.js
index efdbd388..d3916f29 100644
--- a/tests/.eslintrc.js
+++ b/tests/.eslintrc.js
@@ -1,16 +1,16 @@
module.exports = {
- 'env': {
- 'jest': true,
- 'node': true,
+ env: {
+ jest: true,
+ node: true,
},
- 'rules': {
- 'max-len': [ 'off' ],
- 'max-lines': [ 'off' ],
- 'max-lines-per-function': [ 'off' ],
- 'max-params': [ 'off' ],
+ rules: {
+ 'max-len': ['off'],
+ 'max-lines': ['off'],
+ 'max-lines-per-function': ['off'],
+ 'max-params': ['off'],
- 'no-restricted-imports': [ 'off' ],
+ 'no-restricted-imports': ['off'],
- 'no-unsanitized/property':[ 'off' ],
- }
+ 'no-unsanitized/property': ['off'],
+ },
};
diff --git a/tests/integration/parser/parseSong.spec.js b/tests/integration/parser/parseSong.spec.js
index e0698c33..bebc14ac 100644
--- a/tests/integration/parser/parseSong.spec.js
+++ b/tests/integration/parser/parseSong.spec.js
@@ -2,7 +2,7 @@ import parseChordLine from '../../../src/parser/parseChordLine';
import parseChord from '../../../src/parser/parseChord';
import parseSong from '../../../src/parser/parseSong';
import parseTimeSignature from '../../../src/parser/parseTimeSignature';
-
+import parseLyricLine from '../../../src/parser/parseLyricLine';
describe('parseSong', () => {
test('', () => {
@@ -30,24 +30,94 @@ F. Em. Dm. C.
Let it be`;
const expected = {
allLines: [
- { type: 'timeSignature', string: '4/4', model: parseTimeSignature('4/4') },
- { type: 'chord', string: 'C.. G..', model: parseChordLine('C.. G..')} ,
- { type: 'text', string: 'When I find myself in times of trouble' },
- { type: 'chord', string: 'Am.. F..', model: parseChordLine('Am.. F..') },
- { type: 'text', string: 'Mother mary comes to me' },
- { type: 'chord', string: 'C.. G..', model: parseChordLine('C.. G..') },
- { type: 'text', string: 'Speaking words of wisdom' },
- { type: 'chord', string: 'F. Em. Dm. C.', model: parseChordLine('F. Em. Dm. C.') },
- { type: 'text', string: 'Let it be' },
+ {
+ type: 'timeSignature',
+ string: '4/4',
+ model: parseTimeSignature('4/4'),
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: parseChordLine('C.. G..'),
+ },
+ {
+ type: 'lyric',
+ string: 'When I find myself in times of trouble',
+ model: parseLyricLine(
+ 'When I find myself in times of trouble'
+ ),
+ },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: parseChordLine('Am.. F..'),
+ },
+ {
+ type: 'lyric',
+ string: 'Mother mary comes to me',
+ model: parseLyricLine('Mother mary comes to me'),
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: parseChordLine('C.. G..'),
+ },
+ {
+ type: 'lyric',
+ string: 'Speaking words of wisdom',
+ model: parseLyricLine('Speaking words of wisdom'),
+ },
+ {
+ type: 'chord',
+ string: 'F. Em. Dm. C.',
+ model: parseChordLine('F. Em. Dm. C.'),
+ },
+ {
+ type: 'lyric',
+ string: 'Let it be',
+ model: parseLyricLine('Let it be'),
+ },
{ type: 'emptyLine', string: '' },
- { type: 'chord', string: 'Am.. G..', model: parseChordLine('Am.. G..') },
- { type: 'text', string: 'Let it be, let it be' },
- { type: 'chord', string: 'C.. F..', model: parseChordLine('C.. F..') },
- { type: 'text', string: 'Let it be, let it be' },
- { type: 'chord', string: 'C.. G..', model: parseChordLine('C.. G..') },
- { type: 'text', string: 'Whispers words of wisdom' },
- { type: 'chord', string: 'F. Em. Dm. C.', model: parseChordLine('F. Em. Dm. C.') },
- { type: 'text', string: 'Let it be' },
+ {
+ type: 'chord',
+ string: 'Am.. G..',
+ model: parseChordLine('Am.. G..'),
+ },
+ {
+ type: 'lyric',
+ string: 'Let it be, let it be',
+ model: parseLyricLine('Let it be, let it be'),
+ },
+ {
+ type: 'chord',
+ string: 'C.. F..',
+ model: parseChordLine('C.. F..'),
+ },
+ {
+ type: 'lyric',
+ string: 'Let it be, let it be',
+ model: parseLyricLine('Let it be, let it be'),
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: parseChordLine('C.. G..'),
+ },
+ {
+ type: 'lyric',
+ string: 'Whispers words of wisdom',
+ model: parseLyricLine('Whispers words of wisdom'),
+ },
+ {
+ type: 'chord',
+ string: 'F. Em. Dm. C.',
+ model: parseChordLine('F. Em. Dm. C.'),
+ },
+ {
+ type: 'lyric',
+ string: 'Let it be',
+ model: parseLyricLine('Let it be'),
+ },
],
allChords: [
{ model: parseChord('C'), occurrences: 6 },
@@ -56,7 +126,7 @@ Let it be`;
{ model: parseChord('F'), occurrences: 4 },
{ model: parseChord('Em'), occurrences: 2 },
{ model: parseChord('Dm'), occurrences: 2 },
- ]
+ ],
};
expect(parseSong(input)).toEqual(expected);
@@ -67,24 +137,41 @@ Let it be`;
'C.. G..',
'When I find myself in times of trouble',
'Am.. F..',
- 'Mother mary comes to me'
+ 'Mother mary comes to me',
];
const expected = {
allLines: [
- { type: 'chord', string: 'C.. G..', model: parseChordLine('C.. G..') },
- { type: 'text', string: 'When I find myself in times of trouble' },
- { type: 'chord', string: 'Am.. F..', model: parseChordLine('Am.. F..') },
- { type: 'text', string: 'Mother mary comes to me' },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: parseChordLine('C.. G..'),
+ },
+ {
+ type: 'lyric',
+ string: 'When I find myself in times of trouble',
+ model: parseLyricLine(
+ 'When I find myself in times of trouble'
+ ),
+ },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: parseChordLine('Am.. F..'),
+ },
+ {
+ type: 'lyric',
+ string: 'Mother mary comes to me',
+ model: parseLyricLine('Mother mary comes to me'),
+ },
],
allChords: [
{ model: parseChord('C'), occurrences: 1 },
{ model: parseChord('G'), occurrences: 1 },
{ model: parseChord('Am'), occurrences: 1 },
{ model: parseChord('F'), occurrences: 1 },
- ]
+ ],
};
expect(parseSong(input)).toEqual(expected);
});
-
});
diff --git a/tests/integration/renderer/components/renderSong/renderSong.spec.js b/tests/integration/renderer/components/renderSong/renderSong.spec.js
index f33c1e90..5490eccd 100644
--- a/tests/integration/renderer/components/renderSong/renderSong.spec.js
+++ b/tests/integration/renderer/components/renderSong/renderSong.spec.js
@@ -21,17 +21,34 @@ function removeLastLine(fileContent) {
}
describe.each([
-
- ['base rendering', 'song1-input.txt', 'song1-output-simple.txt'],
- ['base rendering', 'song1-input.txt', 'song1-output-simple.txt', {} ],
- ['no transposing', 'song1-input.txt', 'song1-output-simple.txt', { alignBars: false, harmonizeAccidentals: false } ],
- ['aligned rendering', 'song1-input.txt', 'song1-output-aligned.txt', { alignBars: true } ],
- ['transposed', 'song1-input.txt', 'song1-output-transposed.txt', { transposeValue: -4, accidentalsType: 'flat' } ],
-
+ ['base rendering', 'song1-input.txt', 'song1-output-simple.txt'],
+ ['base rendering', 'song1-input.txt', 'song1-output-simple.txt', {}],
+ [
+ 'no transposing',
+ 'song1-input.txt',
+ 'song1-output-simple.txt',
+ { alignBars: false, harmonizeAccidentals: false },
+ ],
+ [
+ 'aligned rendering',
+ 'song1-input.txt',
+ 'song1-output-aligned.txt',
+ { alignBars: true },
+ ],
+ [
+ 'transposed',
+ 'song1-input.txt',
+ 'song1-output-transposed.txt',
+ { transposeValue: -4, accidentalsType: 'flat' },
+ ],
])('Render components: %s', (title, inputFile, outputFile, options) => {
test('produces expected rendering', () => {
- const input = removeLastLine(fs.readFileSync(path.resolve(dataFolder, inputFile), 'utf8'));
- const output = removeLastLine(fs.readFileSync(path.resolve(dataFolder, outputFile), 'utf8'));
+ const input = removeLastLine(
+ fs.readFileSync(path.resolve(dataFolder, inputFile), 'utf8')
+ );
+ const output = removeLastLine(
+ fs.readFileSync(path.resolve(dataFolder, outputFile), 'utf8')
+ );
const parsedSong = parseSong(input);
const rendered = renderSong(parsedSong, options);
diff --git a/tests/unit/core/addEventEmitter.spec.js b/tests/unit/core/addEventEmitter.spec.js
index 710bfcb4..958997ad 100644
--- a/tests/unit/core/addEventEmitter.spec.js
+++ b/tests/unit/core/addEventEmitter.spec.js
@@ -6,12 +6,7 @@ describe('addEventEmitter', () => {
});
});
-describe.each([
- 'on',
- 'once',
- 'off',
- 'emit'
-])('API: .%s()', (method) => {
+describe.each(['on', 'once', 'off', 'emit'])('API: .%s()', (method) => {
test('Method exists', () => {
const withEmitter = addEventEmitter({});
expect(withEmitter[method]).toBeInstanceOf(Function);
@@ -45,18 +40,18 @@ describe('.on()', () => {
const withEmitter = addEventEmitter({});
const listener = jest.fn();
- const params = [
- { test: 'test' },
- ['4', '5'],
- 'string',
- 69
- ];
+ const params = [{ test: 'test' }, ['4', '5'], 'string', 69];
withEmitter.on('test', listener);
withEmitter.emit('test', params[0], params[1], params[2], params[3]);
expect(listener).toHaveBeenCalledTimes(1);
- expect(listener).toHaveBeenLastCalledWith(params[0], params[1], params[2], params[3]);
+ expect(listener).toHaveBeenLastCalledWith(
+ params[0],
+ params[1],
+ params[2],
+ params[3]
+ );
});
});
diff --git a/tests/unit/core/dom/htmlToElement.spec.js b/tests/unit/core/dom/htmlToElement.spec.js
index a6779f25..5efebcbe 100644
--- a/tests/unit/core/dom/htmlToElement.spec.js
+++ b/tests/unit/core/dom/htmlToElement.spec.js
@@ -8,7 +8,8 @@ describe('htmlToElement', () => {
describe('Behavior', () => {
test('Should return valid html from string', () => {
- const html = '';
+ const html =
+ '';
const element = htmlToElement(html);
@@ -19,7 +20,9 @@ describe('Behavior', () => {
expect(element.firstChild.nodeType).toEqual(1);
expect(element.firstChild.nodeName).toEqual('P');
- expect(element.firstChild.classList.contains('test-content')).toEqual(true);
+ expect(element.firstChild.classList.contains('test-content')).toEqual(
+ true
+ );
expect(element.firstChild.textContent).toEqual('Content');
});
diff --git a/tests/unit/core/dom/stripTags.spec.js b/tests/unit/core/dom/stripTags.spec.js
index e5fe6767..a72eb3d0 100644
--- a/tests/unit/core/dom/stripTags.spec.js
+++ b/tests/unit/core/dom/stripTags.spec.js
@@ -7,13 +7,14 @@ describe('stripTags', () => {
});
describe.each([
-
[undefined, ''],
['', ''],
['plain text', 'plain text'],
['', 'Content'],
- ['This text is bold and also italic
', 'This text is bold and also italic'],
-
+ [
+ 'This text is bold and also italic
',
+ 'This text is bold and also italic',
+ ],
])('Should strip tags out of %s', (input, output) => {
test('Correctly strips html tags', () => {
expect(stripTags(input)).toEqual(output);
diff --git a/tests/unit/parser/exceptions/IncorrectBeatCountExpection.spec.js b/tests/unit/parser/exceptions/IncorrectBeatCountExpection.spec.js
index a3fdd6e3..98621340 100644
--- a/tests/unit/parser/exceptions/IncorrectBeatCountExpection.spec.js
+++ b/tests/unit/parser/exceptions/IncorrectBeatCountExpection.spec.js
@@ -12,7 +12,7 @@ describe('Behavior', () => {
string: 'Cm7...',
duration: 3,
currentBeatCount: 6,
- beatCount: 4
+ beatCount: 4,
});
expect(error).toBeInstanceOf(IncorrectBeatCountException);
expect(error.string).toEqual('Cm7...');
@@ -22,28 +22,50 @@ describe('Behavior', () => {
});
test('Throw if given no parameter', () => {
- const throwingFn = () => { throw new IncorrectBeatCountException(); };
+ const throwingFn = () => {
+ throw new IncorrectBeatCountException();
+ };
expect(throwingFn).toThrow(TypeError);
- expect(throwingFn).toThrow('IncorrectBeatCountException cannot be created without chord string, received: undefined');
+ expect(throwingFn).toThrow(
+ 'IncorrectBeatCountException cannot be created without chord string, received: undefined'
+ );
});
});
describe.each([
- ['no string', 'string', 'IncorrectBeatCountException cannot be created without chord string, received: undefined'],
- ['no duration', 'duration', 'IncorrectBeatCountException cannot be created without chord duration, received: undefined'],
- ['no currentBeatCount', 'currentBeatCount', 'IncorrectBeatCountException cannot be created without currentBeatCount, received: undefined'],
- ['no beatCount', 'beatCount', 'IncorrectBeatCountException cannot be created without beatCount, received: undefined'],
+ [
+ 'no string',
+ 'string',
+ 'IncorrectBeatCountException cannot be created without chord string, received: undefined',
+ ],
+ [
+ 'no duration',
+ 'duration',
+ 'IncorrectBeatCountException cannot be created without chord duration, received: undefined',
+ ],
+ [
+ 'no currentBeatCount',
+ 'currentBeatCount',
+ 'IncorrectBeatCountException cannot be created without currentBeatCount, received: undefined',
+ ],
+ [
+ 'no beatCount',
+ 'beatCount',
+ 'IncorrectBeatCountException cannot be created without beatCount, received: undefined',
+ ],
])('Throw TypeError on %s', (title, propertyToRemove, message) => {
test('Test details', () => {
const errorParameters = {
string: 'Cm7...',
duration: 3,
currentBeatCount: 6,
- BeatCount: 4
+ BeatCount: 4,
};
delete errorParameters[propertyToRemove];
- const throwingFn = () => { throw new IncorrectBeatCountException(errorParameters); };
+ const throwingFn = () => {
+ throw new IncorrectBeatCountException(errorParameters);
+ };
expect(throwingFn).toThrow(TypeError);
expect(throwingFn).toThrow(message);
});
diff --git a/tests/unit/parser/exceptions/InvalidChordRepetitionException.spec.js b/tests/unit/parser/exceptions/InvalidChordRepetitionException.spec.js
index b2521df4..e62a1681 100644
--- a/tests/unit/parser/exceptions/InvalidChordRepetitionException.spec.js
+++ b/tests/unit/parser/exceptions/InvalidChordRepetitionException.spec.js
@@ -16,16 +16,22 @@ describe('Behavior', () => {
});
test('Throw if given no parameter', () => {
- const throwingFn = () => { throw new InvalidChordRepetitionException(); };
+ const throwingFn = () => {
+ throw new InvalidChordRepetitionException();
+ };
expect(throwingFn).toThrow(TypeError);
- expect(throwingFn).toThrow('InvalidChordRepetitionException cannot be created without chord string, received: undefined');
+ expect(throwingFn).toThrow(
+ 'InvalidChordRepetitionException cannot be created without chord string, received: undefined'
+ );
});
});
describe.each([
-
- ['no string', 'string', 'InvalidChordRepetitionException cannot be created without chord string, received: undefined'],
-
+ [
+ 'no string',
+ 'string',
+ 'InvalidChordRepetitionException cannot be created without chord string, received: undefined',
+ ],
])('Throw TypeError on %s', (title, propertyToRemove, message) => {
test('Test details', () => {
const errorParameters = {
@@ -33,7 +39,9 @@ describe.each([
};
delete errorParameters[propertyToRemove];
- const throwingFn = () => { throw new InvalidChordRepetitionException(errorParameters); };
+ const throwingFn = () => {
+ throw new InvalidChordRepetitionException(errorParameters);
+ };
expect(throwingFn).toThrow(TypeError);
expect(throwingFn).toThrow(message);
});
diff --git a/tests/unit/parser/helpers/clearSpaces.spec.js b/tests/unit/parser/helpers/clearSpaces.spec.js
index 914d4036..54dfc49a 100644
--- a/tests/unit/parser/helpers/clearSpaces.spec.js
+++ b/tests/unit/parser/helpers/clearSpaces.spec.js
@@ -7,19 +7,18 @@ describe('clearSpaces', () => {
});
describe.each([
- ['Empty input', '', ''],
- ['Preserve text', 'test', 'test'],
- ['1 space', ' ', ''],
- ['2 spaces', ' ', ''],
- ['multiple spaces', ' ', ''],
- ['1 tab', ' ', ''],
- ['2 tabs', ' ', ''],
- ['multiple tabs', ' ', ''],
-
- ['spaces between tokens', ' A B C ', 'A B C'],
- ['tabs between tokens', ' A B C ', 'A B C'],
- ['mix of spaces & tabs', ' A B C D E', 'A B C D E'],
+ ['Empty input', '', ''],
+ ['Preserve text', 'test', 'test'],
+ ['1 space', ' ', ''],
+ ['2 spaces', ' ', ''],
+ ['multiple spaces', ' ', ''],
+ ['1 tab', ' ', ''],
+ ['2 tabs', ' ', ''],
+ ['multiple tabs', ' ', ''],
+ ['spaces between tokens', ' A B C ', 'A B C'],
+ ['tabs between tokens', ' A B C ', 'A B C'],
+ ['mix of spaces & tabs', ' A B C D E', 'A B C D E'],
])('Group title for %s', (title, input, output) => {
test('Test details', () => {
expect(clearSpaces(input)).toEqual(output);
diff --git a/tests/unit/parser/helpers/song.spec.js b/tests/unit/parser/helpers/song.spec.js
index ca2a63d9..c9dd9416 100644
--- a/tests/unit/parser/helpers/song.spec.js
+++ b/tests/unit/parser/helpers/song.spec.js
@@ -42,12 +42,15 @@ D D
I just want your extra time and your...Kiss
`;
const parsed = parseSong(song);
- const applied = forEachChordInSong(parsed.allLines, chord => chord.applied = true);
+ const applied = forEachChordInSong(
+ parsed.allLines,
+ (chord) => (chord.applied = true)
+ );
- applied.forEach(line => {
+ applied.forEach((line) => {
if (line.type === 'chord') {
- line.model.allBars.forEach(bar => {
- bar.allChords.forEach(chord => {
+ line.model.allBars.forEach((bar) => {
+ bar.allChords.forEach((chord) => {
expect(chord.applied).toBe(true);
});
});
@@ -56,7 +59,6 @@ I just want your extra time and your...Kiss
});
});
-
describe('forEachChordInChordLine', () => {
test('Module', () => {
expect(forEachChordInChordLine).toBeInstanceOf(Function);
@@ -75,16 +77,56 @@ describe('forEachChordInChordLine', () => {
const chordLine = 'Am... G/B. C';
const parsed = parseChordLine(chordLine);
- const applied = forEachChordInChordLine(parsed, chord => chord.applied = true);
+ const applied = forEachChordInChordLine(
+ parsed,
+ (chord) => (chord.applied = true)
+ );
- applied.allBars.forEach(bar => {
- bar.allChords.forEach(chord => {
+ applied.allBars.forEach((bar) => {
+ bar.allChords.forEach((chord) => {
expect(chord.applied).toBe(true);
});
});
});
-});
+ test('Should provide the proper barIndex and chordIndex', () => {
+ expect.assertions(32);
+
+ const chordLine = 'Am... G/B. C E. F. G. B7. Em';
+ const parsed = parseChordLine(chordLine);
+ const applied = forEachChordInChordLine(
+ parsed,
+ (chord, chordIndex, barIndex) => {
+ chord.chordIndex = chordIndex;
+ chord.barIndex = barIndex;
+ }
+ );
+
+ let i = 0;
+ const expected = [
+ [0, 0],
+ [0, 1],
+
+ [1, 0],
+
+ [2, 0],
+ [2, 1],
+ [2, 2],
+ [2, 3],
+
+ [3, 0],
+ ];
+ applied.allBars.forEach((bar, barIndex) => {
+ bar.allChords.forEach((chord, chordIndex) => {
+ expect(chord.barIndex).toBe(expected[i][0]);
+ expect(chord.barIndex).toBe(barIndex);
+ expect(chord.chordIndex).toBe(expected[i][1]);
+ expect(chord.chordIndex).toBe(chordIndex);
+ i++;
+ });
+ });
+ });
+});
describe('getNthOfLabel', () => {
test('Module', () => {
@@ -112,15 +154,37 @@ Verse3-line3
Verse3-line4`;
const parsed = parseSong(song);
- const v1 = ['Verse1-line1', 'Verse1-line2', 'Verse1-line3', 'Verse1-line4', ''];
- const v2 = ['Verse2-line1', 'Verse2-line2', 'Verse2-line3', 'Verse2-line4', ''];
- const v3 = ['Verse3-line1', 'Verse3-line2', 'Verse3-line3', 'Verse3-line4'];
+ const v1 = [
+ 'Verse1-line1',
+ 'Verse1-line2',
+ 'Verse1-line3',
+ 'Verse1-line4',
+ '',
+ ];
+ const v2 = [
+ 'Verse2-line1',
+ 'Verse2-line2',
+ 'Verse2-line3',
+ 'Verse2-line4',
+ '',
+ ];
+ const v3 = [
+ 'Verse3-line1',
+ 'Verse3-line2',
+ 'Verse3-line3',
+ 'Verse3-line4',
+ ];
expect(getNthOfLabel(parsed.allLines, 'v', 0)).toEqual([]);
- expect(getNthOfLabel(parsed.allLines, 'v', 1).map(line => line.string)).toEqual(v1);
- expect(getNthOfLabel(parsed.allLines, 'v', 2).map(line => line.string)).toEqual(v2);
- expect(getNthOfLabel(parsed.allLines, 'v', 3).map(line => line.string)).toEqual(v3);
+ expect(
+ getNthOfLabel(parsed.allLines, 'v', 1).map((line) => line.string)
+ ).toEqual(v1);
+ expect(
+ getNthOfLabel(parsed.allLines, 'v', 2).map((line) => line.string)
+ ).toEqual(v2);
+ expect(
+ getNthOfLabel(parsed.allLines, 'v', 3).map((line) => line.string)
+ ).toEqual(v3);
expect(getNthOfLabel(parsed.allLines, 'v', 4)).toEqual([]);
-
});
});
diff --git a/tests/unit/parser/matchers/isChord.spec.js b/tests/unit/parser/matchers/isChord.spec.js
index db044b90..3901809f 100644
--- a/tests/unit/parser/matchers/isChord.spec.js
+++ b/tests/unit/parser/matchers/isChord.spec.js
@@ -7,24 +7,22 @@ describe('isChord', () => {
});
describe.each([
+ ['A', true],
+ ['Am7b5', true],
+ ['A+7', true],
+ ['A9', true],
+ ['AM7', true],
+ ['Asus4', true],
+ ['Ah', true],
+ ['H', true],
+ ['G75-', true],
- [ 'A', true],
- [ 'Am7b5', true],
- [ 'A+7', true],
- [ 'A9', true],
- [ 'AM7', true],
- [ 'Asus4', true],
- [ 'Ah', true],
- [ 'H', true],
- [ 'G75-', true],
-
- [ undefined,false],
- [ {}, false],
- [ '', false],
- [ 'I', false],
- [ 'Amm', false],
- [ '5/4', false],
-
+ [undefined, false],
+ [{}, false],
+ ['', false],
+ ['I', false],
+ ['Amm', false],
+ ['5/4', false],
])('When given %s', (input, output) => {
test('Properly recognize as chord', () => {
expect(isChord(input)).toEqual(output);
diff --git a/tests/unit/parser/matchers/isChordLine.spec.js b/tests/unit/parser/matchers/isChordLine.spec.js
index 5c0ac270..36026d9b 100644
--- a/tests/unit/parser/matchers/isChordLine.spec.js
+++ b/tests/unit/parser/matchers/isChordLine.spec.js
@@ -7,35 +7,33 @@ describe('isChordLine', () => {
});
describe.each([
+ ['A', true],
+ ['A B', true],
+ ['A B', true],
+ [' A B ', true],
+ [' A. C.. ', true],
+ ['Am7 CM7 F+ C/G', true],
+ ['A. C..', true], // with 1 tab
+ ['A C', true], // with 2 tabs
+ ['A C', true], // with tab + space + tav
+ ['A /', true],
+ ['A ///', true],
+ ['A.. B.. /', true],
+ ['A.. B.. ///', true],
- [ 'A', true ],
- [ 'A B', true ],
- [ 'A B', true ],
- [ ' A B ', true ],
- [ ' A. C.. ', true ],
- [ 'Am7 CM7 F+ C/G', true ],
- [ 'A. C..', true ], // with 1 tab
- [ 'A C', true ], // with 2 tabs
- [ 'A C', true ], // with tab + space + tav
- [ 'A /', true ],
- [ 'A ///', true ],
- [ 'A.. B.. /', true ],
- [ 'A.. B.. ///', true ],
-
- [ undefined, false ],
- [ '', false ],
- [ 'AB ', false ],
- [ 'A X ', false ],
- [ 'A C/R ', false ],
- [ ' .A ..C ', false ],
- [ ' .A C./F ', false ],
- [ 'A | B', false ],
- [ '/', false ],
- [ '/ A', false ],
- [ '/..', false ],
- [ 'A B /.', false ],
- [ '5/4\n', false ],
-
+ [undefined, false],
+ ['', false],
+ ['AB ', false],
+ ['A X ', false],
+ ['A C/R ', false],
+ [' .A ..C ', false],
+ [' .A C./F ', false],
+ ['A | B', false],
+ ['/', false],
+ ['/ A', false],
+ ['/..', false],
+ ['A B /.', false],
+ ['5/4\n', false],
])('Test Chord line %s', (line, output) => {
test('Correctly detect chord line', () => {
expect(isChordLine(line)).toEqual(output);
diff --git a/tests/unit/parser/matchers/isChordLineRepeater.spec.js b/tests/unit/parser/matchers/isChordLineRepeater.spec.js
index e69586eb..bb76538c 100644
--- a/tests/unit/parser/matchers/isChordLineRepeater.spec.js
+++ b/tests/unit/parser/matchers/isChordLineRepeater.spec.js
@@ -7,15 +7,13 @@ describe('isChordLineRepeater', () => {
});
describe.each([
+ ['/', true],
+ [' / ', true],
+ [' / ', true],
- ['/', true],
- [' / ', true],
- [' / ', true],
-
- ['/..', false],
- ['/ /', false],
- ['/1', false],
-
+ ['/..', false],
+ ['/ /', false],
+ ['/1', false],
])('Chord line repeater string %s', (string, result) => {
test('Correctly detect chord line repeater', () => {
expect(isChordLineRepeater(string)).toEqual(result);
diff --git a/tests/unit/parser/matchers/isEmptyLine.spec.js b/tests/unit/parser/matchers/isEmptyLine.spec.js
index 4dceb499..09714e91 100644
--- a/tests/unit/parser/matchers/isEmptyLine.spec.js
+++ b/tests/unit/parser/matchers/isEmptyLine.spec.js
@@ -7,17 +7,15 @@ describe('isEmptyLine', () => {
});
describe.each([
+ ['', true],
+ [' ', true],
+ [' ', true],
+ [' ', true], //tab
+ [' ', true], //tab
+ ['\t', true],
+ ['\t\t', true],
- ['', true],
- [' ', true],
- [' ', true],
- [' ', true], //tab
- [' ', true], //tab
- ['\t', true],
- ['\t\t', true],
-
- [' . ', false],
-
+ [' . ', false],
])('Empty line string %s', (string, result) => {
test('Correctly detect empty line', () => {
expect(isEmptyLine(string)).toEqual(result);
diff --git a/tests/unit/parser/matchers/isSectionLabel.spec.js b/tests/unit/parser/matchers/isSectionLabel.spec.js
index e6d46f12..de56b2b4 100644
--- a/tests/unit/parser/matchers/isSectionLabel.spec.js
+++ b/tests/unit/parser/matchers/isSectionLabel.spec.js
@@ -7,46 +7,44 @@ describe('isSectionLabel', () => {
});
describe.each([
-
- ['#a', true],
- ['#b', true],
- ['#c', true],
- ['#i', true],
- ['#v', true],
- ['#b', true],
+ ['#a', true],
+ ['#b', true],
+ ['#c', true],
+ ['#i', true],
+ ['#v', true],
+ ['#b', true],
['#ch', true],
- ['#s', true],
- ['#pre',true],
- ['#o', true],
+ ['#s', true],
+ ['#pre', true],
+ ['#o', true],
['#ad', true],
- ['#other', true],
- ['#a', true],
+ ['#other', true],
+ ['#a', true],
['#other', true],
- [' #a', true],
- ['#a ', true],
+ [' #a', true],
+ ['#a ', true],
[' #a ', true],
[' #a ', true],
- ['#a ', true],
+ ['#a ', true],
[' #a ', true],
['#a x2', true],
['#a x9', true],
['#a x4', true],
- ['# a', false],
+ ['# a', false],
['#a b', false],
- ['#', false],
- ['# ', false],
- ['##', false],
-
- ['#a x', false],
- ['#a x0', false],
- ['#a x1', false],
- ['#a x2', false],
- ['#a x10', false],
- ['#a x-1', false],
-
+ ['#', false],
+ ['# ', false],
+ ['##', false],
+
+ ['#a x', false],
+ ['#a x0', false],
+ ['#a x1', false],
+ ['#a x2', false],
+ ['#a x10', false],
+ ['#a x-1', false],
])('Section identifier string %s', (string, result) => {
test('Correctly detect section label', () => {
expect(isSectionLabel(string)).toEqual(result);
diff --git a/tests/unit/parser/matchers/isTimeSignatureString.spec.js b/tests/unit/parser/matchers/isTimeSignatureString.spec.js
index 85e79fca..f704b4ba 100644
--- a/tests/unit/parser/matchers/isTimeSignatureString.spec.js
+++ b/tests/unit/parser/matchers/isTimeSignatureString.spec.js
@@ -7,28 +7,26 @@ describe('isTimeSignatureString', () => {
});
describe.each([
+ ['2/2', true],
+ ['3/2', true],
- ['2/2', true],
- ['3/2', true],
+ ['2/4', true],
+ ['3/4', true],
+ ['4/4', true],
+ ['5/4', true],
- ['2/4', true],
- ['3/4', true],
- ['4/4', true],
- ['5/4', true],
-
- ['3/8', true],
- ['6/8', true],
- ['9/8', true],
+ ['3/8', true],
+ ['6/8', true],
+ ['9/8', true],
['12/8', true],
[' 4/4', false],
['4/4 ', false],
- [' 4/4 ',false],
+ [' 4/4 ', false],
- ['5/2', false],
- ['3/3', false],
+ ['5/2', false],
+ ['3/3', false],
['13/8', false],
-
])('Time signature string %s', (tsString, result) => {
test('Correctly detect time signature', () => {
expect(isTimeSignatureString(tsString)).toEqual(result);
diff --git a/tests/unit/parser/parseChordLine.spec.js b/tests/unit/parser/parseChordLine.spec.js
index 2449f58d..b5032236 100644
--- a/tests/unit/parser/parseChordLine.spec.js
+++ b/tests/unit/parser/parseChordLine.spec.js
@@ -22,374 +22,678 @@ const ts4_4 = parseTimeSignature('4/4');
const ts5_4 = parseTimeSignature('5/4');
const ts3_8 = parseTimeSignature('3/8');
-parseChord.mockImplementation(chordString => ({ symbol: chordString }));
-getChordSymbol.mockImplementation(chordDef => chordDef.symbol);
+parseChord.mockImplementation((chordString) => ({ symbol: chordString }));
+getChordSymbol.mockImplementation((chordDef) => chordDef.symbol);
describe.each([
- ['1 bar / 1 chord / 4/4', 'Cm', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'Cm', model: { symbol: 'Cm' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 1
- }],
-
- ['1 bar / 2 chords / 4/4', 'Cm.. F..', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'Cm..', model: { symbol: 'Cm' }, duration: 2, beat: 1 },
- { string: 'F..', model: { symbol: 'F' }, duration: 2, beat: 3 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 2
- }],
-
- ['1 bar / 3 chords / 4/4', 'Cm.. F. G.', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'Cm..', model: { symbol: 'Cm' }, duration: 2, beat: 1 },
- { string: 'F.', model: { symbol: 'F' }, duration: 1, beat: 3 },
- { string: 'G.', model: { symbol: 'G' }, duration: 1, beat: 4 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 3
- }],
-
- ['1 bar / 4 chords / 4/4', 'Cm. Em7. F. G.', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'Cm.', model: { symbol: 'Cm' }, duration: 1, beat: 1 },
- { string: 'Em7.', model: { symbol: 'Em7' }, duration: 1, beat: 2 },
- { string: 'F.', model: { symbol: 'F' }, duration: 1, beat: 3 },
- { string: 'G.', model: { symbol: 'G' }, duration: 1, beat: 4 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 4
- }],
-
- ['2 bars / 2 chords / 4/4', 'C F', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'C', model: { symbol: 'C' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- }, {
- allChords: [
- { string: 'F', model: { symbol: 'F' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 2
- }],
-
- ['2 bars / 3 chords / 4/4', 'C F.. G..', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'C', model: { symbol: 'C' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- }, {
- allChords: [
- { string: 'F..', model: { symbol: 'F' }, duration: 2, beat: 1 },
- { string: 'G..', model: { symbol: 'G' }, duration: 2, beat: 3 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 3
- }],
-
- ['2 bars / 4 chords / 4/4', 'C... Em7. F. G...', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'C...', model: { symbol: 'C' }, duration: 3, beat: 1 },
- { string: 'Em7.', model: { symbol: 'Em7' }, duration: 1, beat: 4 },
- ],
- timeSignature: ts4_4,
- }, {
- allChords: [
- { string: 'F.', model: { symbol: 'F' }, duration: 1, beat: 1 },
- { string: 'G...', model: { symbol: 'G' }, duration: 3, beat: 2 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 4
- }],
-
- ['3 bars / 4 chords / 4/4', 'C Em7. F... G', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'C', model: { symbol: 'C' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- }, {
- allChords: [
- { string: 'Em7.', model: { symbol: 'Em7' }, duration: 1, beat: 1 },
- { string: 'F...', model: { symbol: 'F' }, duration: 3, beat: 2 },
- ],
- timeSignature: ts4_4,
- }, {
- allChords: [
- { string: 'G', model: { symbol: 'G' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 4
- }],
-
-
- ['1 bar / 1 chord / 3/4', 'C', ts3_4, {
- allBars: [
- {
- allChords: [
- { string: 'C', model: { symbol: 'C' }, duration: 3, beat: 1 },
- ],
- timeSignature: ts3_4,
- }
- ],
- chordCount: 1
- }],
-
- ['1 bar / 2 chords / 3/4', 'Cm. F..', ts3_4, {
- allBars: [
- {
- allChords: [
- { string: 'Cm.', model: { symbol: 'Cm' }, duration: 1, beat: 1 },
- { string: 'F..', model: { symbol: 'F' }, duration: 2, beat: 2 },
- ],
- timeSignature: ts3_4,
- }
- ],
- chordCount: 2
- }],
-
- ['1 bar / 2 chords / 3/4', 'Cm.. F.', ts3_4, {
- allBars: [
- {
- allChords: [
- { string: 'Cm..', model: { symbol: 'Cm' }, duration: 2, beat: 1 },
- { string: 'F.', model: { symbol: 'F' }, duration: 1, beat: 3 },
- ],
- timeSignature: ts3_4,
- }
- ],
- chordCount: 2
- }],
-
- ['1 bar / 3 chords / 3/4', 'Cm. F. G.', ts3_4, {
- allBars: [
- {
- allChords: [
- { string: 'Cm.', model: { symbol: 'Cm' }, duration: 1, beat: 1 },
- { string: 'F.', model: { symbol: 'F' }, duration: 1, beat: 2 },
- { string: 'G.', model: { symbol: 'G' }, duration: 1, beat: 3 },
- ],
- timeSignature: ts3_4,
- }
- ],
- chordCount: 3
- }],
-
- ['3/8 bar', 'Cm F G.', ts3_8, {
- allBars: [
- {
- allChords: [
- { string: 'Cm', model: { symbol: 'Cm' }, duration: 1, beat: 1 },
- ],
- timeSignature: ts3_8,
- },
- {
- allChords: [
- { string: 'F', model: { symbol: 'F' }, duration: 1, beat: 1 },
- ],
- timeSignature: ts3_8,
- },
- {
- allChords: [
- { string: 'G.', model: { symbol: 'G' }, duration: 1, beat: 1 },
- ],
- timeSignature: ts3_8,
- }
- ],
- chordCount: 3
- }],
-
- ['trim end spaces', 'Cm ', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'Cm', model: { symbol: 'Cm' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 1
- }],
-
- ['trim start spaces', ' Cm', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'Cm', model: { symbol: 'Cm' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 1
- }],
-
- ['trim start and end spaces', ' Cm ', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'Cm', model: { symbol: 'Cm' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 1
- }],
-
- ['handle multiple spaces between chords', 'C.. B..', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'C..', model: { symbol: 'C' }, duration: 2, beat: 1 },
- { string: 'B..', model: { symbol: 'B' }, duration: 2, beat: 3 },
- ],
- timeSignature: ts4_4,
- }
- ],
- chordCount: 2
- }],
-
- ['handle the "no-chord" symbol', 'C NC B.. NC.. D', ts4_4, {
- allBars: [
- {
- allChords: [
- { string: 'C', model: { symbol: 'C' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- },
- {
- allChords: [
- { string: 'NC', model: 'NC', duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- },
- {
- allChords: [
- { string: 'B..', model: { symbol: 'B' }, duration: 2, beat: 1 },
- { string: 'NC..', model: 'NC', duration: 2, beat: 3 },
- ],
- timeSignature: ts4_4,
- },
- {
- allChords: [
- { string: 'D', model: { symbol: 'D' }, duration: 4, beat: 1 },
- ],
- timeSignature: ts4_4,
- },
- ],
- chordCount: 5
- }],
-
-])('Should parses correctly %s: %s', (title, input, timeSignature, expected) => {
- test('is correctly parsed', () => {
- const options = { timeSignature };
- const parsed = parseChordLine(input, options);
-
- expect(parsed).toEqual(expected);
- });
-});
-
+ [
+ '1 bar / 1 chord / 4/4',
+ 'Cm',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm',
+ model: { symbol: 'Cm' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 1,
+ },
+ ],
+
+ [
+ '1 bar / 2 chords / 4/4',
+ 'Cm.. F..',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm..',
+ model: { symbol: 'Cm' },
+ duration: 2,
+ beat: 1,
+ },
+ {
+ string: 'F..',
+ model: { symbol: 'F' },
+ duration: 2,
+ beat: 3,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 2,
+ },
+ ],
+
+ [
+ '1 bar / 3 chords / 4/4',
+ 'Cm.. F. G.',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm..',
+ model: { symbol: 'Cm' },
+ duration: 2,
+ beat: 1,
+ },
+ {
+ string: 'F.',
+ model: { symbol: 'F' },
+ duration: 1,
+ beat: 3,
+ },
+ {
+ string: 'G.',
+ model: { symbol: 'G' },
+ duration: 1,
+ beat: 4,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 3,
+ },
+ ],
+
+ [
+ '1 bar / 4 chords / 4/4',
+ 'Cm. Em7. F. G.',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm.',
+ model: { symbol: 'Cm' },
+ duration: 1,
+ beat: 1,
+ },
+ {
+ string: 'Em7.',
+ model: { symbol: 'Em7' },
+ duration: 1,
+ beat: 2,
+ },
+ {
+ string: 'F.',
+ model: { symbol: 'F' },
+ duration: 1,
+ beat: 3,
+ },
+ {
+ string: 'G.',
+ model: { symbol: 'G' },
+ duration: 1,
+ beat: 4,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 4,
+ },
+ ],
+
+ [
+ '2 bars / 2 chords / 4/4',
+ 'C F',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'C',
+ model: { symbol: 'C' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ {
+ allChords: [
+ {
+ string: 'F',
+ model: { symbol: 'F' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 2,
+ },
+ ],
+
+ [
+ '2 bars / 3 chords / 4/4',
+ 'C F.. G..',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'C',
+ model: { symbol: 'C' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ {
+ allChords: [
+ {
+ string: 'F..',
+ model: { symbol: 'F' },
+ duration: 2,
+ beat: 1,
+ },
+ {
+ string: 'G..',
+ model: { symbol: 'G' },
+ duration: 2,
+ beat: 3,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 3,
+ },
+ ],
+
+ [
+ '2 bars / 4 chords / 4/4',
+ 'C... Em7. F. G...',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'C...',
+ model: { symbol: 'C' },
+ duration: 3,
+ beat: 1,
+ },
+ {
+ string: 'Em7.',
+ model: { symbol: 'Em7' },
+ duration: 1,
+ beat: 4,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ {
+ allChords: [
+ {
+ string: 'F.',
+ model: { symbol: 'F' },
+ duration: 1,
+ beat: 1,
+ },
+ {
+ string: 'G...',
+ model: { symbol: 'G' },
+ duration: 3,
+ beat: 2,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 4,
+ },
+ ],
+
+ [
+ '3 bars / 4 chords / 4/4',
+ 'C Em7. F... G',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'C',
+ model: { symbol: 'C' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ {
+ allChords: [
+ {
+ string: 'Em7.',
+ model: { symbol: 'Em7' },
+ duration: 1,
+ beat: 1,
+ },
+ {
+ string: 'F...',
+ model: { symbol: 'F' },
+ duration: 3,
+ beat: 2,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ {
+ allChords: [
+ {
+ string: 'G',
+ model: { symbol: 'G' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 4,
+ },
+ ],
+
+ [
+ '1 bar / 1 chord / 3/4',
+ 'C',
+ ts3_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'C',
+ model: { symbol: 'C' },
+ duration: 3,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts3_4,
+ },
+ ],
+ chordCount: 1,
+ },
+ ],
+
+ [
+ '1 bar / 2 chords / 3/4',
+ 'Cm. F..',
+ ts3_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm.',
+ model: { symbol: 'Cm' },
+ duration: 1,
+ beat: 1,
+ },
+ {
+ string: 'F..',
+ model: { symbol: 'F' },
+ duration: 2,
+ beat: 2,
+ },
+ ],
+ timeSignature: ts3_4,
+ },
+ ],
+ chordCount: 2,
+ },
+ ],
+
+ [
+ '1 bar / 2 chords / 3/4',
+ 'Cm.. F.',
+ ts3_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm..',
+ model: { symbol: 'Cm' },
+ duration: 2,
+ beat: 1,
+ },
+ {
+ string: 'F.',
+ model: { symbol: 'F' },
+ duration: 1,
+ beat: 3,
+ },
+ ],
+ timeSignature: ts3_4,
+ },
+ ],
+ chordCount: 2,
+ },
+ ],
+
+ [
+ '1 bar / 3 chords / 3/4',
+ 'Cm. F. G.',
+ ts3_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm.',
+ model: { symbol: 'Cm' },
+ duration: 1,
+ beat: 1,
+ },
+ {
+ string: 'F.',
+ model: { symbol: 'F' },
+ duration: 1,
+ beat: 2,
+ },
+ {
+ string: 'G.',
+ model: { symbol: 'G' },
+ duration: 1,
+ beat: 3,
+ },
+ ],
+ timeSignature: ts3_4,
+ },
+ ],
+ chordCount: 3,
+ },
+ ],
+
+ [
+ '3/8 bar',
+ 'Cm F G.',
+ ts3_8,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm',
+ model: { symbol: 'Cm' },
+ duration: 1,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts3_8,
+ },
+ {
+ allChords: [
+ {
+ string: 'F',
+ model: { symbol: 'F' },
+ duration: 1,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts3_8,
+ },
+ {
+ allChords: [
+ {
+ string: 'G.',
+ model: { symbol: 'G' },
+ duration: 1,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts3_8,
+ },
+ ],
+ chordCount: 3,
+ },
+ ],
+
+ [
+ 'trim end spaces',
+ 'Cm ',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm',
+ model: { symbol: 'Cm' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 1,
+ },
+ ],
+
+ [
+ 'trim start spaces',
+ ' Cm',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm',
+ model: { symbol: 'Cm' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 1,
+ },
+ ],
+
+ [
+ 'trim start and end spaces',
+ ' Cm ',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'Cm',
+ model: { symbol: 'Cm' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 1,
+ },
+ ],
+
+ [
+ 'handle multiple spaces between chords',
+ 'C.. B..',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'C..',
+ model: { symbol: 'C' },
+ duration: 2,
+ beat: 1,
+ },
+ {
+ string: 'B..',
+ model: { symbol: 'B' },
+ duration: 2,
+ beat: 3,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 2,
+ },
+ ],
+
+ [
+ 'handle the "no-chord" symbol',
+ 'C NC B.. NC.. D',
+ ts4_4,
+ {
+ allBars: [
+ {
+ allChords: [
+ {
+ string: 'C',
+ model: { symbol: 'C' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ {
+ allChords: [
+ { string: 'NC', model: 'NC', duration: 4, beat: 1 },
+ ],
+ timeSignature: ts4_4,
+ },
+ {
+ allChords: [
+ {
+ string: 'B..',
+ model: { symbol: 'B' },
+ duration: 2,
+ beat: 1,
+ },
+ { string: 'NC..', model: 'NC', duration: 2, beat: 3 },
+ ],
+ timeSignature: ts4_4,
+ },
+ {
+ allChords: [
+ {
+ string: 'D',
+ model: { symbol: 'D' },
+ duration: 4,
+ beat: 1,
+ },
+ ],
+ timeSignature: ts4_4,
+ },
+ ],
+ chordCount: 5,
+ },
+ ],
+])(
+ 'Should parses correctly %s: %s',
+ (title, input, timeSignature, expected) => {
+ test('is correctly parsed', () => {
+ const options = { timeSignature };
+ const parsed = parseChordLine(input, options);
+
+ expect(parsed).toEqual(expected);
+ });
+ }
+);
describe.each([
+ ['1 chord / 1 beat / 4/4', 'Cm.', 'Cm.', 1, 1, ts4_4],
+ ['1 chord / 2 beats / 4/4', 'Cm..', 'Cm..', 2, 2, ts4_4],
+ ['1 chord / 3 beats / 4/4', 'Cm...', 'Cm...', 3, 3, ts4_4],
+ ['1 chord / 5 beats / 4/4', 'Cm.....', 'Cm.....', 5, 5, ts4_4],
+ ['1 chord / 6 beats / 4/4', 'Cm......', 'Cm......', 6, 6, ts4_4],
+ ['1 chord / 7 beats / 4/4', 'Cm.......', 'Cm.......', 7, 7, ts4_4],
+ ['2 chords / 3 beats / 4/4', 'Cm. D..', 'D..', 2, 3, ts4_4],
+ ['2 chords / 5 beats / 4/4', 'Cm... D..', 'D..', 2, 5, ts4_4],
+ ['2 chords / 6 beats / 4/4', 'Cm... D...', 'D...', 3, 6, ts4_4],
+ ['2 chords / 7 beats / 4/4', 'Cm... D', 'D', 4, 7, ts4_4],
+ ['3 chords / 3 beats / 4/4', 'C. D. E.', 'E.', 1, 3, ts4_4],
+ ['3 chords / 5 beats / 4/4', 'C. D.. E..', 'E..', 2, 5, ts4_4],
+
+ ['1 chords / 4 beats / 5/4', 'C....', 'C....', 4, 4, ts5_4],
+ ['2 chords / 4 beats / 5/4', 'C.. D..', 'D..', 2, 4, ts5_4],
+ ['3 chords / 6 beats / 5/4', 'C.. D.. E..', 'E..', 2, 6, ts5_4],
+ ['3 chords / 7 beats / 5/4', 'C.. D... E..', 'E..', 2, 2, ts5_4],
+ ['3 chords / 8 beats / 5/4', 'C... D... E..', 'D...', 3, 6, ts5_4],
+ ['3 chords / 9 beats / 5/4', 'C... D E.', 'D', 5, 8, ts5_4],
+])(
+ 'Throw on %s: %s',
+ (title, input, string, duration, currentBeatCount, timeSignature) => {
+ const throwingFn = () => {
+ parseChordLine(input, { timeSignature });
+ };
+
+ test('Throw InvalidChordRepetitionException', () => {
+ expect(throwingFn).toThrow(IncorrectBeatCountException);
+ });
- ['1 chord / 1 beat / 4/4', 'Cm.', 'Cm.', 1, 1, ts4_4 ],
- ['1 chord / 2 beats / 4/4', 'Cm..', 'Cm..', 2, 2, ts4_4 ],
- ['1 chord / 3 beats / 4/4', 'Cm...', 'Cm...', 3, 3, ts4_4 ],
- ['1 chord / 5 beats / 4/4', 'Cm.....', 'Cm.....', 5, 5, ts4_4 ],
- ['1 chord / 6 beats / 4/4', 'Cm......', 'Cm......', 6, 6, ts4_4 ],
- ['1 chord / 7 beats / 4/4', 'Cm.......', 'Cm.......',7, 7, ts4_4 ],
- ['2 chords / 3 beats / 4/4', 'Cm. D..', 'D..', 2, 3, ts4_4 ],
- ['2 chords / 5 beats / 4/4', 'Cm... D..', 'D..', 2, 5, ts4_4 ],
- ['2 chords / 6 beats / 4/4', 'Cm... D...', 'D...', 3, 6, ts4_4 ],
- ['2 chords / 7 beats / 4/4', 'Cm... D', 'D', 4, 7, ts4_4 ],
- ['3 chords / 3 beats / 4/4', 'C. D. E.', 'E.', 1, 3, ts4_4 ],
- ['3 chords / 5 beats / 4/4', 'C. D.. E..', 'E..', 2, 5, ts4_4 ],
-
- ['1 chords / 4 beats / 5/4', 'C....', 'C....', 4, 4, ts5_4 ],
- ['2 chords / 4 beats / 5/4', 'C.. D..', 'D..', 2, 4, ts5_4 ],
- ['3 chords / 6 beats / 5/4', 'C.. D.. E..', 'E..', 2, 6, ts5_4 ],
- ['3 chords / 7 beats / 5/4', 'C.. D... E..', 'E..', 2, 2, ts5_4 ],
- ['3 chords / 8 beats / 5/4', 'C... D... E..', 'D...', 3, 6, ts5_4 ],
- ['3 chords / 9 beats / 5/4', 'C... D E.', 'D', 5, 8, ts5_4 ],
-
-])('Throw on %s: %s', (title, input, string, duration, currentBeatCount, timeSignature) => {
- const throwingFn = () => { parseChordLine(input, { timeSignature }); };
-
- test('Throw InvalidChordRepetitionException', () => {
- expect(throwingFn).toThrow(IncorrectBeatCountException);
- });
-
- test('Add correct properties to exception', () => {
- try {
- throwingFn();
- expect(false).toBeTruthy();
-
- } catch (e) {
- expect(e.name).toBe('IncorrectBeatCountException');
- expect(e.string).toBe(string);
- expect(e.duration).toBe(duration);
- expect(e.currentBeatCount).toBe(currentBeatCount);
- expect(e.beatCount).toBe(timeSignature.beatCount);
- }
- });
-});
-
+ test('Add correct properties to exception', () => {
+ try {
+ throwingFn();
+ expect(false).toBeTruthy();
+ } catch (e) {
+ expect(e.name).toBe('IncorrectBeatCountException');
+ expect(e.string).toBe(string);
+ expect(e.duration).toBe(duration);
+ expect(e.currentBeatCount).toBe(currentBeatCount);
+ expect(e.beatCount).toBe(timeSignature.beatCount);
+ }
+ });
+ }
+);
describe.each([
-
- ['A. A...', 'A...'],
- ['A.. A..', 'A..'],
- ['A... A.', 'A.'],
- ['A... B. C.. C. F.', 'C.'],
- ['A... B. F... F.', 'F.'],
-
+ ['A. A...', 'A...'],
+ ['A.. A..', 'A..'],
+ ['A... A.', 'A.'],
+ ['A... B. C.. C. F.', 'C.'],
+ ['A... B. F... F.', 'F.'],
])('Throw if repeated chord in a bar: %s', (input, string) => {
- const throwingFn = () => { parseChordLine(input); };
+ const throwingFn = () => {
+ parseChordLine(input);
+ };
test('Throw InvalidChordRepetitionException', () => {
expect(throwingFn).toThrow(InvalidChordRepetitionException);
});
-
test('Add correct properties to exception', () => {
try {
throwingFn();
expect(false).toBeTruthy();
-
} catch (e) {
expect(e.name).toBe('InvalidChordRepetitionException');
expect(e.string).toBe(string);
@@ -397,23 +701,20 @@ describe.each([
});
});
-
describe.each([
-
- ['A /', 'A A'],
- ['A / / /', 'A A A A'],
- ['A / B /', 'A A B B'],
-
- ['A ///', 'A A A A'],
- ['A // /', 'A A A A'],
- ['A / // /', 'A A A A A'],
- ['A / // B / //', 'A A A A B B B B'],
-
+ ['A /', 'A A'],
+ ['A / / /', 'A A A A'],
+ ['A / B /', 'A A B B'],
+
+ ['A ///', 'A A A A'],
+ ['A // /', 'A A A A'],
+ ['A / // /', 'A A A A A'],
+ ['A / // B / //', 'A A A A B B B B'],
])('barRepeat: %s', (input, expected) => {
test('should correctly repeat previous bar', () => {
const parsed = parseChordLine(input);
const parsedArray = [];
- forEachChordInChordLine(parsed, chord => {
+ forEachChordInChordLine(parsed, (chord) => {
parsedArray.push(chord.model.symbol);
});
@@ -421,19 +722,18 @@ describe.each([
});
});
-describe.each([
-
- ['/ A'],
- ['// A'],
- [' / A'],
- [' / A'],
-
-])('Throw if line starts with repeatBar symbol: %s', (input) => {
- const throwingFn = () => { parseChordLine(input); };
-
- test('Throw Error', () => {
- expect(throwingFn).toThrow(Error);
- expect(throwingFn).toThrow('A chord line cannot start with the barRepeat symbol');
- });
-});
-
+describe.each([['/ A'], ['// A'], [' / A'], [' / A']])(
+ 'Throw if line starts with repeatBar symbol: %s',
+ (input) => {
+ const throwingFn = () => {
+ parseChordLine(input);
+ };
+
+ test('Throw Error', () => {
+ expect(throwingFn).toThrow(Error);
+ expect(throwingFn).toThrow(
+ 'A chord line cannot start with the barRepeat symbol'
+ );
+ });
+ }
+);
diff --git a/tests/unit/parser/parseLyricLine.spec.js b/tests/unit/parser/parseLyricLine.spec.js
new file mode 100644
index 00000000..4028e78f
--- /dev/null
+++ b/tests/unit/parser/parseLyricLine.spec.js
@@ -0,0 +1,102 @@
+import parseLyricLine from '../../../src/parser/parseLyricLine';
+
+describe('parseLyricLine', () => {
+ test('Module', () => {
+ expect(parseLyricLine).toBeInstanceOf(Function);
+ });
+});
+
+describe.each([
+ ['empty line', '', '', []],
+ [
+ 'no chords position marker',
+ 'A lyric line with no chords',
+ 'A lyric line with no chords',
+ [],
+ ],
+ [
+ '1 chords position marker, beginning',
+ '_A lyric line with one chord',
+ 'A lyric line with one chord',
+ [0],
+ ],
+ [
+ '1 chords position marker, before lyrics',
+ '_ A lyric line with one chord',
+ ' A lyric line with one chord',
+ [0],
+ ],
+ [
+ '1 chords position marker, middle',
+ 'A lyric line _with one chord',
+ 'A lyric line with one chord',
+ ['A lyric line '.length],
+ ],
+ [
+ '1 chords position marker, end',
+ 'A lyric line with one chord _',
+ 'A lyric line with one chord ',
+ ['A lyric line with one chord '.length],
+ ],
+ [
+ 'multiple chords position marker',
+ '_A lyric _line with _multiple _chords',
+ 'A lyric line with multiple chords',
+ [
+ 0,
+ 'A lyric '.length,
+ 'A lyric line with '.length,
+ 'A lyric line with multiple '.length,
+ ],
+ ],
+ [
+ 'multiple position marker together will count as 1',
+ '_A lyric ___line with a lot __of _chords',
+ 'A lyric line with a lot of chords',
+ [
+ 0,
+ 'A lyric '.length,
+ 'A lyric line with a lot '.length,
+ 'A lyric line with a lot of '.length,
+ ],
+ ],
+ [
+ 'multiple position marker separated with a space',
+ '_A lyric _ _ _line with a lot _ _of _chords',
+ 'A lyric line with a lot of chords',
+ [
+ 0,
+ 'A lyric '.length,
+ 'A lyric '.length,
+ 'A lyric '.length,
+ 'A lyric line with a lot '.length,
+ 'A lyric line with a lot '.length,
+ 'A lyric line with a lot of '.length,
+ ],
+ ],
+ [
+ 'ending a line with multiple chords without lyrics',
+ '_A lyric line _ending with a lot of chords _ _ _ _',
+ 'A lyric line ending with a lot of chords ',
+ [
+ 0,
+ 'A lyric line '.length,
+ 'A lyric line ending with a lot of chords '.length,
+ 'A lyric line ending with a lot of chords '.length,
+ 'A lyric line ending with a lot of chords '.length,
+ 'A lyric line ending with a lot of chords '.length,
+ ],
+ ],
+])('%s ', (title, lyricLine, lyrics, chordPositions) => {
+ test('Correctly detects chords position', () => {
+ const parsed = parseLyricLine(lyricLine);
+ expect(parsed).toHaveProperty('chordPositions');
+ expect(parsed.chordPositions).toEqual(chordPositions);
+ });
+
+ test('Correctly remove chord placeholders in lyrics', () => {
+ const parsed = parseLyricLine(lyricLine);
+ expect(parsed).toHaveProperty('lyrics');
+ expect(parsed.lyrics).toEqual(lyrics);
+ });
+});
diff --git a/tests/unit/parser/parseSectionLabel.spec.js b/tests/unit/parser/parseSectionLabel.spec.js
index f68b159b..249b2d40 100644
--- a/tests/unit/parser/parseSectionLabel.spec.js
+++ b/tests/unit/parser/parseSectionLabel.spec.js
@@ -7,7 +7,6 @@ describe('parseSectionLabel', () => {
});
describe.each([
-
['#A', 'A', 0],
['#B', 'B', 0],
['#C', 'C', 0],
@@ -27,7 +26,6 @@ describe.each([
['#v x2', 'v', 2],
['#c x3', 'c', 3],
['#i x9', 'i', 9],
-
])('Section identifier %s => %s', (string, label, repeatTimes) => {
test('Correctly gets identifier', () => {
expect(parseSectionLabel(string)).toEqual({
@@ -38,17 +36,12 @@ describe.each([
});
});
-
-describe.each([
-
- ['#'],
- ['#'],
- ['#a x'],
- ['#a x33'],
-
-])('Invalid section identifier of %s', (string) => {
- test('Throws TypeError', () => {
- const throwingFn = () => parseSectionLabel(string);
- expect(throwingFn).toThrow(TypeError);
- });
-});
+describe.each([['#'], ['#'], ['#a x'], ['#a x33']])(
+ 'Invalid section identifier of %s',
+ (string) => {
+ test('Throws TypeError', () => {
+ const throwingFn = () => parseSectionLabel(string);
+ expect(throwingFn).toThrow(TypeError);
+ });
+ }
+);
diff --git a/tests/unit/parser/parseSong.spec.js b/tests/unit/parser/parseSong.spec.js
index 88c2ad9b..087021a4 100644
--- a/tests/unit/parser/parseSong.spec.js
+++ b/tests/unit/parser/parseSong.spec.js
@@ -22,19 +22,16 @@ describe('parseSong()', () => {
},
asArray() {
return allLines;
- }
+ },
};
});
test('Remove any html tag', () => {
- const input =
- 'this is a text line
';
+ const input = 'this is a text line
';
const expected = {
- allLines: [
- 'this is a text line'
- ],
- allChords: []
+ allLines: ['this is a text line'],
+ allChords: [],
};
const parsed = parseSong(input);
@@ -42,21 +39,11 @@ describe('parseSong()', () => {
});
test('Accept an array as input', () => {
- const input = [
- 'C.. G..',
- 'line1-1',
- 'Am.. F..',
- 'line1-2',
- ];
+ const input = ['C.. G..', 'line1-1', 'Am.. F..', 'line1-2'];
const expected = {
- allLines: [
- 'C.. G..',
- 'line1-1',
- 'Am.. F..',
- 'line1-2',
- ],
- allChords: []
+ allLines: ['C.. G..', 'line1-1', 'Am.. F..', 'line1-2'],
+ allChords: [],
};
const parsed = parseSong(input);
@@ -70,17 +57,11 @@ Am.. F..
line1-2`;
const expected = {
- allLines: [
- 'C.. G..',
- 'line1-1',
- 'Am.. F..',
- 'line1-2',
- ],
- allChords: []
+ allLines: ['C.. G..', 'line1-1', 'Am.. F..', 'line1-2'],
+ allChords: [],
};
const parsed = parseSong(input);
expect(parsed).toEqual(expected);
});
});
-
diff --git a/tests/unit/parser/parseTimeSignature.spec.js b/tests/unit/parser/parseTimeSignature.spec.js
index b9a55b01..ce8016d1 100644
--- a/tests/unit/parser/parseTimeSignature.spec.js
+++ b/tests/unit/parser/parseTimeSignature.spec.js
@@ -7,35 +7,34 @@ describe('parseTimeSignature', () => {
});
describe.each([
+ ['2/2', 2, 2, 4],
+ ['3/2', 3, 2, 6],
- ['2/2', 2, 2, 4],
- ['3/2', 3, 2, 6],
+ ['3/4', 3, 4, 3],
+ ['4/4', 4, 4, 4],
+ ['5/4', 5, 4, 5],
- ['3/4', 3, 4, 3],
- ['4/4', 4, 4, 4],
- ['5/4', 5, 4, 5],
-
- ['3/8', 3, 8, 1],
- ['6/8', 6, 8, 2],
- ['9/8', 9, 8, 3],
+ ['3/8', 3, 8, 1],
+ ['6/8', 6, 8, 2],
+ ['9/8', 9, 8, 3],
['12/8', 12, 8, 4],
-
])('Time signature of %s', (string, count, value, beatCount) => {
test('Correctly gets definition', () => {
- expect(parseTimeSignature(string)).toEqual({ string, count, value, beatCount });
+ expect(parseTimeSignature(string)).toEqual({
+ string,
+ count,
+ value,
+ beatCount,
+ });
});
});
-describe.each([
-
- ['2/1'],
- ['3/1'],
- ['5/8'],
- ['13/7'],
-
-])('Invalid time signature of %s', (string) => {
- test('Throws TypeError', () => {
- const throwingFn = () => parseTimeSignature(string);
- expect(throwingFn).toThrow(TypeError);
- });
-});
+describe.each([['2/1'], ['3/1'], ['5/8'], ['13/7']])(
+ 'Invalid time signature of %s',
+ (string) => {
+ test('Throws TypeError', () => {
+ const throwingFn = () => parseTimeSignature(string);
+ expect(throwingFn).toThrow(TypeError);
+ });
+ }
+);
diff --git a/tests/unit/parser/songLinesFactory.spec.js b/tests/unit/parser/songLinesFactory.spec.js
index 68a8f369..da35b92c 100644
--- a/tests/unit/parser/songLinesFactory.spec.js
+++ b/tests/unit/parser/songLinesFactory.spec.js
@@ -1,4 +1,5 @@
jest.mock('../../../src/parser/parseChordLine');
+jest.mock('../../../src/parser/parseLyricLine');
import _ from 'lodash';
@@ -7,17 +8,14 @@ import songLinesFactory from '../../../src/parser/songLinesFactory';
import parseChordLine from '../../../src/parser/parseChordLine';
import parseSectionLabel from '../../../src/parser/parseSectionLabel';
import parseTimeSignature from '../../../src/parser/parseTimeSignature';
-
+import parseLyricLine from '../../../src/parser/parseLyricLine';
describe('songLinesFactory', () => {
test('Module', () => {
expect(songLinesFactory).toBeInstanceOf(Function);
});
- describe.each([
- ['addLine'],
- ['asArray']
- ])('API', (method) => {
+ describe.each([['addLine'], ['asArray']])('API', (method) => {
test('has method ' + method, () => {
const songLines = songLinesFactory();
expect(songLines[method]).toBeInstanceOf(Function);
@@ -27,11 +25,13 @@ describe('songLinesFactory', () => {
beforeEach(() => {
parseChordLine.mockClear();
+ parseLyricLine.mockClear();
});
describe('ChordLines', () => {
test('Correctly detect and parses chord lines', () => {
- parseChordLine.mockImplementation(chordLine => chordLine);
+ parseChordLine.mockImplementation((chordLine) => chordLine);
+ parseLyricLine.mockImplementation((lyricLine) => lyricLine);
const input = `C.. G..
When I find myself in times of trouble
@@ -53,22 +53,46 @@ Let it be`;
const expected = [
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'When I find myself in times of trouble'},
+ {
+ type: 'lyric',
+ model: 'When I find myself in times of trouble',
+ string: 'When I find myself in times of trouble',
+ },
{ type: 'chord', string: 'Am.. F..', model: 'Am.. F..' },
- { type: 'text', string: 'Mother mary comes to me'},
+ {
+ type: 'lyric',
+ model: 'Mother mary comes to me',
+ string: 'Mother mary comes to me',
+ },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'Speaking words of wisdom'},
+ {
+ type: 'lyric',
+ model: 'Speaking words of wisdom',
+ string: 'Speaking words of wisdom',
+ },
{ type: 'chord', string: 'F. Em. Dm. C.', model: 'F. Em. Dm. C.' },
- { type: 'text', string: 'Let it be'},
- { type: 'emptyLine', string: ''},
+ { type: 'lyric', model: 'Let it be', string: 'Let it be' },
+ { type: 'emptyLine', string: '' },
{ type: 'chord', string: 'Am.. G..', model: 'Am.. G..' },
- { type: 'text', string: 'Let it be, let it be'},
+ {
+ type: 'lyric',
+ model: 'Let it be, let it be',
+ string: 'Let it be, let it be',
+ },
{ type: 'chord', string: 'C.. F..', model: 'C.. F..' },
- { type: 'text', string: 'Let it be, let it be'},
+ {
+ type: 'lyric',
+ model: 'Let it be, let it be',
+ string: 'Let it be, let it be',
+ },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'Whispers words of wisdom'},
+ {
+ type: 'lyric',
+ model: 'Whispers words of wisdom',
+ string: 'Whispers words of wisdom',
+ },
{ type: 'chord', string: 'F. Em. Dm. C.', model: 'F. Em. Dm. C.' },
- { type: 'text', string: 'Let it be'},
+ { type: 'lyric', model: 'Let it be', string: 'Let it be' },
];
const songLines = songLinesFactory();
@@ -77,14 +101,14 @@ Let it be`;
expect(songLines.asArray()).toEqual(expected);
});
- test('Set chordLine as text if parsing fails', () => {
- parseChordLine.mockImplementation(chordLine => { throw new Error(chordLine); });
+ test('Set chordLine as lyric if parsing fails', () => {
+ parseChordLine.mockImplementation((chordLine) => {
+ throw new Error(chordLine);
+ });
const input = 'C. D.. E..';
- const expected = [
- { type: 'text', string: input }
- ];
+ const expected = [{ type: 'lyric', string: input, model: input }];
const songLines = songLinesFactory();
input.split('\n').forEach(songLines.addLine);
@@ -93,18 +117,13 @@ Let it be`;
});
});
-
describe('timeSignature', () => {
test('Correctly parse time signature', () => {
const ts3_4 = parseTimeSignature('3/4');
const ts4_4 = parseTimeSignature('4/4');
const ts6_8 = parseTimeSignature('6/8');
- const input = [
- '6/8',
- '4/4',
- '3/4',
- ];
+ const input = ['6/8', '4/4', '3/4'];
const expected = [
{ type: 'timeSignature', string: '6/8', model: ts6_8 },
@@ -132,7 +151,7 @@ describe('timeSignature', () => {
'When I find myself in times of trouble',
'3/4',
'D D C A',
- 'Never cared for what they know'
+ 'Never cared for what they know',
];
const songLines = songLinesFactory();
@@ -140,15 +159,20 @@ describe('timeSignature', () => {
expect(parseChordLine.mock.calls.length).toBe(3);
expect(parseChordLine.mock.calls[0][0]).toEqual('Em D. C.');
- expect(parseChordLine.mock.calls[0][1]).toEqual({ timeSignature: ts6_8 });
+ expect(parseChordLine.mock.calls[0][1]).toEqual({
+ timeSignature: ts6_8,
+ });
expect(parseChordLine.mock.calls[1][0]).toEqual('C.. G..');
- expect(parseChordLine.mock.calls[1][1]).toEqual({ timeSignature: ts4_4 });
+ expect(parseChordLine.mock.calls[1][1]).toEqual({
+ timeSignature: ts4_4,
+ });
expect(parseChordLine.mock.calls[2][0]).toEqual('D D C A');
- expect(parseChordLine.mock.calls[2][1]).toEqual({ timeSignature: ts3_4 });
+ expect(parseChordLine.mock.calls[2][1]).toEqual({
+ timeSignature: ts3_4,
+ });
});
});
-
describe('sectionLabels and autoRepeatChords', () => {
test('correctly parse section labels', () => {
const input = [
@@ -167,17 +191,95 @@ describe('sectionLabels and autoRepeatChords', () => {
const sectionsParsed = input.map(parseSectionLabel);
const expected = [
- { type: 'sectionLabel', string: '#i', model: sectionsParsed[0], index: 1, indexWithoutRepeats: 1, id: 'i1' },
- { type: 'sectionLabel', string: '#v', model: sectionsParsed[1], index: 1, indexWithoutRepeats: 1, id: 'v1' },
- { type: 'sectionLabel', string: '#v', model: sectionsParsed[2], index: 2, indexWithoutRepeats: 2, id: 'v2' },
- { type: 'sectionLabel', string: '#c', model: sectionsParsed[3], index: 1, indexWithoutRepeats: 1, id: 'c1' },
- { type: 'sectionLabel', string: '#v', model: sectionsParsed[4], index: 3, indexWithoutRepeats: 3, id: 'v3' },
- { type: 'sectionLabel', string: '#c', model: sectionsParsed[5], index: 2, indexWithoutRepeats: 2, id: 'c2' },
- { type: 'sectionLabel', string: '#v', model: sectionsParsed[6], index: 4, indexWithoutRepeats: 4, id: 'v4' },
- { type: 'sectionLabel', string: '#c x2', model: sectionsParsed[7], index: 3, indexWithoutRepeats: 3, id: 'c3' },
- { type: 'sectionLabel', string: '#c x2', model: _.cloneDeep(sectionsParsed[7]), index: 4, indexWithoutRepeats: 3, id: 'c4', isFromSectionRepeat: true },
- { type: 'sectionLabel', string: '#c', model: sectionsParsed[8], index: 5, indexWithoutRepeats: 4, id: 'c5' },
- { type: 'sectionLabel', string: '#o', model: sectionsParsed[9], index: 1, indexWithoutRepeats: 1, id: 'o1' },
+ {
+ type: 'sectionLabel',
+ string: '#i',
+ model: sectionsParsed[0],
+ index: 1,
+ indexWithoutRepeats: 1,
+ id: 'i1',
+ },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ model: sectionsParsed[1],
+ index: 1,
+ indexWithoutRepeats: 1,
+ id: 'v1',
+ },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ model: sectionsParsed[2],
+ index: 2,
+ indexWithoutRepeats: 2,
+ id: 'v2',
+ },
+ {
+ type: 'sectionLabel',
+ string: '#c',
+ model: sectionsParsed[3],
+ index: 1,
+ indexWithoutRepeats: 1,
+ id: 'c1',
+ },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ model: sectionsParsed[4],
+ index: 3,
+ indexWithoutRepeats: 3,
+ id: 'v3',
+ },
+ {
+ type: 'sectionLabel',
+ string: '#c',
+ model: sectionsParsed[5],
+ index: 2,
+ indexWithoutRepeats: 2,
+ id: 'c2',
+ },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ model: sectionsParsed[6],
+ index: 4,
+ indexWithoutRepeats: 4,
+ id: 'v4',
+ },
+ {
+ type: 'sectionLabel',
+ string: '#c x2',
+ model: sectionsParsed[7],
+ index: 3,
+ indexWithoutRepeats: 3,
+ id: 'c3',
+ },
+ {
+ type: 'sectionLabel',
+ string: '#c x2',
+ model: _.cloneDeep(sectionsParsed[7]),
+ index: 4,
+ indexWithoutRepeats: 3,
+ id: 'c4',
+ isFromSectionRepeat: true,
+ },
+ {
+ type: 'sectionLabel',
+ string: '#c',
+ model: sectionsParsed[8],
+ index: 5,
+ indexWithoutRepeats: 4,
+ id: 'c5',
+ },
+ {
+ type: 'sectionLabel',
+ string: '#o',
+ model: sectionsParsed[9],
+ index: 1,
+ indexWithoutRepeats: 1,
+ id: 'o1',
+ },
];
const songLines = songLinesFactory();
@@ -189,7 +291,7 @@ describe('sectionLabels and autoRepeatChords', () => {
test('automatically apply chords - and other lines - of previously defined identical section. Sections can contain empty lines.', () => {
const ts4_4 = parseTimeSignature('4/4');
- parseChordLine.mockImplementation(chordLine => chordLine);
+ parseChordLine.mockImplementation((chordLine) => chordLine);
const input = `#v
4/4
@@ -234,61 +336,226 @@ Whispers words of wisdom
Let it be`;
const expected = [
- { type: 'sectionLabel', string: '#v', index: 1, indexWithoutRepeats: 1, model: parseSectionLabel('#v'), id: 'v1' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 1,
+ indexWithoutRepeats: 1,
+ model: parseSectionLabel('#v'),
+ id: 'v1',
+ },
{ type: 'timeSignature', string: '4/4', model: _.cloneDeep(ts4_4) },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'When I find myself in times of trouble'},
+ {
+ type: 'lyric',
+ model: 'When I find myself in times of trouble',
+ string: 'When I find myself in times of trouble',
+ },
{ type: 'chord', string: 'Am.. F..', model: 'Am.. F..' },
- { type: 'text', string: 'Mother mary comes to me'},
- { type: 'emptyLine', string: ''},
+ {
+ type: 'lyric',
+ model: 'Mother mary comes to me',
+ string: 'Mother mary comes to me',
+ },
+ { type: 'emptyLine', string: '' },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'Speaking words of wisdom'},
+ {
+ type: 'lyric',
+ model: 'Speaking words of wisdom',
+ string: 'Speaking words of wisdom',
+ },
{ type: 'chord', string: 'F. Em. Dm. C.', model: 'F. Em. Dm. C.' },
- { type: 'text', string: 'Let it be'},
- { type: 'emptyLine', string: ''},
- { type: 'sectionLabel', string: '#v', index: 2, indexWithoutRepeats: 2, model: parseSectionLabel('#v'), id: 'v2' },
- { type: 'timeSignature', string: '4/4', model: _.cloneDeep(ts4_4), isFromAutoRepeatChords: true },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'And in my hour of darkness' },
- { type: 'chord', string: 'Am.. F..', model: 'Am.. F..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'she is standing right in front of me' },
+ { type: 'lyric', model: 'Let it be', string: 'Let it be' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 2,
+ indexWithoutRepeats: 2,
+ model: parseSectionLabel('#v'),
+ id: 'v2',
+ },
+ {
+ type: 'timeSignature',
+ string: '4/4',
+ model: _.cloneDeep(ts4_4),
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ model: 'And in my hour of darkness',
+ string: 'And in my hour of darkness',
+ },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: 'Am.. F..',
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ model: 'she is standing right in front of me',
+ string: 'she is standing right in front of me',
+ },
{ type: 'emptyLine', string: '' },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'Speaking words of wisdom' },
- { type: 'chord', string: 'F. Em. Dm. C.', model: 'F. Em. Dm. C.', isFromAutoRepeatChords: true },
- { type: 'text', string: 'Let it be' },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ model: 'Speaking words of wisdom',
+ string: 'Speaking words of wisdom',
+ },
+ {
+ type: 'chord',
+ string: 'F. Em. Dm. C.',
+ model: 'F. Em. Dm. C.',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', model: 'Let it be', string: 'Let it be' },
{ type: 'emptyLine', string: '' },
- { type: 'sectionLabel', string: '#c', index: 1, indexWithoutRepeats: 1, model: parseSectionLabel('#c'), id: 'c1' },
+ {
+ type: 'sectionLabel',
+ string: '#c',
+ index: 1,
+ indexWithoutRepeats: 1,
+ model: parseSectionLabel('#c'),
+ id: 'c1',
+ },
{ type: 'chord', string: 'Am.. G..', model: 'Am.. G..' },
- { type: 'text', string: 'Let it be, let it be'},
+ {
+ type: 'lyric',
+ model: 'Let it be, let it be',
+ string: 'Let it be, let it be',
+ },
{ type: 'chord', string: 'C.. F..', model: 'C.. F..' },
- { type: 'text', string: 'Let it be, let it be'},
+ {
+ type: 'lyric',
+ model: 'Let it be, let it be',
+ string: 'Let it be, let it be',
+ },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'Whispers words of wisdom'},
+ {
+ type: 'lyric',
+ model: 'Whispers words of wisdom',
+ string: 'Whispers words of wisdom',
+ },
{ type: 'chord', string: 'F. Em. Dm. C.', model: 'F. Em. Dm. C.' },
- { type: 'text', string: 'Let it be'},
- { type: 'emptyLine', string: ''},
- { type: 'sectionLabel', string: '#v', index: 3, indexWithoutRepeats: 3, model: parseSectionLabel('#v'), id: 'v3' },
- { type: 'timeSignature', string: '4/4', model: _.cloneDeep(ts4_4), isFromAutoRepeatChords: true },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'And when the broken hearted people', },
- { type: 'chord', string: 'Am.. F..', model: 'Am.. F..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'Living in the world agree' },
+ { type: 'lyric', model: 'Let it be', string: 'Let it be' },
{ type: 'emptyLine', string: '' },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'There will be an answer' },
- { type: 'chord', string: 'F. Em. Dm. C.', model: 'F. Em. Dm. C.', isFromAutoRepeatChords: true },
- { type: 'text', string: 'Let it be' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 3,
+ indexWithoutRepeats: 3,
+ model: parseSectionLabel('#v'),
+ id: 'v3',
+ },
+ {
+ type: 'timeSignature',
+ string: '4/4',
+ model: _.cloneDeep(ts4_4),
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ model: 'And when the broken hearted people',
+ string: 'And when the broken hearted people',
+ },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: 'Am.. F..',
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ model: 'Living in the world agree',
+ string: 'Living in the world agree',
+ },
{ type: 'emptyLine', string: '' },
- { type: 'sectionLabel', string: '#c', index: 2, indexWithoutRepeats: 2, model: parseSectionLabel('#c'), id: 'c2' },
- { type: 'chord', string: 'Am.. G..', model: 'Am.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'Let it be, let it be', },
- { type: 'chord', string: 'C.. F..', model: 'C.. F..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'Let it be, let it be' },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'Whispers words of wisdom' },
- { type: 'chord', string: 'F. Em. Dm. C.', model: 'F. Em. Dm. C.', isFromAutoRepeatChords: true },
- { type: 'text', string: 'Let it be' },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ model: 'There will be an answer',
+ string: 'There will be an answer',
+ },
+ {
+ type: 'chord',
+ string: 'F. Em. Dm. C.',
+ model: 'F. Em. Dm. C.',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', model: 'Let it be', string: 'Let it be' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'sectionLabel',
+ string: '#c',
+ index: 2,
+ indexWithoutRepeats: 2,
+ model: parseSectionLabel('#c'),
+ id: 'c2',
+ },
+ {
+ type: 'chord',
+ string: 'Am.. G..',
+ model: 'Am.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ model: 'Let it be, let it be',
+ string: 'Let it be, let it be',
+ },
+ {
+ type: 'chord',
+ string: 'C.. F..',
+ model: 'C.. F..',
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ model: 'Let it be, let it be',
+ string: 'Let it be, let it be',
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ model: 'Whispers words of wisdom',
+ string: 'Whispers words of wisdom',
+ },
+ {
+ type: 'chord',
+ string: 'F. Em. Dm. C.',
+ model: 'F. Em. Dm. C.',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', model: 'Let it be', string: 'Let it be' },
];
const songLines = songLinesFactory();
@@ -298,7 +565,7 @@ Let it be`;
});
test('blueprint overflows repeat, last empty line of repeat is not "chorded"', () => {
- parseChordLine.mockImplementation(chordLine => chordLine);
+ parseChordLine.mockImplementation((chordLine) => chordLine);
const input = `#v
C.. G..
@@ -323,32 +590,78 @@ line3-3
`;
const expected = [
- { type: 'sectionLabel', string: '#v', index: 1, indexWithoutRepeats: 1, model: parseSectionLabel('#v'), id: 'v1' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 1,
+ indexWithoutRepeats: 1,
+ model: parseSectionLabel('#v'),
+ id: 'v1',
+ },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'line1-1'},
+ { type: 'lyric', string: 'line1-1', model: 'line1-1' },
{ type: 'chord', string: 'Am.. F..', model: 'Am.. F..' },
- { type: 'text', string: 'line1-2'},
+ { type: 'lyric', string: 'line1-2', model: 'line1-2' },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'line1-3'},
+ { type: 'lyric', string: 'line1-3', model: 'line1-3' },
{ type: 'chord', string: 'F. Em. Dm. C.', model: 'F. Em. Dm. C.' },
- { type: 'text', string: 'line1-4'},
- { type: 'emptyLine', string: ''},
- { type: 'sectionLabel', string: '#v', index: 2, indexWithoutRepeats: 2, model: parseSectionLabel('#v'), id: 'v2' },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line2-1'},
- { type: 'chord', string: 'Am.. F..', model: 'Am.. F..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line2-2'},
- { type: 'emptyLine', string: ''},
- { type: 'sectionLabel', string: '#v', index: 3, indexWithoutRepeats: 3, model: parseSectionLabel('#v'), id: 'v3' },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line3-1'},
- { type: 'chord', string: 'Am.. F..', model: 'Am.. F..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line3-2'},
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line3-3'},
- { type: 'emptyLine', string: ''},
- { type: 'emptyLine', string: ''},
- { type: 'emptyLine', string: ''},
+ { type: 'lyric', string: 'line1-4', model: 'line1-4' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 2,
+ indexWithoutRepeats: 2,
+ model: parseSectionLabel('#v'),
+ id: 'v2',
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line2-1', model: 'line2-1' },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: 'Am.. F..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line2-2', model: 'line2-2' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 3,
+ indexWithoutRepeats: 3,
+ model: parseSectionLabel('#v'),
+ id: 'v3',
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line3-1', model: 'line3-1' },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: 'Am.. F..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line3-2', model: 'line3-2' },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line3-3', model: 'line3-3' },
+ { type: 'emptyLine', string: '' },
+ { type: 'emptyLine', string: '' },
+ { type: 'emptyLine', string: '' },
];
const songLines = songLinesFactory();
@@ -358,7 +671,7 @@ line3-3
});
test('repeat overflows blueprint', () => {
- parseChordLine.mockImplementation(chordLine => chordLine);
+ parseChordLine.mockImplementation((chordLine) => chordLine);
const input = `#v
C.. G..
@@ -375,21 +688,45 @@ F. Em. Dm. C.
line2-4`;
const expected = [
- { type: 'sectionLabel', string: '#v', index: 1, indexWithoutRepeats: 1, model: parseSectionLabel('#v'), id: 'v1' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 1,
+ indexWithoutRepeats: 1,
+ model: parseSectionLabel('#v'),
+ id: 'v1',
+ },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'line1-1'},
+ { type: 'lyric', string: 'line1-1', model: 'line1-1' },
{ type: 'chord', string: 'Am.. F..', model: 'Am.. F..' },
- { type: 'text', string: 'line1-2'},
- { type: 'emptyLine', string: ''},
- { type: 'sectionLabel', string: '#v', index: 2, indexWithoutRepeats: 2, model: parseSectionLabel('#v'), id: 'v2' },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line2-1'},
- { type: 'chord', string: 'Am.. F..', model: 'Am.. F..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line2-2'},
+ { type: 'lyric', string: 'line1-2', model: 'line1-2' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 2,
+ indexWithoutRepeats: 2,
+ model: parseSectionLabel('#v'),
+ id: 'v2',
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line2-1', model: 'line2-1' },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: 'Am.. F..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line2-2', model: 'line2-2' },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'line2-3'},
+ { type: 'lyric', string: 'line2-3', model: 'line2-3' },
{ type: 'chord', string: 'F. Em. Dm. C.', model: 'F. Em. Dm. C.' },
- { type: 'text', string: 'line2-4'},
+ { type: 'lyric', string: 'line2-4', model: 'line2-4' },
];
const songLines = songLinesFactory();
@@ -399,7 +736,7 @@ line2-4`;
});
test('allow chords override in repeat', () => {
- parseChordLine.mockImplementation(chordLine => chordLine);
+ parseChordLine.mockImplementation((chordLine) => chordLine);
const input = `#v
C.. G..
@@ -413,17 +750,36 @@ F. Em. Dm. C.
line2-2`;
const expected = [
- { type: 'sectionLabel', string: '#v', index: 1, indexWithoutRepeats: 1, model: parseSectionLabel('#v'), id: 'v1' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 1,
+ indexWithoutRepeats: 1,
+ model: parseSectionLabel('#v'),
+ id: 'v1',
+ },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'line1-1'},
+ { type: 'lyric', string: 'line1-1', model: 'line1-1' },
{ type: 'chord', string: 'Am.. F..', model: 'Am.. F..' },
- { type: 'text', string: 'line1-2'},
- { type: 'emptyLine', string: ''},
- { type: 'sectionLabel', string: '#v', index: 2, indexWithoutRepeats: 2, model: parseSectionLabel('#v'), id: 'v2' },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line2-1'},
+ { type: 'lyric', string: 'line1-2', model: 'line1-2' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 2,
+ indexWithoutRepeats: 2,
+ model: parseSectionLabel('#v'),
+ id: 'v2',
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line2-1', model: 'line2-1' },
{ type: 'chord', string: 'F. Em. Dm. C.', model: 'F. Em. Dm. C.' },
- { type: 'text', string: 'line2-2'},
+ { type: 'lyric', string: 'line2-2', model: 'line2-2' },
];
const songLines = songLinesFactory();
@@ -435,7 +791,7 @@ line2-2`;
describe('chordLineRepeater', () => {
test('should allow to repeat last chordLine', () => {
- parseChordLine.mockImplementation(chordLine => chordLine);
+ parseChordLine.mockImplementation((chordLine) => chordLine);
const input = `C.. G..
line1-1
@@ -448,13 +804,23 @@ line2-1`;
const expected = [
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'line1-1'},
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromChordLineRepeater: true },
- { type: 'text', string: 'line1-2'},
- { type: 'emptyLine', string: ''},
- { type: 'emptyLine', string: ''},
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromChordLineRepeater: true },
- { type: 'text', string: 'line2-1'},
+ { type: 'lyric', string: 'line1-1', model: 'line1-1' },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromChordLineRepeater: true,
+ },
+ { type: 'lyric', string: 'line1-2', model: 'line1-2' },
+ { type: 'emptyLine', string: '' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromChordLineRepeater: true,
+ },
+ { type: 'lyric', string: 'line2-1', model: 'line2-1' },
];
const songLines = songLinesFactory();
@@ -463,8 +829,8 @@ line2-1`;
expect(songLines.asArray()).toEqual(expected);
});
- test('should be parsed as text line if there is no chordLine before', () => {
- parseChordLine.mockImplementation(chordLine => chordLine);
+ test('should be parsed as lyric line if there is no chordLine before', () => {
+ parseChordLine.mockImplementation((chordLine) => chordLine);
const input = `/
line1-1
@@ -474,12 +840,12 @@ line1-2
line1-3`;
const expected = [
- { type: 'text', string: '/'},
- { type: 'text', string: 'line1-1'},
- { type: 'text', string: '/'},
- { type: 'text', string: 'line1-2'},
- { type: 'text', string: '/'},
- { type: 'text', string: 'line1-3'},
+ { type: 'lyric', string: '/', model: '/' },
+ { type: 'lyric', string: 'line1-1', model: 'line1-1' },
+ { type: 'lyric', string: '/', model: '/' },
+ { type: 'lyric', string: 'line1-2', model: 'line1-2' },
+ { type: 'lyric', string: '/', model: '/' },
+ { type: 'lyric', string: 'line1-3', model: 'line1-3' },
];
const songLines = songLinesFactory();
@@ -489,7 +855,7 @@ line1-3`;
});
test('should be usable in repeated section', () => {
- parseChordLine.mockImplementation(chordLine => chordLine);
+ parseChordLine.mockImplementation((chordLine) => chordLine);
const input = `#v
C.. G..
@@ -503,17 +869,41 @@ line2-1
line2-2`;
const expected = [
- { type: 'sectionLabel', string: '#v', index: 1, indexWithoutRepeats: 1, model: parseSectionLabel('#v'), id: 'v1' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 1,
+ indexWithoutRepeats: 1,
+ model: parseSectionLabel('#v'),
+ id: 'v1',
+ },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'line1-1'},
+ { type: 'lyric', string: 'line1-1', model: 'line1-1' },
{ type: 'chord', string: 'Am.. F..', model: 'Am.. F..' },
- { type: 'text', string: 'line1-2'},
- { type: 'emptyLine', string: ''},
- { type: 'sectionLabel', string: '#v', index: 2, indexWithoutRepeats: 2, model: parseSectionLabel('#v'), id: 'v2' },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line2-1'},
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromChordLineRepeater: true },
- { type: 'text', string: 'line2-2'},
+ { type: 'lyric', string: 'line1-2', model: 'line1-2' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 2,
+ indexWithoutRepeats: 2,
+ model: parseSectionLabel('#v'),
+ id: 'v2',
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line2-1', model: 'line2-1' },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromChordLineRepeater: true,
+ },
+ { type: 'lyric', string: 'line2-2', model: 'line2-2' },
];
const songLines = songLinesFactory();
@@ -523,10 +913,9 @@ line2-2`;
});
});
-
describe('Repeat directive (x3, x5...)', () => {
test('should allow to repeat section', () => {
- parseChordLine.mockImplementation(chordLine => chordLine);
+ parseChordLine.mockImplementation((chordLine) => chordLine);
const input = `#v x2
C.. G..
@@ -535,17 +924,52 @@ Am.. F..
line1-2
`;
const expected = [
- { type: 'sectionLabel', string: '#v x2', index: 1, indexWithoutRepeats: 1, model: parseSectionLabel('#v x2'), id: 'v1' },
+ {
+ type: 'sectionLabel',
+ string: '#v x2',
+ index: 1,
+ indexWithoutRepeats: 1,
+ model: parseSectionLabel('#v x2'),
+ id: 'v1',
+ },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'line1-1'},
+ { type: 'lyric', string: 'line1-1', model: 'line1-1' },
{ type: 'chord', string: 'Am.. F..', model: 'Am.. F..' },
- { type: 'text', string: 'line1-2'},
- { type: 'emptyLine', string: ''},
- { type: 'sectionLabel', string: '#v x2', index: 2, indexWithoutRepeats: 1, model: parseSectionLabel('#v x2'), id: 'v2', isFromSectionRepeat: true },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromSectionRepeat: true },
- { type: 'text', string: 'line1-1', isFromSectionRepeat: true },
- { type: 'chord', string: 'Am.. F..', model: 'Am.. F..', isFromSectionRepeat: true },
- { type: 'text', string: 'line1-2', isFromSectionRepeat: true },
+ { type: 'lyric', string: 'line1-2', model: 'line1-2' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'sectionLabel',
+ string: '#v x2',
+ index: 2,
+ indexWithoutRepeats: 1,
+ model: parseSectionLabel('#v x2'),
+ id: 'v2',
+ isFromSectionRepeat: true,
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromSectionRepeat: true,
+ },
+ {
+ type: 'lyric',
+ string: 'line1-1',
+ model: 'line1-1',
+ isFromSectionRepeat: true,
+ },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: 'Am.. F..',
+ isFromSectionRepeat: true,
+ },
+ {
+ type: 'lyric',
+ string: 'line1-2',
+ model: 'line1-2',
+ isFromSectionRepeat: true,
+ },
{ type: 'emptyLine', string: '', isFromSectionRepeat: true },
];
@@ -556,7 +980,7 @@ line1-2
});
test('should allow to repeat section that contains other kinds of repeats', () => {
- parseChordLine.mockImplementation(chordLine => chordLine);
+ parseChordLine.mockImplementation((chordLine) => chordLine);
const input = `#v
C.. G..
@@ -571,28 +995,98 @@ line2-2
line2-3
`;
const expected = [
- { type: 'sectionLabel', string: '#v', index: 1, indexWithoutRepeats: 1, model: parseSectionLabel('#v'), id: 'v1' },
+ {
+ type: 'sectionLabel',
+ string: '#v',
+ index: 1,
+ indexWithoutRepeats: 1,
+ model: parseSectionLabel('#v'),
+ id: 'v1',
+ },
{ type: 'chord', string: 'C.. G..', model: 'C.. G..' },
- { type: 'text', string: 'line1-1'},
+ { type: 'lyric', string: 'line1-1', model: 'line1-1' },
{ type: 'chord', string: 'Am.. F..', model: 'Am.. F..' },
- { type: 'text', string: 'line1-2'},
- { type: 'emptyLine', string: ''},
- { type: 'sectionLabel', string: '#v x2', index: 2, indexWithoutRepeats: 2, model: parseSectionLabel('#v x2'), id: 'v2' },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line2-1'},
- { type: 'chord', string: 'Am.. F..', model: 'Am.. F..', isFromAutoRepeatChords: true },
- { type: 'text', string: 'line2-2'},
- { type: 'chord', string: 'Am.. F..', model: 'Am.. F..', isFromChordLineRepeater: true },
- { type: 'text', string: 'line2-3'},
- { type: 'emptyLine', string: ''},
- { type: 'sectionLabel', string: '#v x2', index: 3, indexWithoutRepeats: 2, model: parseSectionLabel('#v x2'), id: 'v3', isFromSectionRepeat: true },
- { type: 'chord', string: 'C.. G..', model: 'C.. G..', isFromSectionRepeat: true, isFromAutoRepeatChords: true },
- { type: 'text', string: 'line2-1', isFromSectionRepeat: true },
- { type: 'chord', string: 'Am.. F..', model: 'Am.. F..', isFromSectionRepeat: true, isFromAutoRepeatChords: true },
- { type: 'text', string: 'line2-2', isFromSectionRepeat: true },
- { type: 'chord', string: 'Am.. F..', model: 'Am.. F..', isFromSectionRepeat: true, isFromChordLineRepeater: true },
- { type: 'text', string: 'line2-3', isFromSectionRepeat: true },
- { type: 'emptyLine', string: '', isFromSectionRepeat: true},
+ { type: 'lyric', string: 'line1-2', model: 'line1-2' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'sectionLabel',
+ string: '#v x2',
+ index: 2,
+ indexWithoutRepeats: 2,
+ model: parseSectionLabel('#v x2'),
+ id: 'v2',
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line2-1', model: 'line2-1' },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: 'Am.. F..',
+ isFromAutoRepeatChords: true,
+ },
+ { type: 'lyric', string: 'line2-2', model: 'line2-2' },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: 'Am.. F..',
+ isFromChordLineRepeater: true,
+ },
+ { type: 'lyric', string: 'line2-3', model: 'line2-3' },
+ { type: 'emptyLine', string: '' },
+ {
+ type: 'sectionLabel',
+ string: '#v x2',
+ index: 3,
+ indexWithoutRepeats: 2,
+ model: parseSectionLabel('#v x2'),
+ id: 'v3',
+ isFromSectionRepeat: true,
+ },
+ {
+ type: 'chord',
+ string: 'C.. G..',
+ model: 'C.. G..',
+ isFromSectionRepeat: true,
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ string: 'line2-1',
+ model: 'line2-1',
+ isFromSectionRepeat: true,
+ },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: 'Am.. F..',
+ isFromSectionRepeat: true,
+ isFromAutoRepeatChords: true,
+ },
+ {
+ type: 'lyric',
+ string: 'line2-2',
+ model: 'line2-2',
+ isFromSectionRepeat: true,
+ },
+ {
+ type: 'chord',
+ string: 'Am.. F..',
+ model: 'Am.. F..',
+ isFromSectionRepeat: true,
+ isFromChordLineRepeater: true,
+ },
+ {
+ type: 'lyric',
+ string: 'line2-3',
+ model: 'line2-3',
+ isFromSectionRepeat: true,
+ },
+ { type: 'emptyLine', string: '', isFromSectionRepeat: true },
];
const songLines = songLinesFactory();
diff --git a/tests/unit/renderer/components/renderBarContent.spec.js b/tests/unit/renderer/components/renderBarContent.spec.js
index 02c21660..a16d6b64 100644
--- a/tests/unit/renderer/components/renderBarContent.spec.js
+++ b/tests/unit/renderer/components/renderBarContent.spec.js
@@ -10,7 +10,7 @@ import htmlToElement from '../../../../src/core/dom/htmlToElement';
import { forEachChordInChordLine } from '../../../../src/parser/helper/songs';
-renderChordSymbol.mockImplementation(chordSymbol => chordSymbol);
+renderChordSymbol.mockImplementation((chordSymbol) => chordSymbol);
describe('renderBarContent', () => {
test('Module', () => {
@@ -19,7 +19,10 @@ describe('renderBarContent', () => {
test('Should return valid html', () => {
let parsed = parseChordLine('C.. G. F.');
- parsed = forEachChordInChordLine(parsed, chord => chord.symbol = getChordSymbol(chord.model));
+ parsed = forEachChordInChordLine(
+ parsed,
+ (chord) => (chord.symbol = getChordSymbol(chord.model))
+ );
const rendered = renderBarContent(parsed.allBars[0]);
const element = htmlToElement(rendered);
@@ -31,20 +34,21 @@ describe('renderBarContent', () => {
});
describe.each([
-
- ['1 bar / 1 chord / 4 bpb', 'C', 'C '],
- ['1 bar / 2 chords / 4 bpb (1/3)', 'C. G...', 'C G '],
- ['1 bar / 2 chords / 4 bpb (2/2)', 'C.. G..', 'C G '],
- ['1 bar / 2 chords / 4 bpb (3/1)', 'C... G.', 'C G '],
- ['1 bar / 3 chords / 4 bpb (1/1/2)', 'C. G. F..', 'C G F '],
- ['1 bar / 3 chords / 4 bpb (1/2/1)', 'C. G.. F.', 'C G F '],
- ['1 bar / 3 chords / 4 bpb (2/1/1)', 'C.. G. F.', 'C G F '],
- ['1 bar / 4 chords / 4 bpb (1/1/1/1)', 'C. G. F. Am.', 'C G F Ami '],
-
+ ['1 bar / 1 chord / 4 bpb', 'C', 'C '],
+ ['1 bar / 2 chords / 4 bpb (1/3)', 'C. G...', 'C G '],
+ ['1 bar / 2 chords / 4 bpb (2/2)', 'C.. G..', 'C G '],
+ ['1 bar / 2 chords / 4 bpb (3/1)', 'C... G.', 'C G '],
+ ['1 bar / 3 chords / 4 bpb (1/1/2)', 'C. G. F..', 'C G F '],
+ ['1 bar / 3 chords / 4 bpb (1/2/1)', 'C. G.. F.', 'C G F '],
+ ['1 bar / 3 chords / 4 bpb (2/1/1)', 'C.. G. F.', 'C G F '],
+ ['1 bar / 4 chords / 4 bpb (1/1/1/1)', 'C. G. F. Am.', 'C G F Ami '],
])('%s: %s', (title, input, output) => {
test('Renders with default spacing: ' + output, () => {
let parsed = parseChordLine(input);
- parsed = forEachChordInChordLine(parsed, chord => chord.symbol = getChordSymbol(chord.model));
+ parsed = forEachChordInChordLine(
+ parsed,
+ (chord) => (chord.symbol = getChordSymbol(chord.model))
+ );
const rendered = renderBarContent(parsed.allBars[0]);
expect(stripTags(rendered)).toEqual(output);
@@ -52,46 +56,48 @@ describe.each([
});
describe.each([
-
- ['spacesAfter = 0', 'C. G. F..', 0, 'CGF'],
- ['spacesAfter = 1', 'C. G. F..', 1, 'C G F '],
- ['spacesAfter = 2', 'C. G. F..', 2, 'C G F '],
- ['spacesAfter = 3', 'C. G. F..', 3, 'C G F '],
- ['spacesAfter = 4', 'C. G. F..', 4, 'C G F '],
- ['spacesAfter = 5', 'C. G. F..', 5, 'C G F '],
- ['spacesAfter = 6', 'C. G. F..', 6, 'C G F '],
-
+ ['spacesAfter = 0', 'C. G. F..', 0, 'CGF'],
+ ['spacesAfter = 1', 'C. G. F..', 1, 'C G F '],
+ ['spacesAfter = 2', 'C. G. F..', 2, 'C G F '],
+ ['spacesAfter = 3', 'C. G. F..', 3, 'C G F '],
+ ['spacesAfter = 4', 'C. G. F..', 4, 'C G F '],
+ ['spacesAfter = 5', 'C. G. F..', 5, 'C G F '],
+ ['spacesAfter = 6', 'C. G. F..', 6, 'C G F '],
])('%s: %s', (title, input, spacesAfter, output) => {
test('Respect spacesAfter value: ' + output, () => {
let parsed = parseChordLine(input);
- parsed = forEachChordInChordLine(parsed, chord => chord.symbol = getChordSymbol(chord.model));
+ parsed = forEachChordInChordLine(
+ parsed,
+ (chord) => (chord.symbol = getChordSymbol(chord.model))
+ );
- parsed.allBars[0].allChords.forEach(chord => {
+ parsed.allBars[0].allChords.forEach((chord) => {
chord.spacesAfter = spacesAfter;
});
- const rendered = renderBarContent(parsed.allBars[0] );
+ const rendered = renderBarContent(parsed.allBars[0]);
expect(stripTags(rendered)).toEqual(output);
});
});
describe.each([
-
- ['spacesWithin = 0', 'C. G. F..', 0, 'C G F '],
- ['spacesWithin = 1', 'C. G. F..', 1, 'C G F '],
- ['spacesWithin = 2', 'C. G. F..', 2, 'C G F '],
- ['spacesWithin = 3', 'C. G. F..', 3, 'C G F '],
- ['spacesWithin = 4', 'C. G. F..', 4, 'C G F '],
- ['spacesWithin = 5', 'C. G. F..', 5, 'C G F '],
- ['spacesWithin = 6', 'C. G. F..', 6, 'C G F '],
-
+ ['spacesWithin = 0', 'C. G. F..', 0, 'C G F '],
+ ['spacesWithin = 1', 'C. G. F..', 1, 'C G F '],
+ ['spacesWithin = 2', 'C. G. F..', 2, 'C G F '],
+ ['spacesWithin = 3', 'C. G. F..', 3, 'C G F '],
+ ['spacesWithin = 4', 'C. G. F..', 4, 'C G F '],
+ ['spacesWithin = 5', 'C. G. F..', 5, 'C G F '],
+ ['spacesWithin = 6', 'C. G. F..', 6, 'C G F '],
])('%s: %s', (title, input, spacesWithin, output) => {
test('Respect spacesWithin value: ' + output, () => {
let parsed = parseChordLine(input);
- parsed = forEachChordInChordLine(parsed, chord => chord.symbol = getChordSymbol(chord.model));
+ parsed = forEachChordInChordLine(
+ parsed,
+ (chord) => (chord.symbol = getChordSymbol(chord.model))
+ );
- parsed.allBars[0].allChords.forEach(chord => {
+ parsed.allBars[0].allChords.forEach((chord) => {
chord.spacesWithin = spacesWithin;
});
diff --git a/tests/unit/renderer/components/renderChordLine.spec.js b/tests/unit/renderer/components/renderChordLine.spec.js
index 23dc22d2..88f95c0e 100644
--- a/tests/unit/renderer/components/renderChordLine.spec.js
+++ b/tests/unit/renderer/components/renderChordLine.spec.js
@@ -27,18 +27,37 @@ describe('chordLine renderer', () => {
});
describe.each([
-
- ['A B C', '|A|B|C|'],
- ['A.. B.. C.. D..', '|A B|C D|'],
-
+ ['A B C', '|A|B|C|'],
+ ['A.. B.. C.. D..', '|A B|C D|'],
])('Render chordLine "%s" as "%s"', (input, output) => {
test('expected rendering', () => {
- renderBarContent.mockImplementation(bar => bar.allChords
- .map(chord => getChordSymbol(chord.model))
- .join(' ')
+ renderBarContent.mockImplementation((bar) =>
+ bar.allChords.map((chord) => getChordSymbol(chord.model)).join(' ')
+ );
+
+ const chordLine = parseChordLine(input);
+
+ const rendered = renderChordLine(chordLine);
+
+ expect(stripTags(rendered)).toEqual(output);
+ });
+});
+
+describe.each([
+ ['A B C', undefined, '|A|B|C|'],
+ ['A B C', 0, '|A|B|C|'],
+ ['A B C', 1, ' |A|B|C|'],
+ ['A B C', 2, ' |A|B|C|'],
+ ['A B C', 3, ' |A|B|C|'],
+ ['A B C', 10, ' |A|B|C|'],
+])('respect offset parameter', (input, offset, output) => {
+ test('offset chordline by ' + (offset || '0'), () => {
+ renderBarContent.mockImplementation((bar) =>
+ bar.allChords.map((chord) => getChordSymbol(chord.model)).join(' ')
);
const chordLine = parseChordLine(input);
+ chordLine.offset = offset;
const rendered = renderChordLine(chordLine);
diff --git a/tests/unit/renderer/components/renderChordSymbol.spec.js b/tests/unit/renderer/components/renderChordSymbol.spec.js
index 88d62288..347d9ee8 100644
--- a/tests/unit/renderer/components/renderChordSymbol.spec.js
+++ b/tests/unit/renderer/components/renderChordSymbol.spec.js
@@ -19,10 +19,8 @@ describe('chordSymbol renderer', () => {
});
describe.each([
-
- ['A', 'A'],
- ['AM7', 'AM7'],
-
+ ['A', 'A'],
+ ['AM7', 'AM7'],
])('Render chord %s as %s', (input, output) => {
test('expected rendering', () => {
const rendered = renderChordSymbol(input);
diff --git a/tests/unit/renderer/components/renderEmptyLine.spec.js b/tests/unit/renderer/components/renderEmptyLine.spec.js
index 630d506f..8e335a8e 100644
--- a/tests/unit/renderer/components/renderEmptyLine.spec.js
+++ b/tests/unit/renderer/components/renderEmptyLine.spec.js
@@ -16,7 +16,6 @@ describe('renderEmptyLine', () => {
});
});
-
describe('Behaviour', () => {
test('renders empty line as non-breaking space', () => {
const rendered = renderEmptyLine();
diff --git a/tests/unit/renderer/components/renderLine.spec.js b/tests/unit/renderer/components/renderLine.spec.js
index 3899457a..db71ea13 100644
--- a/tests/unit/renderer/components/renderLine.spec.js
+++ b/tests/unit/renderer/components/renderLine.spec.js
@@ -17,15 +17,57 @@ describe('renderLine', () => {
});
describe.each([
+ [
+ 'none',
+ {
+ isFromSectionRepeat: false,
+ isFromAutoRepeatChords: false,
+ isFromChordLineRepeater: false,
+ },
+ [],
+ ],
- ['none', { isFromSectionRepeat: false, isFromAutoRepeatChords: false, isFromChordLineRepeater: false }, []],
-
- ['isFromSectionRepeat', { isFromSectionRepeat: true, isFromAutoRepeatChords: false, isFromChordLineRepeater: false }, ['cmLine--isFromSectionRepeat']],
- ['isFromAutoRepeatChords', { isFromSectionRepeat: false, isFromAutoRepeatChords: true, isFromChordLineRepeater: false }, ['cmLine--isFromAutoRepeatChords']],
- ['isFromChordLineRepeater', { isFromSectionRepeat: false, isFromAutoRepeatChords: false, isFromChordLineRepeater: true }, ['cmLine--isFromChordLineRepeater']],
-
- ['all', { isFromSectionRepeat: true, isFromAutoRepeatChords: true, isFromChordLineRepeater: true }, ['cmLine--isFromSectionRepeat', 'cmLine--isFromAutoRepeatChords', 'cmLine--isFromChordLineRepeater']],
+ [
+ 'isFromSectionRepeat',
+ {
+ isFromSectionRepeat: true,
+ isFromAutoRepeatChords: false,
+ isFromChordLineRepeater: false,
+ },
+ ['cmLine--isFromSectionRepeat'],
+ ],
+ [
+ 'isFromAutoRepeatChords',
+ {
+ isFromSectionRepeat: false,
+ isFromAutoRepeatChords: true,
+ isFromChordLineRepeater: false,
+ },
+ ['cmLine--isFromAutoRepeatChords'],
+ ],
+ [
+ 'isFromChordLineRepeater',
+ {
+ isFromSectionRepeat: false,
+ isFromAutoRepeatChords: false,
+ isFromChordLineRepeater: true,
+ },
+ ['cmLine--isFromChordLineRepeater'],
+ ],
+ [
+ 'all',
+ {
+ isFromSectionRepeat: true,
+ isFromAutoRepeatChords: true,
+ isFromChordLineRepeater: true,
+ },
+ [
+ 'cmLine--isFromSectionRepeat',
+ 'cmLine--isFromAutoRepeatChords',
+ 'cmLine--isFromChordLineRepeater',
+ ],
+ ],
])('repeat identifier classes', (title, options, expected) => {
test('correctly adds expected classes', () => {
const rendered = renderLine({ line: 'myLine' }, options);
@@ -33,7 +75,7 @@ describe.each([
expect.assertions(expected.length + 1);
expect(element).toBeInstanceOf(Node);
- expected.forEach(className => {
+ expected.forEach((className) => {
expect(element.classList.contains(className)).toBe(true);
});
});
diff --git a/tests/unit/renderer/components/renderLyricLine.spec.js b/tests/unit/renderer/components/renderLyricLine.spec.js
new file mode 100644
index 00000000..1748d6ec
--- /dev/null
+++ b/tests/unit/renderer/components/renderLyricLine.spec.js
@@ -0,0 +1,23 @@
+import renderLyricLine from '../../../../src/renderer/components/renderLyricLine';
+import htmlToElement from '../../../../src/core/dom/htmlToElement';
+
+describe('renderLyricLine', () => {
+ test('Module', () => {
+ expect(renderLyricLine).toBeInstanceOf(Function);
+ });
+
+ test('Should return valid html', () => {
+ const rendered = renderLyricLine({
+ string: 'textContent',
+ model: {
+ lyrics: 'textContent',
+ chordPositions: [],
+ },
+ });
+ const element = htmlToElement(rendered);
+
+ expect(element).toBeInstanceOf(Node);
+ expect(element.nodeName).toBe('SPAN');
+ expect(element.classList.contains('cmLyricLine')).toBe(true);
+ });
+});
diff --git a/tests/unit/renderer/components/renderSectionLabel.spec.js b/tests/unit/renderer/components/renderSectionLabel.spec.js
index 7593d591..8b9671a1 100644
--- a/tests/unit/renderer/components/renderSectionLabel.spec.js
+++ b/tests/unit/renderer/components/renderSectionLabel.spec.js
@@ -23,15 +23,15 @@ describe('renderSectionLabel', () => {
describe('Shortcuts and case', () => {
describe.each([
- [ '#a', 'Adlib' ],
- [ '#b', 'Bridge' ],
- [ '#c', 'Chorus' ],
- [ '#i', 'Intro' ],
- [ '#o', 'Outro' ],
- [ '#p', 'Pre-chorus' ],
- [ '#s', 'Solo' ],
- [ '#u', 'Interlude' ],
- [ '#v', 'Verse' ],
+ ['#a', 'Adlib'],
+ ['#b', 'Bridge'],
+ ['#c', 'Chorus'],
+ ['#i', 'Intro'],
+ ['#o', 'Outro'],
+ ['#p', 'Pre-chorus'],
+ ['#s', 'Solo'],
+ ['#u', 'Interlude'],
+ ['#v', 'Verse'],
])('Should replace shortcuts', (string, output) => {
test('expands ' + string + ' to ' + output, () => {
const line = {
@@ -47,88 +47,106 @@ describe('Shortcuts and case', () => {
});
describe.each([
- [ '#inter', 'Inter' ],
- [ '#special', 'Special' ],
- [ '#other', 'Other' ],
- ])('Should render custom sections with a capital first letter', (string, output) => {
- test('renders ' + string + ' to ' + output, () => {
- const line = {
- model: parseSectionLabel(string),
- index: 1,
- };
- const rendered = renderSectionLabel(line);
- const element = htmlToElement(rendered);
-
- expect(element).toBeInstanceOf(Node);
- expect(element.innerHTML).toBe(output);
- });
- });
+ ['#inter', 'Inter'],
+ ['#special', 'Special'],
+ ['#other', 'Other'],
+ ])(
+ 'Should render custom sections with a capital first letter',
+ (string, output) => {
+ test('renders ' + string + ' to ' + output, () => {
+ const line = {
+ model: parseSectionLabel(string),
+ index: 1,
+ };
+ const rendered = renderSectionLabel(line);
+ const element = htmlToElement(rendered);
+
+ expect(element).toBeInstanceOf(Node);
+ expect(element.innerHTML).toBe(output);
+ });
+ }
+ );
});
-
describe('Label indexes', () => {
describe.each([
- [ '#v', 5, { v: 10 }, 'Verse 5' ],
- [ '#c', 3, { c: 5 }, 'Chorus 3' ],
- [ '#b', 7, { b: 8 }, 'Bridge 7' ],
- ])('Should append index to section label if expandSectionRepeats === true', (string, index, sectionsStats, output) => {
- test('appends ' + index, () => {
- const line = {
- model: parseSectionLabel(string),
- index,
- };
- const rendered = renderSectionLabel(line, { sectionsStats, expandSectionRepeats: true });
- const element = htmlToElement(rendered);
-
- expect(element).toBeInstanceOf(Node);
- expect(element.innerHTML).toBe(output);
- });
- });
+ ['#v', 5, { v: 10 }, 'Verse 5'],
+ ['#c', 3, { c: 5 }, 'Chorus 3'],
+ ['#b', 7, { b: 8 }, 'Bridge 7'],
+ ])(
+ 'Should append index to section label if expandSectionRepeats === true',
+ (string, index, sectionsStats, output) => {
+ test('appends ' + index, () => {
+ const line = {
+ model: parseSectionLabel(string),
+ index,
+ };
+ const rendered = renderSectionLabel(line, {
+ sectionsStats,
+ expandSectionRepeats: true,
+ });
+ const element = htmlToElement(rendered);
+
+ expect(element).toBeInstanceOf(Node);
+ expect(element.innerHTML).toBe(output);
+ });
+ }
+ );
describe.each([
- [ '#v', 5, { v: 10 }, 'Verse 5' ],
- [ '#c', 3, { c: 5 }, 'Chorus 3' ],
- [ '#b', 7, { b: 8 }, 'Bridge 7' ],
- ])('Should append indexWithoutRepeats if expandSectionRepeats === false', (string, indexWithoutRepeats, sectionsStats, output) => {
- test('appends ' + indexWithoutRepeats, () => {
- const line = {
- model: parseSectionLabel(string),
- indexWithoutRepeats,
- };
- const rendered = renderSectionLabel(line, { sectionsStats, expandSectionRepeats: false });
- const element = htmlToElement(rendered);
-
- expect(element).toBeInstanceOf(Node);
- expect(element.innerHTML).toBe(output);
- });
- });
+ ['#v', 5, { v: 10 }, 'Verse 5'],
+ ['#c', 3, { c: 5 }, 'Chorus 3'],
+ ['#b', 7, { b: 8 }, 'Bridge 7'],
+ ])(
+ 'Should append indexWithoutRepeats if expandSectionRepeats === false',
+ (string, indexWithoutRepeats, sectionsStats, output) => {
+ test('appends ' + indexWithoutRepeats, () => {
+ const line = {
+ model: parseSectionLabel(string),
+ indexWithoutRepeats,
+ };
+ const rendered = renderSectionLabel(line, {
+ sectionsStats,
+ expandSectionRepeats: false,
+ });
+ const element = htmlToElement(rendered);
+
+ expect(element).toBeInstanceOf(Node);
+ expect(element.innerHTML).toBe(output);
+ });
+ }
+ );
describe.each([
- [ '#v', 1, { v: 1 }, 'Verse' ],
- [ '#c', 1, { c: 2 }, 'Chorus 1' ],
- ])('Should not append index to section label if section is unique', (string, index, sectionsStats, output) => {
- test('appends ' + index, () => {
- const line = {
- model: parseSectionLabel(string),
- index,
- };
- const rendered = renderSectionLabel(line, { sectionsStats });
- const element = htmlToElement(rendered);
-
- expect(element).toBeInstanceOf(Node);
- expect(element.innerHTML).toBe(output);
- });
- });
+ ['#v', 1, { v: 1 }, 'Verse'],
+ ['#c', 1, { c: 2 }, 'Chorus 1'],
+ ])(
+ 'Should not append index to section label if section is unique',
+ (string, index, sectionsStats, output) => {
+ test('appends ' + index, () => {
+ const line = {
+ model: parseSectionLabel(string),
+ index,
+ };
+ const rendered = renderSectionLabel(line, { sectionsStats });
+ const element = htmlToElement(rendered);
+
+ expect(element).toBeInstanceOf(Node);
+ expect(element.innerHTML).toBe(output);
+ });
+ }
+ );
});
-
describe('Repeat indications', () => {
test('should NOT append repeat indication if expandSectionRepeats === true', () => {
const line = {
model: parseSectionLabel('#v x5'),
index: 1,
};
- const rendered = renderSectionLabel(line, { expandSectionRepeats: true });
+ const rendered = renderSectionLabel(line, {
+ expandSectionRepeats: true,
+ });
const element = htmlToElement(rendered);
expect(element).toBeInstanceOf(Node);
@@ -140,7 +158,9 @@ describe('Repeat indications', () => {
model: parseSectionLabel('#v x5'),
index: 1,
};
- const rendered = renderSectionLabel(line, { expandSectionRepeats: false });
+ const rendered = renderSectionLabel(line, {
+ expandSectionRepeats: false,
+ });
const element = htmlToElement(rendered);
expect(element).toBeInstanceOf(Node);
diff --git a/tests/unit/renderer/components/renderSong.spec.js b/tests/unit/renderer/components/renderSong.spec.js
index b2f79288..89f0690e 100644
--- a/tests/unit/renderer/components/renderSong.spec.js
+++ b/tests/unit/renderer/components/renderSong.spec.js
@@ -12,8 +12,7 @@ describe('renderSong', () => {
});
test('Should return valid html', () => {
- const song =
-`A B
+ const song = `A B
verseLine1
C.. D.. E
verseLine2`;
@@ -26,11 +25,9 @@ verseLine2`;
});
});
-
describe('autoRepeatChords', () => {
test('Should render auto repeated chords & other lines if autoRepeatChords === true', () => {
- const input =
-`#v
+ const input = `#v
C G
line1-1
A D
@@ -39,8 +36,7 @@ line1-2
#v
line2-1
line2-2`;
- const expected =
-`Verse 1
+ const expected = `Verse 1
|C |G |
line1-1
|A |D |
@@ -57,8 +53,7 @@ line2-2`;
});
test('Should NOT render auto repeated chords & other lines if autoRepeatChords === false', () => {
- const input =
-`#v
+ const input = `#v
C G
line1-1
A D
@@ -67,8 +62,7 @@ line1-2
#v
line2-1
line2-2`;
- const expected =
-`Verse 1
+ const expected = `Verse 1
|C |G |
line1-1
|A |D |
@@ -83,17 +77,42 @@ line2-2`;
});
});
+describe('alignChordsWithLyrics', () => {
+ test('Should align chords with lyrics placeholders', () => {
+ const input = `#v
+C... CM7. F
+_Imagine there's _no hea_ven`;
+ const expected = `Verse
+|C CM7 |F |
+Imagine there's no heaven`;
+ const rendered = renderSongText(input, { alignChordsWithLyrics: true });
+ const element = htmlToElement(rendered);
+ expect(element.textContent).toBe(expected);
+ });
+
+ test('Should ignore placeholders if chords positioning is disabled (default behavior)', () => {
+ const input = `#v
+C... CM7. F
+_Imagine there's _no hea_ven`;
+ const expected = `Verse
+|C CM7|F |
+Imagine there's no heaven`;
+ const rendered = renderSongText(input, {
+ alignChordsWithLyrics: false,
+ });
+ const element = htmlToElement(rendered);
+ expect(element.textContent).toBe(expected);
+ });
+});
describe('expandSectionRepeat', () => {
test('Should repeat section when expandSectionRepeat === true', () => {
- const input =
-`#v x2
+ const input = `#v x2
A B
verseLine1
C.. D.. E
verseLine2`;
- const expected =
-`Verse 1
+ const expected = `Verse 1
|A |B |
verseLine1
|C D |E |
@@ -109,14 +128,12 @@ verseLine2`;
});
test('Should not repeat section when expandSectionRepeat === false, and display repeat string (x3) after label', () => {
- const input =
-`#v x2
+ const input = `#v x2
A B
verseLine1
C.. D.. E
verseLine2`;
- const expected =
-`Verse 1 x2
+ const expected = `Verse 1 x2
|A |B |
verseLine1
|C D |E |
@@ -127,12 +144,10 @@ verseLine2`;
});
test('Should number repeats incrementally when expandSectionRepeat === true', () => {
- const input =
-`#v
+ const input = `#v
#v x2
#v`;
- const expected =
-`Verse 1
+ const expected = `Verse 1
Verse 2
Verse 3
Verse 4`;
@@ -142,12 +157,10 @@ Verse 4`;
});
test('Should number repeats incrementally when expandSectionRepeat === false', () => {
- const input =
-`#v
+ const input = `#v
#v x2
#v`;
- const expected =
-`Verse 1
+ const expected = `Verse 1
Verse 2 x2
Verse 3`;
const rendered = renderSongText(input, { expandSectionRepeats: false });
@@ -156,11 +169,9 @@ Verse 3`;
});
});
-
describe('sectionsStats', () => {
test('Should number section only if it is repeated', () => {
- const input =
-`#i
+ const input = `#i
#v
#c
#v
@@ -169,8 +180,7 @@ describe('sectionsStats', () => {
#b
#c x2
#o`;
- const expected =
-`Intro
+ const expected = `Intro
Verse 1
Chorus 1
Verse 2
@@ -186,4 +196,3 @@ Outro`;
expect(element.textContent).toBe(expected);
});
});
-
diff --git a/tests/unit/renderer/components/renderTextLine.spec.js b/tests/unit/renderer/components/renderTextLine.spec.js
deleted file mode 100644
index 0ea9e9f3..00000000
--- a/tests/unit/renderer/components/renderTextLine.spec.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import renderTextLine from '../../../../src/renderer/components/renderTextLine';
-import htmlToElement from '../../../../src/core/dom/htmlToElement';
-
-describe('renderTextLine', () => {
- test('Module', () => {
- expect(renderTextLine).toBeInstanceOf(Function);
- });
-
- test('Should return valid html', () => {
- const rendered = renderTextLine({ string: 'textContent' });
- const element = htmlToElement(rendered);
-
- expect(element).toBeInstanceOf(Node);
- expect(element.nodeName).toBe('SPAN');
- expect(element.classList.contains('cmTextLine')).toBe(true);
- });
-});
diff --git a/tests/unit/renderer/helpers/getChordSymbol.spec.js b/tests/unit/renderer/helpers/getChordSymbol.spec.js
index cb948547..ded713fc 100644
--- a/tests/unit/renderer/helpers/getChordSymbol.spec.js
+++ b/tests/unit/renderer/helpers/getChordSymbol.spec.js
@@ -8,11 +8,9 @@ describe('getChordSymbol', () => {
});
describe.each([
-
['AM7', parseChord('AMaj7'), 'Ama7'],
- ['A+', parseChord('Aaug'), 'A+'],
+ ['A+', parseChord('Aaug'), 'A+'],
['NC', 'NC', 'NC'],
-
])('getChordSymbol() for %s', (title, input, output) => {
test('returns ' + output, () => {
expect(getChordSymbol(input)).toEqual(output);
diff --git a/tests/unit/renderer/helpers/getMainAccidental.spec.js b/tests/unit/renderer/helpers/getMainAccidental.spec.js
index a4794904..d5348a95 100644
--- a/tests/unit/renderer/helpers/getMainAccidental.spec.js
+++ b/tests/unit/renderer/helpers/getMainAccidental.spec.js
@@ -8,18 +8,20 @@ describe('getMainAccidental', () => {
});
describe.each([
+ ['no accidentals', 'A B C', 'sharp'],
- ['no accidentals', 'A B C', 'sharp'],
-
- ['all flats', 'Ab Bb Db Gb', 'flat'],
- ['3 flats, 1 sharp', 'Ab Bb Db G#', 'flat'],
- ['2 flats, 2 sharps', 'Ab Bb D# G#', 'sharp'],
- ['1 flat, 3 sharp', 'Ab F# D# G#', 'sharp'],
- ['all sharps', 'A# F# D# G#', 'sharp'],
+ ['all flats', 'Ab Bb Db Gb', 'flat'],
+ ['3 flats, 1 sharp', 'Ab Bb Db G#', 'flat'],
+ ['2 flats, 2 sharps', 'Ab Bb D# G#', 'sharp'],
+ ['1 flat, 3 sharp', 'Ab F# D# G#', 'sharp'],
+ ['all sharps', 'A# F# D# G#', 'sharp'],
['NC symbol does not count', 'A# Eb NC', 'sharp'],
- ['number of chord occurrences have priority over number of distinct chords', 'Ab Ab Ab G# C#', 'flat'],
-
+ [
+ 'number of chord occurrences have priority over number of distinct chords',
+ 'Ab Ab Ab G# C#',
+ 'flat',
+ ],
])('Detect accidentals for: %s', (title, input, output) => {
test(input + ' => ' + output, () => {
const parsed = parseSong(input);
diff --git a/tests/unit/renderer/helpers/getSectionsStats.spec.js b/tests/unit/renderer/helpers/getSectionsStats.spec.js
index 5193bd0c..c241a01b 100644
--- a/tests/unit/renderer/helpers/getSectionsStats.spec.js
+++ b/tests/unit/renderer/helpers/getSectionsStats.spec.js
@@ -17,7 +17,7 @@ describe('getSectionsStats()', () => {
'#c x2',
'#solo',
'#c x2',
- '#o'
+ '#o',
];
const parsed = parseSong(input);
const expected = {
diff --git a/tests/unit/renderer/spacers/chord/aligned.spec.js b/tests/unit/renderer/spacers/chord/aligned.spec.js
index 3a0214c9..43736565 100644
--- a/tests/unit/renderer/spacers/chord/aligned.spec.js
+++ b/tests/unit/renderer/spacers/chord/aligned.spec.js
@@ -13,86 +13,88 @@ const defaultSpacesAfter = 2;
const emptyBeatSpaces = 1;
describe.each([
-
[
'fills second, third and fourth beat',
'A',
+ [{ 1: 1, 2: 0, 3: 0, 4: 0 }],
+ [0],
[
- { 1: 1, 2: 0, 3: 0, 4: 0 }
+ defaultSpacesAfter +
+ emptyBeatSpaces +
+ emptyBeatSpaces +
+ emptyBeatSpaces,
],
- [ 0 ],
- [ defaultSpacesAfter + emptyBeatSpaces + emptyBeatSpaces + emptyBeatSpaces ]
],
[
'fills second and fourth beat',
'A.. D7..',
+ [{ 1: 1, 2: 0, 3: 2, 4: 0 }],
+ [0, 0, 0],
[
- { 1: 1, 2: 0, 3: 2, 4: 0 }
+ defaultSpacesAfter + emptyBeatSpaces,
+ defaultSpacesAfter + emptyBeatSpaces,
],
- [ 0, 0, 0 ],
- [ defaultSpacesAfter + emptyBeatSpaces, defaultSpacesAfter + emptyBeatSpaces ]
],
[
'fills second beat',
'A.. D7. E7.',
- [
- { 1: 1, 2: 0, 3: 2, 4: 2 }
- ],
- [ 0, 0, 0 ],
- [ defaultSpacesAfter + emptyBeatSpaces, defaultSpacesAfter, 0 ]
+ [{ 1: 1, 2: 0, 3: 2, 4: 2 }],
+ [0, 0, 0],
+ [defaultSpacesAfter + emptyBeatSpaces, defaultSpacesAfter, 0],
],
[
'fills third beat',
'A. Dmi7.. E7.',
- [
- { 1: 1, 2: 4, 3: 0, 4: 2 }
- ],
- [ 0, 0, 0 ],
- [ defaultSpacesAfter, defaultSpacesAfter + emptyBeatSpaces, 0 ]
+ [{ 1: 1, 2: 4, 3: 0, 4: 2 }],
+ [0, 0, 0],
+ [defaultSpacesAfter, defaultSpacesAfter + emptyBeatSpaces, 0],
],
[
'fills space within for "full" beats',
'A. Dmi7.. E7.',
- [
- { 1: 3, 2: 6, 3: 0, 4: 3 }
- ],
- [ 2, 2, 1 ],
- [ defaultSpacesAfter, defaultSpacesAfter + emptyBeatSpaces, 0 ]
+ [{ 1: 3, 2: 6, 3: 0, 4: 3 }],
+ [2, 2, 1],
+ [defaultSpacesAfter, defaultSpacesAfter + emptyBeatSpaces, 0],
],
[
'fills space within for "empty" beats',
'A.. D7..',
- [
- { 1: 3, 2: 6, 3: 3, 4: 7 }
- ],
- [ 2, 1 ],
- [ defaultSpacesAfter + 6 + defaultSpacesAfter, defaultSpacesAfter + 7 ]
+ [{ 1: 3, 2: 6, 3: 3, 4: 7 }],
+ [2, 1],
+ [defaultSpacesAfter + 6 + defaultSpacesAfter, defaultSpacesAfter + 7],
],
+])(
+ 'Aligned spacer: %s',
+ (title, chordLine, maxBeatWidth, spacesWithin, spacesAfter) => {
+ test('Correctly fills .spacesWithin and .spacesAfter properties', () => {
+ let parsed = parseChordLine(chordLine);
+ parsed = forEachChordInChordLine(
+ parsed,
+ (chord) => (chord.symbol = getChordSymbol(chord.model))
+ );
-])('Aligned spacer: %s', (title, chordLine, maxBeatWidth, spacesWithin, spacesAfter) => {
- test('Correctly fills .spacesWithin and .spacesAfter properties', () => {
- let parsed = parseChordLine(chordLine);
- parsed = forEachChordInChordLine(parsed, chord => chord.symbol = getChordSymbol(chord.model));
+ const spaced = alignedSpacer(parsed, maxBeatWidth);
- const spaced = alignedSpacer(parsed, maxBeatWidth);
+ let chordIndex = 0;
- let chordIndex = 0;
+ spaced.allBars.forEach((bar) => {
+ bar.allChords.forEach((chord) => {
+ expect(chord).toHaveProperty('spacesWithin');
+ expect(chord.spacesWithin).toEqual(
+ spacesWithin[chordIndex]
+ );
- spaced.allBars.forEach(bar => {
- bar.allChords.forEach(chord => {
- expect(chord).toHaveProperty('spacesWithin');
- expect(chord.spacesWithin).toEqual(spacesWithin[chordIndex]);
+ expect(chord).toHaveProperty('spacesAfter');
+ expect(chord.spacesAfter).toEqual(spacesAfter[chordIndex]);
- expect(chord).toHaveProperty('spacesAfter');
- expect(chord.spacesAfter).toEqual(spacesAfter[chordIndex]);
-
- chordIndex++;
+ chordIndex++;
+ });
});
});
- });
-});
+ }
+);
diff --git a/tests/unit/renderer/spacers/chord/chordLyrics.spec.js b/tests/unit/renderer/spacers/chord/chordLyrics.spec.js
new file mode 100644
index 00000000..f058a1eb
--- /dev/null
+++ b/tests/unit/renderer/spacers/chord/chordLyrics.spec.js
@@ -0,0 +1,133 @@
+import stripTags from '../../../../../src/core/dom/stripTags';
+import { forEachChordInChordLine } from '../../../../../src/parser/helper/songs';
+
+import chordLyricsSpacer from '../../../../../src/renderer/spacers/chord/chordLyrics';
+import parseLyricLine from '../../../../../src/parser/parseLyricLine';
+import parseChordLine from '../../../../../src/parser/parseChordLine';
+import renderLyricLine from '../../../../../src/renderer/components/renderLyricLine';
+import renderChordLine from '../../../../../src/renderer/components/renderChordLine';
+import getChordSymbol from '../../../../../src/renderer/helpers/getChordSymbol';
+
+describe('chordLyricsSpacer', () => {
+ test('Module', () => {
+ expect(chordLyricsSpacer).toBeInstanceOf(Function);
+ });
+});
+
+describe.each([
+ [
+ 'Single character chords',
+ 'A D A E',
+ '_Put me _on top _of the correct _lyrics',
+ '|A |D |A |E |',
+ 'Put me on top of the correct lyrics',
+ ],
+ [
+ 'Long chords names',
+ 'Am Dm7 A7(b9) E7',
+ '_Put me _on top _of the correct _lyrics',
+ '|Ami |Dmi7 |A7(b9) |E7 |',
+ 'Put me on top of the correct lyrics',
+ ],
+ [
+ 'Multiple chords per bar',
+ 'A.. B.. Dm7 A.. Gmi. F7. E7',
+ '_Put _me _on top _of _the _correct _lyrics',
+ '|A B |Dmi7 |A Gmi F7 |E7 |',
+ 'Put me on top of the correct lyrics',
+ ],
+ [
+ 'Lyrics shorter than chords names should be spaced',
+ 'A7(b9).. BmiMa7.. Dmi7 A7(b9).. Gmi13. F7(b9,#11). E7',
+ '_Put _me _on top _of _the _correct _lyrics',
+ '|A7(b9) BmiMa7 |Dmi7 |A7(b9) Gmi13 F7(b9,#11) |E7 |',
+ 'Put me on top of the correct lyrics',
+ ],
+ [
+ 'Chord symbol size equals lyric token size',
+ 'Ami7 Bmi D13 F13',
+ '_Put _me _on _top',
+ '|Ami7 |Bmi |D13 |F13 |',
+ 'Put me on top',
+ ],
+ [
+ 'Chord token size (incl separator and space) equals lyric token size',
+ 'A7 B D F7',
+ '_Put _me _on _top',
+ '|A7 |B |D |F7 |',
+ 'Put me on top',
+ ],
+ [
+ 'Extra chord position markers should be ignored',
+ 'A7 B',
+ '_Put _me _on _top',
+ '|A7 |B |',
+ 'Put me on top',
+ ],
+ [
+ 'Spacing of extra chords should be reset to 1 (default spacing for chordLyricsSpacer)',
+ 'A7 B C7 B7 F7',
+ '_Put me _on top',
+ '|A7 |B |C7 |B7 |F7 |',
+ 'Put me on top',
+ ],
+ [
+ 'No position markers: default spacing should be kept (2 by default)',
+ 'A B C D',
+ 'I do not know where to put the chords',
+ '|A |B |C |D |',
+ 'I do not know where to put the chords',
+ ],
+ [
+ 'Edge case: no lyrics, single character chord!',
+ 'A B C D',
+ '_ _ _ _',
+ '|A |B |C |D |',
+ '',
+ ],
+ [
+ 'A position marker followed by a space should create space for the full chord name',
+ 'Ami7(#11) B7(b9)',
+ '_ A _ second chord shortly after the first one',
+ '|Ami7(#11) |B7(b9) |',
+ ' A second chord shortly after the first one',
+ ],
+ [
+ 'offset the chord rendering if the first position marker is > 0',
+ 'Ami7(#11) B7(b9)',
+ 'The first chord comes a bit _later, nice _hu?',
+ ' |Ami7(#11) |B7(b9) |',
+ 'The first chord comes a bit later, nice hu?',
+ ],
+])(
+ '%s',
+ (
+ title,
+ chordLineInput,
+ LyricsLineInput,
+ chordsLineOutput,
+ LyricsLineOutput
+ ) => {
+ test('Correctly space chord & lyrics lines', () => {
+ const parsedLyrics = parseLyricLine(LyricsLineInput);
+
+ const parsedChords = parseChordLine(chordLineInput);
+ const parsedChordsWithSymbols = forEachChordInChordLine(
+ parsedChords,
+ (chord) => {
+ chord.symbol = getChordSymbol(chord.model);
+ }
+ );
+ const { chordLine, lyricsLine } = chordLyricsSpacer(
+ parsedChordsWithSymbols,
+ parsedLyrics
+ );
+
+ const renderedChords = renderChordLine(chordLine);
+ const renderedLyrics = renderLyricLine({ model: lyricsLine });
+
+ expect(stripTags(renderedChords)).toEqual(chordsLineOutput);
+ expect(stripTags(renderedLyrics)).toEqual(LyricsLineOutput);
+ });
+ }
+);
diff --git a/tests/unit/renderer/spacers/chord/getMaxBeatsWidth.spec.js b/tests/unit/renderer/spacers/chord/getMaxBeatsWidth.spec.js
index e53f25d1..7c647a6e 100644
--- a/tests/unit/renderer/spacers/chord/getMaxBeatsWidth.spec.js
+++ b/tests/unit/renderer/spacers/chord/getMaxBeatsWidth.spec.js
@@ -12,107 +12,58 @@ describe('getMaxBeatsWidth', () => {
});
describe.each([
-
[
'2 lines / 1 bar / 1 chord, same width ',
- [
- 'A',
- 'B'
- ],
- [
- { 1: 1, 2: 0, 3: 0, 4: 0 },
- ]
+ ['A', 'B'],
+ [{ 1: 1, 2: 0, 3: 0, 4: 0 }],
],
[
'2 lines / 1 bar / 1 chord, different width',
- [
- 'A',
- 'Bmi7'
- ],
- [
- { 1: 4, 2: 0, 3: 0, 4: 0 },
- ]
+ ['A', 'Bmi7'],
+ [{ 1: 4, 2: 0, 3: 0, 4: 0 }],
],
[
'2 lines / 1 bar / 4 chords per bar',
- [
- 'A. Bmi7. C. Dmi7.',
- 'E7. A7. G7. D7/G.'
- ],
- [
- { 1: 2, 2: 4, 3: 2, 4: 4 },
- ]
+ ['A. Bmi7. C. Dmi7.', 'E7. A7. G7. D7/G.'],
+ [{ 1: 2, 2: 4, 3: 2, 4: 4 }],
],
[
'2 lines / 1 bar / 3 chords / gap on beat 2 and 4',
- [
- 'A.. Bmi7..',
- 'E7'
- ],
- [
- { 1: 2, 2: 0, 3: 4, 4: 0 },
- ]
+ ['A.. Bmi7..', 'E7'],
+ [{ 1: 2, 2: 0, 3: 4, 4: 0 }],
],
[
'2 lines / 1 bar / 3 chords / gap on beat 2',
- [
- 'A.. Bmi7..',
- 'E7... A7.'
- ],
- [
- { 1: 2, 2: 0, 3: 4, 4: 2 },
- ]
+ ['A.. Bmi7..', 'E7... A7.'],
+ [{ 1: 2, 2: 0, 3: 4, 4: 2 }],
],
[
'2 lines / 1 bar / 3 chords / gap on beat 3',
- [
- 'A. Bmi7...',
- 'E7... A7.'
- ],
- [
- { 1: 2, 2: 4, 3: 0, 4: 2 },
- ]
+ ['A. Bmi7...', 'E7... A7.'],
+ [{ 1: 2, 2: 4, 3: 0, 4: 2 }],
],
[
'2 lines / 1 bar / 3 chords / gap on beat 4',
- [
- 'A. Bmi7...',
- 'E7.. A7..'
- ],
- [
- { 1: 2, 2: 4, 3: 2, 4: 0 },
- ]
+ ['A. Bmi7...', 'E7.. A7..'],
+ [{ 1: 2, 2: 4, 3: 2, 4: 0 }],
],
[
'3 lines / 1 bar / 4 chords ',
- [
- 'A. Bmi7. C. Dmi7.',
- 'E7. A7. G7. D7.',
- 'E7/G. A. G. D(b5).'
- ],
- [
- { 1: 4, 2: 4, 3: 2, 4: 5 },
- ]
+ ['A. Bmi7. C. Dmi7.', 'E7. A7. G7. D7.', 'E7/G. A. G. D(b5).'],
+ [{ 1: 4, 2: 4, 3: 2, 4: 5 }],
],
[
'3 lines / 1 bar / different beat per line ',
- [
- 'A',
- 'E7. A7...',
- 'D7.. A..',
- 'Dmi7... C(b5).',
- ],
- [
- { 1: 4, 2: 2, 3: 1, 4: 5 },
- ]
+ ['A', 'E7. A7...', 'D7.. A..', 'Dmi7... C(b5).'],
+ [{ 1: 4, 2: 2, 3: 1, 4: 5 }],
],
[
@@ -124,34 +75,32 @@ describe.each([
'Dmi7... C(b5). G(b5). Dmi7... B7',
],
[
- { 1: 4, 2: 2, 3: 1, 4: 5 },
- { 1: 5, 2: 4, 3: 5, 4: 2 },
- { 1: 8, 2: 0, 3: 5, 4: 0 },
- ]
+ { 1: 4, 2: 2, 3: 1, 4: 5 },
+ { 1: 5, 2: 4, 3: 5, 4: 2 },
+ { 1: 8, 2: 0, 3: 5, 4: 0 },
+ ],
],
[
'3 lines / uneven bars per line',
+ ['A A B C G.. E7..', 'G7', 'G Bmi7.. Ami7.. E7'],
[
- 'A A B C G.. E7..',
- 'G7',
- 'G Bmi7.. Ami7.. E7',
+ { 1: 2, 2: 0, 3: 0, 4: 0 },
+ { 1: 4, 2: 0, 3: 4, 4: 0 },
+ { 1: 2, 2: 0, 3: 0, 4: 0 },
+ { 1: 1, 2: 0, 3: 0, 4: 0 },
+ { 1: 1, 2: 0, 3: 2, 4: 0 },
],
- [
- { 1: 2, 2: 0, 3: 0, 4: 0 },
- { 1: 4, 2: 0, 3: 4, 4: 0 },
- { 1: 2, 2: 0, 3: 0, 4: 0 },
- { 1: 1, 2: 0, 3: 0, 4: 0 },
- { 1: 1, 2: 0, 3: 2, 4: 0 },
- ]
],
-
])('getMaxBeatsWidth(): %s', (title, input, output) => {
test('Correctly computes the maximum width for each beat', () => {
const parsedSong = parseSong(input);
let { allLines } = parsedSong;
- allLines = forEachChordInSong(allLines, chord => chord.symbol = getChordSymbol(chord.model));
+ allLines = forEachChordInSong(
+ allLines,
+ (chord) => (chord.symbol = getChordSymbol(chord.model))
+ );
const maxBeatsWidth = getMaxBeatsWidth(allLines);
expect(maxBeatsWidth).toEqual(output);
diff --git a/tests/unit/renderer/spacers/chord/simple.spec.js b/tests/unit/renderer/spacers/chord/simple.spec.js
index 52a1acc7..11b083da 100644
--- a/tests/unit/renderer/spacers/chord/simple.spec.js
+++ b/tests/unit/renderer/spacers/chord/simple.spec.js
@@ -14,29 +14,27 @@ const ts6_8 = parseTimeSignature('6/8');
const ts5_4 = parseTimeSignature('5/4');
describe.each([
-
- ['1 bar / 1 chord / 6/8', ts6_8, 'C', [3] ],
- ['1 bar / 2 chords / 6/8', ts6_8, 'C. F.', [3, 2] ],
-
- ['1 bar / 1 chord / 3/4', ts3_4, 'C', [3] ],
- ['1 bar / 2 chords (1/2) / 3/4', ts3_4, 'C. F..', [2, 4] ],
- ['1 bar / 2 chords (2/1) / 3/4', ts3_4, 'C.. F.', [6, 0] ],
- ['1 bar / 3 chords / 3/4', ts3_4, 'C. F. G.', [2, 2, 0] ],
-
- ['1 bar / 1 chord / 4/4', ts4_4, 'C', [3] ],
- ['1 bar / 2 chords (1/3) / 4/4', ts4_4, 'C. F...', [1, 4] ],
- ['1 bar / 2 chords (2/2) / 4/4', ts4_4, 'C.. F..', [3, 2] ],
- ['1 bar / 2 chords (3/1) / 4/4', ts4_4, 'C... F.', [5, 0] ],
- ['1 bar / 3 chords (1/1/2) / 4/4', ts4_4, 'C. F. G..', [1, 1, 3] ],
- ['1 bar / 3 chords (1/2/1) / 4/4', ts4_4, 'C. F.. G.', [1, 4, 0] ],
- ['1 bar / 3 chords (2/1/1) / 4/4', ts4_4, 'C.. F. G.', [4, 1, 0] ],
- ['1 bar / 4 chords / 4/4', ts4_4, 'C. F. G. Em.', [2, 2, 2, 0] ],
-
- ['1 bar / 1 chords / 5/4', ts5_4, 'C', [2] ],
- ['1 bar / 2 chords (1/4) / 5/4', ts5_4, 'C. F....', [2, 2] ],
- ['1 bar / 2 chords (2/3) / 5/4', ts5_4, 'C.. F...', [2, 2] ],
- ['1 bar / 3 chords (1/2/2) / 5/4', ts5_4, 'C. F.. G..', [2, 2, 2] ],
-
+ ['1 bar / 1 chord / 6/8', ts6_8, 'C', [3]],
+ ['1 bar / 2 chords / 6/8', ts6_8, 'C. F.', [3, 2]],
+
+ ['1 bar / 1 chord / 3/4', ts3_4, 'C', [3]],
+ ['1 bar / 2 chords (1/2) / 3/4', ts3_4, 'C. F..', [2, 4]],
+ ['1 bar / 2 chords (2/1) / 3/4', ts3_4, 'C.. F.', [6, 0]],
+ ['1 bar / 3 chords / 3/4', ts3_4, 'C. F. G.', [2, 2, 0]],
+
+ ['1 bar / 1 chord / 4/4', ts4_4, 'C', [3]],
+ ['1 bar / 2 chords (1/3) / 4/4', ts4_4, 'C. F...', [1, 4]],
+ ['1 bar / 2 chords (2/2) / 4/4', ts4_4, 'C.. F..', [3, 2]],
+ ['1 bar / 2 chords (3/1) / 4/4', ts4_4, 'C... F.', [5, 0]],
+ ['1 bar / 3 chords (1/1/2) / 4/4', ts4_4, 'C. F. G..', [1, 1, 3]],
+ ['1 bar / 3 chords (1/2/1) / 4/4', ts4_4, 'C. F.. G.', [1, 4, 0]],
+ ['1 bar / 3 chords (2/1/1) / 4/4', ts4_4, 'C.. F. G.', [4, 1, 0]],
+ ['1 bar / 4 chords / 4/4', ts4_4, 'C. F. G. Em.', [2, 2, 2, 0]],
+
+ ['1 bar / 1 chords / 5/4', ts5_4, 'C', [2]],
+ ['1 bar / 2 chords (1/4) / 5/4', ts5_4, 'C. F....', [2, 2]],
+ ['1 bar / 2 chords (2/3) / 5/4', ts5_4, 'C.. F...', [2, 2]],
+ ['1 bar / 3 chords (1/2/2) / 5/4', ts5_4, 'C. F.. G..', [2, 2, 2]],
])('%s', (title, timeSignature, input, spacesAfter) => {
test('Correctly compute .spacesAfter', () => {
const parsed = parseChordLine(input, { timeSignature });
@@ -44,8 +42,8 @@ describe.each([
let chordIndex = 0;
- spaced.allBars.forEach(bar => {
- bar.allChords.forEach(chord => {
+ spaced.allBars.forEach((bar) => {
+ bar.allChords.forEach((chord) => {
expect(chord).toHaveProperty('spacesAfter');
expect(chord.spacesAfter).toEqual(spacesAfter[chordIndex]);
chordIndex++;
diff --git a/todo.md b/todo.md
index 16fb2a66..790fe9f4 100644
--- a/todo.md
+++ b/todo.md
@@ -1,5 +1,7 @@
# Tech debt
-- memoize most parsing functions
+
+- memoize most parsing functions
# Todo
-- remove duplicate chords after simplification
+
+- remove duplicate chords after simplification
diff --git a/webpack.config.js b/webpack.config.js
index 34d6d971..95d91766 100755
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -3,8 +3,9 @@ const path = require('path');
const webpack = require('webpack');
-const { CleanWebpackPlugin }= require('clean-webpack-plugin');
-const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
+const { CleanWebpackPlugin } = require('clean-webpack-plugin');
+const BundleAnalyzerPlugin =
+ require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const buildDir = 'lib';
@@ -23,7 +24,7 @@ const config = {
library: 'chord-mark',
libraryTarget: 'umd',
// https://github.com/webpack/webpack/pull/8625
- globalObject: 'typeof self !== \'undefined\' ? self : this',
+ globalObject: "typeof self !== 'undefined' ? self : this",
},
optimization: {
@@ -31,7 +32,7 @@ const config = {
},
performance: {
- hints: false
+ hints: false,
},
plugins: [
@@ -48,15 +49,14 @@ const config = {
{
test: /\.js$/,
exclude: /node_modules/,
- loader: 'babel-loader'
+ loader: 'babel-loader',
},
{
test: /\.hbs$/,
- loader: 'handlebars-loader'
+ loader: 'handlebars-loader',
},
- ]
- }
+ ],
+ },
};
module.exports = config;
-