@angular-wave/angular.ts 0.14.1 → 0.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/angular.d.ts +4 -3
- package/@types/animations/interface.d.ts +2 -2
- package/@types/animations/queue/animate-queue.d.ts +0 -1
- package/@types/animations/raf-scheduler.d.ts +3 -3
- package/@types/animations/runner/animate-runner.d.ts +9 -6
- package/@types/core/compile/attributes.d.ts +3 -6
- package/@types/core/compile/compile.d.ts +1 -1
- package/@types/core/compile/inteface.d.ts +13 -9
- package/@types/core/di/ng-module/ng-module.d.ts +8 -7
- package/@types/core/filter/filter.d.ts +1 -1
- package/@types/core/parse/ast/ast.d.ts +30 -39
- package/@types/core/parse/ast-type.d.ts +16 -16
- package/@types/core/parse/interpreter.d.ts +1 -26
- package/@types/core/parse/lexer/lexer.d.ts +19 -19
- package/@types/core/parse/parser/parser.d.ts +4 -9
- package/@types/core/scope/interface.d.ts +0 -6
- package/@types/namespace.d.ts +4 -13
- package/@types/router/common/trace.d.ts +5 -5
- package/@types/router/params/interface.d.ts +2 -2
- package/@types/router/params/param.d.ts +3 -3
- package/@types/router/transition/reject-factory.d.ts +5 -5
- package/@types/router/transition/transition-hook.d.ts +11 -23
- package/@types/services/cookie/cookie.d.ts +2 -2
- package/@types/services/http/http.d.ts +8 -7
- package/@types/services/pubsub/pubsub.d.ts +1 -2
- package/@types/services/rest/rest.d.ts +5 -5
- package/@types/services/sse/sse.d.ts +1 -1
- package/@types/shared/node.d.ts +8 -0
- package/@types/shared/noderef.d.ts +8 -11
- package/@types/shared/utils.d.ts +25 -36
- package/@types/shared/validate.d.ts +36 -0
- package/dist/angular-ts.esm.js +1061 -1094
- package/dist/angular-ts.umd.js +1061 -1094
- package/dist/angular-ts.umd.min.js +2 -1
- package/dist/angular-ts.umd.min.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angular-ts.umd.min.js","sources":["../src/shared/constants.js","../src/shared/node.js","../src/shared/utils.js","../src/core/parse/ast-type.js","../src/animations/shared.js","../src/shared/dom.js","../src/injection-tokens.js","../src/core/di/di.js","../src/core/di/internal-injector.js","../src/services/storage/storage.js","../src/shared/predicates.js","../src/shared/validate.js","../src/core/di/injector.js","../src/shared/url-utils/url-utils.js","../src/services/http/http.js","../src/directive/http/http.js","../src/directive/worker/worker.js","../src/core/di/ng-module/ng-module.js","../src/shared/noderef.js","../src/core/controller/controller.js","../src/services/sce/sce.js","../src/directive/events/events.js","../src/core/compile/attributes.js","../src/directive/observe/observe.js","../src/core/compile/compile.js","../src/directive/form/form.js","../src/directive/model-options/model-options.js","../src/directive/model/model.js","../src/directive/input/input.js","../src/directive/script/script.js","../src/directive/select/select.js","../src/directive/bind/bind.js","../src/directive/class/class.js","../src/directive/cloak/cloak.js","../src/directive/controller/controller.js","../src/directive/show-hide/show-hide.js","../src/directive/if/if.js","../src/directive/include/include.js","../src/directive/init/init.js","../src/directive/non-bindable/non-bindable.js","../src/directive/ref/ref.js","../src/directive/repeat/repeat.js","../src/directive/style/style.js","../src/directive/switch/switch.js","../src/directive/options/options.js","../src/directive/transclude/transclude.js","../src/directive/attrs/attrs.js","../src/directive/validators/validators.js","../src/services/anchor-scroll/anchor-scroll.js","../src/animations/animate.js","../src/services/template-cache/template-cache.js","../src/services/exception/exception.js","../src/filters/filter.js","../src/filters/filters.js","../src/filters/limit-to.js","../src/filters/order-by.js","../src/router/state-filters.js","../src/core/filter/filter.js","../src/core/parse/interpreter.js","../src/core/parse/lexer/lexer.js","../src/core/parse/ast/ast.js","../src/core/parse/parser/parser.js","../src/core/parse/parse.js","../src/core/interpolate/interpolate.js","../src/services/location/location.js","../src/services/log/log.js","../src/core/scope/scope.js","../src/services/template-request/template-request.js","../src/core/sanitize/sanitize-uri.js","../src/directive/messages/messages.js","../src/directive/aria/aria.js","../src/animations/runner/animate-runner.js","../src/animations/animate-css.js","../src/animations/queue/animate-queue.js","../src/animations/animate-js.js","../src/animations/animation.js","../src/animations/raf-scheduler.js","../src/animations/animate-cache.js","../src/animations/animate-css-driver.js","../src/animations/animate-js-driver.js","../src/animations/animate-swap.js","../src/animations/animate-children-directive.js","../src/shared/common.js","../src/shared/hof.js","../src/router/params/param-type.js","../src/router/params/param-types.js","../src/router/url/url-config.js","../src/router/params/state-params.js","../src/shared/queue.js","../src/router/router.js","../src/shared/strings.js","../src/router/common/trace.js","../src/router/resolve/resolvable.js","../src/router/state/target-state.js","../src/router/params/param.js","../src/router/path/path-node.js","../src/router/path/path-utils.js","../src/router/resolve/resolve-context.js","../src/router/state/views.js","../src/router/view/view.js","../src/router/transition/reject-factory.js","../src/services/pubsub/pubsub.js","../src/router/transition/transition-hook.js","../src/router/glob/glob.js","../src/router/transition/hook-registry.js","../src/router/transition/hook-builder.js","../src/router/transition/transition.js","../src/router/hooks/core-resolvables.js","../src/router/hooks/on-enter-exit-retain.js","../src/router/hooks/resolve.js","../src/router/hooks/views.js","../src/router/hooks/update-globals.js","../src/router/hooks/lazy-load.js","../src/router/transition/transition-event-type.js","../src/router/hooks/ignored-transition.js","../src/router/hooks/invalid-transition.js","../src/router/transition/transition-service.js","../src/router/hooks/url.js","../src/router/hooks/redirect-to.js","../src/router/state/state-service.js","../src/router/view-scroll.js","../src/router/template-factory.js","../src/router/url/url-matcher.js","../src/router/state/state-object.js","../src/router/url/url-rule.js","../src/router/url/url-rules.js","../src/router/params/param-factory.js","../src/router/url/url-service.js","../src/router/state/state-matcher.js","../src/router/state/state-builder.js","../src/router/state/state-queue-manager.js","../src/router/state/state-registry.js","../src/router/directives/state-directives.js","../src/router/directives/view-directive.js","../src/directive/channel/channel.js","../src/directive/setter/setter.js","../src/directive/inject/inject.js","../src/directive/el/el.js","../src/services/sse/sse.js","../src/directive/viewport/viewport.js","../src/directive/wasm/wasm.js","../src/directive/scope/scope.js","../src/services/cookie/cookie.js","../src/services/rest/rfc.js","../src/services/rest/rest.js","../src/index.js","../src/angular.js","../src/ng.js"],"sourcesContent":["export const VALID_CLASS = \"ng-valid\";\nexport const INVALID_CLASS = \"ng-invalid\";\nexport const PRISTINE_CLASS = \"ng-pristine\";\nexport const DIRTY_CLASS = \"ng-dirty\";\nexport const UNTOUCHED_CLASS = \"ng-untouched\";\nexport const TOUCHED_CLASS = \"ng-touched\";\nexport const EMPTY_CLASS = \"ng-empty\";\nexport const NOT_EMPTY_CLASS = \"ng-not-empty\";\n\n// x prefix is being kept for view-directive.spec lines 1550, 565\nexport const PREFIX_REGEXP = /^((?:x|data)[-])/i;\nexport const SPECIAL_CHARS_REGEXP = /[-]+(.)/g;\n\nexport const ALIASED_ATTR = {\n ngMinlength: \"minlength\",\n ngMaxlength: \"maxlength\",\n ngMin: \"min\",\n ngMax: \"max\",\n ngPattern: \"pattern\",\n ngStep: \"step\",\n};\n","/** @internal */\n/** @enum {number} */\nexport const NodeType = {\n _ELEMENT_NODE: Node.ELEMENT_NODE,\n _DOCUMENT_NODE: Node.DOCUMENT_NODE,\n _TEXT_NODE: Node.TEXT_NODE,\n _COMMENT_NODE: Node.COMMENT_NODE,\n _DOCUMENT_FRAGMENT_NODE: Node.DOCUMENT_FRAGMENT_NODE,\n};\n","import { PREFIX_REGEXP, SPECIAL_CHARS_REGEXP } from \"./constants.js\";\nimport { NodeType } from \"./node.js\";\n\nexport const isProxySymbol = Symbol(\"isProxy\");\n\n/**\n *\n * @param {*} value\n * @returns {boolean}\n */\nexport function isProxy(value) {\n return !!(value && value[isProxySymbol]);\n}\n\nconst ngMinErr = minErr(\"ng\");\n\n/**\n * @type {number}\n */\nlet uid = 0;\n\n/**\n * @returns {number} an unique alpha-numeric string\n */\nexport function nextUid() {\n uid += 1;\n\n return uid;\n}\n\n/**\n *\n * @description Converts the specified string to lowercase.\n * @param {string} string String to be converted to lowercase.\n * @returns {string} Lowercased string.\n */\nexport function lowercase(string) {\n return isString(string) ? string.toLowerCase() : string;\n}\n\n/**\n *\n * @description Converts the specified string to uppercase.\n * @param {string} string String to be converted to uppercase.\n * @returns {string} Uppercased string.\n */\nexport function uppercase(string) {\n return isString(string) ? string.toUpperCase() : string;\n}\n\n/**\n * @param {*} obj Reference to check.\n * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,\n * String ...)\n */\nexport function isArrayLike(obj) {\n // `null`, `undefined` and `window` are not array-like\n if (isNull(obj) || isWindow(obj)) return false;\n\n // arrays, strings and jQuery/jqLite objects are array like\n // * we have to check the existence of JQLite first as this method is called\n // via the forEach method when constructing the JQLite object in the first place\n if (isArray(obj) || obj instanceof Array || isString(obj)) return true;\n\n // Support: iOS 8.2 (not reproducible in simulator)\n // \"length\" in obj used to prevent JIT error (gh-11508)\n const length = \"length\" in Object(obj) && obj.length;\n\n // NodeList objects (with `item` method) and\n // other objects with suitable length characteristics are array-like\n return (\n isNumber(length) &&\n ((length >= 0 && length - 1 in obj) || typeof obj.item === \"function\")\n );\n}\n\n/**\n * Determines if a reference is undefined.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is undefined.\n */\nexport function isUndefined(value) {\n return typeof value === \"undefined\";\n}\n\n/**\n * Determines if a reference is defined.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is defined.\n */\nexport function isDefined(value) {\n return typeof value !== \"undefined\";\n}\n\n/**\n * Wrapper for minification\n *\n * @template T\n * @param {any} array\n * @returns {array is T[]} true if array is an Array\n */\nexport function isArray(array) {\n return Array.isArray(array);\n}\n\n/**\n * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not\n * considered to be objects. Note that JavaScript arrays are objects.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is an `Object` but not `null`.\n */\nexport function isObject(value) {\n // http://jsperf.com/isobject4\n return value !== null && typeof value === \"object\";\n}\n\n/**\n * Determines if a value is an object with a null prototype\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is an `Object` with a null prototype\n */\nexport function isBlankObject(value) {\n return (\n value !== null && typeof value === \"object\" && !Object.getPrototypeOf(value)\n );\n}\n\n/**\n * Determines if a reference is a `String`.\n *\n * @type {ng.Validator}\n */\nexport function isString(value) {\n return typeof value === \"string\";\n}\n\n/**\n * Determines if a reference is a null.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a null.\n */\nexport function isNull(value) {\n return value === null;\n}\n\n/**\n * Determines if a reference is null or undefined.\n *\n * @param {*} obj Reference to check.\n * @returns {boolean} True if `value` is null or undefined.\n */\nexport function isNullOrUndefined(obj) {\n return obj === null || typeof obj === \"undefined\";\n}\n\n/**\n * Determines if a reference is not null or undefined.\n *\n * @param {*} obj Reference to check.\n * @returns {boolean} True if `value` is null or undefined.\n */\nexport function notNullOrUndefined(obj) {\n return !isNullOrUndefined(obj);\n}\n\n/**\n * Determines if a reference is a `Number`.\n *\n * This includes the \"special\" numbers `NaN`, `+Infinity` and `-Infinity`.\n *\n * If you wish to exclude these then you can use the native\n * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)\n * method.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `Number`.\n */\nexport function isNumber(value) {\n return typeof value === \"number\";\n}\n\n/**\n *\n * Determines if a value is a date.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `Date`.\n */\nexport function isDate(value) {\n return toString.call(value) === \"[object Date]\";\n}\n\n/**\n * Determines if a reference is an `Error`.\n * Loosely based on https://www.npmjs.com/package/iserror\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is an `Error`.\n */\nexport function isError(value) {\n const tag = toString.call(value);\n\n switch (tag) {\n case \"[object Error]\":\n return true;\n case \"[object Exception]\":\n return true;\n case \"[object DOMException]\":\n return true;\n default:\n return value instanceof Error;\n }\n}\n\n/**\n * Determines if a reference is a `Function`.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `Function`.\n */\nexport function isFunction(value) {\n return typeof value === \"function\";\n}\n\n/**\n * Determines if a value is a regular expression object.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `RegExp`.\n */\nexport function isRegExp(value) {\n return toString.call(value) === \"[object RegExp]\";\n}\n\n/**\n * Checks if `obj` is a window object.\n *\n * @param {*} obj Object to check\n * @returns {boolean} True if `obj` is a window obj.\n */\nexport function isWindow(obj) {\n return obj && obj.window === obj;\n}\n\n/**\n * @param {*} obj\n * @returns {boolean}\n */\nexport function isScope(obj) {\n return obj && obj.$watch;\n}\n\n/**\n * @param {*} obj\n * @returns {boolean}\n */\nexport function isFile(obj) {\n return toString.call(obj) === \"[object File]\";\n}\n\n/**\n * @param {*} obj\n * @returns {boolean}\n */\nexport function isFormData(obj) {\n return toString.call(obj) === \"[object FormData]\";\n}\n\n/**\n * @param {*} obj\n * @returns {boolean}\n */\nexport function isBlob(obj) {\n return toString.call(obj) === \"[object Blob]\";\n}\n\n/**\n * @param {*} value\n * @returns {boolean}\n */\nexport function isBoolean(value) {\n return typeof value === \"boolean\";\n}\n\n/**\n * @param {*} obj\n * @returns {boolean}\n */\nexport function isPromiseLike(obj) {\n return obj && isFunction(obj.then);\n}\n\n/**\n * @param {*} value\n * @returns {boolean}\n */\nexport function isTypedArray(value) {\n return (\n value &&\n isNumber(value.length) &&\n /^\\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array]$/.test(\n toString.call(value),\n )\n );\n}\n\n/**\n * @param {*} obj\n * @returns {boolean}\n */\nexport function isArrayBuffer(obj) {\n return toString.call(obj) === \"[object ArrayBuffer]\";\n}\n\n/**\n * @param {*} value\n * @returns {string | *}\n */\nexport function trim(value) {\n return isString(value) ? value.trim() : value;\n}\n\nexport function snakeCase(name, separator) {\n const modseparator = separator || \"_\";\n\n return name.replace(\n /[A-Z]/g,\n (letter, pos) => (pos ? modseparator : \"\") + letter.toLowerCase(),\n );\n}\n\n/**\n * Set or clear the hashkey for an object.\n * @param obj object\n * @param hashkey the hashkey (!truthy to delete the hashkey)\n */\nexport function setHashKey(obj, hashkey) {\n if (hashkey) {\n obj.$$hashKey = hashkey;\n } else {\n delete obj.$$hashKey;\n }\n}\n\n/**\n * Deeply extends a destination object with one or more source objects.\n * Safely handles Dates, RegExps, DOM nodes, arrays, and nested objects.\n * Ignores the `__proto__` key to prevent prototype pollution.\n *\n * @param {Object<string, any>} dst - The destination object to extend.\n * @param {Array<Object<string, any>>} objs - Array of source objects to copy properties from.\n * @param {boolean} [deep=false] - Whether to perform a deep merge of nested objects.\n * @returns {Object<string, any>} The extended destination object.\n */\nexport function baseExtend(dst, objs, deep = false) {\n const hasKey = dst.$$hashKey;\n\n for (let i = 0, ii = objs.length; i < ii; ++i) {\n const obj = objs[i];\n\n if (!isObject(obj) && !isFunction(obj)) continue;\n const keyList = keys(obj);\n\n for (let j = 0, jj = keyList.length; j < jj; j++) {\n const key = keyList[j];\n\n const src = obj[key];\n\n if (deep && isObject(src)) {\n if (isDate(src)) {\n dst[key] = new Date(src.valueOf());\n } else if (isRegExp(src)) {\n dst[key] = new RegExp(src);\n } else if (src.nodeName) {\n dst[key] = src.cloneNode(true);\n } else if (key !== \"__proto__\") {\n if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};\n baseExtend(dst[key], [src], true);\n }\n } else {\n dst[key] = src;\n }\n }\n }\n\n setHashKey(dst, hasKey);\n\n return dst;\n}\n\n/**\n * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)\n * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so\n * by passing an empty object as the target: `let object = angular.extend({}, object1, object2)`.\n *\n * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy).\n *\n * @param {Object} dst Destination object.\n * @param {...Object} src Source object(s).\n * @returns {Object} Reference to `dst`.\n */\nexport function extend(dst, ...src) {\n return baseExtend(dst, src, false);\n}\n\n/**\n * @param {any} num\n * @returns {boolean}\n */\nexport function isNumberNaN(num) {\n return Number.isNaN(num);\n}\n\n/**\n * @param {Object} parent\n * @param {Object} extra\n * @returns {Object}\n */\nexport function inherit(parent, extra) {\n return extend(Object.create(parent), extra);\n}\n\nexport function hasCustomToString(obj) {\n return isFunction(obj.toString) && obj.toString !== toString;\n}\n\n/**\n * Returns a string appropriate for the type of node.\n *\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeName)\n *\n * @param {Element} element\n * @returns\n */\nexport function getNodeName(element) {\n return lowercase(element.nodeName);\n}\n\nexport function includes(array, obj) {\n return Array.prototype.indexOf.call(array, obj) !== -1;\n}\n\n/**\n * Removes the first occurrence of a specified value from an array.\n *\n * @template T\n * @param {Array<T>} array - The array from which to remove the value.\n * @param {T} value - The value to remove.\n * @returns {number} - The index of the removed value, or -1 if the value was not found.\n */\nexport function arrayRemove(array, value) {\n const index = array.indexOf(value);\n\n if (index >= 0) {\n array.splice(index, 1);\n }\n\n return index;\n}\n\nexport function simpleCompare(val1, val2) {\n return val1 === val2 || (Number.isNaN(val1) && Number.isNaN(val2));\n}\n\n/**\n * Determines if two objects or two values are equivalent. Supports value types, regular\n * expressions, arrays and objects.\n *\n * Two objects or values are considered equivalent if at least one of the following is true:\n *\n * * Both objects or values pass `===` comparison.\n * * Both objects or values are of the same type and all of their properties are equal by\n * comparing them with `angular.equals`.\n * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)\n * * Both values represent the same regular expression (In JavaScript,\n * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual\n * representation matches).\n *\n * During a property comparison, properties of `function` type and properties with names\n * that begin with `$` are ignored.\n *\n * Scope and DOMWindow objects are being compared only by identify (`===`).\n *\n * @param {*} o1 Object or value to compare.\n * @param {*} o2 Object or value to compare.\n * @returns {boolean} True if arguments are equal.\n *\n * @example\n <example module=\"equalsExample\" name=\"equalsExample\">\n <file name=\"index.html\">\n <div ng-controller=\"ExampleController\">\n <form novalidate>\n <h3>User 1</h3>\n Name: <input type=\"text\" ng-model=\"user1.name\">\n Age: <input type=\"number\" ng-model=\"user1.age\">\n\n <h3>User 2</h3>\n Name: <input type=\"text\" ng-model=\"user2.name\">\n Age: <input type=\"number\" ng-model=\"user2.age\">\n\n <div>\n <br/>\n <input type=\"button\" value=\"Compare\" ng-click=\"compare()\">\n </div>\n User 1: <pre>{{user1 | json}}</pre>\n User 2: <pre>{{user2 | json}}</pre>\n Equal: <pre>{{result}}</pre>\n </form>\n </div>\n </file>\n <file name=\"script.js\">\n angular.module('equalsExample', []).controller('ExampleController', ['$scope', function($scope) {\n $scope.user1 = {};\n $scope.user2 = {};\n $scope.compare = function() {\n $scope.result = angular.equals($scope.user1, $scope.user2);\n };\n }]);\n </file>\n </example>\n */\nexport function equals(o1, o2) {\n if (o1 === o2) return true;\n\n if (o1 === null || o2 === null) return false;\n\n if (Number.isNaN(o1) && Number.isNaN(o2)) return true; // NaN === NaN\n\n const t1 = typeof o1;\n\n const t2 = typeof o2;\n\n if (t1 !== t2 || t1 !== \"object\") return false;\n\n // Handle arrays\n if (isArray(o1)) {\n if (!isArray(o2)) return false;\n\n const { length } = o1;\n\n if (length !== o2.length) return false;\n\n for (let key = 0; key < length; key++) {\n if (!equals(o1[key], o2[key])) return false;\n }\n\n return true;\n }\n\n // Handle Dates\n if (isDate(o1)) {\n if (!isDate(o2)) return false;\n\n return simpleCompare(o1.getTime(), o2.getTime());\n }\n\n // Handle RegExps\n if (isRegExp(o1)) {\n if (!isRegExp(o2)) return false;\n\n return o1.toString() === o2.toString();\n }\n\n // Reject unsafe objects\n if (\n isScope(o1) ||\n isScope(o2) ||\n isWindow(o1) ||\n isWindow(o2) ||\n isArray(o2) ||\n isDate(o2) ||\n isRegExp(o2)\n )\n return false;\n\n // Handle general objects\n const keySet = Object.create(null);\n\n for (const key in o1) {\n if (key.charAt(0) === \"$\" || isFunction(o1[key])) continue;\n\n if (!equals(o1[key], o2[key])) return false;\n keySet[key] = true;\n }\n\n for (const key in o2) {\n if (\n !(key in keySet) &&\n key.charAt(0) !== \"$\" &&\n isDefined(o2[key]) &&\n !isFunction(o2[key])\n ) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * throw error if the name given is hasOwnProperty\n * @param {string} name the name to test\n * @param {string} context the context in which the name is used, such as module or directive\n */\nexport function assertNotHasOwnProperty(name, context) {\n if (name === \"hasOwnProperty\") {\n throw ngMinErr(\n \"badname\",\n \"hasOwnProperty is not a valid {0} name\",\n context,\n );\n }\n}\n\nexport function stringify(value) {\n if (isNull(value) || isUndefined(value)) {\n return \"\";\n }\n switch (typeof value) {\n case \"string\":\n break;\n case \"number\":\n value = `${value}`;\n break;\n default:\n if (hasCustomToString(value) && !isArray(value) && !isDate(value)) {\n value = value.toString();\n } else {\n value = toJson(value);\n }\n }\n\n return value;\n}\n\n/**\n * @param {Number} maxDepth\n * @return {boolean}\n */\nexport function isValidObjectMaxDepth(maxDepth) {\n return isNumber(maxDepth) && maxDepth > 0;\n}\n\nexport function concat(array1, array2, index) {\n return array1.concat(Array.prototype.slice.call(array2, index));\n}\n\nexport function sliceArgs(args, startIndex) {\n return Array.prototype.slice.call(args, startIndex || 0);\n}\n\n/**\n * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for\n * `fn`). You can supply optional `args` that are prebound to the function. This feature is also\n * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as\n * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).\n *\n * @param {Object} context Context which `fn` should be evaluated in.\n * @param {*} fn Function to be bound.\n * @returns {Function} Function that wraps the `fn` with all the specified bindings.\n */\nexport function bind(context, fn) {\n const curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];\n\n if (isFunction(fn) && !(fn instanceof RegExp)) {\n return curryArgs.length\n ? function () {\n return arguments.length\n ? fn.apply(context, concat(curryArgs, arguments, 0))\n : fn.apply(context, curryArgs);\n }\n : function () {\n return arguments.length\n ? fn.apply(context, arguments)\n : fn.call(context);\n };\n }\n\n // In IE, native methods are not functions so they cannot be bound (note: they don't need to be).\n return fn;\n}\n\nfunction toJsonReplacer(key, value) {\n let val = value;\n\n if (\n typeof key === \"string\" &&\n key.charAt(0) === \"$\" &&\n key.charAt(1) === \"$\"\n ) {\n val = undefined;\n } else if (isWindow(value)) {\n val = \"$WINDOW\";\n } else if (value && window.document === value) {\n val = \"$DOCUMENT\";\n } else if (isScope(value)) {\n val = \"$SCOPE\";\n }\n\n return val;\n}\n\n/**\n * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be\n * stripped since AngularTS uses this notation internally.\n *\n * @param {Object|Array|Date|string|number|boolean} obj Input to be serialized into JSON.\n * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.\n * If set to an integer, the JSON output will contain that many spaces per indentation.\n * @returns {string|undefined} JSON-ified string representing `obj`.\n * @knownIssue\n *\n * The Safari browser throws a `RangeError` instead of returning `null` when it tries to stringify a `Date`\n * object with an invalid date value. The only reliable way to prevent this is to monkeypatch the\n * `Date.prototype.toJSON` method as follows:\n *\n * ```\n * let _DatetoJSON = Date.prototype.toJSON;\n * Date.prototype.toJSON = function() {\n * try {\n * return _DatetoJSON.call(this);\n * } catch(e) {\n * if (e instanceof RangeError) {\n * return null;\n * }\n * throw e;\n * }\n * };\n * ```\n *\n * See https://github.com/angular/angular.js/pull/14221 for more information.\n */\nexport function toJson(obj, pretty) {\n if (isUndefined(obj)) return undefined;\n\n if (!isNumber(pretty)) {\n pretty = pretty ? 2 : null;\n }\n\n return JSON.stringify(obj, toJsonReplacer, /** @type {Number} */ (pretty));\n}\n\n/**\n * Deserializes a JSON string.\n *\n * @param {string} json JSON string to deserialize.\n * @returns {Object|Array|string|number} Deserialized JSON string.\n */\nexport function fromJson(json) {\n return isString(json) ? JSON.parse(json) : json;\n}\n\nconst MS_PER_MINUTE = 60_000; // 60,000 ms in a minute\n\nexport function timezoneToOffset(timezone, fallback) {\n const requestedTimezoneOffset =\n Date.parse(`Jan 01, 1970 00:00:00 ${timezone}`) / MS_PER_MINUTE;\n\n return isNumberNaN(requestedTimezoneOffset)\n ? fallback\n : requestedTimezoneOffset;\n}\n\nexport function addDateMinutes(date, minutes) {\n const newDate = new Date(date.getTime());\n\n newDate.setMinutes(newDate.getMinutes() + minutes);\n\n return newDate;\n}\n\nexport function convertTimezoneToLocal(date, timezone, reverse) {\n const doReverse = reverse ? -1 : 1;\n\n const dateTimezoneOffset = date.getTimezoneOffset();\n\n const timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);\n\n return addDateMinutes(\n date,\n doReverse * (timezoneOffset - dateTimezoneOffset),\n );\n}\n\n/**\n * Parses an escaped url query string into key-value pairs.\n * @param {string} keyValue\n * @returns {Object.<string,boolean|Array>}\n */\nexport function parseKeyValue(keyValue) {\n const obj = {};\n\n (keyValue || \"\").split(\"&\").forEach((item) => {\n let splitPoint;\n\n let key;\n\n let val;\n\n if (item) {\n key = keyValue = item.replace(/\\+/g, \"%20\");\n splitPoint = item.indexOf(\"=\");\n\n if (splitPoint !== -1) {\n key = item.substring(0, splitPoint);\n val = item.substring(splitPoint + 1);\n }\n key = tryDecodeURIComponent(key);\n\n if (isDefined(key)) {\n val = isDefined(val) ? tryDecodeURIComponent(val) : true;\n\n if (!hasOwn(obj, /** @type {string} */ (key))) {\n obj[key] = val;\n } else if (isArray(obj[key])) {\n obj[key].push(val);\n } else {\n obj[key] = [obj[key], val];\n }\n }\n }\n });\n\n return /** @type {Object.<string,boolean|Array>} */ (obj);\n}\n\nexport function toKeyValue(obj) {\n const parts = [];\n\n obj &&\n entries(obj).forEach(([key, value]) => {\n if (isArray(value)) {\n value.forEach((arrayValue) => {\n parts.push(\n encodeUriQuery(key, true) +\n (arrayValue === true\n ? \"\"\n : `=${encodeUriQuery(arrayValue, true)}`),\n );\n });\n } else {\n parts.push(\n encodeUriQuery(key, true) +\n (value === true ? \"\" : `=${encodeUriQuery(value, true)}`),\n );\n }\n });\n\n return parts.length ? parts.join(\"&\") : \"\";\n}\n\n/**\n * Tries to decode the URI component without throwing an exception.\n *\n * @param {string} value potential URI component to check.\n * @returns {string|undefined}\n */\nexport function tryDecodeURIComponent(value) {\n try {\n return decodeURIComponent(value);\n } catch {\n return undefined;\n }\n}\n\n/**\n * We need our custom method because encodeURIComponent is too aggressive and doesn't follow\n * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path\n * segments:\n * segment = *pchar\n * pchar = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n * pct-encoded = \"%\" HEXDIG HEXDIG\n * unreserved = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n * sub-delims = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n * / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n * @param {string} val\n */\nexport function encodeUriSegment(val) {\n return encodeUriQuery(val, true)\n .replace(/%26/gi, \"&\")\n .replace(/%3D/gi, \"=\")\n .replace(/%2B/gi, \"+\");\n}\n\n/**\n * This method is intended for encoding *key* or *value* parts of query component. We need a custom\n * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be\n * encoded per http://tools.ietf.org/html/rfc3986:\n * query = *( pchar / \"/\" / \"?\" )\n * pchar = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n * unreserved = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n * pct-encoded = \"%\" HEXDIG HEXDIG\n * sub-delims = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n * / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n */\nexport function encodeUriQuery(val, pctEncodeSpaces) {\n return encodeURIComponent(val)\n .replace(/%40/gi, \"@\")\n .replace(/%3A/gi, \":\")\n .replace(/%24/g, \"$\")\n .replace(/%2C/gi, \",\")\n .replace(/%3B/gi, \";\")\n .replace(/%20/g, pctEncodeSpaces ? \"%20\" : \"+\");\n}\n\nexport const ngAttrPrefixes = [\"ng-\", \"data-ng-\"];\n\nexport function getNgAttribute(element, ngAttr) {\n let attr;\n\n let i;\n\n const ii = ngAttrPrefixes.length;\n\n for (i = 0; i < ii; ++i) {\n attr = ngAttrPrefixes[i] + ngAttr;\n\n if (isString((attr = element.getAttribute(attr)))) {\n return attr;\n }\n }\n\n return null;\n}\n\n/**\n * Creates a shallow copy of an object, an array or a primitive.\n *\n * Assumes that there are no proto properties for objects.\n */\nexport function shallowCopy(src, dst) {\n if (isArray(src)) {\n dst = dst || [];\n\n for (let i = 0, ii = src.length; i < ii; i++) {\n dst[i] = src[i];\n }\n } else if (isObject(src)) {\n dst = dst || {};\n\n for (const key in src) {\n if (!(key.startsWith(\"$\") && key.charAt(1) === \"$\")) {\n dst[key] = src[key];\n }\n }\n }\n\n return dst || src;\n}\n\n/**\n * Throw error if the argument is false\n * @param {boolean} argument\n * @param {string} errorMsg\n */\nexport function assert(argument, errorMsg = \"Assertion failed\") {\n if (!argument) {\n throw new Error(errorMsg);\n }\n}\n\n/**\n * Throw error if the argument is falsy.\n */\nexport function assertArg(arg, name, reason) {\n if (!arg) {\n throw ngMinErr(\n \"areq\",\n \"Argument '{0}' is {1}\",\n name || \"?\",\n reason || \"required\",\n );\n }\n\n return arg;\n}\n\nexport function assertArgFn(arg, name, acceptArrayAnnotation) {\n if (acceptArrayAnnotation && isArray(arg)) {\n arg = arg[arg.length - 1];\n }\n\n assertArg(\n isFunction(arg),\n name,\n `not a function, got ${\n arg && typeof arg === \"object\"\n ? arg.constructor.name || \"Object\"\n : typeof arg\n }`,\n );\n\n return arg;\n}\n\n/** @type {ng.ErrorHandlingConfig} */\nconst minErrConfig = {\n objectMaxDepth: 5,\n urlErrorParamsEnabled: true,\n};\n\n/**\n * Configure several aspects of error handling if used as a setter or return the\n * current configuration if used as a getter.\n *\n * Omitted or undefined options will leave the corresponding configuration values unchanged.\n *\n * @param {ng.ErrorHandlingConfig} [config]\n * @returns {ng.ErrorHandlingConfig}\n */\nexport function errorHandlingConfig(config) {\n if (isObject(config)) {\n if (isDefined(config.objectMaxDepth)) {\n minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth)\n ? config.objectMaxDepth\n : NaN;\n }\n\n if (\n isDefined(config.urlErrorParamsEnabled) &&\n isBoolean(config.urlErrorParamsEnabled)\n ) {\n minErrConfig.urlErrorParamsEnabled = config.urlErrorParamsEnabled;\n }\n }\n\n return minErrConfig;\n}\n\n/**\n * This object provides a utility for producing rich Error messages within\n * AngularTS. It can be called as follows:\n *\n * let exampleMinErr = minErr('example');\n * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);\n *\n * The above creates an instance of minErr in the example namespace. The\n * resulting error will have a namespaced error code of example.one. The\n * resulting error will replace {0} with the value of foo, and {1} with the\n * value of bar. The object is not restricted in the number of arguments it can\n * take.\n *\n * If fewer arguments are specified than necessary for interpolation, the extra\n * interpolation markers will be preserved in the final string.\n *\n * Since data will be parsed statically during a build step, some restrictions\n * are applied with respect to how minErr instances are created and called.\n * Instances should have names of the form namespaceMinErr for a minErr created\n * using minErr('namespace'). Error codes, namespaces and template strings\n * should all be static strings, not variables or general expressions.\n *\n * @param {string} module The namespace to use for the new minErr instance.\n * @returns {function(string, ...*): Error} minErr instance\n */\nexport function minErr(module) {\n return function (...args) {\n const code = args[0];\n\n const template = args[1];\n\n let message = `[${module ? `${module}:` : \"\"}${code}] `;\n\n const templateArgs = sliceArgs(args, 2).map((arg) => toDebugString(arg));\n\n message += template.replace(/\\{\\d+\\}/g, (match) => {\n const index = +match.slice(1, -1);\n\n if (index < templateArgs.length) {\n return templateArgs[index];\n }\n\n return match;\n });\n\n return new Error(message);\n };\n}\n\nexport function toDebugString(obj) {\n if (typeof obj === \"function\") {\n return obj.toString().replace(/ \\{[\\s\\S]*$/, \"\");\n }\n\n if (isUndefined(obj)) {\n return \"undefined\";\n }\n\n if (typeof obj !== \"string\") {\n const seen = [];\n\n const copyObj = structuredClone(isProxy(obj) ? obj.$target : obj);\n\n return JSON.stringify(copyObj, (key, val) => {\n const replace = toJsonReplacer(key, val);\n\n if (isObject(replace)) {\n if (seen.indexOf(replace) >= 0) return \"...\";\n\n seen.push(replace);\n }\n\n return replace;\n });\n }\n\n return obj;\n}\n\n/**\n * Computes a hash of an 'obj'.\n * Hash of a:\n * string is string\n * number is number as string\n * object is either result of calling $$hashKey function on the object or uniquely generated id,\n * that is also assigned to the $$hashKey property of the object.\n *\n * @param {*} obj\n * @returns {string} hash string such that the same input will have the same hash string.\n * The resulting string key is in 'type:hashKey' format.\n */\nexport function hashKey(obj) {\n const key = obj && obj.$$hashKey;\n\n if (key) {\n if (typeof key === \"function\") {\n return obj.$$hashKey();\n }\n\n return key;\n }\n\n const objType = typeof obj;\n\n if (objType === \"function\" || (objType === \"object\" && obj !== null)) {\n obj.$$hashKey = `${objType}:${nextUid()}`;\n\n return obj.$$hashKey;\n }\n\n if (objType === \"undefined\") {\n return `${objType}:${nextUid()}`;\n }\n\n // account for primitives\n return `${objType}:${obj}`;\n}\n\n/**\n * Merges two class name values into a single space-separated string.\n * Accepts strings, arrays of strings, or null/undefined values.\n *\n * @param {string | string[] | null | undefined} firstClass - The first class name(s).\n * @param {string | string[] | null | undefined} secondClass - The second class name(s).\n * @returns {string} A single string containing all class names separated by spaces.\n */\nexport function mergeClasses(firstClass, secondClass) {\n if (!firstClass && !secondClass) return \"\";\n\n if (!firstClass)\n // @ts-ignore\n return isArray(secondClass) ? secondClass.join(\" \").trim() : secondClass;\n\n if (!secondClass)\n // @ts-ignore\n return isArray(firstClass) ? firstClass.join(\" \").trim() : firstClass;\n\n // @ts-ignore\n if (isArray(firstClass)) firstClass = normalizeStringArray(firstClass);\n\n // @ts-ignore\n if (isArray(secondClass)) secondClass = normalizeStringArray(secondClass);\n\n // @ts-ignore\n return `${firstClass.trim()} ${secondClass.trim()}`.trim();\n}\n\n/**\n * Joins an array of strings into a single string, trimming each\n * element and ignoring empty strings, null, and undefined\n * @param {any[]} arr\n * @returns {string}\n */\nfunction normalizeStringArray(arr) {\n const cleaned = [];\n\n for (const item of arr) {\n if (item) {\n const trimmed = item.trim();\n\n if (trimmed) cleaned.push(trimmed);\n }\n }\n\n return cleaned.join(\" \");\n}\n\n/**\n * Converts all accepted directives format into proper directive name.\n * @param {string} name Name to normalize\n * @returns {string}\n */\n\nexport function directiveNormalize(name) {\n return name\n .replace(PREFIX_REGEXP, \"\")\n .replace(SPECIAL_CHARS_REGEXP, (_name, letter, offset) =>\n offset ? letter.toUpperCase() : letter,\n );\n}\n\n/**\n * Whether element should be animated\n * @param {Node} node\n * @returns {boolean}\n */\nexport function hasAnimate(node) {\n return hasCustomOrDataAttribute(node, \"animate\");\n}\n\n/**\n * @param {Node} node\n * @param {string} attr\n * @returns {boolean}\n */\nfunction hasCustomOrDataAttribute(node, attr) {\n if (node.nodeType !== NodeType._ELEMENT_NODE) return false;\n const element = /** @type {HTMLElement} */ (node);\n\n return (\n element.dataset[attr] === \"true\" || element.getAttribute(attr) === \"true\"\n );\n}\n\n/**\n * @param {Object|null|undefined} obj\n * @returns {boolean}\n */\nexport function isObjectEmpty(obj) {\n if (!obj) return true;\n\n return !keys(obj).length;\n}\n\n/**\n * Checks whether the given object has the specified property as its own (not inherited).\n *\n * This is a safe version of `hasOwnProperty` that avoids issues with objects\n * that have it overridden or missing from their prototype chain.\n *\n * @param {object} obj - The object to check.\n * @param {string|number|symbol} key - The property key to look for.\n * @returns {boolean} True if the object has the property as its own; otherwise, false.\n *\n * @example\n * hasOwn({ foo: 123 }, 'foo'); // true\n * hasOwn({}, 'bar'); // false\n */\nexport function hasOwn(obj, key) {\n return Object.prototype.hasOwnProperty.call(obj, key);\n}\n\n/**\n * @param {Object} obj\n * @returns {string[]}\n */\nexport function keys(obj) {\n return Object.keys(obj);\n}\n\n/**\n * @template T\n * @param {{ [s: string]: T; } | ArrayLike<T>} obj\n * @returns {[string, T][]}\n */\nexport function entries(obj) {\n return Object.entries(obj);\n}\n\n/**\n * Wraps a function so it can only be called once.\n * Subsequent calls do nothing and return undefined.\n *\n * @param {Function} fn - The function to wrap.\n * @returns {Function} A new function that will call `fn` only once.\n */\nexport function callBackOnce(fn) {\n let called = false;\n\n return (...args) => {\n if (!called) {\n called = true;\n\n return fn(...args);\n }\n\n return undefined; // satisfies consistent-return\n };\n}\n\n/**\n * Wraps a function so it will only be called starting from the second invocation.\n * The first call does nothing and returns undefined.\n *\n * @param {Function} fn - The function to wrap.\n * @returns {Function} A new function that will skip the first call.\n */\nexport function callBackAfterFirst(fn) {\n let calledOnce = false;\n\n return (...args) => {\n if (calledOnce) {\n return fn(...args);\n }\n calledOnce = true;\n\n return undefined;\n };\n}\n\n/**\n * Delays execution for a specified number of milliseconds.\n *\n * @param {number} [timeout=0] - The number of milliseconds to wait. Defaults to 0.\n * @returns {Promise<void>} A promise that resolves after the delay.\n */\nexport function wait(timeout = 0) {\n return new Promise((resolve) => setTimeout(resolve, timeout));\n}\n\n/**\n * Checks if a given string starts with a specified substring.\n *\n * This is a simple polyfill-like function that mimics the behavior of\n * `String.prototype.startsWith` without using the built-in method.\n *\n * @param {string} str - The full string to evaluate.\n * @param {string} search - The substring to test against the beginning of `str`.\n * @returns {boolean} `true` if `str` starts with `search`, otherwise `false`.\n *\n * @example\n * startsWith(\"hello world\", \"hello\");\n * // returns true\n *\n * @example\n * startsWith(\"hello world\", \"world\");\n * // returns false\n *\n * @example\n * startsWith(\"test\", \"\");\n * // returns true (empty search string always matches)\n *\n * @example\n * startsWith(\"abc\", \"abcd\");\n * // returns false\n */\nexport function startsWith(str, search) {\n return str.slice(0, search.length) === search;\n}\n\n/**\n * Loads and instantiates a WebAssembly module.\n * Tries streaming first, then falls back.\n */\nexport async function instantiateWasm(src, imports = {}) {\n const res = await fetch(src);\n\n if (!res.ok) throw new Error(\"fetch failed\");\n\n try {\n const { instance, module } = await WebAssembly.instantiateStreaming(\n res.clone(),\n imports,\n );\n\n return { instance, exports: instance.exports, module };\n } catch {\n /* empty */\n }\n\n const bytes = await res.arrayBuffer();\n\n const { instance, module } = await WebAssembly.instantiate(bytes, imports);\n\n return { instance, exports: instance.exports, module };\n}\n\n/**\n * @param {*} fn\n * @returns {boolean}\n */\nexport function isArrowFunction(fn) {\n return typeof fn === \"function\" && !fn.prototype;\n}\n","/**\n * @readonly\n * @enum {number}\n */\nexport const ASTType = {\n _Program: 1,\n _ExpressionStatement: 2,\n _AssignmentExpression: 3,\n _ConditionalExpression: 4,\n _LogicalExpression: 5,\n _BinaryExpression: 6,\n _UnaryExpression: 7,\n _CallExpression: 8,\n _MemberExpression: 9,\n _Identifier: 10,\n _Literal: 11,\n _ArrayExpression: 12,\n _Property: 13,\n _ObjectExpression: 14,\n _ThisExpression: 15,\n _LocalsExpression: 16,\n NGValueParameter: 17,\n};\n","import {\n entries,\n extend,\n isArray,\n isString,\n keys,\n minErr,\n} from \"../shared/utils.js\";\nimport { ASTType } from \"../core/parse/ast-type.js\";\nimport { NodeType } from \"../shared/node.js\";\n\nexport const ADD_CLASS_SUFFIX = \"-add\";\nexport const REMOVE_CLASS_SUFFIX = \"-remove\";\nexport const EVENT_CLASS_PREFIX = \"ng-\";\nexport const ACTIVE_CLASS_SUFFIX = \"-active\";\nexport const PREPARE_CLASS_SUFFIX = \"-prepare\";\n\nexport const NG_ANIMATE_CLASSNAME = \"ng-animate\";\nexport const NG_ANIMATE_CHILDREN_DATA = \"$$ngAnimateChildren\";\n\n// Detect proper transitionend/animationend event names.\nexport let CSS_PREFIX = \"\";\nexport let TRANSITION_PROP;\nexport let TRANSITIONEND_EVENT;\nexport let ANIMATION_PROP;\nexport let ANIMATIONEND_EVENT;\n\n// If unprefixed events are not supported but webkit-prefixed are, use the latter.\n// Otherwise, just use W3C names, browsers not supporting them at all will just ignore them.\n// Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend`\n// but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`.\n// Register both events in case `window.onanimationend` is not supported because of that,\n// do the same for `transitionend` as Safari is likely to exhibit similar behavior.\n// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit\n// therefore there is no reason to test anymore for other vendor prefixes:\n// http://caniuse.com/#search=transition\nif (\n window.ontransitionend === undefined &&\n window.onwebkittransitionend !== undefined\n) {\n CSS_PREFIX = \"-webkit-\";\n TRANSITION_PROP = \"WebkitTransition\";\n TRANSITIONEND_EVENT = \"webkitTransitionEnd transitionend\";\n} else {\n TRANSITION_PROP = \"transition\";\n TRANSITIONEND_EVENT = \"transitionend\";\n}\n\nif (\n window.onanimationend === undefined &&\n window.onwebkitanimationend !== undefined\n) {\n CSS_PREFIX = \"-webkit-\";\n ANIMATION_PROP = \"WebkitAnimation\";\n ANIMATIONEND_EVENT = \"webkitAnimationEnd animationend\";\n} else {\n ANIMATION_PROP = \"animation\";\n ANIMATIONEND_EVENT = \"animationend\";\n}\n\nexport const DURATION_KEY = \"Duration\";\nexport const PROPERTY_KEY = ASTType._Property;\nexport const DELAY_KEY = \"Delay\";\nexport const TIMING_KEY = \"TimingFunction\";\nexport const ANIMATION_ITERATION_COUNT_KEY = \"IterationCount\";\nexport const ANIMATION_PLAYSTATE_KEY = \"PlayState\";\nexport const SAFE_FAST_FORWARD_DURATION_VALUE = 9999;\n\nexport const ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY;\nexport const ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY;\nexport const TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY;\nexport const TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY;\n\nexport const ngMinErr = minErr(\"ng\");\nexport function assertArg(arg, name, reason) {\n if (!arg) {\n throw ngMinErr(\n \"areq\",\n \"Argument '{0}' is {1}\",\n name || \"?\",\n reason || \"required\",\n );\n }\n\n return arg;\n}\n\nexport function packageStyles(options) {\n const styles = {};\n\n if (options && (options.to || options.from)) {\n styles.to = options.to;\n styles.from = options.from;\n }\n\n return styles;\n}\n\nexport function pendClasses(classes, fix, isPrefix) {\n let className = \"\";\n\n classes = isArray(classes)\n ? classes\n : classes && isString(classes) && classes.length\n ? classes.split(/\\s+/)\n : [];\n classes.forEach((klass, i) => {\n if (klass && klass.length > 0) {\n className += i > 0 ? \" \" : \"\";\n className += isPrefix ? fix + klass : klass + fix;\n }\n });\n\n return className;\n}\n\nexport function removeFromArray(arr, val) {\n const index = arr.indexOf(val);\n\n if (val >= 0) {\n arr.splice(index, 1);\n }\n}\n\n/**\n *\n * @param {NodeList|Node} element\n * @returns {Node[]|Node|undefined}\n */\nexport function stripCommentsFromElement(element) {\n if (element instanceof NodeList) {\n return Array.from(element).filter(\n (x) => x.nodeType === NodeType._ELEMENT_NODE,\n );\n } else if (element.nodeType === NodeType._ELEMENT_NODE) {\n return /** @type {Node} */ (element);\n } else {\n return undefined;\n }\n}\n\n/**\n * @param {NodeList|Node} element\n * @returns {Node}\n */\nexport function extractElementNode(element) {\n if (!element || !isArray(element)) return /** @type {Node} */ (element);\n\n for (let i = 0; i < /** @type {NodeList} */ (element).length; i++) {\n const elm = element[i];\n\n if (elm.nodeType === NodeType._ELEMENT_NODE) {\n return elm;\n }\n }\n\n return undefined; // TODO mayb throw?\n}\n\nexport function applyAnimationClassesFactory() {\n return function (element, options) {\n if (options.addClass) {\n element.classList.add(...options.addClass.trim().split(\" \"));\n options.addClass = null;\n }\n\n if (options.removeClass) {\n element.classList.remove(...options.removeClass.trim().split(\" \"));\n options.removeClass = null;\n }\n };\n}\n\nexport function prepareAnimationOptions(options) {\n options = options || {};\n\n if (!options.$$prepared) {\n let domOperation =\n options.domOperation ||\n (() => {\n /* empty */\n });\n\n options.domOperation = function () {\n options.$$domOperationFired = true;\n domOperation();\n domOperation = () => {\n /* empty */\n };\n };\n options.$$prepared = true;\n }\n\n return options;\n}\n\nexport function applyAnimationStyles(element, options) {\n applyAnimationFromStyles(element, options);\n applyAnimationToStyles(element, options);\n}\n\n/**\n * Applies initial animation styles to a DOM element.\n *\n * This function sets the element's inline styles using the properties\n * defined in `options.from`, then clears the property to prevent reuse.\n *\n * @param {HTMLElement} element - The target DOM element to apply styles to.\n * @param {{ from?: Partial<CSSStyleDeclaration> | null }} options - options containing a `from` object with CSS property–value pairs.\n */\nexport function applyAnimationFromStyles(element, options) {\n if (options.from) {\n Object.assign(element.style, options.from);\n options.from = null;\n }\n}\n\n/**\n * Applies final animation styles to a DOM element.\n *\n * This function sets the element's inline styles using the properties\n * defined in `options.to`, then clears the property to prevent reuse.\n *\n * @param {HTMLElement} element - The target DOM element to apply styles to.\n * @param {{ to?: Partial<CSSStyleDeclaration> | null }} options - options containing a `from` object with CSS property–value pairs.\n */\nexport function applyAnimationToStyles(element, options) {\n if (options.to) {\n Object.assign(element.style, options.to);\n options.to = null;\n }\n}\n\nexport function mergeAnimationDetails(element, oldAnimation, newAnimation) {\n const target = oldAnimation.options || {};\n\n const newOptions = newAnimation.options || {};\n\n const toAdd = `${target.addClass || \"\"} ${newOptions.addClass || \"\"}`;\n\n const toRemove = `${target.removeClass || \"\"} ${newOptions.removeClass || \"\"}`;\n\n const classes = resolveElementClasses(\n element.getAttribute(\"class\"),\n toAdd,\n toRemove,\n );\n\n if (newOptions.preparationClasses) {\n target.preparationClasses = concatWithSpace(\n newOptions.preparationClasses,\n target.preparationClasses,\n );\n delete newOptions.preparationClasses;\n }\n\n extend(target, newOptions);\n\n if (classes.addClass) {\n target.addClass = classes.addClass;\n } else {\n target.addClass = null;\n }\n\n if (classes.removeClass) {\n target.removeClass = classes.removeClass;\n } else {\n target.removeClass = null;\n }\n\n oldAnimation.addClass = target.addClass;\n oldAnimation.removeClass = target.removeClass;\n\n return target;\n}\n\nexport function resolveElementClasses(existing, toAdd, toRemove) {\n const ADD_CLASS = 1;\n\n const REMOVE_CLASS = -1;\n\n const flags = {};\n\n existing = splitClassesToLookup(existing);\n\n toAdd = splitClassesToLookup(toAdd);\n Object.keys(toAdd).forEach((key) => {\n flags[key] = ADD_CLASS;\n });\n\n toRemove = splitClassesToLookup(toRemove);\n keys(toRemove).forEach((key) => {\n flags[key] = flags[key] === ADD_CLASS ? null : REMOVE_CLASS;\n });\n\n const classes = {\n addClass: \"\",\n removeClass: \"\",\n };\n\n entries(flags).forEach(([klass, val]) => {\n let prop, allow;\n\n if (val === ADD_CLASS) {\n prop = \"addClass\";\n allow = !existing[klass] || existing[klass + REMOVE_CLASS_SUFFIX];\n } else if (val === REMOVE_CLASS) {\n prop = \"removeClass\";\n allow = existing[klass] || existing[klass + ADD_CLASS_SUFFIX];\n }\n\n if (allow) {\n if (classes[prop].length) {\n classes[prop] += \" \";\n }\n classes[prop] += klass;\n }\n });\n\n function splitClassesToLookup(cls) {\n if (isString(cls)) {\n cls = cls.trim().split(\" \");\n }\n\n const obj = {};\n\n if (cls) {\n cls.forEach((klass) => {\n // sometimes the split leaves empty string values\n // incase extra spaces were applied to the options\n if (klass.length) {\n obj[klass] = true;\n }\n });\n }\n\n return obj;\n }\n\n return classes;\n}\n\nexport function applyGeneratedPreparationClasses(element, event, options) {\n let classes = \"\";\n\n if (event) {\n classes = pendClasses(event, EVENT_CLASS_PREFIX, true);\n }\n\n if (options.addClass) {\n classes = concatWithSpace(\n classes,\n pendClasses(options.addClass, ADD_CLASS_SUFFIX),\n );\n }\n\n if (options.removeClass) {\n classes = concatWithSpace(\n classes,\n pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX),\n );\n }\n\n if (classes.length) {\n options.preparationClasses = classes;\n element.className += ` ${classes}`;\n }\n}\n\nexport function clearGeneratedClasses(element, options) {\n if (options.preparationClasses) {\n options.preparationClasses\n .split(\" \")\n .forEach((cls) => element.classList.remove(cls));\n options.preparationClasses = null;\n }\n\n if (options.activeClasses) {\n options.activeClasses\n .split(\" \")\n .forEach((cls) => element.classList.remove(cls));\n options.activeClasses = null;\n }\n}\n\nexport function blockKeyframeAnimations(node, applyBlock) {\n const value = applyBlock ? \"paused\" : \"\";\n\n const key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY;\n\n applyInlineStyle(node, [key, value]);\n\n return [key, value];\n}\n\nexport function applyInlineStyle(node, styleTuple) {\n const prop = styleTuple[0];\n\n node.style[prop] = styleTuple[1];\n}\n\nexport function concatWithSpace(a, b) {\n if (!a) return b;\n\n if (!b) return a;\n\n return `${a} ${b}`;\n}\n","import { concat, hasOwn, isArray, isDefined, isObject, keys } from \"./utils.js\";\nimport { Cache } from \"./cache.js\";\nimport { extractElementNode } from \"../animations/shared.js\";\nimport { NodeType } from \"./node.js\";\n\n/** @type {number} */\nlet elId = 1;\n\n/**\n * Key for storing isolate scope data, attached to an element\n */\nconst ISOLATE_SCOPE_KEY = \"$isolateScope\";\n\nconst EXPANDO = \"ng\";\n\n/**\n * Key for storing scope data, attached to an element\n */\nconst SCOPE_KEY = \"$scope\";\n\nconst DASH_LOWERCASE_REGEXP = /-([a-z])/g;\n\nconst UNDERSCORE_LOWERCASE_REGEXP = /_([a-z])/g;\n\nconst SINGLE_TAG_REGEXP = /^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/;\n\nconst TAG_NAME_REGEXP = /<([\\w:-]+)/;\n\n// Table parts need to be wrapped with `<table>` or they're\n// stripped to their contents when put in a div.\n// XHTML parsers do not magically insert elements in the\n// same way that tag soup parsers do, so we cannot shorten\n// this by omitting <tbody> or other required elements.\nconst wrapMap = {\n thead: [\"table\"],\n col: [\"colgroup\", \"table\"],\n tr: [\"tbody\", \"table\"],\n td: [\"tr\", \"tbody\", \"table\"],\n};\n\nwrapMap.tbody =\n wrapMap.tfoot =\n wrapMap.colgroup =\n wrapMap.caption =\n wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n/**\n * A list of boolean attributes in HTML.\n * @type {string[]}\n */\nexport const BOOLEAN_ATTR = [\n \"multiple\",\n \"selected\",\n \"checked\",\n \"disabled\",\n \"readonly\",\n \"required\",\n \"open\",\n];\n\n/**\n * A list of boolean attributes in HTML\n * @type {string[]}\n */\nconst BOOLEAN_ELEMENTS = [\n \"INPUT\",\n \"SELECT\",\n \"OPTION\",\n \"TEXTAREA\",\n \"BUTTON\",\n \"FORM\",\n \"DETAILS\",\n];\n\n///////////////////////////////////////////////////////////////////\n//////////// HELPER FUNCTIONS /////////////////////////\n///////////////////////////////////////////////////////////////////\n\n/**\n *\n * @returns {number} Next unique JQInstance id\n */\nfunction elemNextId() {\n return ++elId;\n}\n\n/**\n * @param {string} _all\n * @param {string} letter\n * @returns {string}\n */\nfunction fnCamelCaseReplace(_all, letter) {\n return letter.toUpperCase();\n}\n\n/**\n * Converts kebab-case to camelCase.\n * @param {string} name Name to normalize\n * @returns {string}\n */\nexport function kebabToCamel(name) {\n return name.replace(DASH_LOWERCASE_REGEXP, fnCamelCaseReplace);\n}\n\n/**\n * Converts sname to camelCase.\n * @param {string} name\n * @returns {string}\n */\nexport function snakeToCamel(name) {\n return name.replace(UNDERSCORE_LOWERCASE_REGEXP, fnCamelCaseReplace);\n}\n\n/**\n * Removes expando data from this element. If key is provided, only\n * its field is removed. If data is empty, also removes `ExpandoStore`\n * from cache.\n * @param {Element} element\n * @param {string} [name] - key of field to remove\n */\nexport function removeElementData(element, name) {\n const expandoId = element[EXPANDO];\n\n const expandoStore = expandoId && Cache.get(expandoId);\n\n if (expandoStore) {\n if (name) {\n delete expandoStore.data[name];\n } else {\n expandoStore.data = {};\n }\n\n removeIfEmptyData(element);\n }\n}\n\n/**\n * Stores data associated with an element inside the expando property of the DOM element.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Glossary/Expando MDN Glossary: Expando}\n *\n * @param {Element} element\n * @param {boolean} [createIfNecessary=false]\n * @returns {import(\"../interface.ts\").ExpandoStore}\n */\nexport function getExpando(element, createIfNecessary = false) {\n let expandoId = element[EXPANDO];\n\n let expandoStore = expandoId && Cache.get(expandoId);\n\n if (createIfNecessary && !expandoStore) {\n element[EXPANDO] = expandoId = elemNextId();\n expandoStore = {\n data: {},\n };\n Cache.set(expandoId, expandoStore);\n }\n\n return expandoStore;\n}\n\n/**\n * Checks if the string contains HTML tags or entities.\n * @param {string} html\n * @returns {boolean} True if the string is plain text, false if it contains HTML tags or entities.\n */\nexport function isTextNode(html) {\n return !/<|&#?\\w+;/.test(html);\n}\n\n/**\n * Check if element can accept expando data\n * @param {Element|Node} node\n * @returns {boolean}\n */\nfunction elementAcceptsData(node) {\n // The window object can accept data but has no nodeType\n // Otherwise we are only interested in elements (1) and documents (9)\n switch (node.nodeType) {\n case NodeType._ELEMENT_NODE:\n case NodeType._DOCUMENT_NODE:\n case NodeType._COMMENT_NODE:\n case undefined: // window.object\n return true;\n default:\n return false;\n }\n}\n\n/**\n * @param {string} html\n * @returns {DocumentFragment}\n */\nexport function buildFragment(html) {\n /** @type {HTMLDivElement} */\n let tmp;\n\n let tag;\n\n let wrap;\n\n const tempFragment = document.createDocumentFragment();\n\n let nodes = [];\n\n let i;\n\n if (isTextNode(html)) {\n // Convert non-html into a text node\n nodes.push(document.createTextNode(html));\n } else {\n // Convert html into DOM nodes\n\n tmp = tempFragment.appendChild(document.createElement(\"div\"));\n tag = (TAG_NAME_REGEXP.exec(html) || [\"\", \"\"])[1].toLowerCase();\n\n wrap = wrapMap[tag] || [];\n\n // Create wrappers & descend into them\n i = wrap.length;\n\n while (--i > -1) {\n tmp.appendChild(document.createElement(wrap[i]));\n tmp = /** @type {HTMLDivElement} */ (tmp.firstChild);\n }\n tmp.innerHTML = html;\n\n nodes = concat(nodes, tmp.childNodes);\n\n tmp = /** @type {HTMLDivElement} */ (tempFragment.firstChild);\n tmp.textContent = \"\";\n }\n\n const fragment = document.createDocumentFragment();\n\n fragment.append(...nodes);\n\n return fragment;\n}\n\n/**\n * @param {string} html\n * @returns {NodeListOf<ChildNode> | HTMLElement[]}\n */\nexport function parseHtml(html) {\n const regEx = SINGLE_TAG_REGEXP.exec(html);\n\n if (regEx) {\n return [document.createElement(regEx[1])];\n }\n const fragment = buildFragment(html);\n\n if (fragment) {\n return fragment.childNodes;\n }\n\n return [];\n}\n\n/**\n * @param {Element} element\n * @param {boolean} [onlyDescendants]\n * @returns {void}\n */\nexport function dealoc(element, onlyDescendants) {\n if (!element || element instanceof Comment) return;\n\n if (isArray(element)) {\n /* @ts-ignore */\n element.forEach((item) => dealoc(item, onlyDescendants));\n } else {\n if (!onlyDescendants && elementAcceptsData(element)) {\n cleanElementData([element]);\n }\n\n if (elementAcceptsData(element)) {\n cleanElementData(element.querySelectorAll(\"*\"));\n }\n }\n delete element[EXPANDO];\n element.innerHTML = \"\";\n}\n\n/**\n * If expando store data is empty, then delete it and set its expando id.\n * to undefined.\n * @param {Element} element\n */\nfunction removeIfEmptyData(element) {\n const expandoId = element[EXPANDO];\n\n const { data } = Cache.get(expandoId);\n\n if (!data || !keys(data).length) {\n Cache.delete(expandoId);\n element[EXPANDO] = undefined; // don't delete DOM expandos. Chrome don't like it\n }\n}\n\n/**\n * Gets or sets cache data for a given element.\n *\n * @param {Element} element - The DOM element to get or set data on.\n * @param {string|Object} key - The key (as a string) to get/set or an object for mass-setting.\n * @param {*} [value] - The value to set. If not provided, the function acts as a getter.\n * @returns {*} - The retrieved data if acting as a getter. Otherwise, returns undefined.\n */\nexport function getOrSetCacheData(element, key, value) {\n if (elementAcceptsData(element)) {\n let prop;\n\n const isSimpleSetter = isDefined(value);\n\n const isSimpleGetter = !isSimpleSetter && key && !isObject(key);\n\n const massGetter = !key;\n\n const expandoStore = getExpando(element, !isSimpleGetter);\n\n const data = expandoStore && expandoStore.data;\n\n if (isSimpleSetter) {\n data[kebabToCamel(key)] = value;\n } else {\n if (massGetter) {\n return data;\n }\n\n if (isSimpleGetter) {\n // don't force creation of expandoStore if it doesn't exist yet\n return data && data[kebabToCamel(key)];\n }\n\n // mass-setter: data({key1: val1, key2: val2})\n for (prop in key) {\n data[kebabToCamel(prop)] = key[prop];\n }\n }\n\n return undefined;\n } else {\n // TODO: check should occur perhaps prior at compilation level that this is a valid element\n return undefined;\n }\n}\n\n/**\n * Sets cache data for a given element.\n *\n * @param {Element|Node} element - The DOM element to get or set data on.\n * @param {string} key - The key (as a string) to get/set or an object for mass-setting.\n * @param {*} [value] - The value to set. If not provided, the function acts as a getter.\n * @returns\n */\nexport function setCacheData(element, key, value) {\n if (elementAcceptsData(element)) {\n const expandoStore = getExpando(/** @type {Element} */ (element), true);\n\n const data = expandoStore && expandoStore.data;\n\n data[kebabToCamel(key)] = value;\n } else {\n if (element.parentElement) {\n // TODO: check should occur perhaps prior at compilation level that this is a valid element\n setCacheData(element.parentElement, key, value);\n }\n }\n}\n\n/**\n * Gets cache data for a given element.\n *\n * @param {Element} element - The DOM element to get data from.\n * @param {string} [key] - The key (as a string) to retrieve. If not provided, returns all data.\n * @returns {*} - The retrieved data for the given key or all data if no key is provided.\n */\nexport function getCacheData(element, key) {\n if (elementAcceptsData(element)) {\n const expandoStore = getExpando(element, false); // Don't create if it doesn't exist\n\n const data = expandoStore && expandoStore.data;\n\n if (!key) {\n return undefined;\n }\n\n return data && data[kebabToCamel(key)];\n }\n\n return undefined;\n}\n\n/**\n * Deletes cache data for a given element for a particular key.\n *\n * @param {Element} element - The DOM element to delete data from.\n * @param {string} key - The key (as a string) to delete.\n * @returns void\n */\nexport function deleteCacheData(element, key) {\n if (!key) return;\n\n if (elementAcceptsData(element)) {\n const expandoStore = getExpando(element, false); // Don't create if it doesn't exist\n\n const data = expandoStore?.data;\n\n if (data && hasOwn(data, kebabToCamel(key))) {\n delete data[kebabToCamel(key)];\n }\n }\n}\n/**\n * Gets scope for a given element.\n *\n * @param {Element} element - The DOM element to get data from.\n * @returns {ng.Scope} - The retrieved data for the given key or all data if no key is provided.\n */\nexport function getScope(element) {\n return getCacheData(element, SCOPE_KEY);\n}\n\n/**\n * Set scope for a given element.\n *\n * @param {Element|Node|ChildNode} element - The DOM element to set data on.\n * @param {ng.Scope} scope - The Scope attached to this element\n */\nexport function setScope(element, scope) {\n return setCacheData(element, SCOPE_KEY, scope);\n}\n\n/**\n * Gets isolate scope for a given element.\n *\n * @param {Element} element - The DOM element to get data from.\n * @returns {*} - The retrieved data for the given key or all data if no key is provided.\n */\nexport function getIsolateScope(element) {\n return getCacheData(element, ISOLATE_SCOPE_KEY);\n}\n\n/**\n * Set isolate scope for a given element.\n *\n * @param {Element} element - The DOM element to set data on.\n * @param {ng.Scope} scope - The Scope attached to this element\n */\nexport function setIsolateScope(element, scope) {\n return setCacheData(element, ISOLATE_SCOPE_KEY, scope);\n}\n\n/**\n * Gets the controller instance for a given element, if exists. Defaults to \"ngControllerController\"\n *\n * @param {Element} element - The DOM element to get data from.\n * @param {string} [name] - Controller name.\n * @returns {ng.Scope|undefined} - The retrieved data\n */\nexport function getController(element, name) {\n return getInheritedData(element, `$${name || \"ngController\"}Controller`);\n}\n\n/**\n *\n * @param {Node} element\n * @param {string} name\n * @returns\n */\nexport function getInheritedData(element, name) {\n // if element is the document object work with the html element instead\n // this makes $(document).scope() possible\n if (element.nodeType === NodeType._DOCUMENT_NODE) {\n element = /** @type {Document} */ (element).documentElement;\n }\n\n let value;\n\n while (element) {\n if (\n isDefined((value = getCacheData(/** @type {Element} */ (element), name)))\n )\n return value;\n\n // If dealing with a document fragment node with a host element, and no parent, use the host\n // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM\n // to lookup parent controllers.\n element =\n element.parentNode ||\n (element.nodeType === NodeType._DOCUMENT_FRAGMENT_NODE &&\n /** @type {ShadowRoot} */ (element).host);\n }\n\n return undefined;\n}\n\n/**\n *\n * @param {Node} element\n * @param {string|string[]} name\n * @param {any} [value]\n * @returns {any|undefined}\n */\nexport function setInheritedData(element, name, value) {\n // if element is the document object work with the html element instead\n // this makes $(document).scope() possible\n if (element.nodeType === NodeType._DOCUMENT_NODE) {\n element = /** @type {Document} */ (element).documentElement;\n }\n\n const names = isArray(name) ? name : [name];\n\n while (element) {\n for (let i = 0, ii = names.length; i < ii; i++) {\n if (\n isDefined(\n (value = setCacheData(/** @type {Element} */ (element), names[i])),\n )\n )\n return value;\n }\n\n // If dealing with a document fragment node with a host element, and no parent, use the host\n // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM\n // to lookup parent controllers.\n element =\n element.parentNode ||\n (element.nodeType === NodeType._DOCUMENT_FRAGMENT_NODE &&\n /** @type {ShadowRoot} */ (element).host);\n }\n\n return undefined;\n}\n\n/**\n *\n * @param {Element} element\n * @param {boolean} keepData\n */\nexport function removeElement(element, keepData = false) {\n if (!keepData) {\n dealoc(element);\n }\n const parent = element.parentNode;\n\n if (parent) parent.removeChild(element);\n}\n\n/**\n * Extracts the starting tag from an HTML string or DOM element.\n *\n * @param {string|Element|Node} elementOrStr - The HTML string or DOM element to process.\n * @returns {string} The starting tag or processed result.\n */\nexport function startingTag(elementOrStr) {\n let clone;\n\n if (typeof elementOrStr === \"string\") {\n const parser = new DOMParser();\n\n const doc = parser.parseFromString(elementOrStr, \"text/html\");\n\n clone = doc.body.firstChild.cloneNode(true);\n } else if (elementOrStr instanceof Element || elementOrStr instanceof Node) {\n clone = elementOrStr.cloneNode(true);\n } else {\n throw new Error(\"Input must be an HTML string or a DOM element.\");\n }\n\n while (clone.firstChild) {\n clone.removeChild(clone.firstChild);\n }\n\n const divWrapper = document.createElement(\"div\");\n\n divWrapper.appendChild(clone);\n const elemHtml = divWrapper.innerHTML;\n\n try {\n if (clone.nodeType === NodeType._TEXT_NODE) {\n return elemHtml.toLowerCase();\n } else if (clone.nodeType === NodeType._COMMENT_NODE) {\n return `<!--${/** @type {Comment} **/ (clone).data.trim()}-->`;\n } else {\n const match = elemHtml.match(/^(<[^>]+>)/);\n\n if (match) {\n return match[1].replace(/^<([\\w-]+)/, (_match, nodeName) => {\n return `<${nodeName.toLowerCase()}`;\n });\n }\n }\n } catch {\n return elemHtml.toLowerCase();\n }\n\n return elemHtml.toLowerCase();\n}\n\n/**\n * Return the DOM siblings between the first and last node in the given array.\n * @param {Array<Node>} nodes An array-like object\n * @returns {Element} the inputted object or a JQLite collection containing the nodes\n */\nexport function getBlockNodes(nodes) {\n // TODO(perf): update `nodes` instead of creating a new object?\n let node = nodes[0];\n\n const endNode = nodes[nodes.length - 1];\n\n let blockNodes;\n\n for (let i = 1; node !== endNode && (node = node.nextSibling); i++) {\n if (blockNodes || nodes[i] !== node) {\n if (!blockNodes) {\n // use element to avoid circular dependency\n blockNodes = Array.prototype.slice.call(nodes, 0, i);\n }\n blockNodes.push(node);\n }\n }\n\n return blockNodes || nodes;\n}\n\n/**\n * Gets the name of a boolean attribute if it exists on a given element.\n *\n * @param {Element} element - The DOM element to check.\n * @param {string} name - The name of the attribute.\n * @returns {string|false} - The attribute name if valid, otherwise false.\n */\nexport function getBooleanAttrName(element, name) {\n const normalizedName = name.toLowerCase();\n\n const isBooleanAttr = BOOLEAN_ATTR.includes(normalizedName);\n\n return isBooleanAttr && BOOLEAN_ELEMENTS.includes(element.nodeName)\n ? normalizedName\n : false;\n}\n\n/**\n * Takes an array of elements, calls any `$destroy` event handlers, removes any data in cache, and finally removes any\n * listeners.\n * @param {NodeListOf<Element>|Element[]} nodes\n */\nexport function cleanElementData(nodes) {\n for (let i = 0, ii = nodes.length; i < ii; i++) {\n removeElementData(nodes[i]);\n }\n}\n\n/**\n * Return instance of InjectorService attached to element\n * @param {Element} element\n * @returns {ng.InjectorService}\n */\nexport function getInjector(element) {\n return getInheritedData(element, \"$injector\");\n}\n\n/**\n * Creates a DOM element from an HTML string.\n * @param {string} htmlString - A string representing the HTML to parse. Must have only one root element.\n * @returns {Element} - The parsed DOM element.\n */\nexport function createElementFromHTML(htmlString) {\n const template = document.createElement(\"template\");\n\n template.innerHTML = htmlString.trim();\n\n return /** @type {Element} */ (template.content.firstChild);\n}\n\n/**\n * Creates a DOM element from an HTML string.\n * @param {string} htmlString - A string representing the HTML to parse.\n * @returns {NodeList} - The parsed DOM element.\n */\nexport function createNodelistFromHTML(htmlString) {\n const template = document.createElement(\"template\");\n\n template.innerHTML = htmlString.trim();\n\n return template.content.childNodes;\n}\n\n/**\n * Appends nodes or an HTML string to a given DOM element.\n * @param {Element} element - The element to append nodes to.\n * @param {Node | Node[] | string} nodes - Nodes or HTML string to append.\n */\nexport function appendNodesToElement(element, nodes) {\n if (typeof nodes === \"string\") {\n const template = document.createElement(\"template\");\n\n template.innerHTML = nodes.trim();\n nodes = Array.from(template.content.childNodes);\n } else if (nodes instanceof Node) {\n nodes = [nodes];\n } else if (!isArray(nodes)) {\n throw new TypeError(\"Expected a Node, Node[], or HTML string\");\n }\n\n nodes.forEach((node) => element.appendChild(node));\n}\n\n/**\n * Remove element from the DOM and clear Cache data, associated with the node.\n * @param {Element} element\n */\nexport function emptyElement(element) {\n dealoc(element, true);\n switch (element.nodeType) {\n case NodeType._ELEMENT_NODE:\n case NodeType._DOCUMENT_NODE:\n case NodeType._DOCUMENT_FRAGMENT_NODE:\n element.replaceChildren();\n break;\n }\n}\n\n/**\n * Checks if the element is root\n * @param {Element} element\n * @returns {boolean}\n */\nexport function isRoot(element) {\n return !!getCacheData(element, \"$injector\");\n}\n\n/**\n * Inserts a DOM element before or at the beginning of a parent element.\n *\n * @param {HTMLElement | Element} element\n * The element to insert into the DOM.\n *\n * @param {HTMLElement | Element} parentElement\n * The parent element that will receive the inserted element.\n *\n * @param {HTMLElement | Element | null} [afterElement]\n * An optional sibling element — if present and valid, `element`\n * will be inserted after it. If omitted or invalid, `element`\n * is prepended to `parentElement`.\n *\n * @returns {void}\n */\nexport function domInsert(element, parentElement, afterElement) {\n // if for some reason the previous element was removed\n // from the dom sometime before this code runs then let's\n // just stick to using the parent element as the anchor\n if (afterElement) {\n const afterNode = extractElementNode(afterElement);\n\n if (afterNode && !afterNode.parentNode && !afterNode.previousSibling) {\n afterElement = null;\n }\n }\n\n if (afterElement) {\n afterElement.after(element);\n } else {\n parentElement.prepend(element);\n }\n}\n\nexport function animatedomInsert(element, parent, after) {\n const originalVisibility = element.style.visibility;\n\n const originalPosition = element.style.position;\n\n const originalPointerEvents = element.style.pointerEvents;\n\n Object.assign(element.style, {\n visibility: \"hidden\",\n position: \"absolute\",\n pointerEvents: \"none\",\n });\n\n domInsert(element, parent, after);\n\n requestAnimationFrame(() => {\n element.style.visibility = originalVisibility;\n element.style.position = originalPosition;\n element.style.pointerEvents = originalPointerEvents;\n });\n}\n\n/**\n * Returns the base href of the document.\n *\n * @returns {string} The base href.\n */\nexport function getBaseHref() {\n const href = document.querySelector(\"base\")?.getAttribute(\"href\");\n\n return href ? href.replace(/^(https?:)?\\/\\/[^/]*/, \"\") : \"\";\n}\n","/**\n * A helper list of tokens matching the standard injectables that come predefined in the core `ng` module.\n * These string tokens are commonly injected into services, directives, or components via `$inject`.\n *\n * Example:\n * ```js\n *\n * myDirective.$inject = [\n * angular.$injectTokens.$animate,\n * angular.$injectTokens.$templateRequest,\n * ];\n *\n * function myDirective($animate, $templateRequest) { ... }\n *\n * ```\n * @type Readonly<Record<string, string>>\n */\nexport const $injectTokens = Object.freeze({\n $attrs: \"$attrs\",\n $scope: \"$scope\",\n $element: \"$element\",\n $$animateCache: \"$$animateCache\",\n $$animateCssDriver: \"$$animateCssDriver\",\n $$animateJs: \"$$animateJs\",\n $$animateJsDriver: \"$$animateJsDriver\",\n $$animateQueue: \"$$animateQueue\",\n $$animation: \"$$animation\",\n $$rAFScheduler: \"$$rAFScheduler\",\n $$taskTrackerFactory: \"$$taskTrackerFactory\",\n $anchorScroll: \"$anchorScroll\",\n $animate: \"$animate\",\n $animateCss: \"$animateCss\",\n $aria: \"$aria\",\n $compile: \"$compile\",\n $cookie: \"$cookie\",\n $controller: \"$controller\",\n $document: \"$document\",\n $eventBus: \"$eventBus\",\n $exceptionHandler: \"$exceptionHandler\",\n $filter: \"$filter\",\n $http: \"$http\",\n $httpParamSerializer: \"$httpParamSerializer\",\n $interpolate: \"$interpolate\",\n $location: \"$location\",\n $log: \"$log\",\n $viewScroll: \"$viewScroll\",\n $parse: \"$parse\",\n $rest: \"$rest\",\n $rootScope: \"$rootScope\",\n $rootElement: \"$rootElement\",\n $router: \"$router\",\n $sce: \"$sce\",\n $sceDelegate: \"$sceDelegate\",\n $state: \"$state\",\n $stateRegistry: \"$stateRegistry\",\n $sse: \"$sse\",\n $$sanitizeUri: \"$$sanitizeUri\",\n $$sanitizeUriProvider: \"$$sanitizeUriProvider\",\n $templateCache: \"$templateCache\",\n $templateFactory: \"$templateFactory\",\n $templateRequest: \"$templateRequest\",\n $transitions: \"$transitions\",\n $urlConfig: \"$urlConfig\",\n $url: \"$url\",\n $view: \"$view\",\n $window: \"$window\",\n // provide literals\n $provide: \"$provide\",\n $injector: \"$injector\",\n $compileProvider: \"$compileProvider\",\n $animateProvider: \"$animateProvider\",\n $filterProvider: \"$filterProvider\",\n $controllerProvider: \"$controllerProvider\",\n});\n\n/**\n * Utility for mapping to service-names to providers\n * @param {String[]} services\n */\nexport function provider(services) {\n return services.map((x) => `${x}Provider`);\n}\n","import {\n assertArgFn,\n isArray,\n isFunction,\n minErr,\n} from \"../../shared/utils.js\";\nimport { $injectTokens } from \"../../injection-tokens.js\";\n\n/**\n * Shared utility functions\n */\n\nconst $injectorMinErr = minErr($injectTokens.$injector);\n\nconst ARROW_ARG = /^([^(]+?)=>/;\n\nconst FN_ARGS = /^[^(]*\\(\\s*([^)]*)\\)/m;\n\nconst FN_ARG = /^\\s*(_?)(\\S+?)\\1\\s*$/;\n\nconst STRIP_COMMENTS = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/gm;\n\n/**\n * @param {Function} fn\n * @returns {string}\n */\nexport function stringifyFn(fn) {\n return Function.prototype.toString.call(fn);\n}\n\n/**\n * @param {Function} fn\n * @returns {Array<any>}\n */\nexport function extractArgs(fn) {\n const fnText = stringifyFn(fn).replace(STRIP_COMMENTS, \"\");\n\n return fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);\n}\n\n/**\n * @param {Function} func\n * @returns {boolean}\n */\nexport function isClass(func) {\n return /^class\\b/.test(stringifyFn(func));\n}\n\n/**\n * @param {any} fn\n * @param {boolean} [strictDi]\n * @param {string} [name]\n * @returns {Array<string>}\n */\nexport function annotate(fn, strictDi, name) {\n let $inject, argDecl, last;\n\n if (isFunction(fn)) {\n // eslint-disable-next-line prefer-destructuring\n $inject = fn.$inject;\n\n if (!$inject) {\n $inject = [];\n\n if (fn.length) {\n if (strictDi) {\n throw $injectorMinErr(\n \"strictdi\",\n \"{0} is not using explicit annotation and cannot be invoked in strict mode\",\n name,\n );\n }\n argDecl = extractArgs(fn);\n argDecl[1].split(/,/).forEach(function (arg) {\n arg.replace(FN_ARG, function (_all, _underscore, injName) {\n $inject.push(injName);\n });\n });\n }\n fn.$inject = $inject;\n }\n } else if (isArray(fn)) {\n last = /** @type {Array} */ (fn).length - 1;\n assertArgFn(fn[last], \"fn\");\n $inject = /** @type {Array} */ (fn).slice(0, last);\n } else {\n assertArgFn(fn, \"fn\", true);\n }\n\n return $inject;\n}\n","import {\n hasOwn,\n isArray,\n isArrowFunction,\n minErr,\n} from \"../../shared/utils.js\";\nimport { annotate, isClass } from \"./di.js\";\nimport { $injectTokens } from \"../../injection-tokens.js\";\n\nconst $injectorMinErr = minErr($injectTokens.$injector);\n\nconst providerSuffix = \"Provider\";\n\nconst INSTANTIATING = true;\n\nclass AbstractInjector {\n /**\n * @param {boolean} strictDi - Indicates if strict dependency injection is enforced.\n */\n constructor(strictDi) {\n /**\n * @type {Object<String, Function>}\n */\n this.cache = {};\n /** @type {boolean} */\n this.strictDi = strictDi;\n /** @type {string[]} */\n this.path = [];\n /** @type {Object.<string, ng.NgModule>} */\n this.modules = {};\n }\n\n /**\n * Get a service by name.\n *\n * @param {string} serviceName\n * @returns {any}\n */\n get(serviceName) {\n if (hasOwn(this.cache, serviceName)) {\n if (this.cache[serviceName] === INSTANTIATING) {\n throw $injectorMinErr(\n \"cdep\",\n \"Circular dependency found: {0}\",\n `${serviceName} <- ${this.path.join(\" <- \")}`,\n );\n }\n\n return this.cache[serviceName];\n }\n\n this.path.unshift(serviceName);\n this.cache[serviceName] = INSTANTIATING;\n\n try {\n this.cache[serviceName] = this.factory(serviceName);\n } catch (err) {\n // this is for the error handling being thrown by the providerCache multiple times\n delete this.cache[serviceName];\n throw err;\n }\n\n return this.cache[serviceName];\n }\n\n /**\n * Get the injection arguments for a function.\n *\n * @param {Function|Array} fn\n * @param {Object} locals\n * @param {string} serviceName\n * @returns\n */\n injectionArgs(fn, locals, serviceName) {\n const args = [];\n\n const $inject = annotate(fn, this.strictDi, serviceName);\n\n for (let i = 0, { length } = $inject; i < length; i++) {\n const key = $inject[i];\n\n if (typeof key !== \"string\") {\n throw $injectorMinErr(\n \"itkn\",\n \"Incorrect injection token! Expected service name as string, got {0}\",\n key,\n );\n }\n args.push(locals && hasOwn(locals, key) ? locals[key] : this.get(key));\n }\n\n return args;\n }\n\n /**\n * Invoke a function with optional context and locals.\n *\n * @param {Function|String|Array<any>} fn\n * @param {*} [self]\n * @param {Object} [locals]\n * @param {string} [serviceName]\n * @returns {*}\n */\n invoke(fn, self, locals, serviceName) {\n if (typeof locals === \"string\") {\n serviceName = locals;\n locals = null;\n }\n\n const args = this.injectionArgs(\n /** @type {Function} */ (fn),\n locals,\n serviceName,\n );\n\n if (isArray(fn)) {\n fn = fn[fn.length - 1];\n }\n\n if (isClass(/** @type {Function} */ (fn))) {\n args.unshift(null);\n\n return new (Function.prototype.bind.apply(fn, args))();\n } else {\n return /** @type {Function} */ (fn).apply(self, args);\n }\n }\n\n /**\n * Instantiate a type constructor with optional locals.\n * @param {Function|Array} type\n * @param {*} [locals]\n * @param {string} [serviceName]\n */\n instantiate(type, locals, serviceName) {\n // Check if type is annotated and use just the given function at n-1 as parameter\n // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);\n const ctor = isArray(type) ? type[type.length - 1] : type;\n\n const args = this.injectionArgs(type, locals, serviceName);\n\n // Empty object at position 0 is ignored for invocation with `new`, but required.\n args.unshift(null);\n\n try {\n return new (Function.prototype.bind.apply(ctor, args))();\n } catch (err) {\n // try arrow function\n if (isArrowFunction(ctor)) {\n return ctor(args);\n } else {\n throw err;\n }\n }\n }\n\n /**\n * @abstract\n */\n loadNewModules() {\n /* empty */\n }\n\n /**\n * @abstract\n * @param {string} _serviceName\n * @returns {any}\n */\n // eslint-disable-next-line no-unused-vars\n factory(_serviceName) {\n /* empty */\n }\n}\n\n/**\n * Injector for providers\n */\nexport class ProviderInjector extends AbstractInjector {\n /**\n * @param {Object} cache\n * @param {boolean} strictDi - Indicates if strict dependency injection is enforced.\n */\n constructor(cache, strictDi) {\n super(strictDi);\n this.cache = cache;\n }\n\n /**\n * Factory method for creating services.\n * @param {string} caller - The name of the caller requesting the service.\n * @throws {Error} If the provider is unknown.\n */\n factory(caller) {\n this.path.push(caller);\n // prevents lookups to providers through get\n throw $injectorMinErr(\n \"unpr\",\n \"Unknown provider: {0}\",\n this.path.join(\" <- \"),\n );\n }\n\n loadNewModules() {\n /* empty */\n }\n}\n\n/**\n * Injector for factories and services\n */\nexport class InjectorService extends AbstractInjector {\n /**\n * @param {ProviderInjector} providerInjector\n * @param {boolean} strictDi - Indicates if strict dependency injection is enforced.\n */\n constructor(providerInjector, strictDi) {\n super(strictDi);\n\n /** @type {ProviderInjector} */\n this.providerInjector = providerInjector;\n /** @type {Object.<string, ng.NgModule>} */\n this.modules = providerInjector.modules;\n }\n\n /**\n * @param {string} serviceName\n * @returns {*}\n */\n factory(serviceName) {\n const provider = this.providerInjector.get(serviceName + providerSuffix);\n\n return this.invoke(provider.$get, provider, undefined, serviceName);\n }\n\n /**\n *\n * @param {string} name\n * @returns {boolean}\n */\n has(name) {\n const hasProvider = hasOwn(\n this.providerInjector.cache,\n name + providerSuffix,\n );\n\n const hasCache = hasOwn(this.cache, name);\n\n return hasProvider || hasCache;\n }\n\n loadNewModules() {\n /* empty */\n }\n}\n","/**\n * Creates a proxy that automatically persists an object's state\n * into a storage backend whenever a property is set.\n *\n * @param {object} target - The object to wrap\n * @param {string} key - The storage key\n * @param {object} storage - Any storage-like object with getItem/setItem/removeItem\n * @param {{serialize?: function, deserialize?: function}} [options] - Optional custom (de)serialization\n * @returns {Proxy}\n */\nexport function createPersistentProxy(target, key, storage, options = {}) {\n const serialize = options.serialize || JSON.stringify;\n\n const deserialize = options.deserialize || JSON.parse;\n\n // Restore saved state\n const saved = storage.getItem(key);\n\n if (saved) {\n Object.assign(target, deserialize(saved));\n }\n\n return new Proxy(target, {\n set(obj, prop, value) {\n obj[prop] = value;\n storage.setItem(key, serialize(obj));\n\n return true;\n },\n deleteProperty(obj, prop) {\n const deleted = delete obj[prop];\n\n storage.setItem(key, serialize(obj));\n\n return deleted;\n },\n });\n}\n","import { isArray, isFunction, isString } from \"./utils.js\";\n\n/**\n * Predicate which checks if a value is injectable\n *\n * A value is \"injectable\" if it is a function, or if it is an ng1 array-notation-style array\n * where all the elements in the array are Strings, except the last one, which is a Function\n * @param {*} val\n * @returns {boolean}\n */\nexport function isInjectable(val) {\n if (isArray(val) && val.length) {\n const head = val.slice(0, -1),\n tail = val.slice(-1);\n\n return !(\n head.filter((injectable) => !isString(injectable)).length ||\n tail.filter((injectable) => !isFunction(injectable)).length\n );\n }\n\n return isFunction(val);\n}\n/**\n * Predicate which checks if a value looks like a Promise\n *\n * It is probably a Promise if it's an object, and it has a `then` property which is a Function\n * @param {any} obj\n * @returns {boolean}\n */\nexport function isPromise(obj) {\n return (\n obj !== null && typeof obj === \"object\" && typeof obj.then === \"function\"\n );\n}\n","import { isInjectable } from \"./predicates.js\";\nimport { isArray, isDefined, isString, notNullOrUndefined } from \"./utils.js\";\n\nexport const BADARG = \"badarg\";\nexport const BADARGKEY = \"badarg: key\";\nexport const BADARGVALUE = \"badarg: value\";\n\n/** @type {Map<ng.Validator, string>} */\nconst reasons = new Map([\n [notNullOrUndefined, \"required\"],\n [isArray, \"notarray\"],\n [isInjectable, \"notinjectable\"],\n [isDefined, \"required\"],\n [isString, \"notstring\"],\n]);\n\n/**\n *\n * @param {ng.Validator} val\n * @returns {string}\n */\nfunction getReason(val) {\n return reasons.get(val) ?? \"fail\";\n}\n\n/**\n * Validate a value using a predicate function.\n * Throws if the predicate returns false.\n * IMPORTANT: use this function only for developper errors and not for user/data errors\n *\n * @param {ng.Validator} fn - Predicate validator function.\n * @param {*} arg - The value to validate.\n * @param {string} name - Parameter name (included in error message).\n * @returns {*} The validated value.\n * @throws {TypeError} If the value does not satisfy the validator.\n */\nexport function validate(fn, arg, name) {\n if (fn(arg)) return arg;\n\n let v;\n\n try {\n v = JSON.stringify(arg);\n } catch {\n v = String(arg);\n }\n\n throw new TypeError(`badarg:${getReason(fn)} ${name}=${v}`);\n}\n\n/**\n * @param {*} arg - The value to validate.\n * @param {string} name - Parameter name (included in error message).\n * @returns {*} The validated value.\n * @throws {TypeError} If the value does not satisfy the validator.\n */\nexport function validateRequired(arg, name) {\n return validate(notNullOrUndefined, arg, name);\n}\n\n/**\n * @param {*} arg - The value to validate.\n * @param {string} name - Parameter name (included in error message).\n * @returns {*} The validated value.\n * @throws {TypeError} If the value does not satisfy the validator.\n */\nexport function validateArray(arg, name) {\n return validate(isArray, arg, name);\n}\n\n/**\n * @param {*} arg - The value to validate.\n * @param {string} name - Parameter name (included in error message).\n * @returns {*} The validated value.\n * @throws {TypeError} If the value does not satisfy the validator.\n */\nexport function validateIsString(arg, name) {\n return validate(isString, arg, name);\n}\n","import {\n assert,\n assertArgFn,\n assertNotHasOwnProperty,\n entries,\n isArray,\n isFunction,\n isNullOrUndefined,\n isObject,\n isString,\n isUndefined,\n minErr,\n} from \"../../shared/utils.js\";\nimport { InjectorService, ProviderInjector } from \"./internal-injector.js\";\nimport { createPersistentProxy } from \"../../services/storage/storage.js\";\nimport { $injectTokens } from \"../../injection-tokens.js\";\nimport { validateArray } from \"../../shared/validate.js\";\n\nconst $injectorMinErr = minErr($injectTokens.$injector);\n\nconst providerSuffix = \"Provider\";\n\n/**\n *\n * @param {Array<String|Function>} modulesToLoad\n * @param {boolean} [strictDi]\n * @returns {InjectorService}\n */\nexport function createInjector(modulesToLoad, strictDi = false) {\n assert(isArray(modulesToLoad), \"modules required\");\n\n /** @type {Map<String|Function, boolean>} */\n const loadedModules = new Map(); // Keep track of loaded modules to avoid circular dependencies\n\n const providerCache = {\n $provide: {\n provider: supportObject(provider),\n factory: supportObject(factory),\n service: supportObject(service),\n value: supportObject(value),\n constant: supportObject(constant),\n store,\n decorator,\n },\n };\n\n const providerInjector = (providerCache.$injector = new ProviderInjector(\n providerCache,\n strictDi,\n ));\n\n const protoInstanceInjector = new InjectorService(providerInjector, strictDi);\n\n providerCache.$injectorProvider = {\n // $injectionProvider return instance injector\n $get: () => protoInstanceInjector,\n };\n\n let instanceInjector = protoInstanceInjector;\n\n const runBlocks = loadModules(modulesToLoad);\n\n instanceInjector = protoInstanceInjector.get($injectTokens.$injector);\n\n runBlocks.forEach((fn) => fn && instanceInjector.invoke(fn));\n\n instanceInjector.loadNewModules = (mods) =>\n loadModules(mods).forEach((fn) => fn && instanceInjector.invoke(fn));\n\n return instanceInjector;\n\n ////////////////////////////////////\n // $provide methods\n ////////////////////////////////////\n\n /**\n * Registers a provider.\n * @param {string} name\n * @param {import('../../interface.ts').ServiceProvider | import('../../interface.ts').Injectable<any>} provider\n * @returns {import('../../interface.ts').ServiceProvider}\n */\n // eslint-disable-next-line no-shadow\n function provider(name, provider) {\n assertNotHasOwnProperty(name, \"service\");\n let newProvider;\n\n if (isFunction(provider) || isArray(provider)) {\n newProvider = providerInjector.instantiate(\n /** @type {Function} */ (provider),\n );\n } else {\n newProvider = provider;\n }\n\n if (!newProvider.$get) {\n throw $injectorMinErr(\n \"pget\",\n \"Provider '{0}' must define $get factory method.\",\n name,\n );\n }\n providerCache[name + providerSuffix] = newProvider;\n\n return newProvider;\n }\n\n /**\n * Registers a factory.\n * @param {string} name\n * @param {(string|(function(*): *))[]} factoryFn\n * @returns {import('../../interface.ts').ServiceProvider}\n */\n function factory(name, factoryFn) {\n return provider(name, {\n $get() {\n const result = instanceInjector.invoke(factoryFn, this);\n\n if (isUndefined(result)) {\n throw $injectorMinErr(\n \"undef\",\n \"Provider '{0}' must return a value from $get factory method.\",\n name,\n );\n }\n\n return result;\n },\n });\n }\n\n /**\n * Registers a service constructor.\n * @param {string} name\n * @param {Function} constructor\n * @returns {import('../../interface.ts').ServiceProvider}\n */\n function service(name, constructor) {\n return factory(name, [\n $injectTokens.$injector,\n ($injector) => $injector.instantiate(constructor),\n ]);\n }\n\n /**\n * Register a fixed value as a service.\n * @param {String} name\n * @param {any} val\n * @returns {ng.ServiceProvider}\n */\n function value(name, val) {\n return (providerCache[name + providerSuffix] = { $get: () => val });\n }\n\n /**\n * Register a constant value (available during config).\n * @param {string} name\n * @param {any} value\n * @returns {void}\n */\n // eslint-disable-next-line no-shadow\n function constant(name, value) {\n assertNotHasOwnProperty(name, \"constant\");\n providerInjector.cache[name] = value;\n protoInstanceInjector.cache[name] = value;\n }\n\n /**\n * Register a decorator function to modify or replace an existing service.\n * @param {string} serviceName - The name of the service to decorate.\n * @param {Function} decorFn - A function that takes `$delegate` and returns a decorated service.\n * @returns {void}\n */\n function decorator(serviceName, decorFn) {\n const origProvider = providerInjector.get(serviceName + providerSuffix);\n\n const origGet = origProvider.$get;\n\n origProvider.$get = function () {\n const origInstance = instanceInjector.invoke(origGet, origProvider);\n\n return instanceInjector.invoke(decorFn, null, {\n $delegate: origInstance,\n });\n };\n }\n\n /**\n * Registers a service persisted in a storage\n *\n * @param {string} name - Service name\n * @param {Function} ctor - Constructor for the service\n * @param {ng.StorageType} type - Type of storage to be instantiated\n * @param {Storage|Object} backendOrConfig - Either a Storage-like object (getItem/setItem) or a config object\n * with { backend, serialize, deserialize }\n */\n function store(name, ctor, type, backendOrConfig = {}) {\n return provider(name, {\n $get: /** @param {ng.InjectorService} $injector */ ($injector) => {\n switch (type) {\n case \"session\": {\n const instance = $injector.instantiate(ctor);\n\n return createPersistentProxy(instance, name, sessionStorage);\n }\n case \"local\": {\n const instance = $injector.instantiate(ctor);\n\n return createPersistentProxy(instance, name, localStorage);\n }\n case \"cookie\": {\n const instance = $injector.instantiate(ctor);\n\n const $cookie = $injector.get($injectTokens.$cookie);\n\n const serialize = backendOrConfig.serialize ?? JSON.stringify;\n\n const deserialize = backendOrConfig.deserialize ?? JSON.parse;\n\n const cookieOpts = backendOrConfig.cookie ?? {};\n\n return createPersistentProxy(instance, name, {\n getItem(key) {\n const raw = $cookie.get(key);\n\n return isNullOrUndefined(raw) ? null : raw;\n },\n\n setItem(k, v) {\n $cookie.put(k, v, cookieOpts);\n },\n\n removeItem(k) {\n $cookie.remove(k, cookieOpts);\n },\n\n serialize,\n deserialize,\n });\n }\n case \"custom\": {\n const instance = $injector.instantiate(ctor);\n\n let backend;\n\n let serialize = JSON.stringify;\n\n let deserialize = JSON.parse;\n\n if (backendOrConfig) {\n if (typeof backendOrConfig.getItem === \"function\") {\n // raw Storage object\n backend = backendOrConfig;\n } else if (isObject(backendOrConfig)) {\n backend = backendOrConfig.backend || localStorage;\n\n if (backendOrConfig.serialize)\n // eslint-disable-next-line prefer-destructuring\n serialize = backendOrConfig.serialize;\n\n if (backendOrConfig.deserialize)\n // eslint-disable-next-line prefer-destructuring\n deserialize = backendOrConfig.deserialize;\n }\n } else {\n // fallback default\n backend = localStorage;\n }\n\n return createPersistentProxy(instance, name, backend, {\n serialize,\n deserialize,\n });\n }\n }\n\n return undefined;\n },\n });\n }\n\n /**\n *\n * @param {Array<String|Function>} modules\n * @returns\n */\n function loadModules(modules) {\n validateArray(modules, \"modules\");\n let moduleRunBlocks = [];\n\n modules.forEach((module) => {\n if (loadedModules.get(module)) return;\n loadedModules.set(module, true);\n\n try {\n if (isString(module)) {\n /** @type {ng.NgModule} */\n const moduleFn = window.angular.module(\n /** @type {string} */ (module),\n );\n\n instanceInjector.modules[/** @type {string } */ (module)] = moduleFn;\n moduleRunBlocks = moduleRunBlocks\n .concat(loadModules(moduleFn._requires))\n .concat(moduleFn._runBlocks);\n\n const invokeQueue = moduleFn._invokeQueue.concat(\n moduleFn._configBlocks,\n );\n\n invokeQueue.forEach((invokeArgs) => {\n const providerInstance = providerInjector.get(invokeArgs[0]);\n\n providerInstance[invokeArgs[1]].apply(\n providerInstance,\n invokeArgs[2],\n );\n });\n } else if (isFunction(module)) {\n moduleRunBlocks.push(providerInjector.invoke(module));\n } else if (isArray(module)) {\n moduleRunBlocks.push(providerInjector.invoke(module));\n } else {\n assertArgFn(module, \"module\");\n }\n } catch (err) {\n if (isArray(module)) {\n module = module[module.length - 1];\n }\n throw $injectorMinErr(\n \"modulerr\",\n \"Failed to instantiate module {0} due to:\\n{1}\",\n module,\n err.stack || err.message || err,\n );\n }\n });\n\n return moduleRunBlocks;\n }\n}\n\nfunction supportObject(delegate) {\n return function (key, value) {\n if (isObject(key)) {\n entries(key).forEach(([k, v]) => {\n delegate(k, v);\n });\n\n return undefined;\n } else {\n return delegate(key, value);\n }\n };\n}\n","import { isString } from \"../../shared/utils.js\";\n\nconst originUrl = urlResolve(window.location.href);\n\n/**\n * @param {import(\"./interface.ts\").ResolvableUrl} url\n * @return {import(\"./interface.ts\").ParsedUrl}\n */\nexport function urlResolve(url) {\n if (!isString(url))\n return /** @type {import(\"./interface.ts\").ParsedUrl} */ (url);\n\n const urlParsingNode = new URL(\n /** @type {string} */ (url),\n window.location.href,\n );\n\n const hostname = urlParsingNode.hostname.includes(\":\")\n ? `[${urlParsingNode.hostname}]`\n : urlParsingNode.hostname;\n\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol,\n host: urlParsingNode.host,\n search: urlParsingNode.search\n ? urlParsingNode.search.replace(/^\\?/, \"\")\n : \"\",\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, \"\") : \"\",\n hostname,\n port: urlParsingNode.port,\n pathname:\n urlParsingNode.pathname.charAt(0) === \"/\"\n ? urlParsingNode.pathname\n : `/${urlParsingNode.pathname}`,\n };\n}\n\n/**\n * Parse a request URL and determine whether this is a same-origin request as the application\n * document.\n *\n * @param {import(\"./interface.ts\").ResolvableUrl} requestUrl The url of the request as a string that will be resolved\n * or a parsed URL object.\n * @returns {boolean} Whether the request is for the same origin as the application document.\n */\nexport function urlIsSameOrigin(requestUrl) {\n return urlsAreSameOrigin(requestUrl, originUrl);\n}\n\n/**\n * Parse a request URL and determine whether it is same-origin as the current document base URL.\n *\n * Note: The base URL is usually the same as the document location (`location.href`) but can\n * be overriden by using the `<base>` tag.\n *\n * @param {import(\"./interface.ts\").ResolvableUrl} requestUrl The url of the request as a string that will be resolved\n * or a parsed URL object.\n * @returns {boolean} Whether the URL is same-origin as the document base URL.\n */\nexport function urlIsSameOriginAsBaseUrl(requestUrl) {\n return urlsAreSameOrigin(requestUrl, document.baseURI);\n}\n\n/**\n * Create a function that can check a URL's origin against a list of allowed/trusted origins.\n * The current location's origin is implicitly trusted.\n *\n * @param {string[]} trustedOriginUrls - A list of URLs (strings), whose origins are trusted.\n *\n * @returns {(url: import(\"./interface.ts\").ResolvableUrl) => boolean } - A function that receives a URL (string or parsed URL object) and returns\n * whether it is of an allowed origin.\n */\nexport function urlIsAllowedOriginFactory(trustedOriginUrls) {\n const parsedAllowedOriginUrls = [originUrl].concat(\n trustedOriginUrls.map(urlResolve),\n );\n\n /**\n * Check whether the specified URL (string or parsed URL object) has an origin that is allowed\n * based on a list of trusted-origin URLs. The current location's origin is implicitly\n * trusted.\n *\n * @param {import(\"./interface.ts\").ResolvableUrl} requestUrl - The URL to be checked (provided as a string that will be\n * resolved or a parsed URL object).\n *\n * @returns {boolean} - Whether the specified URL is of an allowed origin.\n */\n return function urlIsAllowedOrigin(requestUrl) {\n const parsedUrl = urlResolve(requestUrl);\n\n return parsedAllowedOriginUrls.some(\n urlsAreSameOrigin.bind(null, parsedUrl),\n );\n };\n}\n\n/**\n * Determine if two URLs share the same origin.\n *\n * @param {import(\"./interface.ts\").ResolvableUrl} url1 - First URL to compare as a string or a normalized URL in the form of\n * a dictionary object returned by `urlResolve()`.\n * @param {import(\"./interface.ts\").ResolvableUrl} url2 - Second URL to compare as a string or a normalized URL in the form\n * of a dictionary object returned by `urlResolve()`.\n *\n * @returns {boolean} - True if both URLs have the same origin, and false otherwise.\n */\nexport function urlsAreSameOrigin(url1, url2) {\n url1 = urlResolve(url1);\n url2 = urlResolve(url2);\n\n return url1.protocol === url2.protocol && url1.host === url2.host;\n}\n\n/**\n * Removes a trailing hash ('#') from the given URL if it exists.\n *\n * @param {string} url\n * @returns {string}\n */\nexport function trimEmptyHash(url) {\n return url.replace(/#$/, \"\");\n}\n","import {\n trimEmptyHash,\n urlIsAllowedOriginFactory,\n} from \"../../shared/url-utils/url-utils.js\";\nimport {\n encodeUriQuery,\n entries,\n extend,\n fromJson,\n isArray,\n isBlob,\n isDate,\n isDefined,\n isFile,\n isFormData,\n isFunction,\n isNullOrUndefined,\n isObject,\n isPromiseLike,\n isString,\n isUndefined,\n keys,\n lowercase,\n minErr,\n shallowCopy,\n toJson,\n trim,\n uppercase,\n} from \"../../shared/utils.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n\nconst APPLICATION_JSON = \"application/json\";\n\n/**\n * @internal\n * @enum {number}\n */\nexport const Http = {\n _OK: 200,\n _MultipleChoices: 300,\n _BadRequest: 400,\n _NotFound: 404,\n _ErrorMax: 599,\n};\n\nconst CONTENT_TYPE_APPLICATION_JSON = {\n \"Content-Type\": `${APPLICATION_JSON};charset=utf-8`,\n};\n\nconst JSON_START = /^\\[|^\\{(?!\\{)/;\n\nconst JSON_ENDS = {\n \"[\": /]$/,\n \"{\": /}$/,\n};\n\nconst JSON_PROTECTION_PREFIX = /^\\)]\\}',?\\n/;\n\nconst $httpMinErr = minErr(\"$http\");\n\nfunction serializeValue(v) {\n if (isObject(v)) {\n return isDate(v) ? v.toISOString() : toJson(v);\n }\n\n return v;\n}\n\n/**\n * Default params serializer that converts objects to strings\n * according to the following rules:\n *\n * * `{'foo': 'bar'}` results in `foo=bar`\n * * `{'foo': Date.now()}` results in `foo=2015-04-01T09%3A50%3A49.262Z` (`toISOString()` and encoded representation of a Date object)\n * * `{'foo': ['bar', 'baz']}` results in `foo=bar&foo=baz` (repeated key for each array element)\n * * `{'foo': {'bar':'baz'}}` results in `foo=%7B%22bar%22%3A%22baz%22%7D` (stringified and encoded representation of an object)\n *\n * Note that serializer will sort the request parameters alphabetically.\n */\nexport function HttpParamSerializerProvider() {\n /**\n * @returns {import('./interface.ts').HttpParamSerializer}\n * A function that serializes parameters into a query string.\n */\n this.$get = () => {\n return (params) => {\n if (!params) return \"\";\n const parts = [];\n\n keys(params)\n .sort()\n .forEach((key) => {\n const value = params[key];\n\n if (value === null || isUndefined(value) || isFunction(value)) return;\n\n if (isArray(value)) {\n /** @type {any[]} */ (value).forEach((v) => {\n parts.push(\n `${encodeUriQuery(key)}=${encodeUriQuery(serializeValue(v))}`,\n );\n });\n } else {\n parts.push(\n `${encodeUriQuery(key)}=${encodeUriQuery(serializeValue(value))}`,\n );\n }\n });\n\n return parts.join(\"&\");\n };\n };\n}\n\nexport function defaultHttpResponseTransform(data, headers) {\n if (isString(data)) {\n // Strip json vulnerability protection prefix and trim whitespace\n const tempData = data.replace(JSON_PROTECTION_PREFIX, \"\").trim();\n\n if (tempData) {\n const contentType = headers(\"Content-Type\");\n\n const hasJsonContentType =\n contentType && contentType.indexOf(APPLICATION_JSON) === 0;\n\n if (hasJsonContentType || isJsonLike(tempData)) {\n try {\n data = fromJson(tempData);\n } catch (err) {\n if (!hasJsonContentType) {\n return data;\n }\n throw $httpMinErr(\n \"baddata\",\n 'Data must be a valid JSON object. Received: \"{0}\". ' +\n 'Parse error: \"{1}\"',\n data,\n err,\n );\n }\n }\n }\n }\n\n return data;\n}\n\nfunction isJsonLike(str) {\n const jsonStart = str.match(JSON_START);\n\n return jsonStart && JSON_ENDS[jsonStart[0]].test(str);\n}\n\n/**\n * Parse headers into key value object\n *\n * @param {string} headers Raw headers as a string\n * @returns {Object} Parsed headers as key value object\n */\nfunction parseHeaders(headers) {\n const parsed = Object.create(null);\n\n let i;\n\n function fillInParsed(key, val) {\n if (key) {\n parsed[key] = parsed[key] ? `${parsed[key]}, ${val}` : val;\n }\n }\n\n if (isString(headers)) {\n headers.split(\"\\n\").forEach(\n /** @param {string} line */\n (line) => {\n i = line.indexOf(\":\");\n fillInParsed(\n line.substring(0, i).trim().toLowerCase(),\n trim(line.substring(i + 1)),\n );\n },\n );\n } else if (isObject(headers)) {\n entries(headers).forEach(([headerKey, headerVal]) => {\n fillInParsed(headerKey.toLowerCase(), trim(headerVal));\n });\n }\n\n return parsed;\n}\n\n/**\n * Returns a function that provides access to parsed headers.\n *\n * Headers are lazy parsed when first requested.\n * @see parseHeaders\n *\n * @param {(string|Object)} headers Headers to provide access to.\n * @returns {function(string=)} Returns a getter function which if called with:\n *\n * - if called with an argument returns a single header value or null\n * - if called with no arguments returns an object containing all headers.\n */\nfunction headersGetter(headers) {\n let headersObj;\n\n return function (name) {\n if (!headersObj) headersObj = parseHeaders(headers);\n\n if (name) {\n let value = headersObj[name.toLowerCase()];\n\n if (value === undefined) {\n value = null;\n }\n\n return value;\n }\n\n return headersObj;\n };\n}\n\n/**\n * Chain all given functions\n *\n * This function is used for both request and response transforming\n *\n * @param {*} data Data to transform.\n * @param {function(string=):any} headers HTTP headers getter fn.\n * @param {number} status HTTP status code of the response.\n * @param {function(...any): any | Array<Function>} fns Function or an array of functions.\n * @returns {*} Transformed data.\n */\nfunction transformData(data, headers, status, fns) {\n if (isFunction(fns)) {\n return fns(data, headers, status);\n }\n\n if (isArray(fns)) {\n /** @type {Array<function(...any): any>} */ (fns).forEach((fn) => {\n data = fn(data, headers, status);\n });\n }\n\n return data;\n}\n\nfunction isSuccess(status) {\n return status >= Http._OK && status < Http._MultipleChoices;\n}\n\n/**\n * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.\n */\nexport function HttpProvider() {\n /**\n * Object containing default values for all {@link ng.$http $http} requests.\n *\n * - **`defaults.cache`** - {boolean|Object} - A boolean value or object created with\n * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of HTTP responses\n * by default. See {@link $http#caching $http Caching} for more information.\n *\n * - **`defaults.headers`** - {Object} - Default headers for all $http requests.\n * Refer to {@link ng.$http#setting-http-headers $http} for documentation on\n * setting default headers.\n * - **`defaults.headers.common`**\n * - **`defaults.headers.post`**\n * - **`defaults.headers.put`**\n * - **`defaults.headers.patch`**\n * *\n * - **`defaults.paramSerializer`** - `{string|function(Object<string,string>):string}` - A function\n * used to the prepare string representation of request parameters (specified as an object).\n * If specified as string, it is interpreted as a function registered with the {@link auto.$injector $injector}.\n * Defaults to {@link ng.$httpParamSerializer $httpParamSerializer}.\n *\n * - **`defaults.transformRequest`** -\n * `{Array<function(data, headersGetter)>|function(data, headersGetter)}` -\n * An array of functions (or a single function) which are applied to the request data.\n * By default, this is an array with one request transformation function:\n *\n * - If the `data` property of the request configuration object contains an object, serialize it\n * into JSON format.\n *\n * - **`defaults.transformResponse`** -\n * `{Array<function(data, headersGetter, status)>|function(data, headersGetter, status)}` -\n * An array of functions (or a single function) which are applied to the response data. By default,\n * this is an array which applies one response transformation function that does two things:\n *\n * - If XSRF prefix is detected, strip it\n * (see {@link ng.$http#security-considerations Security Considerations in the $http docs}).\n * - If the `Content-Type` is `application/json` or the response looks like JSON,\n * deserialize it using a JSON parser.\n *\n * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.\n * Defaults value is `'XSRF-TOKEN'`.\n *\n * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the\n * XSRF token. Defaults value is `'X-XSRF-TOKEN'`.\n *\n */\n const defaults = (this.defaults = {\n // transform incoming response data\n transformResponse: [defaultHttpResponseTransform],\n\n // transform outgoing request data\n transformRequest: [\n function (data) {\n return isObject(data) &&\n !isFile(data) &&\n !isBlob(data) &&\n !isFormData(data)\n ? toJson(data)\n : data;\n },\n ],\n\n // default headers\n headers: {\n common: {\n Accept: \"application/json, text/plain, */*\",\n },\n post: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),\n put: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),\n patch: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),\n },\n\n xsrfCookieName: \"XSRF-TOKEN\",\n xsrfHeaderName: \"X-XSRF-TOKEN\",\n\n paramSerializer: \"$httpParamSerializer\",\n });\n\n let useApplyAsync = false;\n\n /**\n * Configure $http service to combine processing of multiple http responses received at around\n * the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in\n * significant performance improvement for bigger applications that make many HTTP requests\n * concurrently (common during application bootstrap).\n *\n * Defaults to false. If no value is specified, returns the current configured value.\n *\n * @param {boolean=} value If true, when requests are loaded, they will schedule a deferred\n * \"apply\" on the next tick, giving time for subsequent requests in a roughly ~10ms window\n * to load and share the same digest cycle.\n *\n * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining.\n * otherwise, returns the current configured value.\n */\n this.useApplyAsync = function (value) {\n if (isDefined(value)) {\n useApplyAsync = !!value;\n\n return this;\n }\n\n return useApplyAsync;\n };\n\n /**\n * Array containing service factories for all synchronous or asynchronous {@link ng.$http $http}\n * pre-processing of request or postprocessing of responses.\n *\n * These service factories are ordered by request, i.e. they are applied in the same order as the\n * array, on request, but reverse order, on response.\n *\n * {@link ng.$http#interceptors Interceptors detailed info}\n */\n this.interceptors = [];\n\n /**\n * Array containing URLs whose origins are trusted to receive the XSRF token. See the\n * {@link ng.$http#security-considerations Security Considerations} sections for more details on\n * XSRF.\n *\n * **Note:** An \"origin\" consists of the [URI scheme](https://en.wikipedia.org/wiki/URI_scheme),\n * the [hostname](https://en.wikipedia.org/wiki/Hostname) and the\n * [port number](https://en.wikipedia.org/wiki/Port_(computer_networking). For `http:` and\n * `https:`, the port number can be omitted if using th default ports (80 and 443 respectively).\n * Examples: `http://example.com`, `https://api.example.com:9876`\n *\n * <div class=\"alert alert-warning\">\n * It is not possible to trust specific URLs/paths. The `path`, `query` and `fragment` parts\n * of a URL will be ignored. For example, `https://foo.com/path/bar?query=baz#fragment` will be\n * treated as `https://foo.com`, meaning that **all** requests to URLs starting with\n * `https://foo.com/` will include the XSRF token.\n * </div>\n *\n * @example\n *\n * ```js\n * // App served from `https://example.com/`.\n * angular.\n * module('xsrfTrustedOriginsExample', []).\n * config(['$httpProvider', function($httpProvider) {\n * $httpProvider.xsrfTrustedOrigins.push('https://api.example.com');\n * }]).\n * run(['$http', function($http) {\n * // The XSRF token will be sent.\n * $http.get('https://api.example.com/preferences').then(...);\n *\n * // The XSRF token will NOT be sent.\n * $http.get('https://stats.example.com/activity').then(...);\n * }]);\n * ```\n *\n * @type {string[]}\n */\n this.xsrfTrustedOrigins = [];\n\n /**\n * This property is deprecated. Use {@link $httpProvider#xsrfTrustedOrigins xsrfTrustedOrigins}\n * instead.\n */\n Object.defineProperty(this, \"xsrfWhitelistedOrigins\", {\n get() {\n return this.xsrfTrustedOrigins;\n },\n set(origins) {\n this.xsrfTrustedOrigins = origins;\n },\n });\n\n const that = this;\n\n this.$get = [\n $t.$injector,\n $t.$sce,\n $t.$cookie,\n /**\n *\n * @param {ng.InjectorService} $injector\n * @param {*} $sce\n * @param {ng.CookieService} $cookie\n * @returns\n */\n function ($injector, $sce, $cookie) {\n /**\n * @type {Map<string, string>}\n */\n const defaultCache = new Map();\n\n /**\n * Make sure that default param serializer is exposed as a function\n */\n defaults.paramSerializer = isString(defaults.paramSerializer)\n ? $injector.get(defaults.paramSerializer)\n : defaults.paramSerializer;\n\n /**\n * Interceptors stored in reverse order. Inner interceptors before outer interceptors.\n * The reversal is needed so that we can build up the interception chain around the\n * server request.\n */\n const reversedInterceptors = [];\n\n that.interceptors.forEach((interceptorFactory) => {\n reversedInterceptors.unshift(\n isString(interceptorFactory)\n ? $injector.get(interceptorFactory)\n : $injector.invoke(interceptorFactory),\n );\n });\n\n /**\n * A function to check request URLs against a list of allowed origins.\n */\n const urlIsAllowedOrigin = urlIsAllowedOriginFactory(\n that.xsrfTrustedOrigins,\n );\n\n /**\n * @property {Array.<Object>} requestConfig Array of config objects for currently pending\n * requests. This is primarily meant to be used for debugging purposes.\n */\n function $http(requestConfig) {\n if (!isObject(requestConfig)) {\n throw minErr(\"$http\")(\n \"badreq\",\n \"Http request configuration must be an object. Received: {0}\",\n requestConfig,\n );\n }\n\n if (!isString($sce.valueOf(requestConfig.url))) {\n throw minErr(\"$http\")(\n \"badreq\",\n \"Http request configuration url must be a string or a $sce trusted object. Received: {0}\",\n requestConfig.url,\n );\n }\n\n const config = extend(\n {\n method: \"get\",\n transformRequest: defaults.transformRequest,\n transformResponse: defaults.transformResponse,\n paramSerializer: defaults.paramSerializer,\n },\n requestConfig,\n );\n\n config.headers = mergeHeaders(requestConfig);\n config.method = uppercase(config.method);\n config.paramSerializer = isString(config.paramSerializer)\n ? $injector.get(config.paramSerializer)\n : config.paramSerializer;\n\n const requestInterceptors = [];\n\n const responseInterceptors = [];\n\n let promise = Promise.resolve(config);\n\n // apply interceptors\n reversedInterceptors.forEach((interceptor) => {\n if (interceptor.request || interceptor.requestError) {\n requestInterceptors.unshift(\n interceptor.request,\n interceptor.requestError,\n );\n }\n\n if (interceptor.response || interceptor.responseError) {\n responseInterceptors.push(\n interceptor.response,\n interceptor.responseError,\n );\n }\n });\n\n promise = chainInterceptors(promise, requestInterceptors);\n promise = promise.then(serverRequest);\n promise = chainInterceptors(promise, responseInterceptors);\n\n return promise;\n\n function chainInterceptors(promiseParam, interceptors) {\n for (let i = 0, ii = interceptors.length; i < ii; ) {\n const thenFn = interceptors[i++];\n\n const rejectFn = interceptors[i++];\n\n promiseParam = promiseParam.then(thenFn, rejectFn);\n }\n\n interceptors.length = 0;\n\n return promiseParam;\n }\n\n function executeHeaderFns(headers, configParam) {\n let headerContent;\n\n const processedHeaders = {};\n\n entries(headers).forEach(([header, headerFn]) => {\n if (isFunction(headerFn)) {\n headerContent = headerFn(configParam);\n\n if (!isNullOrUndefined(headerContent)) {\n processedHeaders[header] = headerContent;\n }\n } else {\n processedHeaders[header] = headerFn;\n }\n });\n\n return processedHeaders;\n }\n\n function mergeHeaders(configParam) {\n let defHeaders = defaults.headers;\n\n const reqHeaders = extend({}, configParam.headers);\n\n defHeaders = extend(\n {},\n defHeaders.common,\n defHeaders[lowercase(configParam.method)],\n );\n\n keys(defHeaders).forEach((defHeaderName) => {\n const lowercaseDefHeaderName = lowercase(defHeaderName);\n\n const hasMatchingHeader = keys(reqHeaders).some((reqHeaderName) => {\n return lowercase(reqHeaderName) === lowercaseDefHeaderName;\n });\n\n if (!hasMatchingHeader) {\n reqHeaders[defHeaderName] = defHeaders[defHeaderName];\n }\n });\n\n // execute if header value is a function for merged headers\n return executeHeaderFns(reqHeaders, shallowCopy(configParam));\n }\n\n function serverRequest(configParam) {\n const { headers } = configParam;\n\n const reqData = transformData(\n configParam.data,\n headersGetter(headers),\n undefined,\n configParam.transformRequest,\n );\n\n // strip content-type if data is undefined\n if (isUndefined(reqData)) {\n keys(headers).forEach((header) => {\n if (lowercase(header) === \"content-type\") {\n delete headers[header];\n }\n });\n }\n\n if (\n isUndefined(configParam.withCredentials) &&\n !isUndefined(defaults.withCredentials)\n ) {\n configParam.withCredentials = defaults.withCredentials;\n }\n\n // send request\n return sendReq(configParam, reqData).then(\n transformResponse,\n transformResponse,\n );\n }\n\n function transformResponse(response) {\n // make a copy since the response must be cacheable\n const resp = extend({}, response);\n\n resp.data = transformData(\n response.data,\n response.headers,\n response.status,\n config.transformResponse,\n );\n\n return isSuccess(response.status) ? resp : Promise.reject(resp);\n }\n }\n\n $http.pendingRequests = [];\n\n /**\n * Shortcut method to perform `GET` request.\n *\n * @param {string} url Absolute or relative URL of the resource that is being requested;\n * or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n * @param {Object=} config Optional configuration object. See {@link ng.$http#$http-arguments `$http()` arguments}.\n * @returns {HttpPromise} A Promise that will be resolved or rejected with a response object.\n * See {@link ng.$http#$http-returns `$http()` return value}.\n */\n\n /**\n * Shortcut method to perform `DELETE` request.\n *\n * @param {string} url Absolute or relative URL of the resource that is being requested;\n * or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n * @param {Object=} config Optional configuration object. See {@link ng.$http#$http-arguments `$http()` arguments}.\n * @returns {HttpPromise} A Promise that will be resolved or rejected with a response object.\n * See {@link ng.$http#$http-returns `$http()` return value}.\n */\n\n /**\n * Shortcut method to perform `HEAD` request.\n *\n * @param {string} url Absolute or relative URL of the resource that is being requested;\n * or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n * @param {Object=} config Optional configuration object. See {@link ng.$http#$http-arguments `$http()` arguments}.\n * @returns {HttpPromise} A Promise that will be resolved or rejected with a response object.\n * See {@link ng.$http#$http-returns `$http()` return value}.\n */\n\n /**\n * Shortcut method to perform `JSONP` request.\n *\n * Note that, since JSONP requests are sensitive because the response is given full access to the browser,\n * the url must be declared, via {@link $sce} as a trusted resource URL.\n * You can trust a URL by adding it to the trusted resource URL list via\n * {@link $sceDelegateProvider#trustedResourceUrlList `$sceDelegateProvider.trustedResourceUrlList`} or\n * by explicitly trusting the URL via {@link $sce#trustAsResourceUrl `$sce.trustAsResourceUrl(url)`}.\n *\n * You should avoid generating the URL for the JSONP request from user provided data.\n * Provide additional query parameters via `params` property of the `config` parameter, rather than\n * modifying the URL itself.\n *\n * You can also specify a default callback parameter name in `$http.defaults.jsonpCallbackParam`.\n * Initially this is set to `'callback'`.\n *\n * <div class=\"alert alert-danger\">\n * You can no longer use the `JSON_CALLBACK` string as a placeholder for specifying where the callback\n * parameter value should go.\n * </div>\n *\n * If you would like to customise where and how the callbacks are stored then try overriding\n * or decorating the {@link $jsonpCallbacks} service.\n *\n * @param {string} url Absolute or relative URL of the resource that is being requested;\n * or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n * @param {Object=} config Optional configuration object. See {@link ng.$http#$http-arguments `$http()` arguments}.\n * @returns {HttpPromise} A Promise that will be resolved or rejected with a response object.\n * See {@link ng.$http#$http-returns `$http()` return value}.\n */\n createShortMethods(\"get\", \"delete\", \"head\");\n\n /**\n * Shortcut method to perform `POST` request.\n *\n * @param {string} url Relative or absolute URL specifying the destination of the request\n * @param {*} data Request content\n * @param {Object=} config Optional configuration object. See {@link ng.$http#$http-arguments `$http()` arguments}.\n * @returns {HttpPromise} A Promise that will be resolved or rejected with a response object.\n * See {@link ng.$http#$http-returns `$http()` return value}.\n */\n\n /**\n * Shortcut method to perform `PUT` request.\n *\n * @param {string} url Relative or absolute URL specifying the destination of the request\n * @param {*} data Request content\n * @param {Object=} config Optional configuration object. See {@link ng.$http#$http-arguments `$http()` arguments}.\n * @returns {HttpPromise} A Promise that will be resolved or rejected with a response object.\n * See {@link ng.$http#$http-returns `$http()` return value}.\n */\n\n /**\n * Shortcut method to perform `PATCH` request.\n *\n * @param {string} url Relative or absolute URL specifying the destination of the request\n * @param {*} data Request content\n * @param {Object=} config Optional configuration object. See {@link ng.$http#$http-arguments `$http()` arguments}.\n * @returns {HttpPromise} A Promise that will be resolved or rejected with a response object.\n * See {@link ng.$http#$http-returns `$http()` return value}.\n */\n createShortMethodsWithData(\"post\", \"put\", \"patch\");\n\n /**\n * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of\n * default headers, withCredentials as well as request and response transformations.\n *\n * See \"Setting HTTP Headers\" and \"Transforming Requests and Responses\" sections above.\n */\n $http.defaults = defaults;\n\n return $http;\n\n function createShortMethods(...names) {\n names.forEach((name) => {\n $http[name] = function (url, config) {\n return $http(\n extend({}, config || {}, {\n method: name,\n url,\n }),\n );\n };\n });\n }\n\n function createShortMethodsWithData(...names) {\n names.forEach((name) => {\n $http[name] = function (url, data, config) {\n return $http(\n extend({}, config || {}, {\n method: name,\n url,\n data,\n }),\n );\n };\n });\n }\n\n /**\n * Makes the request.\n *\n * !!! ACCESSES CLOSURE VARS:\n * defaults, $log, $rootScope, defaultCache, $http.pendingRequests\n */\n function sendReq(config, reqData) {\n const { promise, resolve, reject } = Promise.withResolvers();\n\n let cache;\n\n let cachedResp;\n\n const reqHeaders = config.headers;\n\n let { url } = config;\n\n if (!isString(url)) {\n // If it is not a string then the URL must be a $sce trusted object\n url = $sce.valueOf(url);\n }\n\n url = buildUrl(url, config.paramSerializer(config.params));\n\n $http.pendingRequests.push(config);\n promise.then(removePendingReq, removePendingReq);\n\n if (\n (config.cache || defaults.cache) &&\n config.cache !== false &&\n config.method === \"GET\"\n ) {\n cache = isObject(config.cache)\n ? config.cache\n : isObject(/** @type {?} */ (defaults).cache)\n ? /** @type {?} */ (defaults).cache\n : defaultCache;\n }\n\n if (cache) {\n cachedResp = cache.get(url);\n\n if (isDefined(cachedResp)) {\n if (isPromiseLike(cachedResp)) {\n // cached request has already been sent, but there is no response yet\n cachedResp.then(\n resolvePromiseWithResult,\n resolvePromiseWithResult,\n );\n } else {\n // serving from cache\n if (isArray(cachedResp)) {\n resolvePromise(\n cachedResp[1],\n cachedResp[0],\n shallowCopy(cachedResp[2]),\n cachedResp[3],\n cachedResp[4],\n );\n } else {\n resolvePromise(cachedResp, Http._OK, {}, \"OK\", \"complete\");\n }\n }\n } else {\n // put the promise for the non-transformed response into cache as a placeholder\n cache.set(url, promise);\n }\n }\n\n // if we won't have the response in cache, set the xsrf headers and\n // send the request to the backend\n if (isUndefined(cachedResp)) {\n const xsrfValue = urlIsAllowedOrigin(config.url)\n ? $cookie.getAll()[config.xsrfCookieName || defaults.xsrfCookieName]\n : undefined;\n\n if (xsrfValue) {\n reqHeaders[config.xsrfHeaderName || defaults.xsrfHeaderName] =\n xsrfValue;\n }\n\n http(\n config.method,\n url,\n reqData,\n done,\n reqHeaders,\n config.timeout,\n config.withCredentials,\n config.responseType,\n createApplyHandlers(config.eventHandlers),\n createApplyHandlers(config.uploadEventHandlers),\n );\n }\n\n return promise;\n\n /**\n * @param eventHandlers\n * @return {Record<string, EventListener>}\n */\n function createApplyHandlers(eventHandlers) {\n if (eventHandlers) {\n const applyHandlers = {};\n\n entries(eventHandlers).forEach(([key, eventHandler]) => {\n applyHandlers[key] = function (event) {\n if (useApplyAsync) {\n setTimeout(() => callEventHandler());\n } else {\n callEventHandler();\n }\n\n function callEventHandler() {\n eventHandler(event);\n }\n };\n });\n\n return /** @type {Record<string, EventListener>} */ (applyHandlers);\n } else {\n return {};\n }\n }\n\n /**\n * Callback registered to http():\n * - caches the response if desired\n * - resolves the raw $http promise\n * - calls $apply\n */\n function done(status, response, headersString, statusText, xhrStatus) {\n if (cache) {\n if (isSuccess(status)) {\n cache.set(url, [\n status,\n response,\n parseHeaders(headersString),\n statusText,\n xhrStatus,\n ]);\n } else {\n // remove promise from the cache\n cache.delete(url);\n }\n }\n\n function resolveHttpPromise() {\n resolvePromise(\n response,\n status,\n headersString,\n statusText,\n xhrStatus,\n );\n }\n\n if (useApplyAsync) {\n setTimeout(resolveHttpPromise);\n } else {\n resolveHttpPromise();\n }\n }\n\n /**\n * Resolves the raw $http promise.\n */\n function resolvePromise(\n response,\n status,\n headers,\n statusText,\n xhrStatus,\n ) {\n // status: HTTP response status code, 0, -1 (aborted by timeout / promise)\n status = status >= -1 ? status : 0;\n\n (isSuccess(status) ? resolve : reject)({\n data: response,\n status,\n headers: headersGetter(headers),\n config,\n statusText,\n xhrStatus,\n });\n }\n\n function resolvePromiseWithResult(result) {\n resolvePromise(\n result.data,\n result.status,\n shallowCopy(result.headers()),\n result.statusText,\n result.xhrStatus,\n );\n }\n\n function removePendingReq() {\n const idx = $http.pendingRequests.indexOf(config);\n\n if (idx !== -1) $http.pendingRequests.splice(idx, 1);\n }\n }\n\n function buildUrl(url, serializedParams) {\n if (serializedParams.length > 0) {\n url += (url.indexOf(\"?\") === -1 ? \"?\" : \"&\") + serializedParams;\n }\n\n return url;\n }\n },\n ];\n}\n\n/**\n * Makes an HTTP request using XMLHttpRequest with flexible options.\n *\n * @param {string} method - The HTTP method (e.g., \"GET\", \"POST\").\n * @param {string} [url] - The URL to send the request to. Defaults to the current page URL.\n * @param {*} [post] - The body to send with the request, if any.\n * @param {function(number, any, string|null, string, string): void} [callback] - Callback invoked when the request completes.\n * @param {Object<string, string|undefined>} [headers] - Headers to set on the request.\n * @param {number|Promise<any>} [timeout] - Timeout in ms or a cancellable promise.\n * @param {boolean} [withCredentials] - Whether to send credentials with the request.\n * @param {XMLHttpRequestResponseType} [responseType] - The type of data expected in the response.\n * @param {Record<string, EventListener>} [eventHandlers] - Event listeners for the XMLHttpRequest object.\n * @param {Record<string, EventListener>} [uploadEventHandlers] - Event listeners for the XMLHttpRequest.upload object.\n * @returns {void}\n */\nexport function http(\n method,\n url,\n post,\n callback,\n headers,\n timeout,\n withCredentials,\n responseType,\n eventHandlers,\n uploadEventHandlers,\n) {\n url = url || trimEmptyHash(window.location.href);\n\n const xhr = new XMLHttpRequest();\n\n let abortedByTimeout = false;\n\n let timeoutId;\n\n xhr.open(method, url, true);\n\n if (headers) {\n for (const [key, value] of entries(headers)) {\n if (isDefined(value)) {\n xhr.setRequestHeader(key, value);\n }\n }\n }\n\n xhr.onload = () => {\n let status = xhr.status || 0;\n\n const statusText = xhr.statusText || \"\";\n\n if (status === 0) {\n status = xhr.response\n ? Http._OK\n : new URL(url).protocol === \"file:\"\n ? Http._NotFound\n : 0;\n }\n\n completeRequest(\n status,\n xhr.response,\n xhr.getAllResponseHeaders(),\n statusText,\n \"complete\",\n );\n };\n\n xhr.onerror = () => completeRequest(-1, null, null, \"\", \"error\");\n xhr.ontimeout = () => completeRequest(-1, null, null, \"\", \"timeout\");\n\n xhr.onabort = () => {\n completeRequest(-1, null, null, \"\", abortedByTimeout ? \"timeout\" : \"abort\");\n };\n\n if (eventHandlers) {\n for (const [key, handler] of entries(eventHandlers)) {\n xhr.addEventListener(key, handler);\n }\n }\n\n if (uploadEventHandlers) {\n for (const [key, handler] of entries(uploadEventHandlers)) {\n xhr.upload.addEventListener(key, handler);\n }\n }\n\n if (withCredentials) {\n xhr.withCredentials = true;\n }\n\n if (responseType) {\n try {\n xhr.responseType = responseType;\n } catch (err) {\n if (responseType !== \"json\") throw err;\n }\n }\n\n xhr.send(isUndefined(post) ? null : post);\n\n if (typeof timeout === \"number\" && timeout > 0) {\n timeoutId = setTimeout(() => timeoutRequest(\"timeout\"), timeout);\n } else if (isPromiseLike(timeout)) {\n /** @type {Promise} */ (timeout).then(() => {\n timeoutRequest(\"abort\");\n });\n }\n\n /**\n * @param {\"timeout\"|\"abort\"} reason\n */\n function timeoutRequest(reason) {\n abortedByTimeout = reason === \"timeout\";\n\n if (xhr) xhr.abort();\n }\n\n /**\n * @param {number} status - HTTP status code or -1 for network errors.\n * @param {*} response - The parsed or raw response from the server.\n * @param {string|null} headersString - The raw response headers as a string.\n * @param {string} statusText - The status text returned by the server.\n * @param {\"complete\"|\"error\"|\"timeout\"|\"abort\"} xhrStatus - Final status of the request.\n */\n function completeRequest(\n status,\n response,\n headersString,\n statusText,\n xhrStatus,\n ) {\n if (isDefined(timeoutId)) {\n clearTimeout(timeoutId);\n }\n callback(status, response, headersString, statusText, xhrStatus);\n }\n}\n","import { $injectTokens as $t } from \"../../injection-tokens.js\";\nimport { Http } from \"../../services/http/http.js\";\nimport { NodeType } from \"../../shared/node.js\";\nimport {\n callBackAfterFirst,\n isDefined,\n isObject,\n isString,\n toKeyValue,\n wait,\n} from \"../../shared/utils.js\";\n\n/**\n * @param {\"get\" | \"delete\" | \"post\" | \"put\"} method - HTTP method applied to request\n * @param {string} [attrOverride] - Custom name to use for the attribute\n * @returns {ng.DirectiveFactory}\n */\nfunction defineDirective(method, attrOverride) {\n const attrName =\n attrOverride || `ng${method.charAt(0).toUpperCase()}${method.slice(1)}`;\n\n const directive = createHttpDirective(method, attrName);\n\n directive.$inject = [\n $t.$http,\n $t.$compile,\n $t.$log,\n $t.$parse,\n $t.$state,\n $t.$sse,\n $t.$animate,\n ];\n\n return directive;\n}\n\n/** @type {ng.DirectiveFactory} */\nexport const ngGetDirective = defineDirective(\"get\");\n\n/** @type {ng.DirectiveFactory} */\nexport const ngDeleteDirective = defineDirective(\"delete\");\n\n/** @type {ng.DirectiveFactory} */\nexport const ngPostDirective = defineDirective(\"post\");\n\n/** @type {ng.DirectiveFactory} */\nexport const ngPutDirective = defineDirective(\"put\");\n\n/** @type {ng.DirectiveFactory} */\nexport const ngSseDirective = defineDirective(\"get\", \"ngSse\");\n\n/**\n * Selects DOM event to listen for based on the element type.\n *\n * @param {Element} element - The DOM element to inspect.\n * @returns {\"click\" | \"change\" | \"submit\"} The name of the event to listen for.\n */\nexport function getEventNameForElement(element) {\n const tag = element.tagName.toLowerCase();\n\n if ([\"input\", \"textarea\", \"select\"].includes(tag)) {\n return \"change\";\n } else if (tag === \"form\") {\n return \"submit\";\n }\n\n return \"click\";\n}\n\n/**\n * Creates an HTTP directive factory that supports GET, DELETE, POST, PUT.\n *\n * @param {\"get\" | \"delete\" | \"post\" | \"put\"} method - HTTP method to use.\n * @param {string} attrName - Attribute name containing the URL.\n * @returns {ng.DirectiveFactory}\n */\nexport function createHttpDirective(method, attrName) {\n /**\n * @param {ng.HttpService} $http\n * @param {ng.CompileService} $compile\n * @param {ng.LogService} $log\n * @param {ng.ParseService} $parse\n * @param {ng.StateService} $state\n * @param {ng.SseService} $sse\n * @param {ng.AnimateService} $animate\n * @returns {ng.Directive}\n */\n return function ($http, $compile, $log, $parse, $state, $sse, $animate) {\n /**\n * Collects form data from the element or its associated form.\n *\n * @param {HTMLElement} element\n * @returns {Object<string, any>}\n */\n function collectFormData(element) {\n /** @type {HTMLFormElement | null} */\n let form = null;\n\n const tag = element.tagName.toLowerCase();\n\n if (tag === \"form\") {\n form = /** @type {HTMLFormElement} */ (element);\n } else if (\"form\" in element && element.form) {\n // eslint-disable-next-line prefer-destructuring\n form = /** @type {HTMLFormElement} */ (element.form);\n } else if (element.hasAttribute(\"form\")) {\n const formId = element.getAttribute(\"form\");\n\n if (formId) {\n const maybeForm = document.getElementById(formId);\n\n if (maybeForm && maybeForm.tagName.toLowerCase() === \"form\") {\n form = /** @type {HTMLFormElement} */ (maybeForm);\n }\n }\n }\n\n if (!form) {\n if (\n \"name\" in element &&\n typeof element.name === \"string\" &&\n element.name.length > 0\n ) {\n if (\n element instanceof HTMLInputElement ||\n element instanceof HTMLTextAreaElement ||\n element instanceof HTMLSelectElement\n ) {\n const key = element.name;\n\n const { value } = element;\n\n return { [key]: value };\n }\n }\n\n return {};\n }\n\n const formData = new FormData(form);\n\n const data = {};\n\n formData.forEach((value, key) => {\n data[key] = value;\n });\n\n return data;\n }\n\n return {\n restrict: \"A\",\n link(scope, element, attrs) {\n const eventName = attrs.trigger || getEventNameForElement(element);\n\n const tag = element.tagName.toLowerCase();\n\n let content = undefined;\n\n if (isDefined(attrs.latch)) {\n attrs.$observe(\n \"latch\",\n callBackAfterFirst(() =>\n element.dispatchEvent(new Event(eventName)),\n ),\n );\n }\n\n let throttled = false;\n\n let intervalId;\n\n if (isDefined(attrs.interval)) {\n element.dispatchEvent(new Event(eventName));\n intervalId = setInterval(\n () => element.dispatchEvent(new Event(eventName)),\n parseInt(attrs.interval) || 1000,\n );\n }\n\n /**\n * Handles DOM manipulation based on a swap strategy and server-rendered HTML.\n *\n * @param {string | Object} html - The HTML string or object returned from the server.\n * @param {import(\"./interface.ts\").SwapModeType} swap\n * @param {ng.Scope} scopeParam\n * @param {ng.Attributes} attrsParam\n * @param {Element} elmenetParam\n */\n function handleSwapResponse(\n html,\n swap,\n scopeParam,\n attrsParam,\n elmenetParam,\n ) {\n let animationEnabled = false;\n\n if (attrsParam.animate) {\n animationEnabled = true;\n }\n let nodes = [];\n\n if (![\"textcontent\", \"delete\", \"none\"].includes(swap)) {\n if (!html) return;\n const compiled = $compile(html)(scopeParam);\n\n nodes =\n compiled instanceof DocumentFragment\n ? Array.from(compiled.childNodes)\n : [compiled];\n }\n\n const targetSelector = attrsParam.target;\n\n const target = targetSelector\n ? document.querySelector(targetSelector)\n : elmenetParam;\n\n if (!target) {\n $log.warn(`${attrName}: target \"${targetSelector}\" not found`);\n\n return;\n }\n\n switch (swap) {\n case \"outerHTML\": {\n const parent = target.parentNode;\n\n if (!parent) return;\n\n // Build fragment for static replacement OR a list for animation\n const frag = document.createDocumentFragment();\n\n nodes.forEach((x) => frag.appendChild(x));\n\n if (!animationEnabled) {\n parent.replaceChild(frag, target);\n break;\n }\n\n const placeholder = document.createElement(\"span\");\n\n placeholder.style.display = \"none\";\n parent.insertBefore(placeholder, target.nextSibling);\n\n $animate.leave(target).done(() => {\n const insertedNodes = Array.from(frag.childNodes);\n\n // Insert each node in order\n for (const x of insertedNodes) {\n if (x.nodeType === NodeType._ELEMENT_NODE) {\n // Animate elements\n $animate.enter(\n /** @type {Element} */ (x),\n parent,\n placeholder,\n );\n } else {\n // Insert text nodes statically\n parent.insertBefore(x, placeholder);\n }\n }\n\n content = insertedNodes;\n scopeParam.$flushQueue(); // flush once after all insertions\n });\n\n scopeParam.$flushQueue(); // flush leave animation\n break;\n }\n\n case \"textContent\":\n if (animationEnabled) {\n $animate.leave(target).done(() => {\n target.textContent = html;\n $animate.enter(target, target.parentNode);\n scopeParam.$flushQueue();\n });\n\n scopeParam.$flushQueue();\n } else {\n target.textContent = html;\n }\n break;\n\n case \"beforebegin\": {\n const parent = target.parentNode;\n\n if (!parent) break;\n\n nodes.forEach((node) => {\n if (\n animationEnabled &&\n node.nodeType === NodeType._ELEMENT_NODE\n ) {\n $animate.enter(node, parent, target); // insert before target\n } else {\n parent.insertBefore(node, target);\n }\n });\n\n if (animationEnabled) scopeParam.$flushQueue();\n break;\n }\n\n case \"afterbegin\": {\n const { firstChild } = target;\n\n [...nodes].reverse().forEach((node) => {\n if (\n animationEnabled &&\n node.nodeType === NodeType._ELEMENT_NODE\n ) {\n $animate.enter(node, target, firstChild); // insert before first child\n } else {\n target.insertBefore(node, firstChild);\n }\n });\n\n if (animationEnabled) scopeParam.$flushQueue();\n break;\n }\n\n case \"beforeend\": {\n nodes.forEach((node) => {\n if (\n animationEnabled &&\n node.nodeType === NodeType._ELEMENT_NODE\n ) {\n $animate.enter(node, target, null); // append at end\n } else {\n target.appendChild(node);\n }\n });\n\n if (animationEnabled) scopeParam.$flushQueue();\n break;\n }\n\n case \"afterend\": {\n const parent = target.parentNode;\n\n if (!parent) break;\n const { nextSibling } = target;\n\n [...nodes].reverse().forEach((node) => {\n if (\n animationEnabled &&\n node.nodeType === NodeType._ELEMENT_NODE\n ) {\n $animate.enter(node, parent, nextSibling); // insert after target\n } else {\n parent.insertBefore(node, nextSibling);\n }\n });\n\n if (animationEnabled) scopeParam.$flushQueue();\n break;\n }\n\n case \"delete\":\n if (animationEnabled) {\n $animate.leave(target).done(() => {\n target.remove(); // safety: actually remove in case $animate.leave didn't\n scopeParam.$flushQueue();\n });\n scopeParam.$flushQueue();\n } else {\n target.remove();\n }\n break;\n\n case \"none\":\n break;\n\n case \"innerHTML\":\n default:\n if (animationEnabled) {\n if (content && content.nodeType !== NodeType._TEXT_NODE) {\n $animate.leave(content).done(() => {\n content = nodes[0];\n $animate.enter(nodes[0], target);\n scopeParam.$flushQueue();\n });\n scopeParam.$flushQueue();\n } else {\n content = nodes[0];\n\n if (content.nodeType === NodeType._TEXT_NODE) {\n target.replaceChildren(...nodes);\n } else {\n $animate.enter(nodes[0], target);\n scopeParam.$flushQueue();\n }\n }\n } else {\n target.replaceChildren(...nodes);\n }\n break;\n }\n }\n\n element.addEventListener(eventName, async (event) => {\n if (/** @type {HTMLButtonElement} */ (element).disabled) return;\n\n if (tag === \"form\") event.preventDefault();\n const swap = attrs.swap || \"innerHTML\";\n\n const url = attrs[attrName];\n\n if (!url) {\n $log.warn(`${attrName}: no URL specified`);\n\n return;\n }\n\n const handler = (res) => {\n if (isDefined(attrs.loading)) {\n attrs.$set(\"loading\", false);\n }\n\n if (isDefined(attrs.loadingClass)) {\n attrs.$removeClass(attrs.loadingClass);\n }\n\n const html = res.data;\n\n if (\n Http._OK <= res.status &&\n res.status <= Http._MultipleChoices - 1\n ) {\n if (isDefined(attrs.success)) {\n $parse(attrs.success)(scope, { $res: html });\n }\n\n if (isDefined(attrs.stateSuccess)) {\n $state.go(attrs.stateSuccess);\n }\n } else if (\n Http._BadRequest <= res.status &&\n res.status <= Http._ErrorMax\n ) {\n if (isDefined(attrs.error)) {\n $parse(attrs.error)(scope, { $res: html });\n }\n\n if (isDefined(attrs.stateError)) {\n $state.go(attrs.stateError);\n }\n }\n\n if (isObject(html)) {\n if (attrs.target) {\n scope.$eval(`${attrs.target} = ${JSON.stringify(html)}`);\n } else {\n scope.$merge(html);\n }\n } else if (isString(html)) {\n handleSwapResponse(html, swap, scope, attrs, element);\n }\n };\n\n if (isDefined(attrs.delay)) {\n await wait(parseInt(attrs.delay) | 0);\n }\n\n if (throttled) return;\n\n if (isDefined(attrs.throttle)) {\n throttled = true;\n attrs.$set(\"throttled\", true);\n setTimeout(() => {\n attrs.$set(\"throttled\", false);\n throttled = false;\n }, parseInt(attrs.throttle));\n }\n\n if (isDefined(attrs.loading)) {\n attrs.$set(\"loading\", true);\n }\n\n if (isDefined(attrs.loadingClass)) {\n attrs.$addClass(attrs.loadingClass);\n }\n\n if (method === \"post\" || method === \"put\") {\n let data;\n\n const config = {};\n\n if (attrs.enctype) {\n config.headers = {\n \"Content-Type\": attrs.enctype,\n };\n data = toKeyValue(collectFormData(element));\n } else {\n data = collectFormData(element);\n }\n $http[method](url, data, config).then(handler).catch(handler);\n } else {\n if (method === \"get\" && attrs.ngSse) {\n const sseUrl = url;\n\n const config = {\n withCredentials: attrs.withCredentials === \"true\",\n transformMessage: (data) => {\n try {\n return JSON.parse(data);\n } catch {\n return data;\n }\n },\n onOpen: () => {\n $log.info(`${attrName}: SSE connection opened to ${sseUrl}`);\n\n if (isDefined(attrs.loading)) attrs.$set(\"loading\", false);\n\n if (isDefined(attrs.loadingClass))\n attrs.$removeClass(attrs.loadingClass);\n },\n onMessage: (data) => {\n const res = { status: 200, data };\n\n handler(res);\n },\n onError: (err) => {\n $log.error(`${attrName}: SSE error`, err);\n const res = { status: 500, data: err };\n\n handler(res);\n },\n onReconnect: (count) => {\n $log.info(`ngSse: reconnected ${count} time(s)`);\n\n if (attrs.onReconnect)\n $parse(attrs.onReconnect)(scope, { $count: count });\n },\n };\n\n const source = $sse(sseUrl, config);\n\n scope.$on(\"$destroy\", () => {\n $log.info(`${attrName}: closing SSE connection`);\n source.close();\n });\n } else {\n $http[method](url).then(handler).catch(handler);\n }\n }\n });\n\n if (intervalId) {\n scope.$on(\"$destroy\", () => clearInterval(intervalId));\n }\n\n if (eventName === \"load\") {\n element.dispatchEvent(new Event(\"load\"));\n }\n },\n };\n };\n}\n","import { $injectTokens as $t } from \"../../injection-tokens.js\";\nimport { callBackAfterFirst, isDefined, wait } from \"../../shared/utils.js\";\nimport { getEventNameForElement } from \"../http/http.js\";\n\nngWorkerDirective.$inject = [$t.$parse, $t.$log, $t.$exceptionHandler];\n/**\n * Usage: <div ng-worker=\"workerName\" data-params=\"{{ expression }}\" data-on-result=\"callback($result)\"></div>\n *\n * @param {ng.ParseService} $parse\n * @param {ng.LogService} $log\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @returns {ng.Directive}\n */\nexport function ngWorkerDirective($parse, $log, $exceptionHandler) {\n return {\n restrict: \"A\",\n link(scope, element, attrs) {\n const workerName = attrs.ngWorker;\n\n if (!workerName) {\n $log.warn(\"ngWorker: missing worker name\");\n\n return;\n }\n\n /** @type {string} */\n const eventName = attrs.trigger || getEventNameForElement(element);\n\n let throttled = false;\n\n let intervalId;\n\n if (isDefined(attrs.latch)) {\n attrs.$observe(\n \"latch\",\n callBackAfterFirst(() => element.dispatchEvent(new Event(eventName))),\n );\n }\n\n if (isDefined(attrs.interval)) {\n element.dispatchEvent(new Event(eventName));\n intervalId = setInterval(\n () => element.dispatchEvent(new Event(eventName)),\n parseInt(attrs.interval) || 1000,\n );\n }\n\n const worker = createWorkerConnection(workerName, {\n logger: $log,\n err: $exceptionHandler,\n onMessage: (result) => {\n if (isDefined(attrs.dataOnResult)) {\n $parse(attrs.dataOnResult)(scope, { $result: result });\n } else {\n const swap = attrs.swap || \"innerHTML\";\n\n handleSwap(result, swap, element);\n }\n },\n onError: (err) => {\n $log.error(`[ng-worker:${workerName}]`, err);\n\n if (isDefined(attrs.dataOnError)) {\n $parse(attrs.dataOnError)(scope, { $error: err });\n } else {\n element.textContent = \"Error\";\n }\n },\n });\n\n element.addEventListener(eventName, async () => {\n if (element.hasAttribute(\"disabled\")) return;\n\n if (isDefined(attrs.delay)) {\n await wait(parseInt(attrs.delay) || 0);\n }\n\n if (throttled) return;\n\n if (isDefined(attrs.throttle)) {\n throttled = true;\n attrs.$set(\"throttled\", true);\n setTimeout(() => {\n attrs.$set(\"throttled\", false);\n throttled = false;\n }, parseInt(attrs.throttle));\n }\n\n let params;\n\n try {\n params = attrs.params ? scope.$eval(attrs.params) : undefined;\n } catch (err) {\n $log.error(\"ngWorker: failed to evaluate data-params\", err);\n params = undefined;\n }\n\n worker.post(params);\n });\n\n if (intervalId) {\n scope.$on(\"$destroy\", () => clearInterval(intervalId));\n }\n\n if (eventName === \"load\") {\n element.dispatchEvent(new Event(\"load\"));\n }\n },\n };\n}\n\n/**\n * Swap result into DOM based on strategy\n */\nfunction handleSwap(result, swap, element) {\n switch (swap) {\n case \"outerHTML\": {\n const parent = element.parentNode;\n\n if (!parent) return;\n const temp = document.createElement(\"div\");\n\n temp.innerHTML = result;\n parent.replaceChild(temp.firstChild, element);\n break;\n }\n case \"textContent\":\n element.textContent = result;\n break;\n case \"beforebegin\":\n element.insertAdjacentHTML(\"beforebegin\", result);\n break;\n case \"afterbegin\":\n element.insertAdjacentHTML(\"afterbegin\", result);\n break;\n case \"beforeend\":\n element.insertAdjacentHTML(\"beforeend\", result);\n break;\n case \"afterend\":\n element.insertAdjacentHTML(\"afterend\", result);\n break;\n case \"innerHTML\":\n default:\n element.innerHTML = result;\n break;\n }\n}\n\n/**\n * Creates a managed Web Worker connection.\n *\n * @param {string | URL} scriptPath\n * @param {ng.WorkerConfig} [config]\n * @returns {ng.WorkerConnection}\n */\nexport function createWorkerConnection(scriptPath, config) {\n if (!scriptPath) throw new Error(\"Worker script path required\");\n\n const defaults = {\n autoRestart: false,\n autoTerminate: false,\n onMessage() {\n /* empty */\n },\n onError() {\n /* empty */\n },\n transformMessage(data) {\n try {\n return JSON.parse(data);\n } catch {\n return data;\n }\n },\n };\n\n /** @type {ng.WorkerConfig} */\n const cfg = Object.assign({}, defaults, config);\n\n let worker = new Worker(scriptPath, { type: \"module\" });\n\n let terminated = false;\n\n const reconnect = function () {\n if (terminated) return;\n cfg.logger.info(\"Worker: restarting...\");\n worker.terminate();\n worker = new Worker(scriptPath, { type: \"module\" });\n wire(worker);\n };\n\n const wire = (workerParam) => {\n workerParam.onmessage = function (event) {\n let { data } = event;\n\n try {\n data = cfg.transformMessage(data);\n } catch {\n /* no-op */\n }\n cfg.onMessage(data, event); // always provide both args\n };\n\n workerParam.onerror = function (err) {\n cfg.onError(err);\n\n if (cfg.autoRestart) reconnect();\n };\n };\n\n wire(worker);\n\n return {\n post(data) {\n if (terminated) {\n cfg.logger.warn(\"Worker already terminated\");\n }\n\n try {\n worker.postMessage(data);\n } catch (err) {\n cfg.logger.log(\"Worker post failed\", err);\n }\n },\n\n terminate() {\n terminated = true;\n worker.terminate();\n },\n\n restart() {\n if (terminated) cfg.logger.warn(\"Worker cannot restart after terminate\");\n reconnect();\n },\n\n config: cfg,\n };\n}\n","import { $injectTokens as $t } from \"../../../injection-tokens.js\";\nimport { createWorkerConnection } from \"../../../directive/worker/worker.js\";\nimport {\n instantiateWasm,\n isFunction,\n isString,\n isDefined,\n isObject,\n isArray,\n} from \"../../../shared/utils.js\";\nimport { isInjectable } from \"../../../shared/predicates.js\";\nimport { validate, validateRequired } from \"../../../shared/validate.js\";\n\n/**\n * Modules are collections of application configuration information for components:\n * controllers, directives, filters, etc. They provide recipes for the injector\n * to do the actual instantiation. A module itself has no behaviour but only state.\n * A such, it acts as a data structure between the Angular instance and the injector service.\n */\nexport class NgModule {\n /**\n * @param {string} name - Name of the module\n * @param {Array<string>} requires - List of modules which the injector will load before the current module\n * @param {ng.Injectable<any>} [configFn]\n */\n constructor(name, requires, configFn) {\n validate(isString, name, \"name\");\n validate(isArray, requires, \"requires\");\n /**\n * @public\n * Name of the current module.\n * @type {string}\n */\n this.name = name;\n\n /**\n * Array of module names that this module depends on.\n * @type {string[]}\n */\n this._requires = requires;\n\n /**\n * Holds a collection of tasks, required to instantiate an angular component\n * @type {!Array<Array<*>>}\n */\n this._invokeQueue = [];\n\n /** @type {!Array<Array<*>>} */\n this._configBlocks = [];\n\n /** @type {!Array.<ng.Injectable<any>>} */\n this._runBlocks = [];\n\n if (configFn) {\n this.config(configFn);\n }\n\n this._services = [];\n\n this._restDefinitions = [];\n }\n\n /**\n * @param {string} name\n * @param {any} object - Allows undefined\n * @returns {NgModule}\n */\n value(name, object) {\n validate(isString, name, \"name\");\n\n this._invokeQueue.push([$t.$provide, \"value\", [name, object]]);\n\n return this;\n }\n\n /**\n * @param {string} name\n * @param {Object|string|number} object\n * @returns {NgModule}\n */\n constant(name, object) {\n validate(isString, name, \"name\");\n validate(isDefined, object, \"object\");\n\n this._invokeQueue.unshift([$t.$provide, \"constant\", [name, object]]);\n\n return this;\n }\n\n /**\n *\n * @param {ng.Injectable<any>} configFn\n * @returns {NgModule}\n */\n config(configFn) {\n validate(isInjectable, configFn, \"configFn\");\n\n this._configBlocks.push([$t.$injector, \"invoke\", [configFn]]);\n\n return this;\n }\n\n /**\n * @param {ng.Injectable<any>} block\n * @returns {NgModule}\n */\n run(block) {\n validate(isInjectable, block, \"block\");\n\n this._runBlocks.push(block);\n\n return this;\n }\n\n /**\n * @param {string} name\n * @param {ng.Component} options\n * @returns {NgModule}\n */\n component(name, options) {\n validate(isString, name, \"name\");\n validate(isDefined, options, \"object\");\n\n this._invokeQueue.push([$t.$compileProvider, \"component\", [name, options]]);\n\n return this;\n }\n\n /**\n * @param {string} name\n * @param {ng.Injectable<any>} providerFunction\n * @returns {NgModule}\n */\n factory(name, providerFunction) {\n validate(isString, name, \"name\");\n validateRequired(providerFunction, \"providerFunction\");\n this._invokeQueue.push([$t.$provide, \"factory\", [name, providerFunction]]);\n\n return this;\n }\n\n /**\n * @param {string} name\n * @param {ng.Injectable<any>} serviceFunction\n * @returns {NgModule}\n */\n service(name, serviceFunction) {\n validate(isString, name, \"name\");\n validateRequired(serviceFunction, \"serviceFunction\");\n this._services.push(name);\n this._invokeQueue.push([$t.$provide, \"service\", [name, serviceFunction]]);\n\n return this;\n }\n\n /**\n * @param {string} name\n * @param {ng.Injectable<any>} providerType\n * @returns {NgModule}\n */\n provider(name, providerType) {\n validate(isString, name, \"name\");\n validateRequired(providerType, \"providerType\");\n this._invokeQueue.push([$t.$provide, \"provider\", [name, providerType]]);\n\n return this;\n }\n\n /**\n * @param {string} name\n * @param {ng.Injectable<any>} decorFn\n * @returns {NgModule}\n */\n decorator(name, decorFn) {\n validate(isString, name, \"name\");\n validateRequired(decorFn, \"decorFn\");\n this._configBlocks.push([$t.$provide, \"decorator\", [name, decorFn]]);\n\n return this;\n }\n\n /**\n * @param {string} name\n * @param {ng.Injectable<any>} directiveFactory\n * @returns {NgModule}\n */\n directive(name, directiveFactory) {\n validate(isString, name, \"name\");\n validateRequired(directiveFactory, \"directiveFactory\");\n this._invokeQueue.push([\n $t.$compileProvider,\n \"directive\",\n [name, directiveFactory],\n ]);\n\n return this;\n }\n\n /**\n * @param {string} name\n * @param {ng.Injectable<any>} animationFactory\n * @returns {NgModule}\n */\n animation(name, animationFactory) {\n validate(isString, name, \"name\");\n validateRequired(animationFactory, \"animationFactory\");\n this._invokeQueue.push([\n $t.$animateProvider,\n \"register\",\n [name, animationFactory],\n ]);\n\n return this;\n }\n\n /**\n * @param {string} name\n * @param {ng.FilterFactory} filterFn\n * @return {NgModule}\n */\n filter(name, filterFn) {\n validate(isString, name, \"name\");\n validate(isFunction, filterFn, `filterFn`);\n this._invokeQueue.push([$t.$filterProvider, \"register\", [name, filterFn]]);\n\n return this;\n }\n\n /**\n * The $controller service is used by Angular to create new controllers.\n * This provider allows controller registration via the register method.\n *\n * @param {string} name Controller name\n * @param {ng.Injectable<ng.ControllerConstructor>} ctlFn Controller constructor fn (optionally decorated with DI annotations in the array notation)\n * @returns {NgModule}\n */\n controller(name, ctlFn) {\n validate(isString, name, \"name\");\n validateRequired(ctlFn, `fictlFnlterFn`);\n this._invokeQueue.push([$t.$controllerProvider, \"register\", [name, ctlFn]]);\n\n return this;\n }\n\n /**\n * Register a named WebAssembly module that will be instantiated via $provide.\n *\n * @param {string} name - The injectable name used to access the instantiated WebAssembly module.\n *\n * @param {string} src - URL of the `.wasm` file to fetch and instantiate.\n *\n * @param {Object<string, any>} [imports] WebAssembly import object, passed to `WebAssembly.instantiate` or `WebAssembly.instantiateStreaming`.\n *\n * @param {Object<string, any>} [opts] - Configuration object.\n *\n * Supported keys:\n * - **raw**: `boolean`\n * - `false` (default): the injectable resolves to `instance.exports`\n * (ideal for plain WASM modules).\n * - `true`: the injectable resolves to the full instantiation result:\n * `{ instance, exports, module }`\n * (required for runtimes such as Go, Emscripten, wasm-bindgen, etc).\n *\n * @returns {NgModule}\n */\n wasm(name, src, imports = {}, opts = {}) {\n validate(isString, name, \"name\");\n validate(isString, src, \"src\");\n const raw = !!opts.raw;\n\n this._invokeQueue.push([\n $t.$provide,\n \"provider\",\n [\n name,\n class {\n $get() {\n return instantiateWasm(src, imports).then((result) =>\n raw ? result : result.exports,\n );\n }\n },\n ],\n ]);\n\n return this;\n }\n\n /**\n * Register a named worker that will be instantiated via $provide.\n *\n * @param {string} name\n * @param {string | URL} scriptPath\n * @param {ng.WorkerConfig} [config]\n * @returns {NgModule}\n */\n worker(name, scriptPath, config) {\n validate(isString, name, \"name\");\n validate(isString, scriptPath, \"scriptPath\");\n this._invokeQueue.push([\n $t.$provide,\n \"provider\",\n [\n name,\n class {\n $get = () => createWorkerConnection(scriptPath, config);\n },\n ],\n ]);\n\n return this;\n }\n\n /**\n * @param {string} name\n * @param {Function|Object} ctor - A regular function, an arrow function or an object\n * @param {ng.StorageType} type\n * @param {ng.StorageBackend} [backendOrConfig]\n * @returns {NgModule}\n */\n store(name, ctor, type, backendOrConfig) {\n validate(isString, name, \"name\");\n validateRequired(ctor, \"ctor\");\n this._invokeQueue.push([\n $t.$provide,\n \"store\",\n [name, isObject(ctor) ? () => ctor : ctor, type, backendOrConfig],\n ]);\n\n return this;\n }\n\n /**\n * @template T, ID\n * Register a REST resource during module configuration.\n * @param {string} name - Service name\n * @param {string} url - Base URL or URI template\n * @param {ng.EntityClass<T>} entityClass - Optional constructor for mapping JSON\n * @param {Object=} options - Optional RestService options (interceptors, etc)\n * @returns {NgModule}\n */\n rest(name, url, entityClass, options = {}) {\n validate(isString, name, \"name\");\n validate(isString, url, \"url\");\n validate(isFunction, entityClass, \"entityClass\");\n const def = { name, url, entityClass, options };\n\n this._restDefinitions.push(def);\n\n // push provider/factory to invokeQueue\n this._invokeQueue.push([\n $t.$provide,\n \"factory\",\n [\n name,\n [\n $t.$rest,\n /** @param {(baseUrl:string, entityClass?:Function, options?:object) => ng.RestService<T, ID>} $rest */ (\n $rest,\n ) => $rest(url, entityClass, options),\n ],\n ],\n ]);\n\n return this;\n }\n}\n","import { isArray, isString } from \"./utils.js\";\nimport { createElementFromHTML } from \"./dom.js\";\nimport { NodeType } from \"./node.js\";\n\n/**\n * A type-safe wrapper around a DOM Node, HTMLElement, HTML string, NodeList, or an array of Nodes.\n * Provides guarantees around presence and access.\n */\nexport class NodeRef {\n static $nonscope = true;\n /**\n * @param {Node | Element | string | NodeList | Node[]} element - The DOM node(s) or HTML string to wrap.\n * @throws {Error} If the argument is invalid or cannot be wrapped properly.\n */\n constructor(element) {\n /** @private @type {Node | ChildNode | null} */\n this._node = null;\n\n /** @private @type {Element | undefined} */\n this._element = undefined;\n\n /** @private @type {Array<Node>} a stable list on nodes */\n this._nodes = undefined;\n\n /** @type {boolean} */\n this._isList = false;\n\n // Handle HTML string\n if (isString(element)) {\n const res = createElementFromHTML(/** @type {string} */ (element));\n\n switch (true) {\n case res instanceof Element:\n this.element = res;\n break;\n case res instanceof Node:\n this.node = res;\n break;\n }\n }\n\n // Handle NodeList\n else if (element instanceof NodeList) {\n if (element.length === 1) {\n this.node = element[0];\n } else {\n this._nodes = Array.from(element);\n this._isList = true;\n }\n }\n\n // Handle single Element\n else if (element instanceof Element) {\n this.element = /** @type {Element} */ element;\n }\n\n // Handle single Node\n else if (element instanceof Node) {\n this._node = element;\n }\n\n // Handle array of elements\n else if (isArray(element)) {\n if (element.length === 1) {\n this.node = /** @type {Node} */ (element[0]);\n } else {\n this.nodes = /** @type {Node[]} */ (element);\n }\n } else {\n throw new Error(\"Invalid element passed to NodeRef\");\n }\n }\n\n /** @returns {Element} */\n get element() {\n return this._element;\n }\n\n /** @param {Element} el */\n set element(el) {\n this._element = el;\n this._nodes = undefined;\n this._isList = false;\n }\n\n /** @returns {Node | ChildNode} */\n get node() {\n return this._node || this._element;\n }\n\n /** @param {Node | ChildNode} node */\n set node(node) {\n this._node = node;\n\n if (node.nodeType === NodeType._ELEMENT_NODE) {\n this._element = /** @type {Element} */ (node);\n } else {\n this._element = undefined;\n }\n }\n\n /** @param {Array<Node>} nodes */\n set nodes(nodes) {\n this._nodes = nodes;\n this._isList = true;\n }\n\n /** @returns {Array<Node>} */\n get nodes() {\n return this._nodes;\n }\n\n /** @returns {NodeList|Node[]} */\n get nodelist() {\n if (this._nodes.length === 0) return [];\n\n if (this._nodes[0].parentElement)\n return this._nodes[0].parentElement.childNodes;\n const fragment = document.createDocumentFragment();\n\n this._nodes.forEach((el) => fragment.appendChild(el));\n\n return fragment.childNodes;\n }\n\n /** @returns {Element | Node | ChildNode | NodeList | Node[]} */\n get dom() {\n if (this._isList) return this.nodelist;\n else return this.node;\n }\n\n /** @returns {number} */\n get size() {\n return this._isList ? this._nodes.length : 1;\n }\n\n /** @returns {Element | Node | ChildNode} */\n _getAny() {\n if (this._isList) {\n return this._nodes[0];\n } else {\n return this._element || this._node;\n }\n }\n\n /** @returns {Element | Array<Node> | Node | ChildNode} */\n _getAll() {\n if (this._isList) {\n return this._nodes;\n } else {\n return this._element || this._node;\n }\n }\n\n /** @returns {Array<Element> | Array<Node>} */\n _collection() {\n if (this._isList) {\n return Array.from(this._nodes);\n } else {\n return [this._element || this._node];\n }\n }\n\n /**\n * @param {number} index\n * @returns {Element | Node | ChildNode}\n */\n _getIndex(index) {\n if (this._isList) {\n return this._nodes[index];\n } else {\n return this.node;\n }\n }\n\n /**\n * @param {number} index\n * @param {Element | Node | ChildNode} node\n */\n _setIndex(index, node) {\n if (this._isList) {\n this._nodes[index] = node;\n } else {\n this.node = node;\n }\n }\n\n /**\n * @returns {NodeRef}\n */\n _clone() {\n const cloned = this._isList\n ? this.nodes.map((el) => el.cloneNode(true))\n : this.node.cloneNode(true);\n\n return new NodeRef(cloned);\n }\n\n _isElement() {\n return this._element !== undefined;\n }\n}\n","import {\n assertArgFn,\n assertNotHasOwnProperty,\n entries,\n isArray,\n isFunction,\n isObject,\n isString,\n minErr,\n} from \"../../shared/utils.js\";\n\nconst $controllerMinErr = minErr(\"$controller\");\n\nconst CNTRL_REG = /^(\\S+)(\\s+as\\s+([\\w$]+))?$/;\n\nexport function identifierForController(controller, ident) {\n if (ident && isString(ident)) return ident;\n\n if (isString(controller)) {\n const match = CNTRL_REG.exec(controller);\n\n if (match) return match[3];\n }\n\n return undefined;\n}\n\n/**\n * The {@link ng.$controller $controller service} is used by AngularTS to create new\n * controllers.\n *\n * This provider allows controller registration via the\n * {@link ng.$controllerProvider#register register} method.\n */\nexport class ControllerProvider {\n constructor() {\n /**\n * @type {Map<string, Function|Object>}\n * @private\n */\n this.controllers = new Map();\n }\n\n /**\n * Check if a controller with a given name exists.\n *\n * @param {string} name Controller name to check.\n * @returns {boolean} True if the controller exists, false otherwise.\n */\n has(name) {\n return this.controllers.has(name);\n }\n\n /**\n * Register a controller.\n *\n * @param {string|Object} name Controller name, or an object map of controllers where the keys are\n * the names and the values are the constructors.\n * @param {Function|Array} constructor Controller constructor function (optionally decorated with DI\n * annotations in the array notation).\n */\n register(name, constructor) {\n assertNotHasOwnProperty(name, \"controller\");\n\n if (isObject(name)) {\n entries(name).forEach(([key, value]) => {\n this.controllers.set(key, value);\n });\n } else {\n this.controllers.set(name, constructor);\n }\n }\n\n /**\n * $get method for dependency injection.\n */\n $get = [\n \"$injector\",\n\n /**\n * @param {ng.InjectorService} $injector\n * @returns {import(\"./interface.ts\").ControllerService} A service function that creates controllers.\n */\n ($injector) => {\n return (expression, locals, later, ident) => {\n let instance;\n\n let match;\n\n let constructor;\n\n let identifier = ident && isString(ident) ? ident : null;\n\n later = later === true;\n\n if (isString(expression)) {\n match = /** @type {string} */ (expression).match(CNTRL_REG);\n\n if (!match) {\n throw $controllerMinErr(\n \"ctrlfmt\",\n \"Badly formed controller string '{0}'. Must match `__name__ as __id__` or `__name__`.\",\n expression,\n );\n }\n constructor = match[1];\n identifier = identifier || match[3];\n expression = this.controllers.get(constructor);\n\n if (!expression) {\n throw $controllerMinErr(\n \"ctrlreg\",\n \"The controller with the name '{0}' is not registered.\",\n constructor,\n );\n }\n\n assertArgFn(expression, constructor, true);\n }\n\n if (later) {\n const controllerPrototype = (\n isArray(expression) ? expression[expression.length - 1] : expression\n ).prototype;\n\n instance = Object.create(controllerPrototype || null);\n\n if (identifier) {\n instance.$controllerIdentifier = identifier;\n this.addIdentifier(\n locals,\n identifier,\n instance,\n constructor || /** @type {any} */ (expression).name,\n );\n }\n\n if (instance?.constructor?.$scopename) {\n locals.$scope.$scopename = instance.constructor.$scopename;\n }\n\n return function () {\n const result = $injector.invoke(\n expression,\n instance,\n locals,\n constructor,\n );\n\n if (\n result !== instance &&\n (isObject(result) || isFunction(result))\n ) {\n instance = result;\n\n if (identifier) {\n instance.$controllerIdentifier = identifier;\n this.addIdentifier(\n locals,\n identifier,\n instance,\n constructor || /** @type {any} */ (expression).name,\n );\n }\n }\n\n return instance;\n }.bind(this, { instance, identifier });\n }\n\n instance = $injector.instantiate(\n /** @type {any} */ (expression),\n locals,\n constructor,\n );\n\n if (identifier) {\n this.addIdentifier(\n locals,\n identifier,\n instance,\n constructor || /** @type {any} */ (expression).name,\n );\n }\n\n return instance;\n };\n },\n ];\n\n /**\n * Adds an identifier to the controller instance in the given locals' scope.\n *\n * @param {Object} locals The locals object containing the scope.\n * @param {string} identifier The identifier to assign.\n * @param {Object} instance The controller instance.\n * @param {string} name The name of the controller.\n */\n addIdentifier(locals, identifier, instance, name) {\n if (!(locals && isObject(locals.$scope))) {\n throw minErr(\"$controller\")(\n \"noscp\",\n \"Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.\",\n name,\n identifier,\n );\n }\n locals.$scope[identifier] = instance;\n locals.$scope.$controllerIdentifier = identifier;\n }\n}\n","import {\n urlIsSameOrigin,\n urlIsSameOriginAsBaseUrl,\n urlResolve,\n} from \"../../shared/url-utils/url-utils.js\";\nimport {\n entries,\n hasOwn,\n isFunction,\n isRegExp,\n isString,\n isUndefined,\n minErr,\n shallowCopy,\n} from \"../../shared/utils.js\";\n\nimport { snakeToCamel } from \"../../shared/dom.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n\nconst $sceMinErr = minErr(\"$sce\");\n\nexport const SCE_CONTEXTS = {\n // HTML is used when there's HTML rendered (e.g. ng-bind-html, iframe srcdoc binding).\n HTML: \"html\",\n\n // Style statements or stylesheets. Currently unused in AngularTS.\n CSS: \"css\",\n\n // An URL used in a context where it refers to the source of media, which are not expected to be run\n // as scripts, such as an image, audio, video, etc.\n MEDIA_URL: \"mediaUrl\",\n\n // An URL used in a context where it does not refer to a resource that loads code.\n // A value that can be trusted as a URL can also trusted as a MEDIA_URL.\n URL: \"url\",\n\n // RESOURCE_URL is a subtype of URL used where the referred-to resource could be interpreted as\n // code. (e.g. ng-include, script src binding, templateUrl)\n // A value that can be trusted as a RESOURCE_URL, can also trusted as a URL and a MEDIA_URL.\n RESOURCE_URL: \"resourceUrl\",\n\n // Script. Currently unused in AngularTS.\n JS: \"js\",\n};\n\n// Copied from:\n// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021\n// Prereq: s is a string.\nexport function escapeForRegexp(str) {\n return str.replace(/([-()[\\]{}+?*.$^|,:#<!\\\\])/g, \"\\\\$1\");\n}\n\nexport function adjustMatcher(matcher) {\n if (matcher === \"self\") {\n return matcher;\n }\n\n if (isString(matcher)) {\n // Strings match exactly except for 2 wildcards - '*' and '**'.\n // '*' matches any character except those from the set ':/.?&'.\n // '**' matches any character (like .* in a RegExp).\n // More than 2 *'s raises an error as it's ill defined.\n if (matcher.indexOf(\"***\") > -1) {\n throw $sceMinErr(\n \"iwcard\",\n \"Illegal sequence *** in string matcher. String: {0}\",\n matcher,\n );\n }\n matcher = escapeForRegexp(matcher)\n .replace(/\\\\\\*\\\\\\*/g, \".*\")\n .replace(/\\\\\\*/g, \"[^:/.?&;]*\");\n\n return new RegExp(`^${matcher}$`);\n }\n\n if (isRegExp(matcher)) {\n // The only other type of matcher allowed is a Regexp.\n // Match entire URL / disallow partial matches.\n // Flags are reset (i.e. no global, ignoreCase or multiline)\n return new RegExp(`^${matcher.source}$`);\n }\n throw $sceMinErr(\n \"imatcher\",\n 'Matchers may only be \"self\", string patterns or RegExp objects',\n );\n}\n\n/**\n * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict\n * Contextual Escaping (SCE)} services to AngularTS.\n *\n * For an overview of this service and the functionality it provides in AngularTS, see the main\n * page for {@link ng.$sce SCE}. The current page is targeted for developers who need to alter how\n * SCE works in their application, which shouldn't be needed in most cases.\n *\n * <div class=\"alert alert-danger\">\n * AngularTS strongly relies on contextual escaping for the security of bindings: disabling or\n * modifying this might cause cross site scripting (XSS) vulnerabilities. For libraries owners,\n * changes to this service will also influence users, so be extra careful and document your changes.\n * </div>\n *\n * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of\n * the `$sce` service to customize the way Strict Contextual Escaping works in AngularTS. This is\n * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to\n * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things\n * work because `$sce` delegates to `$sceDelegate` for these operations.\n *\n * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service.\n *\n * The default instance of `$sceDelegate` should work out of the box with little pain. While you\n * can override it completely to change the behavior of `$sce`, the common case would\n * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting\n * your own trusted and banned resource lists for trusting URLs used for loading AngularTS resources\n * such as templates. Refer {@link ng.$sceDelegateProvider#trustedResourceUrlList\n * $sceDelegateProvider.trustedResourceUrlList} and {@link\n * ng.$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList}\n */\n\n/**\n *\n * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate\n * $sceDelegate service}, used as a delegate for {@link ng.$sce Strict Contextual Escaping (SCE)}.\n *\n * The `$sceDelegateProvider` allows one to get/set the `trustedResourceUrlList` and\n * `bannedResourceUrlList` used to ensure that the URLs used for sourcing AngularTS templates and\n * other script-running URLs are safe (all places that use the `$sce.RESOURCE_URL` context). See\n * {@link ng.$sceDelegateProvider#trustedResourceUrlList\n * $sceDelegateProvider.trustedResourceUrlList} and\n * {@link ng.$sceDelegateProvider#bannedResourceUrlList $sceDelegateProvider.bannedResourceUrlList},\n *\n * For the general details about this service in AngularTS, read the main page for {@link ng.$sce\n * Strict Contextual Escaping (SCE)}.\n *\n * **Example**: Consider the following case. <a name=\"example\"></a>\n *\n * - your app is hosted at url `http://myapp.example.com/`\n * - but some of your templates are hosted on other domains you control such as\n * `http://srv01.assets.example.com/`, `http://srv02.assets.example.com/`, etc.\n * - and you have an open redirect at `http://myapp.example.com/clickThru?...`.\n *\n * Here is what a secure configuration for this scenario might look like:\n *\n * ```\n * angular.module('myApp', []).config(function($sceDelegateProvider) {\n * $sceDelegateProvider.trustedResourceUrlList([\n * // Allow same origin resource loads.\n * 'self',\n * // Allow loading from our assets domain. Notice the difference between * and **.\n * 'http://srv*.assets.example.com/**'\n * ]);\n *\n * // The banned resource URL list overrides the trusted resource URL list so the open redirect\n * // here is blocked.\n * $sceDelegateProvider.bannedResourceUrlList([\n * 'http://myapp.example.com/clickThru**'\n * ]);\n * });\n * ```\n * Note that an empty trusted resource URL list will block every resource URL from being loaded, and will require\n * you to manually mark each one as trusted with `$sce.trustAsResourceUrl`. However, templates\n * requested by {@link ng.$templateRequest $templateRequest} that are present in\n * {@link ng.$templateCache $templateCache} will not go through this check. If you have a mechanism\n * to populate your templates in that cache at config time, then it is a good idea to remove 'self'\n * from the trusted resource URL lsit. This helps to mitigate the security impact of certain types\n * of issues, like for instance attacker-controlled `ng-includes`.\n */\nexport class SceDelegateProvider {\n constructor() {\n // Resource URLs can also be trusted by policy.\n let trustedResourceUrlList = [\"self\"];\n\n let bannedResourceUrlList = [];\n\n /**\n *\n * @param {Array=} value When provided, replaces the trustedResourceUrlList with\n * the value provided. This must be an array or null. A snapshot of this array is used so\n * further changes to the array are ignored.\n * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items\n * allowed in this array.\n *\n * @return {Array} The currently set trusted resource URL array.\n *\n * @description\n * Sets/Gets the list trusted of resource URLs.\n *\n * The **default value** when no `trustedResourceUrlList` has been explicitly set is `['self']`\n * allowing only same origin resource requests.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** the default `trustedResourceUrlList` of 'self' is not recommended if your app shares\n * its origin with other apps! It is a good idea to limit it to only your application's directory.\n * </div>\n */\n this.trustedResourceUrlList = function (value) {\n if (arguments.length) {\n trustedResourceUrlList = value.map(adjustMatcher);\n }\n\n return trustedResourceUrlList;\n };\n\n /**\n *\n * @param {Array=} bannedResourceUrlList When provided, replaces the `bannedResourceUrlList` with\n * the value provided. This must be an array or null. A snapshot of this array is used so\n * further changes to the array are ignored.</p><p>\n * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items\n * allowed in this array.</p><p>\n * The typical usage for the `bannedResourceUrlList` is to **block\n * [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as\n * these would otherwise be trusted but actually return content from the redirected domain.\n * </p><p>\n * Finally, **the banned resource URL list overrides the trusted resource URL list** and has\n * the final say.\n *\n * @return {Array} The currently set `bannedResourceUrlList` array.\n *\n * @description\n * Sets/Gets the `bannedResourceUrlList` of trusted resource URLs.\n *\n * The **default value** when no trusted resource URL list has been explicitly set is the empty\n * array (i.e. there is no `bannedResourceUrlList`.)\n */\n this.bannedResourceUrlList = function (value) {\n if (arguments.length) {\n bannedResourceUrlList = value.map(adjustMatcher);\n }\n\n return bannedResourceUrlList;\n };\n\n this.$get = [\n $t.$injector,\n $t.$$sanitizeUri,\n $t.$exceptionHandler,\n /**\n *\n * @param {ng.InjectorService} $injector\n * @param {import(\"../../core/sanitize/interface.ts\").SanitizerFn} $$sanitizeUri\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @returns\n */\n function ($injector, $$sanitizeUri, $exceptionHandler) {\n let htmlSanitizer = function () {\n $exceptionHandler(\n $sceMinErr(\n \"unsafe\",\n \"Attempting to use an unsafe value in a safe context.\",\n ),\n );\n };\n\n if ($injector.has(\"$sanitize\")) {\n htmlSanitizer = $injector.get(\"$sanitize\");\n }\n\n /**\n * @param {string|RegExp} matcher\n * @param {import(\"../../shared/url-utils/interface.ts\").ParsedUrl} parsedUrl\n * @return {boolean}\n */\n function matchUrl(matcher, parsedUrl) {\n if (matcher === \"self\") {\n return (\n urlIsSameOrigin(parsedUrl) || urlIsSameOriginAsBaseUrl(parsedUrl)\n );\n }\n\n // definitely a regex. See adjustMatchers()\n return !!(/** @type {RegExp} */ (matcher).exec(parsedUrl.href));\n }\n\n function isResourceUrlAllowedByPolicy(url) {\n const parsedUrl = urlResolve(url.toString());\n\n let i,\n j,\n allowed = false;\n\n // Ensure that at least one item from the trusted resource URL list allows this url.\n for (i = 0, j = trustedResourceUrlList.length; i < j; i++) {\n if (matchUrl(trustedResourceUrlList[i], parsedUrl)) {\n allowed = true;\n break;\n }\n }\n\n if (allowed) {\n // Ensure that no item from the banned resource URL list has blocked this url.\n for (i = 0, j = bannedResourceUrlList.length; i < j; i++) {\n if (matchUrl(bannedResourceUrlList[i], parsedUrl)) {\n allowed = false;\n break;\n }\n }\n }\n\n return allowed;\n }\n\n function generateHolderType(Base) {\n const holderType = function TrustedValueHolderType(trustedValue) {\n this.$$unwrapTrustedValue = function () {\n return trustedValue;\n };\n };\n\n if (Base) {\n holderType.prototype = new Base();\n }\n holderType.prototype.valueOf = function sceValueOf() {\n return this.$$unwrapTrustedValue();\n };\n holderType.prototype.toString = function sceToString() {\n return this.$$unwrapTrustedValue().toString();\n };\n\n return holderType;\n }\n\n const trustedValueHolderBase = generateHolderType();\n\n const byType = {};\n\n byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase);\n byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase);\n byType[SCE_CONTEXTS.MEDIA_URL] = generateHolderType(\n trustedValueHolderBase,\n );\n byType[SCE_CONTEXTS.URL] = generateHolderType(\n byType[SCE_CONTEXTS.MEDIA_URL],\n );\n byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase);\n byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(\n byType[SCE_CONTEXTS.URL],\n );\n\n /**\n * Returns a trusted representation of the parameter for the specified context. This trusted\n * object will later on be used as-is, without any security check, by bindings or directives\n * that require this security context.\n * For instance, marking a string as trusted for the `$sce.HTML` context will entirely bypass\n * the potential `$sanitize` call in corresponding `$sce.HTML` bindings or directives, such as\n * `ng-bind-html`. Note that in most cases you won't need to call this function: if you have the\n * sanitizer loaded, passing the value itself will render all the HTML that does not pose a\n * security risk.\n *\n * See {@link ng.$sceDelegate#getTrusted getTrusted} for the function that will consume those\n * trusted values, and {@link ng.$sce $sce} for general documentation about strict contextual\n * escaping.\n *\n * @param {string} type The context in which this value is safe for use, e.g. `$sce.URL`,\n * `$sce.RESOURCE_URL`, `$sce.HTML`, `$sce.JS` or `$sce.CSS`.\n *\n * @param {*} trustedValue The value that should be considered trusted.\n * @return {*} A trusted representation of value, that can be used in the given context.\n */\n function trustAs(type, trustedValue) {\n const Constructor = hasOwn(byType, type) ? byType[type] : null;\n\n if (!Constructor) {\n $exceptionHandler(\n $sceMinErr(\n \"icontext\",\n \"Attempted to trust a value in invalid context. Context: {0}; Value: {1}\",\n type,\n trustedValue,\n ),\n );\n\n return undefined;\n }\n\n if (\n trustedValue === null ||\n isUndefined(trustedValue) ||\n trustedValue === \"\"\n ) {\n return trustedValue;\n }\n\n // All the current contexts in SCE_CONTEXTS happen to be strings. In order to avoid trusting\n // mutable objects, we ensure here that the value passed in is actually a string.\n if (typeof trustedValue !== \"string\") {\n $exceptionHandler(\n $sceMinErr(\n \"itype\",\n \"Attempted to trust a non-string value in a content requiring a string: Context: {0}\",\n type,\n ),\n );\n\n return undefined;\n }\n\n const tst = new Constructor(trustedValue);\n\n return tst;\n }\n\n /**\n * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#trustAs\n * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link\n * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.\n *\n * If the passed parameter is not a value that had been returned by {@link\n * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}, it must be returned as-is.\n *\n * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}\n * call or anything else.\n * @return {*} The `value` that was originally provided to {@link ng.$sceDelegate#trustAs\n * `$sceDelegate.trustAs`} if `value` is the result of such a call. Otherwise, returns\n * `value` unchanged.\n */\n function valueOf(maybeTrusted) {\n if (maybeTrusted instanceof trustedValueHolderBase) {\n return maybeTrusted.$$unwrapTrustedValue();\n }\n\n return maybeTrusted;\n }\n\n /**\n * @description\n * Given an object and a security context in which to assign it, returns a value that's safe to\n * use in this context, which was represented by the parameter. To do so, this function either\n * unwraps the safe type it has been given (for instance, a {@link ng.$sceDelegate#trustAs\n * `$sceDelegate.trustAs`} result), or it might try to sanitize the value given, depending on\n * the context and sanitizer availablility.\n *\n * The contexts that can be sanitized are $sce.MEDIA_URL, $sce.URL and $sce.HTML. The first two are available\n * by default, and the third one relies on the `$sanitize` service (which may be loaded through\n * the `ngSanitize` module). Furthermore, for $sce.RESOURCE_URL context, a plain string may be\n * accepted if the resource url policy defined by {@link ng.$sceDelegateProvider#trustedResourceUrlList\n * `$sceDelegateProvider.trustedResourceUrlList`} and {@link ng.$sceDelegateProvider#bannedResourceUrlList\n * `$sceDelegateProvider.bannedResourceUrlList`} accepts that resource.\n *\n * This function will throw if the safe type isn't appropriate for this context, or if the\n * value given cannot be accepted in the context (which might be caused by sanitization not\n * being available, or the value not being recognized as safe).\n *\n * <div class=\"alert alert-danger\">\n * Disabling auto-escaping is extremely dangerous, it usually creates a Cross Site Scripting\n * (XSS) vulnerability in your application.\n * </div>\n *\n * @param {string} type The context in which this value is to be used (such as `$sce.HTML`).\n * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs\n * `$sceDelegate.trustAs`} call, or anything else (which will not be considered trusted.)\n * @return {*} A version of the value that's safe to use in the given context, or throws an\n * exception if this is impossible.\n */\n function getTrusted(type, maybeTrusted) {\n if (\n maybeTrusted === null ||\n isUndefined(maybeTrusted) ||\n maybeTrusted === \"\"\n ) {\n return maybeTrusted;\n }\n const constructor = hasOwn(byType, type) ? byType[type] : null;\n\n // If maybeTrusted is a trusted class instance or subclass instance, then unwrap and return\n // as-is.\n if (constructor && maybeTrusted instanceof constructor) {\n return maybeTrusted.$$unwrapTrustedValue();\n }\n\n // If maybeTrusted is a trusted class instance but not of the correct trusted type\n // then unwrap it and allow it to pass through to the rest of the checks\n if (isFunction(maybeTrusted.$$unwrapTrustedValue)) {\n maybeTrusted = maybeTrusted.$$unwrapTrustedValue();\n }\n\n // If we get here, then we will either sanitize the value or throw an exception.\n if (type === SCE_CONTEXTS.MEDIA_URL || type === SCE_CONTEXTS.URL) {\n // we attempt to sanitize non-resource URLs\n return $$sanitizeUri(\n maybeTrusted.toString(),\n type === SCE_CONTEXTS.MEDIA_URL,\n );\n }\n\n if (type === SCE_CONTEXTS.RESOURCE_URL) {\n if (isResourceUrlAllowedByPolicy(maybeTrusted)) {\n return maybeTrusted;\n }\n $exceptionHandler(\n $sceMinErr(\n \"insecurl\",\n \"Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}\",\n maybeTrusted.toString(),\n ),\n );\n\n return undefined;\n } else if (type === SCE_CONTEXTS.HTML) {\n // htmlSanitizer throws its own error when no sanitizer is available.\n return htmlSanitizer();\n }\n\n // Default error when the $sce service has no way to make the input safe.\n return $exceptionHandler(\n $sceMinErr(\n \"unsafe\",\n \"Attempting to use an unsafe value in a safe context.\",\n ),\n );\n }\n\n return { trustAs, getTrusted, valueOf };\n },\n ];\n }\n}\n\nexport function SceProvider() {\n let enabled = true;\n\n /**\n * @param {boolean=} value If provided, then enables/disables SCE application-wide.\n * @return {boolean} True if SCE is enabled, false otherwise.\n *\n * @description\n * Enables/disables SCE and returns the current value.\n */\n this.enabled = function (value) {\n if (arguments.length) {\n enabled = !!value;\n }\n\n return enabled;\n };\n\n this.$get = [\n $t.$parse,\n $t.$sceDelegate,\n /**\n *\n * @param {ng.ParseService} $parse\n * @param $sceDelegate\n * @return {*}\n */\n ($parse, $sceDelegate) => {\n const sce = shallowCopy(SCE_CONTEXTS);\n\n /**\n * @return {Boolean} True if SCE is enabled, false otherwise. If you want to set the value, you\n * have to do it at module config time on {@link ng.$sceProvider $sceProvider}.\n *\n * @description\n * Returns a boolean indicating if SCE is enabled.\n */\n sce.isEnabled = function () {\n return enabled;\n };\n sce.trustAs = $sceDelegate.trustAs;\n sce.getTrusted = $sceDelegate.getTrusted;\n sce.valueOf = $sceDelegate.valueOf;\n\n if (!enabled) {\n sce.trustAs = sce.getTrusted = function (type, value) {\n return value;\n };\n sce.valueOf = (v) => v;\n }\n\n /**\n * Converts AngularTS {@link guide/expression expression} into a function. This is like {@link\n * ng.$parse $parse} and is identical when the expression is a literal constant. Otherwise, it\n * wraps the expression in a call to {@link ng.$sce#getTrusted $sce.getTrusted(*type*,\n * *result*)}\n *\n * @param {string} type The SCE context in which this result will be used.\n * @param {string} expr String expression to compile.\n * @return {import(\"../../core/parse/interface.ts\").CompiledExpression} A function which represents the compiled expression:\n *\n * * `context` – `{object}` – an object against which any expressions embedded in the\n * strings are evaluated against (typically a scope object).\n * * `locals` – `{object=}` – local variables context object, useful for overriding values\n * in `context`.\n */\n sce.parseAs = (type, expr) => {\n const parsed = $parse(expr);\n\n if (parsed.literal && parsed.constant) {\n return parsed;\n }\n\n return $parse(expr, (value) => sce.getTrusted(type, value));\n };\n\n /**\n * Delegates to {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}. As such, returns a\n * wrapped object that represents your value, and the trust you have in its safety for the given\n * context. AngularTS can then use that value as-is in bindings of the specified secure context.\n * This is used in bindings for `ng-bind-html`, `ng-include`, and most `src` attribute\n * interpolations. See {@link ng.$sce $sce} for strict contextual escaping.\n *\n * @param {string} type The context in which this value is safe for use, e.g. `$sce.URL`,\n * `$sce.RESOURCE_URL`, `$sce.HTML`, `$sce.JS` or `$sce.CSS`.\n *\n * @param {*} value The value that that should be considered trusted.\n * @return {*} A wrapped version of value that can be used as a trusted variant of your `value`\n * in the context you specified.\n */\n\n /**\n * Shorthand method. `$sce.trustAsHtml(value)` →\n * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.HTML, value)`}\n *\n * @param {*} value The value to mark as trusted for `$sce.HTML` context.\n * @return {*} A wrapped version of value that can be used as a trusted variant of your `value`\n * in `$sce.HTML` context (like `ng-bind-html`).\n */\n\n /**\n * Shorthand method. `$sce.trustAsCss(value)` →\n * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.CSS, value)`}\n *\n * @param {*} value The value to mark as trusted for `$sce.CSS` context.\n * @return {*} A wrapped version of value that can be used as a trusted variant\n * of your `value` in `$sce.CSS` context. This context is currently unused, so there are\n * almost no reasons to use this function so far.\n */\n\n /**\n * Shorthand method. `$sce.trustAsUrl(value)` →\n * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.URL, value)`}\n *\n * @param {*} value The value to mark as trusted for `$sce.URL` context.\n * @return {*} A wrapped version of value that can be used as a trusted variant of your `value`\n * in `$sce.URL` context. That context is currently unused, so there are almost no reasons\n * to use this function so far.\n */\n\n /**\n * Shorthand method. `$sce.trustAsResourceUrl(value)` →\n * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`}\n *\n * @param {*} value The value to mark as trusted for `$sce.RESOURCE_URL` context.\n * @return {*} A wrapped version of value that can be used as a trusted variant of your `value`\n * in `$sce.RESOURCE_URL` context (template URLs in `ng-include`, most `src` attribute\n * bindings, ...)\n */\n\n /**\n * Shorthand method. `$sce.trustAsJs(value)` →\n * {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.JS, value)`}\n *\n * @param {*} value The value to mark as trusted for `$sce.JS` context.\n * @return {*} A wrapped version of value that can be used as a trusted variant of your `value`\n * in `$sce.JS` context. That context is currently unused, so there are almost no reasons to\n * use this function so far.\n */\n\n /**\n * Delegates to {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted`}. As such,\n * takes any input, and either returns a value that's safe to use in the specified context,\n * or throws an exception. This function is aware of trusted values created by the `trustAs`\n * function and its shorthands, and when contexts are appropriate, returns the unwrapped value\n * as-is. Finally, this function can also throw when there is no way to turn `maybeTrusted` in a\n * safe value (e.g., no sanitization is available or possible.)\n *\n * @param {string} type The context in which this value is to be used.\n * @param {*} maybeTrusted The result of a prior {@link ng.$sce#trustAs\n * `$sce.trustAs`} call, or anything else (which will not be considered trusted.)\n * @return {*} A version of the value that's safe to use in the given context, or throws an\n * exception if this is impossible.\n */\n\n /**\n * Shorthand method. `$sce.getTrustedHtml(value)` →\n * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`}\n *\n * @param {*} value The value to pass to `$sce.getTrusted`.\n * @return {*} The return value of `$sce.getTrusted($sce.HTML, value)`\n */\n\n /**\n * Shorthand method. `$sce.getTrustedCss(value)` →\n * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`}\n *\n * @param {*} value The value to pass to `$sce.getTrusted`.\n * @return {*} The return value of `$sce.getTrusted($sce.CSS, value)`\n */\n\n /**\n * Shorthand method. `$sce.getTrustedUrl(value)` →\n * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.URL, value)`}\n *\n * @param {*} value The value to pass to `$sce.getTrusted`.\n * @return {*} The return value of `$sce.getTrusted($sce.URL, value)`\n */\n\n /**\n * Shorthand method. `$sce.getTrustedResourceUrl(value)` →\n * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`}\n *\n * @param {*} value The value to pass to `$sceDelegate.getTrusted`.\n * @return {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)`\n */\n\n /**\n * Shorthand method. `$sce.getTrustedJs(value)` →\n * {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.JS, value)`}\n *\n * @param {*} value The value to pass to `$sce.getTrusted`.\n * @return {*} The return value of `$sce.getTrusted($sce.JS, value)`\n */\n\n /**\n * Shorthand method. `$sce.parseAsHtml(expression string)` →\n * {@link ng.$sceparseAs `$sce.parseAs($sce.HTML, value)`}\n *\n * @param {string} expression String expression to compile.\n * @return {function(context, locals)} A function which represents the compiled expression:\n *\n * * `context` – `{object}` – an object against which any expressions embedded in the\n * strings are evaluated against (typically a scope object).\n * * `locals` – `{object=}` – local variables context object, useful for overriding values\n * in `context`.\n */\n\n /**\n * Shorthand method. `$sce.parseAsCss(value)` →\n * {@link ng.$sceparseAs `$sce.parseAs($sce.CSS, value)`}\n *\n * @param {string} expression String expression to compile.\n * @return {function(context, locals)} A function which represents the compiled expression:\n *\n * * `context` – `{object}` – an object against which any expressions embedded in the\n * strings are evaluated against (typically a scope object).\n * * `locals` – `{object=}` – local variables context object, useful for overriding values\n * in `context`.\n */\n\n /**\n * Shorthand method. `$sce.parseAsUrl(value)` →\n * {@link ng.$sceparseAs `$sce.parseAs($sce.URL, value)`}\n *\n * @param {string} expression String expression to compile.\n * @return {function(context, locals)} A function which represents the compiled expression:\n *\n * * `context` – `{object}` – an object against which any expressions embedded in the\n * strings are evaluated against (typically a scope object).\n * * `locals` – `{object=}` – local variables context object, useful for overriding values\n * in `context`.\n */\n\n /**\n * Shorthand method. `$sce.parseAsResourceUrl(value)` →\n * {@link ng.$sceparseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}\n *\n * @param {string} expression String expression to compile.\n * @return {function(context, locals)} A function which represents the compiled expression:\n *\n * * `context` – `{object}` – an object against which any expressions embedded in the\n * strings are evaluated against (typically a scope object).\n * * `locals` – `{object=}` – local variables context object, useful for overriding values\n * in `context`.\n */\n\n /**\n * Shorthand method. `$sce.parseAsJs(value)` →\n * {@link ng.$sceparseAs `$sce.parseAs($sce.JS, value)`}\n *\n * @param {string} expression String expression to compile.\n * @return {function(context, locals)} A function which represents the compiled expression:\n *\n * * `context` – `{object}` – an object against which any expressions embedded in the\n * strings are evaluated against (typically a scope object).\n * * `locals` – `{object=}` – local variables context object, useful for overriding values\n * in `context`.\n */\n\n // Shorthand delegations.\n const parse = sce.parseAs;\n\n const { getTrusted } = sce;\n\n const { trustAs } = sce;\n\n entries(SCE_CONTEXTS).forEach(([name, enumValue]) => {\n const lName = name.toLowerCase();\n\n sce[snakeToCamel(`parse_as_${lName}`)] = function (expr) {\n return parse(enumValue, expr);\n };\n sce[snakeToCamel(`get_trusted_${lName}`)] = function (value) {\n return getTrusted(enumValue, value);\n };\n sce[snakeToCamel(`trust_as_${lName}`)] = function (value) {\n return trustAs(enumValue, value);\n };\n });\n\n return sce;\n },\n ];\n}\n","import { directiveNormalize } from \"../../shared/utils.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n/*\n * A collection of directives that allows creation of custom event handlers that are defined as\n * AngularTS expressions and are compiled and executed within the current scope.\n */\n\n/**\n * @type {Record<string, ng.Injectable<any>>}\n */\nexport const ngEventDirectives = {};\n\n\"click copy cut dblclick focus blur keydown keyup load mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup paste submit touchstart touchend touchmove\"\n .split(\" \")\n .forEach((eventName) => {\n const directiveName = directiveNormalize(`ng-${eventName}`);\n\n ngEventDirectives[directiveName] = [\n $t.$parse,\n $t.$exceptionHandler,\n\n /**\n * @param {ng.ParseService} $parse\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @returns\n */\n ($parse, $exceptionHandler) => {\n return createEventDirective(\n $parse,\n $exceptionHandler,\n directiveName,\n eventName,\n );\n },\n ];\n });\n\n/**\n *\n * @param {ng.ParseService} $parse\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @param {string} directiveName\n * @param {string} eventName\n * @returns {ng.Directive}\n */\nexport function createEventDirective(\n $parse,\n $exceptionHandler,\n directiveName,\n eventName,\n) {\n return {\n restrict: \"A\",\n compile(_element, attr) {\n const fn = $parse(attr[directiveName]);\n\n return (scope, element) => {\n const handler = (event) => {\n try {\n fn(scope, { $event: event });\n } catch (error) {\n $exceptionHandler(error);\n }\n };\n\n element.addEventListener(eventName, handler);\n\n scope.$on(\"$destroy\", () =>\n element.removeEventListener(eventName, handler),\n );\n };\n },\n };\n}\n\n/**\n *\n * @param {ng.ParseService} $parse\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @param {ng.WindowService} $window\n * @param {string} directiveName\n * @param {string} eventName\n * @returns {ng.Directive}\n */\nexport function createWindowEventDirective(\n $parse,\n $exceptionHandler,\n $window,\n directiveName,\n eventName,\n) {\n return {\n restrict: \"A\",\n compile(_element, attr) {\n const fn = $parse(attr[directiveName]);\n\n return (scope) => {\n const handler = (event) => {\n try {\n fn(scope, { $event: event });\n } catch (error) {\n $exceptionHandler(error);\n }\n };\n\n $window.addEventListener(eventName, handler);\n\n scope.$on(\"$destroy\", () =>\n $window.removeEventListener(eventName, handler),\n );\n };\n },\n };\n}\n","import { getBooleanAttrName } from \"../../shared/dom.js\";\nimport {\n arrayRemove,\n directiveNormalize,\n hasAnimate,\n hasOwn,\n isString,\n isUndefined,\n minErr,\n snakeCase,\n trim,\n} from \"../../shared/utils.js\";\nimport { ALIASED_ATTR } from \"../../shared/constants.js\";\n\nconst $compileMinErr = minErr(\"$compile\");\n\nconst SIMPLE_ATTR_NAME = /^\\w/;\n\nconst specialAttrHolder = document.createElement(\"div\");\n\nexport class Attributes {\n static $nonscope = true;\n\n /**\n * @param {ng.AnimateService} $animate\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @param {*} $sce\n * @param {import(\"../../shared/noderef.js\").NodeRef} [nodeRef]\n * @param {Object} [attributesToCopy]\n */\n constructor($animate, $exceptionHandler, $sce, nodeRef, attributesToCopy) {\n this._$animate = $animate;\n this._$exceptionHandler = $exceptionHandler;\n this._$sce = $sce;\n\n if (attributesToCopy) {\n const keys = Object.keys(attributesToCopy);\n\n for (let i = 0, l = keys.length; i < l; i++) {\n const key = keys[i];\n\n this[key] = attributesToCopy[key];\n }\n } else {\n this.$attr = {};\n }\n\n /** @type {import(\"../../shared/noderef.js\").NodeRef} */\n this.$nodeRef = nodeRef;\n }\n\n /** @type {Node|Element} */\n get $$element() {\n return this.$nodeRef.node;\n }\n\n /**\n * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with `x-` or\n * `data-`) to its normalized, camelCase form.\n *\n * Also there is special case for Moz prefix starting with upper case letter.\n *\n * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}\n *\n * @param {string} name Name to normalize\n */\n $normalize = directiveNormalize;\n\n /**\n * Adds the CSS class value specified by the classVal parameter to the element. If animations\n * are enabled then an animation will be triggered for the class addition.\n *\n * @param {string} classVal The className value that will be added to the element\n */\n $addClass(classVal) {\n if (classVal && classVal.length > 0) {\n if (hasAnimate(this.$$element)) {\n this._$animate.addClass(\n /** @type {Element} */ (this.$$element),\n classVal,\n );\n } else {\n this.$nodeRef.element.classList.add(classVal);\n }\n }\n }\n\n /**\n * Removes the CSS class value specified by the classVal parameter from the element. If\n * animations are enabled then an animation will be triggered for the class removal.\n *\n * @param {string} classVal The className value that will be removed from the element\n */\n $removeClass(classVal) {\n if (classVal && classVal.length > 0) {\n if (hasAnimate(this.$$element)) {\n this._$animate.removeClass(\n /** @type {Element} */ (this.$$element),\n classVal,\n );\n } else {\n this.$nodeRef.element.classList.remove(classVal);\n }\n }\n }\n\n /**\n * Adds and removes the appropriate CSS class values to the element based on the difference\n * between the new and old CSS class values (specified as newClasses and oldClasses).\n *\n * @param {string} newClasses The current CSS className value\n * @param {string} oldClasses The former CSS className value\n */\n $updateClass(newClasses, oldClasses) {\n const toAdd = tokenDifference(newClasses, oldClasses);\n\n if (toAdd && toAdd.length) {\n if (hasAnimate(this.$$element)) {\n this._$animate.addClass(/** @type {Element }*/ (this.$$element), toAdd);\n } else {\n this.$nodeRef.element.classList.add(...toAdd.trim().split(/\\s+/));\n }\n }\n const toRemove = tokenDifference(oldClasses, newClasses);\n\n if (toRemove && toRemove.length) {\n if (hasAnimate(this.$$element)) {\n this._$animate.removeClass(\n /** @type {Element }*/ (this.$$element),\n toRemove,\n );\n } else {\n this.$nodeRef.element.classList.remove(...toRemove.trim().split(/\\s+/));\n }\n }\n }\n\n /**\n * Set a normalized attribute on the element in a way such that all directives\n * can share the attribute. This function properly handles boolean attributes.\n * @param {string} key Normalized key. (ie ngAttribute)\n * @param {string|boolean} value The value to set. If `null` attribute will be deleted.\n * @param {boolean=} writeAttr If false, does not write the value to DOM element attribute.\n * Defaults to true.\n * @param {string=} attrName Optional none normalized name. Defaults to key.\n */\n $set(key, value, writeAttr, attrName) {\n // TODO: decide whether or not to throw an error if \"class\"\n // is set through this function since it may cause $updateClass to\n // become unstable.\n\n const node = this.$$element;\n\n const booleanKey = getBooleanAttrName(/** @type {Element} */ (node), key);\n\n const aliasedKey = ALIASED_ATTR[key];\n\n let observer = key;\n\n if (booleanKey) {\n this.$$element[key] = value;\n attrName = booleanKey;\n } else if (aliasedKey) {\n this[aliasedKey] = value;\n observer = aliasedKey;\n }\n\n this[key] = value;\n\n // translate normalized key to actual key\n if (attrName) {\n this.$attr[key] = attrName;\n } else {\n attrName = this.$attr[key];\n\n if (!attrName) {\n this.$attr[key] = attrName = snakeCase(key, \"-\");\n }\n }\n\n const nodeName = this.$nodeRef.node.nodeName.toLowerCase();\n\n // Sanitize img[srcset] values.\n if (nodeName === \"img\" && key === \"srcset\") {\n this[key] = value = this.sanitizeSrcset(value, \"$set('srcset', value)\");\n }\n\n if (writeAttr !== false) {\n const elem = /** @type {Element} */ (this.$$element);\n\n if (value === null || isUndefined(value)) {\n elem.removeAttribute(attrName);\n //\n } else if (SIMPLE_ATTR_NAME.test(attrName)) {\n // jQuery skips special boolean attrs treatment in XML nodes for\n // historical reasons and hence AngularTS cannot freely call\n // `.getAttribute(attrName, false) with such attributes. To avoid issues\n // in XHTML, call `removeAttr` in such cases instead.\n // See https://github.com/jquery/jquery/issues/4249\n if (booleanKey && value === false) {\n elem.removeAttribute(attrName);\n } else {\n if (booleanKey) {\n elem.toggleAttribute(attrName, /** @type {boolean} */ (value));\n } else {\n elem.setAttribute(attrName, /** @type {string} */ (value));\n }\n }\n } else {\n this.setSpecialAttr(this.$$element, attrName, value);\n }\n }\n\n // fire observers\n const { $$observers } = this;\n\n if ($$observers && $$observers[observer]) {\n $$observers[observer].forEach((fn) => {\n try {\n fn(value);\n } catch (err) {\n this._$exceptionHandler(err);\n }\n });\n }\n }\n\n /**\n * Observes an interpolated attribute.\n * \n * The observer function will be invoked once during the next `$digest` following\n * compilation. The observer is then invoked whenever the interpolated value\n * changes.\n *\n * @param {string} key Normalized key. (ie ngAttribute) .\n * @param {any} fn Function that will be called whenever\n the interpolated value of the attribute changes.\n * See the {@link guide/interpolation#how-text-and-attribute-bindings-work Interpolation\n * guide} for more info.\n * @returns {function()} Returns a deregistration function for this observer.\n */\n $observe(key, fn) {\n const $$observers =\n this.$$observers || (this.$$observers = Object.create(null));\n\n const listeners = $$observers[key] || ($$observers[key] = []);\n\n listeners.push(fn);\n\n if (!listeners.$$inter && hasOwn(this, key) && !isUndefined(this[key])) {\n // no one registered attribute interpolation function, so lets call it manually\n fn(this[key]);\n }\n\n return function () {\n arrayRemove(listeners, fn);\n };\n }\n\n setSpecialAttr(element, attrName, value) {\n // Attributes names that do not start with letters (such as `(click)`) cannot be set using `setAttribute`\n // so we have to jump through some hoops to get such an attribute\n // https://github.com/angular/angular.js/pull/13318\n specialAttrHolder.innerHTML = `<span ${attrName}>`;\n const { attributes } = /** @type {Element} */ (\n specialAttrHolder.firstChild\n );\n\n const attribute = attributes[0];\n\n // We have to remove the attribute from its container element before we can add it to the destination element\n attributes.removeNamedItem(attribute.name);\n attribute.value = value;\n element.attributes.setNamedItem(attribute);\n }\n\n sanitizeSrcset(value, invokeType) {\n let i;\n\n if (!value) {\n return value;\n }\n\n if (!isString(value)) {\n throw $compileMinErr(\n \"srcset\",\n 'Can\\'t pass trusted values to `{0}`: \"{1}\"',\n invokeType,\n value.toString(),\n );\n }\n\n // Such values are a bit too complex to handle automatically inside $sce.\n // Instead, we sanitize each of the URIs individually, which works, even dynamically.\n\n // It's not possible to work around this using `$sce.trustAsMediaUrl`.\n // If you want to programmatically set explicitly trusted unsafe URLs, you should use\n // `$sce.trustAsHtml` on the whole `img` tag and inject it into the DOM using the\n // `ng-bind-html` directive.\n\n let result = \"\";\n\n // first check if there are spaces because it's not the same pattern\n const trimmedSrcset = trim(value);\n\n // ( 999x ,| 999w ,| ,|, )\n const srcPattern = /(\\s+\\d+x\\s*,|\\s+\\d+w\\s*,|\\s+,|,\\s+)/;\n\n const pattern = /\\s/.test(trimmedSrcset) ? srcPattern : /(,)/;\n\n // split srcset into tuple of uri and descriptor except for the last item\n const rawUris = trimmedSrcset.split(pattern);\n\n // for each tuples\n const nbrUrisWith2parts = Math.floor(rawUris.length / 2);\n\n for (i = 0; i < nbrUrisWith2parts; i++) {\n const innerIdx = i * 2;\n\n // sanitize the uri\n result += this._$sce.getTrustedMediaUrl(trim(rawUris[innerIdx]));\n // add the descriptor\n result += ` ${trim(rawUris[innerIdx + 1])}`;\n }\n\n // split the last item into uri and descriptor\n const lastTuple = trim(rawUris[i * 2]).split(/\\s/);\n\n // sanitize the last uri\n result += this._$sce.getTrustedMediaUrl(trim(lastTuple[0]));\n\n // and add the last descriptor if any\n if (lastTuple.length === 2) {\n result += ` ${trim(lastTuple[1])}`;\n }\n\n return result.replace(/unsafe:unsafe/g, \"unsafe\");\n }\n}\n\n/**\n * Computes the difference between two space-separated token strings.\n *\n * @param {string} str1 - The first string containing space-separated tokens.\n * @param {string} str2 - The second string containing space-separated tokens.\n * @returns {string} A string containing tokens that are in str1 but not in str2, separated by spaces.\n *\n */\nfunction tokenDifference(str1, str2) {\n const tokens1 = new Set(str1.split(/\\s+/));\n\n const tokens2 = new Set(str2.split(/\\s+/));\n\n const difference = Array.from(tokens1).filter((token) => !tokens2.has(token));\n\n return difference.join(\" \");\n}\n","import { kebabToCamel } from \"../../shared/dom.js\";\n\n/**\n * @param {string} source - the name of the attribute to be observed\n * @param {string} prop - the scope property to be updated with attribute value\n * @returns {ng.Directive}\n */\nexport function ngObserveDirective(source, prop) {\n return {\n restrict: \"A\",\n compile: () => (scope, element) => {\n if (prop === \"\") {\n prop = source;\n }\n const normalized = kebabToCamel(prop);\n\n if (!scope[normalized]) {\n scope[normalized] = element.getAttribute(source);\n }\n\n const observer = new MutationObserver((mutations) => {\n const mutation = mutations[0];\n\n const newValue = /** @type {HTMLElement} */ (\n mutation.target\n ).getAttribute(source);\n\n if (scope[normalized] !== newValue) {\n scope[normalized] = newValue;\n }\n });\n\n observer.observe(element, {\n attributes: true,\n attributeFilter: [source],\n });\n\n scope.$on(\"$destroy\", () => {\n observer.disconnect();\n });\n },\n };\n}\n","import {\n createElementFromHTML,\n createNodelistFromHTML,\n emptyElement,\n getBooleanAttrName,\n getCacheData,\n getInheritedData,\n isTextNode,\n setCacheData,\n setIsolateScope,\n setScope,\n startingTag,\n} from \"../../shared/dom.js\";\nimport { NodeType } from \"../../shared/node.js\";\nimport { NodeRef } from \"../../shared/noderef.js\";\nimport { identifierForController } from \"../controller/controller.js\";\nimport {\n assertArg,\n assertNotHasOwnProperty,\n bind,\n directiveNormalize,\n entries,\n equals,\n extend,\n getNodeName,\n hasOwn,\n inherit,\n isArray,\n isBoolean,\n isDefined,\n isError,\n isFunction,\n isObject,\n isProxy,\n isScope,\n isString,\n isUndefined,\n minErr,\n simpleCompare,\n trim,\n} from \"../../shared/utils.js\";\nimport { SCE_CONTEXTS } from \"../../services/sce/sce.js\";\nimport { PREFIX_REGEXP } from \"../../shared/constants.js\";\nimport {\n createEventDirective,\n createWindowEventDirective,\n} from \"../../directive/events/events.js\";\nimport { Attributes } from \"./attributes.js\";\nimport { ngObserveDirective } from \"../../directive/observe/observe.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n\nconst $compileMinErr = minErr(\"$compile\");\n\nconst EXCLUDED_DIRECTIVES = [\"ngIf\", \"ngRepeat\"];\n\nconst ALL_OR_NOTHING_ATTRS = [\"ngSrc\", \"ngSrcset\", \"src\", \"srcset\"];\n\nconst REQUIRE_PREFIX_REGEXP = /^(?:(\\^\\^?)?(\\?)?(\\^\\^?)?)?/;\n\n// Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes\n// The assumption is that future DOM event attribute names will begin with\n// 'on' and be composed of only English letters.\nconst EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;\n\nconst valueFn = (value) => () => value;\n\nexport const DirectiveSuffix = \"Directive\";\n\nexport class CompileProvider {\n /* @ignore */ static $inject = [$t.$provide, $t.$$sanitizeUriProvider];\n\n /**\n * @param {import('../../interface.ts').Provider} $provide\n * @param {import('../sanitize/sanitize-uri.js').SanitizeUriProvider} $$sanitizeUriProvider\n */\n constructor($provide, $$sanitizeUriProvider) {\n const hasDirectives = {};\n\n const bindingCache = Object.create(null);\n\n /**\n * @param {ng.Scope} scope\n * @param {string} directiveName\n * @param {boolean} isController\n * @returns {Object} a configuration object for attribute bindings\n */\n function parseIsolateBindings(scope, directiveName, isController) {\n const LOCAL_REGEXP = /^([@&]|[=<]())(\\??)\\s*([\\w$]*)$/;\n\n const bindings = Object.create(null);\n\n entries(scope).forEach(([scopeName, definition]) => {\n definition = definition.trim();\n\n if (definition in bindingCache) {\n bindings[scopeName] = bindingCache[definition];\n\n return;\n }\n const match = definition.match(LOCAL_REGEXP);\n\n if (!match) {\n throw $compileMinErr(\n \"iscp\",\n \"Invalid {3} for directive '{0}'.\" +\n \" Definition: {... {1}: '{2}' ...}\",\n directiveName,\n scopeName,\n definition,\n isController\n ? \"controller bindings definition\"\n : \"isolate scope definition\",\n );\n }\n\n bindings[scopeName] = {\n mode: match[1][0],\n collection: match[2] === \"*\",\n optional: match[3] === \"?\",\n attrName: match[4] || scopeName,\n };\n\n if (match[4]) {\n bindingCache[definition] = bindings[scopeName];\n }\n });\n\n return bindings;\n }\n\n function parseDirectiveBindings(directive, directiveName) {\n const bindings = {\n isolateScope: null,\n bindToController: null,\n };\n\n if (isObject(directive.scope)) {\n if (directive.bindToController === true) {\n bindings.bindToController = parseIsolateBindings(\n directive.scope,\n directiveName,\n true,\n );\n bindings.isolateScope = {};\n } else {\n bindings.isolateScope = parseIsolateBindings(\n directive.scope,\n directiveName,\n false,\n );\n }\n }\n\n if (isObject(directive.bindToController)) {\n bindings.bindToController = parseIsolateBindings(\n directive.bindToController,\n directiveName,\n true,\n );\n }\n\n if (bindings.bindToController && !directive.controller) {\n // There is no controller\n throw $compileMinErr(\n \"noctrl\",\n \"Cannot bind to controller without directive '{0}'s controller.\",\n directiveName,\n );\n }\n\n return bindings;\n }\n\n function getDirectiveRequire(directive) {\n const require =\n directive.require || (directive.controller && directive.name);\n\n if (!isArray(require) && isObject(require)) {\n const entryList = entries(require);\n\n for (let i = 0, len = entryList.length; i < len; i++) {\n const [key, value] = entryList[i];\n\n const match = value.match(REQUIRE_PREFIX_REGEXP);\n\n if (!match) continue; // safety check if match fails\n\n const name = value.substring(match[0].length);\n\n if (!name) {\n require[key] = match[0] + key;\n }\n }\n }\n\n return require;\n }\n\n function getDirectiveRestrict(restrict, name) {\n if (restrict && !(isString(restrict) && /[EA]/.test(restrict))) {\n throw $compileMinErr(\n \"badrestrict\",\n \"Restrict property '{0}' of directive '{1}' is invalid\",\n restrict,\n name,\n );\n }\n\n // Default is element or attribute\n return restrict || \"EA\";\n }\n\n /**\n * Register a new directive with the compiler.\n *\n * @param {string|Object} name Name of the directive in camel-case (i.e. `ngBind` which will match\n * as `ng-bind`), or an object map of directives where the keys are the names and the values\n * are the factories.\n * @param {Function|Array} directiveFactory An injectable directive factory function. See the\n * {@link guide/directive directive guide} and the {@link $compile compile API} for more info.\n * @returns {CompileProvider} Self for chaining.\n */\n this.directive = function registerDirective(name, directiveFactory) {\n assertArg(name, \"name\");\n assertNotHasOwnProperty(name, \"directive\");\n\n if (isString(name)) {\n assertValidDirectiveName(name);\n assertArg(directiveFactory, \"directiveFactory\");\n\n if (!hasOwn(hasDirectives, name)) {\n hasDirectives[name] = [];\n $provide.factory(name + DirectiveSuffix, [\n \"$injector\",\n \"$exceptionHandler\",\n /**\n * @param {ng.InjectorService} $injector\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n */\n function ($injector, $exceptionHandler) {\n const directives = [];\n\n for (let i = 0, l = hasDirectives[name].length; i < l; i++) {\n const directiveFactoryInstance = hasDirectives[name][i];\n\n try {\n let directive = $injector.invoke(directiveFactoryInstance);\n\n if (isFunction(directive)) {\n directive = { compile: valueFn(directive) };\n } else if (!directive.compile && directive.link) {\n directive.compile = valueFn(directive.link);\n }\n\n directive.priority = directive.priority || 0;\n directive.index = i;\n directive.name = directive.name || name;\n directive.require = getDirectiveRequire(directive);\n directive.restrict = getDirectiveRestrict(\n directive.restrict,\n name,\n );\n\n directives.push(directive);\n } catch (err) {\n $exceptionHandler(err);\n }\n }\n\n return directives;\n },\n ]);\n }\n hasDirectives[name].push(directiveFactory);\n } else {\n entries(name).forEach(([k, v]) => registerDirective(k, v));\n }\n\n return this;\n };\n\n /**\n * @param {string|Object} name Name of the component in camelCase (i.e. `myComp` which will match `<my-comp>`),\n * or an object map of components where the keys are the names and the values are the component definition objects.\n * @param {import(\"../../interface.ts\").Component} options Component definition object (a simplified\n * {directive definition object}),\n * with the following properties (all optional):\n *\n * - `controller` – `{(string|function()=}` – controller constructor function that should be\n * associated with newly created scope or the name of a {controller} if passed as a string. An empty `noop` function by default.\n * - `controllerAs` – `{string=}` – identifier name for to reference the controller in the component's scope.\n * If present, the controller will be published to scope under the `controllerAs` name.\n * If not present, this will default to be `$ctrl`.\n * - `template` – `{string=|function()=}` – html template as a string or a function that\n * returns an html template as a string which should be used as the contents of this component.\n * Empty string by default.\n *\n * If `template` is a function, then it is {injected} with\n * the following locals:\n *\n * - `$element` - Current element\n * - `$attrs` - Current attributes object for the element\n *\n * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html\n * template that should be used as the contents of this component.\n *\n * If `templateUrl` is a function, then it is {injected} with\n * the following locals:\n *\n * - `$element` - Current element\n * - `$attrs` - Current attributes object for the element\n *\n * - `bindings` – `{object=}` – defines bindings between DOM attributes and component properties.\n * Component properties are always bound to the component controller and not to the scope.\n * See {`bindToController`}.\n * - `transclude` – `{boolean=}` – whether {content transclusion} is enabled.\n * Disabled by default.\n * - `require` - `{Object<string, string>=}` - requires the controllers of other directives and binds them to\n * this component's controller. The object keys specify the property names under which the required\n * controllers (object values) will be bound. See {`require`}.\n * - `$...` – additional properties to attach to the directive factory function and the controller\n * constructor function. (This is used by the component router to annotate)\n *\n * @returns {CompileProvider} the compile provider itself, for chaining of function calls.\n */\n this.component = function (name, options) {\n if (!isString(name)) {\n entries(name).forEach(([key, val]) => this.component(key, val));\n\n return this;\n }\n\n const controller =\n options.controller ||\n function () {\n /* empty */\n };\n\n function factory($injector) {\n function makeInjectable(fn) {\n if (isFunction(fn) || isArray(fn)) {\n return function (tElement, tAttrs) {\n // eslint-disable-next-line no-invalid-this\n return $injector.invoke(fn, this, {\n $element: tElement,\n $attrs: tAttrs,\n });\n };\n }\n\n return fn;\n }\n\n const template =\n !options.template && !options.templateUrl ? \"\" : options.template;\n\n const ddo = {\n controller,\n controllerAs:\n identifierForController(options.controller) ||\n options.controllerAs ||\n \"$ctrl\",\n template: makeInjectable(template),\n templateUrl: makeInjectable(options.templateUrl),\n transclude: options.transclude,\n scope: {},\n bindToController: options.bindings || {},\n restrict: \"E\",\n require: options.require,\n };\n\n // Copy annotations (starting with $) over to the DDO\n entries(options).forEach(([key, val]) => {\n if (key.charAt(0) === \"$\") {\n ddo[key] = val;\n }\n });\n\n return ddo;\n }\n\n // Copy any annotation properties (starting with $) over to the factory and controller constructor functions\n // These could be used by libraries such as the new component router\n entries(options).forEach(([key, val]) => {\n if (key.charAt(0) === \"$\") {\n factory[key] = val;\n\n // Don't try to copy over annotations to named controller\n if (isFunction(controller)) {\n controller[key] = val;\n }\n }\n });\n\n factory.$inject = [\"$injector\"];\n\n return this.directive(name, factory);\n };\n\n /**\n * Retrieves or overrides the default regular expression that is used for determining trusted safe\n * urls during a[href] sanitization.\n *\n * The sanitization is a security measure aimed at preventing XSS attacks via html links.\n *\n * Any url about to be assigned to a[href] via data-binding is first normalized and turned into\n * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationTrustedUrlList`\n * regular expression. If a match is found, the original url is written into the dom. Otherwise,\n * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.\n *\n * @param {RegExp=} regexp New regexp to trust urls with.\n * @returns {RegExp|import('../sanitize/sanitize-uri.js').SanitizeUriProvider} Current RegExp if called without value or self for\n * chaining otherwise.\n */\n this.aHrefSanitizationTrustedUrlList = function (regexp) {\n if (isDefined(regexp)) {\n $$sanitizeUriProvider.aHrefSanitizationTrustedUrlList(regexp);\n\n return undefined;\n }\n\n return $$sanitizeUriProvider.aHrefSanitizationTrustedUrlList();\n };\n\n /**\n * Retrieves or overrides the default regular expression that is used for determining trusted safe\n * urls during img[src] sanitization.\n *\n * The sanitization is a security measure aimed at prevent XSS attacks via html links.\n *\n * Any url about to be assigned to img[src] via data-binding is first normalized and turned into\n * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationTrustedUrlList`\n * regular expression. If a match is found, the original url is written into the dom. Otherwise,\n * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.\n *\n * @param {RegExp=} regexp New regexp to trust urls with.\n * @returns {RegExp|import('../sanitize/sanitize-uri.js').SanitizeUriProvider} Current RegExp if called without value or self for\n * chaining otherwise.\n */\n this.imgSrcSanitizationTrustedUrlList = function (regexp) {\n if (isDefined(regexp)) {\n $$sanitizeUriProvider.imgSrcSanitizationTrustedUrlList(regexp);\n\n return undefined;\n }\n\n return $$sanitizeUriProvider.imgSrcSanitizationTrustedUrlList();\n };\n\n /**\n * @param {boolean=} enabled update the strictComponentBindingsEnabled state if provided,\n * otherwise return the current strictComponentBindingsEnabled state.\n * @returns {*} current value if used as getter or itself (chaining) if used as setter\n *\n * Call this method to enable / disable the strict component bindings check. If enabled, the\n * compiler will enforce that all scope / controller bindings of a\n * {@link $compileProvider#directive directive} / {@link $compileProvider#component component}\n * that are not set as optional with `?`, must be provided when the directive is instantiated.\n * If not provided, the compiler will throw the\n * {@link error/$compile/missingattr $compile:missingattr error}.\n *\n * The default value is false.\n */\n let strictComponentBindingsEnabled = false;\n\n this.strictComponentBindingsEnabled = function (enabled) {\n if (isDefined(enabled)) {\n strictComponentBindingsEnabled = enabled;\n\n return this;\n }\n\n return strictComponentBindingsEnabled;\n };\n\n /**\n * The security context of DOM Properties.\n */\n const PROP_CONTEXTS = Object.create(null);\n\n /**\n * Defines the security context for DOM properties bound by ng-prop-*.\n *\n * @param {string} elementName The element name or '*' to match any element.\n * @param {string} propertyName The DOM property name.\n * @param {string} ctx The {@link _$sce} security context in which this value is safe for use, e.g. `$sce.URL`\n * @returns {object} `this` for chaining\n */\n this.addPropertySecurityContext = function (\n elementName,\n propertyName,\n ctx,\n ) {\n const key = `${elementName.toLowerCase()}|${propertyName.toLowerCase()}`;\n\n if (key in PROP_CONTEXTS && PROP_CONTEXTS[key] !== ctx) {\n throw $compileMinErr(\n \"ctxoverride\",\n \"Property context '{0}.{1}' already set to '{2}', cannot override to '{3}'.\",\n elementName,\n propertyName,\n PROP_CONTEXTS[key],\n ctx,\n );\n }\n\n PROP_CONTEXTS[key] = ctx;\n\n return this;\n };\n\n /* Default property contexts.\n *\n * Copy of https://github.com/angular/angular/blob/6.0.6/packages/compiler/src/schema/dom_security_schema.ts#L31-L58\n * Changing:\n * - SecurityContext.* => SCE_CONTEXTS/$sce.*\n * - STYLE => CSS\n * - various URL => MEDIA_URL\n * - *|formAction, form|action URL => RESOURCE_URL (like the attribute)\n */\n (function registerNativePropertyContexts() {\n function registerContext(ctx, values) {\n values.forEach((v) => {\n PROP_CONTEXTS[v.toLowerCase()] = ctx;\n });\n }\n\n registerContext(SCE_CONTEXTS.HTML, [\n \"iframe|srcdoc\",\n \"*|innerHTML\",\n \"*|outerHTML\",\n ]);\n registerContext(SCE_CONTEXTS.CSS, [\"*|style\"]);\n registerContext(SCE_CONTEXTS.URL, [\n \"area|href\",\n \"area|ping\",\n \"a|href\",\n \"a|ping\",\n \"blockquote|cite\",\n \"body|background\",\n \"del|cite\",\n \"input|src\",\n \"ins|cite\",\n \"q|cite\",\n ]);\n registerContext(SCE_CONTEXTS.MEDIA_URL, [\n \"audio|src\",\n \"img|src\",\n \"img|srcset\",\n \"source|src\",\n \"source|srcset\",\n \"track|src\",\n \"video|src\",\n \"video|poster\",\n ]);\n registerContext(SCE_CONTEXTS.RESOURCE_URL, [\n \"*|formAction\",\n \"applet|code\",\n \"applet|codebase\",\n \"base|href\",\n \"embed|src\",\n \"frame|src\",\n \"form|action\",\n \"head|profile\",\n \"html|manifest\",\n \"iframe|src\",\n \"link|href\",\n \"media|src\",\n \"object|codebase\",\n \"object|data\",\n \"script|src\",\n ]);\n })();\n\n this.$get = [\n \"$injector\",\n \"$interpolate\",\n \"$exceptionHandler\",\n \"$templateRequest\",\n \"$parse\",\n \"$controller\",\n \"$rootScope\",\n \"$sce\",\n \"$animate\",\n /**\n * @param {ng.InjectorService} $injector\n * @param {*} $interpolate\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @param {ng.TemplateRequestService} $templateRequest\n * @param {ng.ParseService} $parse\n * @param {*} $controller\n * @param {ng.Scope} $rootScope\n * @param {*} $sce\n * @param {ng.AnimateService} $animate\n * @returns\n */\n function (\n $injector,\n $interpolate,\n $exceptionHandler,\n $templateRequest,\n $parse,\n $controller,\n $rootScope,\n $sce,\n $animate,\n ) {\n // The onChanges hooks should all be run together in a single digest\n // When changes occur, the call to trigger their hooks will be added to this queue\n let onChangesQueue;\n\n // This function is called in a $postUpdate to trigger all the onChanges hooks in a single digest\n function flushOnChangesQueue() {\n for (let i = 0, ii = onChangesQueue.length; i < ii; ++i) {\n try {\n onChangesQueue[i]();\n } catch (err) {\n $exceptionHandler(err);\n }\n }\n // Reset the queue to trigger a new schedule next time there is a change\n onChangesQueue = undefined;\n }\n\n const startSymbol = $interpolate.startSymbol();\n\n const endSymbol = $interpolate.endSymbol();\n\n /** @type {(string) => string} */\n const denormalizeTemplate =\n startSymbol === \"{{\" && endSymbol === \"}}\"\n ? (x) => x\n : (x) => x.replace(/\\{\\{/g, startSymbol).replace(/}}/g, endSymbol);\n\n const NG_PREFIX_BINDING = /^ng(Attr|Prop|On|Observe|Window)([A-Z].*)$/;\n\n return compile;\n\n /**\n * @type {ng.CompileService}\n */\n function compile(\n element,\n transcludeFn,\n maxPriority,\n ignoreDirective,\n previousCompileContext,\n ) {\n /** @type {NodeRef | null } */\n let nodeRef = new NodeRef(element);\n\n /**\n * The composite link function is a composite of individual node linking functions.\n * It will be invoke by the public link function below.\n * @type {ng.CompositeLinkFn}\n */\n let compositeLinkFn = compileNodes(\n nodeRef,\n transcludeFn,\n maxPriority,\n ignoreDirective,\n previousCompileContext,\n );\n\n let namespace = null;\n\n return publicLinkFn;\n\n /** @type {ng.PublicLinkFn} */\n function publicLinkFn(scope, cloneConnectFn, options) {\n if (!nodeRef) {\n throw $compileMinErr(\n \"multilink\",\n \"This element has already been linked.\",\n );\n }\n\n assertArg(scope, \"scope\");\n\n // could be empty nodelist\n if (nodeRef._getAny()) {\n setScope(nodeRef._getAny(), scope);\n }\n\n if (\n previousCompileContext &&\n previousCompileContext.needsNewScope\n ) {\n // A parent directive did a replace and a directive on this element asked\n // for transclusion, which caused us to lose a layer of element on which\n // we could hold the new transclusion scope, so we will create it manually\n // here.\n scope = scope.$parent.$new();\n }\n\n options = options || {};\n let { parentBoundTranscludeFn } = options;\n\n const { transcludeControllers, futureParentElement } = options;\n\n // When `parentBoundTranscludeFn` is passed, it is a\n // `controllersBoundTransclude` function (it was previously passed\n // as `transclude` to directive.link) so we must unwrap it to get\n // its `boundTranscludeFn`\n if (\n parentBoundTranscludeFn &&\n parentBoundTranscludeFn.$$boundTransclude\n ) {\n parentBoundTranscludeFn =\n parentBoundTranscludeFn.$$boundTransclude;\n }\n\n if (!namespace) {\n namespace = detectNamespaceForChildElements(futureParentElement);\n }\n /** @type {NodeRef} */\n let $linkNode;\n\n if (namespace !== \"html\") {\n // When using a directive with replace:true and templateUrl the jqCompileNodes\n // (or a child element inside of them)\n // might change, so we need to recreate the namespace adapted compileNodes\n // for call to the link function.\n // Note: This will already clone the nodes...\n const fragment = createElementFromHTML(\"<div></div>\");\n\n fragment.append(nodeRef.node);\n const wrappedTemplate = wrapTemplate(\n namespace,\n fragment.innerHTML,\n );\n\n $linkNode = new NodeRef(wrappedTemplate[0]);\n } else if (cloneConnectFn) {\n $linkNode = nodeRef._clone();\n } else {\n $linkNode = nodeRef;\n }\n\n if (transcludeControllers) {\n for (const controllerName in transcludeControllers) {\n assertArg($linkNode.element, \"element\");\n setCacheData(\n $linkNode.element,\n `$${controllerName}Controller`,\n transcludeControllers[controllerName].instance,\n );\n }\n }\n\n if (cloneConnectFn) {\n cloneConnectFn($linkNode.dom, scope);\n }\n\n if (compositeLinkFn) {\n compositeLinkFn(scope, $linkNode, parentBoundTranscludeFn);\n }\n\n if (!cloneConnectFn) {\n nodeRef = compositeLinkFn = null;\n }\n\n return $linkNode._getAll();\n }\n }\n\n function detectNamespaceForChildElements(parentElement) {\n // TODO: Make this detect MathML as well...\n const node = parentElement;\n\n if (!node) {\n return \"html\";\n }\n\n return getNodeName(node) !== \"foreignobject\" &&\n toString.call(node).match(/SVG/)\n ? \"svg\"\n : \"html\";\n }\n\n /**\n * Compile function matches each node in nodeList against the directives. Once all directives\n * for a particular node are collected their compile functions are executed. The compile\n * functions return values - the linking functions - are combined into a composite linking\n * function, which is a linking function for the node.\n *\n * @param {NodeRef} nodeRefList a node or an array of nodes or NodeList to compile\n * @param {*} transcludeFn A linking function, where the\n * scope argument is auto-generated to the new child of the transcluded parent scope.\n * @param {number=} [maxPriority] Max directive priority.\n * @param {*} [ignoreDirective]\n * @param {*} [previousCompileContext]\n * @returns {ng.CompositeLinkFn} A composite linking function of all of the matched directives or null.\n */\n function compileNodes(\n nodeRefList,\n transcludeFn,\n maxPriority,\n ignoreDirective,\n previousCompileContext,\n ) {\n /**\n * Aggregates for the composite linking function, where a node in a node list is mapped\n * to a corresponding link function. For single elements, the node should be mapped to\n * a single node link function.\n * @type {ng.LinkFnMapping[]}\n */\n const linkFnsList = []; // An array to hold node indices and their linkFns\n\n let nodeLinkFnFound;\n\n let linkFnFound = false;\n\n for (let i = 0; i < nodeRefList.size; i++) {\n const attrs = new Attributes($animate, $exceptionHandler, $sce);\n\n const directives = collectDirectives(\n /** @type Element */ (nodeRefList._getIndex(i)),\n attrs,\n i === 0 ? maxPriority : undefined,\n ignoreDirective,\n );\n\n /** @type {ng.NodeLinkFnCtx} */\n let nodeLinkFnCtx;\n\n if (directives.length) {\n nodeLinkFnCtx = applyDirectivesToNode(\n directives,\n nodeRefList._getIndex(i),\n attrs,\n transcludeFn,\n null,\n [],\n [],\n Object.assign({}, previousCompileContext, {\n index: i,\n parentNodeRef: nodeRefList,\n ctxNodeRef: nodeRefList,\n }),\n );\n }\n\n let childLinkFn;\n\n const nodeLinkFn = nodeLinkFnCtx?.nodeLinkFn;\n\n const { childNodes } = nodeRefList._getIndex(i);\n\n if (\n (nodeLinkFn && nodeLinkFnCtx.terminal) ||\n !childNodes ||\n !childNodes.length\n ) {\n childLinkFn = null;\n } else {\n const transcluded = nodeLinkFn\n ? (nodeLinkFnCtx.transcludeOnThisElement ||\n !nodeLinkFnCtx.templateOnThisElement) &&\n nodeLinkFnCtx.transclude\n : transcludeFn;\n\n // recursive call\n const childNodeRef = new NodeRef(childNodes);\n\n childLinkFn = compileNodes(childNodeRef, transcluded);\n }\n\n if (nodeLinkFn || childLinkFn) {\n linkFnsList.push({\n index: i,\n nodeLinkFnCtx,\n childLinkFn,\n });\n linkFnFound = true;\n nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn;\n }\n\n // use the previous context only for the first element in the virtual group\n previousCompileContext = null;\n }\n\n // return a composite linking function if we have found anything, null otherwise\n return linkFnFound ? compositeLinkFn : null;\n\n /**\n * The composite link function links all the individual nodes\n *\n * @param {ng.Scope} scope\n * @param {NodeRef} nodeRef\n * @param {*} [parentBoundTranscludeFn]\n */\n function compositeLinkFn(scope, nodeRef, parentBoundTranscludeFn) {\n assertArg(nodeRef, \"nodeRef\");\n let stableNodeList = [];\n\n if (nodeLinkFnFound) {\n // create a stable copy of the nodeList, only copying elements with linkFns\n const stableLength = nodeRef._isList ? nodeRef.nodes.length : 1;\n\n stableNodeList = new Array(stableLength);\n // create a sparse array by only copying the elements which have a linkFn\n linkFnsList.forEach((val) => {\n const idx = val.index;\n\n if (idx === 0) {\n stableNodeList[idx] = nodeRef._isList\n ? nodeRef.nodes[idx]\n : nodeRef.node;\n } else {\n if (nodeRefList._getIndex(idx)) {\n stableNodeList[idx] = nodeRef.nodes[idx];\n }\n }\n });\n } else {\n if (nodeRef._isList) {\n nodeRef.nodes.forEach((elem) => stableNodeList.push(elem));\n } else {\n stableNodeList.push(nodeRef.node);\n }\n }\n\n linkFnsList.forEach(({ index, nodeLinkFnCtx, childLinkFn }) => {\n const node = stableNodeList[index];\n\n node.stable = true;\n let childScope;\n\n let childBoundTranscludeFn;\n\n if (nodeLinkFnCtx?.nodeLinkFn) {\n childScope = nodeLinkFnCtx.newScope ? scope.$new() : scope;\n\n if (nodeLinkFnCtx.transcludeOnThisElement) {\n // bind proper scope for the translusion function\n childBoundTranscludeFn = createBoundTranscludeFn(\n scope,\n nodeLinkFnCtx.transclude,\n parentBoundTranscludeFn,\n );\n } else if (\n !nodeLinkFnCtx.templateOnThisElement &&\n parentBoundTranscludeFn\n ) {\n childBoundTranscludeFn = parentBoundTranscludeFn;\n } else if (!parentBoundTranscludeFn && transcludeFn) {\n childBoundTranscludeFn = createBoundTranscludeFn(\n scope,\n transcludeFn,\n );\n } else {\n childBoundTranscludeFn = null;\n }\n\n // attach new scope to element\n if (nodeLinkFnCtx?.newScope) {\n setScope(node, childScope);\n }\n // @ts-ignore\n nodeLinkFnCtx.nodeLinkFn(\n // @ts-ignore\n childLinkFn,\n childScope,\n node,\n childBoundTranscludeFn,\n );\n } else if (childLinkFn) {\n childLinkFn(\n scope,\n new NodeRef(node.childNodes),\n parentBoundTranscludeFn,\n );\n }\n });\n }\n }\n\n /**\n * Prebinds the transclusion function to a scope\n * @param {ng.Scope} scope\n * @param {*} transcludeFn\n * @param {*} previousBoundTranscludeFn\n * @returns {ng.BoundTranscludeFn}\n */\n function createBoundTranscludeFn(\n scope,\n transcludeFn,\n previousBoundTranscludeFn,\n ) {\n function boundTranscludeFn(\n transcludedScope,\n cloneFn,\n controllers,\n futureParentElement,\n containingScope,\n ) {\n if (!transcludedScope) {\n transcludedScope = scope.$transcluded(containingScope);\n transcludedScope.$$transcluded = true;\n }\n\n const transcludeRes = transcludeFn(transcludedScope, cloneFn, {\n parentBoundTranscludeFn: previousBoundTranscludeFn,\n transcludeControllers: controllers,\n futureParentElement,\n });\n\n return transcludeRes;\n }\n\n // We need to attach the transclusion slots onto the `boundTranscludeFn`\n // so that they are available inside the `controllersBoundTransclude` function\n const boundSlots = (boundTranscludeFn.$$slots = Object.create(null));\n\n for (const slotName in transcludeFn.$$slots) {\n if (transcludeFn.$$slots[slotName]) {\n boundSlots[slotName] = createBoundTranscludeFn(\n scope,\n transcludeFn.$$slots[slotName],\n previousBoundTranscludeFn,\n );\n } else {\n boundSlots[slotName] = null;\n }\n }\n\n return boundTranscludeFn;\n }\n\n /**\n * Looks for directives on the given node and adds them to the directive collection which is\n * sorted.\n *\n * @param {Element} node Node to search.\n * @param {Attributes|any} attrs The shared attrs object which is used to populate the normalized attributes.\n * @param {number=} maxPriority Max directive priority.\n * @param {string} [ignoreDirective]\n * @return {import('../../interface.ts').Directive[]} An array to which the directives are added to. This array is sorted before the function returns.\n */\n function collectDirectives(node, attrs, maxPriority, ignoreDirective) {\n /**\n * @type {ng.Directive[]}\n */\n const directives = [];\n\n const { nodeType } = node;\n\n const attrsMap = attrs.$attr;\n\n let nodeName;\n\n switch (nodeType) {\n case NodeType._ELEMENT_NODE /* Element */:\n nodeName = node.nodeName.toLowerCase();\n\n if (ignoreDirective !== directiveNormalize(nodeName)) {\n // use the node name: <directive>\n addDirective(\n directives,\n directiveNormalize(nodeName),\n \"E\",\n maxPriority,\n );\n }\n\n // iterate over the attributes\n for (let j = 0; j < node.attributes?.length; j++) {\n let isNgAttr = false;\n\n let isNgProp = false;\n\n let isNgEvent = false;\n\n let isNgObserve = false;\n\n let isWindow = false;\n\n const attr = node.attributes[j];\n\n let { name } = attr;\n\n const { value } = attr;\n\n let nName = directiveNormalize(name.toLowerCase());\n\n // Support ng-attr-*, ng-prop-* and ng-on-*\n const ngPrefixMatch = nName.match(NG_PREFIX_BINDING);\n\n if (ngPrefixMatch) {\n isNgAttr = ngPrefixMatch[1] === \"Attr\";\n isNgProp = ngPrefixMatch[1] === \"Prop\";\n isNgEvent = ngPrefixMatch[1] === \"On\";\n isNgObserve = ngPrefixMatch[1] === \"Observe\";\n isWindow = ngPrefixMatch[1] === \"Window\";\n\n // Normalize the non-prefixed name\n name = name\n .replace(PREFIX_REGEXP, \"\")\n .toLowerCase()\n .substring(4 + ngPrefixMatch[1].length)\n .replace(/_(.)/g, (match, letter) => letter.toUpperCase());\n }\n\n if (isNgProp || isNgEvent || isWindow) {\n attrs[nName] = value;\n attrsMap[nName] = attr.name;\n\n if (isNgProp) {\n addPropertyDirective(node, directives, nName, name);\n } else if (isNgEvent) {\n directives.push(\n createEventDirective(\n $parse,\n $exceptionHandler,\n nName,\n name,\n ),\n );\n } else {\n // isWindow\n directives.push(\n createWindowEventDirective(\n $parse,\n $exceptionHandler,\n window,\n nName,\n name,\n ),\n );\n }\n } else if (isNgObserve) {\n directives.push(ngObserveDirective(name, value));\n } else {\n // Update nName for cases where a prefix was removed\n // NOTE: the .toLowerCase() is unnecessary and causes https://github.com/angular/angular.js/issues/16624 for ng-attr-*\n nName = directiveNormalize(name.toLowerCase());\n attrsMap[nName] = name;\n\n if (isNgAttr || !hasOwn(attrs, nName)) {\n attrs[nName] = value;\n\n if (getBooleanAttrName(node, nName)) {\n attrs[nName] = true; // presence means true\n }\n }\n\n addAttrInterpolateDirective(\n node,\n directives,\n value,\n nName,\n isNgAttr,\n );\n\n if (nName !== ignoreDirective) {\n addDirective(directives, nName, \"A\", maxPriority);\n }\n }\n }\n\n if (\n nodeName === \"input\" &&\n node.getAttribute(\"type\") === \"hidden\"\n ) {\n // Hidden input elements can have strange behaviour when navigating back to the page\n // This tells the browser not to try to cache and reinstate previous values\n node.setAttribute(\"autocomplete\", \"off\");\n }\n\n break;\n case NodeType._TEXT_NODE:\n addTextInterpolateDirective(directives, node.nodeValue);\n break;\n default:\n break;\n }\n\n directives.sort(byPriority);\n\n return directives;\n }\n\n /**\n * A function generator that is used to support both eager and lazy compilation\n * linking function.\n * @param eager\n * @param {NodeList|Node} nodes\n * @param transcludeFn\n * @param maxPriority\n * @param ignoreDirective\n * @param previousCompileContext\n * @returns {ng.PublicLinkFn|ng.TranscludeFn}\n */\n function compilationGenerator(\n eager,\n nodes,\n transcludeFn,\n maxPriority,\n ignoreDirective,\n previousCompileContext,\n ) {\n let compiled;\n\n if (eager) {\n return /** @type {ng.PublicLinkFn} */ (\n compile(\n nodes,\n transcludeFn,\n maxPriority,\n ignoreDirective,\n previousCompileContext,\n )\n );\n }\n\n function lazyCompilation() {\n if (!compiled) {\n compiled = compile(\n nodes,\n transcludeFn,\n maxPriority,\n ignoreDirective,\n previousCompileContext,\n );\n\n nodes = transcludeFn = previousCompileContext = null;\n }\n\n /* eslint-disable no-invalid-this */\n const ctx = this;\n\n return compiled.apply(ctx, arguments);\n }\n\n return /** @type {ng.PublicLinkFn} */ (lazyCompilation);\n }\n\n /**\n * Once the directives have been collected, their compile functions are executed. This method\n * is responsible for inlining directive templates as well as terminating the application\n * of the directives if the terminal directive has been reached.\n *\n * @param {Array} directives Array of collected directives to execute their compile function.\n * this needs to be pre-sorted by priority order.\n * @param {Node | Element} compileNode DOM node to apply the compile functions to\n * @param {Attributes} templateAttrs The shared attribute function\n * @param {ng.TranscludeFn} transcludeFn\n * @param {Object=} originalReplaceDirective An optional directive that will be ignored when\n * compiling the transclusion.\n * @param {Array.<Function>} [preLinkFns]\n * @param {Array.<Function>} [postLinkFns]\n * @param {Object} [previousCompileContext] Context used for previous compilation of the current\n * node\n * @returns {ng.NodeLinkFnCtx} node link function\n */\n function applyDirectivesToNode(\n directives,\n compileNode,\n templateAttrs,\n transcludeFn,\n originalReplaceDirective,\n preLinkFns,\n postLinkFns,\n previousCompileContext,\n ) {\n previousCompileContext = previousCompileContext || {};\n\n let terminalPriority = -Number.MAX_VALUE;\n\n let terminal = false;\n\n let {\n newScopeDirective,\n controllerDirectives,\n newIsolateScopeDirective,\n templateDirective,\n nonTlbTranscludeDirective,\n hasElementTranscludeDirective,\n } = previousCompileContext;\n\n const { ctxNodeRef, parentNodeRef } = previousCompileContext;\n\n let hasTranscludeDirective = false;\n\n let hasTemplate = false;\n\n let compileNodeRef = new NodeRef(compileNode);\n\n const { index } = previousCompileContext;\n\n templateAttrs.$nodeRef = compileNodeRef;\n let directive;\n\n let directiveName;\n\n let $template;\n\n let replaceDirective = originalReplaceDirective;\n\n /** @type {ng.TranscludeFn} */\n let childTranscludeFn = transcludeFn;\n\n let didScanForMultipleTransclusion = false;\n\n let mightHaveMultipleTransclusionError = false;\n\n let directiveValue;\n\n /**\n * Links all the directives of a single node.\n * @type {ng.NodeLinkFn}\n */\n // @ts-ignore\n let nodeLinkFn = function (\n childLinkFn,\n scope,\n linkNode,\n boundTranscludeFn,\n ) {\n let i;\n\n let ii;\n\n let isolateScope;\n\n let controllerScope;\n\n let elementControllers;\n\n let scopeToChild = scope;\n\n /** @type {NodeRef} */\n let $element;\n\n /** @type {Attributes} */\n let attrs;\n\n let scopeBindingInfo;\n\n if (compileNode === linkNode) {\n attrs = templateAttrs;\n $element = templateAttrs.$nodeRef;\n } else {\n $element = new NodeRef(linkNode);\n attrs = new Attributes(\n $animate,\n $exceptionHandler,\n $sce,\n $element,\n templateAttrs,\n );\n }\n\n controllerScope = scope;\n\n if (newIsolateScopeDirective) {\n isolateScope = scope.$newIsolate();\n } else if (newScopeDirective) {\n controllerScope = scope.$parent;\n }\n\n if (boundTranscludeFn) {\n // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`\n // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`\n /** @type {any} */\n const newTrancludeFn = /** @type {any} */ (\n controllersBoundTransclude\n );\n\n newTrancludeFn.$$boundTransclude = boundTranscludeFn;\n // expose the slots on the `$transclude` function\n newTrancludeFn.isSlotFilled = function (slotName) {\n return !!boundTranscludeFn.$$slots[slotName];\n };\n transcludeFn = newTrancludeFn;\n }\n\n if (controllerDirectives) {\n elementControllers = setupControllers(\n $element,\n attrs,\n transcludeFn,\n controllerDirectives,\n isolateScope,\n scope,\n newIsolateScopeDirective,\n );\n }\n\n if (newIsolateScopeDirective) {\n isolateScope.$target.$$isolateBindings =\n newIsolateScopeDirective.$$isolateBindings;\n scopeBindingInfo = initializeDirectiveBindings(\n scope,\n attrs,\n isolateScope,\n isolateScope.$$isolateBindings,\n newIsolateScopeDirective,\n );\n\n if (scopeBindingInfo.removeWatches) {\n isolateScope.$on(\"$destroy\", scopeBindingInfo.removeWatches);\n }\n }\n\n // Initialize bindToController bindings\n for (const name in elementControllers) {\n const controllerDirective = controllerDirectives[name];\n\n const controller = elementControllers[name];\n\n const bindings = controllerDirective.$$bindings.bindToController;\n\n // Controller instance is bound to the scope\n const controllerInstance = controller();\n\n controller.instance = controllerScope.$new(controllerInstance);\n setCacheData(\n $element.node,\n `$${controllerDirective.name}Controller`,\n controller.instance,\n );\n controller.bindingInfo = initializeDirectiveBindings(\n controllerScope,\n attrs,\n controller.instance,\n bindings,\n controllerDirective,\n );\n }\n\n // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy\n if (controllerDirectives) {\n entries(controllerDirectives).forEach(\n ([name, controllerDirective]) => {\n const { require } = controllerDirective;\n\n if (\n controllerDirective.bindToController &&\n !isArray(require) &&\n isObject(require)\n ) {\n extend(\n elementControllers[name].instance,\n getControllers(\n name,\n require,\n $element.element,\n elementControllers,\n ),\n );\n }\n },\n );\n }\n\n // Handle the init and destroy lifecycle hooks on all controllers that have them\n if (elementControllers) {\n Object.values(elementControllers).forEach((controller) => {\n const controllerInstance = controller.instance;\n\n if (isFunction(controllerInstance.$onChanges)) {\n try {\n controllerInstance.$onChanges(\n controller.bindingInfo.initialChanges,\n );\n } catch (err) {\n $exceptionHandler(err);\n }\n }\n\n if (isFunction(controllerInstance.$onInit)) {\n try {\n controllerInstance.$target.$onInit();\n } catch (err) {\n $exceptionHandler(err);\n }\n }\n\n if (isFunction(controllerInstance.$onDestroy)) {\n controllerScope.$on(\"$destroy\", () => {\n controllerInstance.$onDestroy();\n });\n }\n });\n }\n\n // PRELINKING\n for (i = 0, ii = preLinkFns.length; i < ii; i++) {\n const preLinkFn = /** @type {any} */ (preLinkFns[i]);\n\n const controllers =\n preLinkFn.require &&\n getControllers(\n preLinkFn.directiveName,\n preLinkFn.require,\n $element.element,\n elementControllers,\n );\n\n // invoke link function\n try {\n preLinkFn(\n preLinkFn.isolateScope ? isolateScope : scope,\n $element.node, // Prelink functions accept a Node\n attrs,\n controllers,\n transcludeFn,\n );\n } catch (err) {\n $exceptionHandler(err);\n }\n }\n\n // RECURSION\n // We only pass the isolate scope, if the isolate directive has a template,\n // otherwise the child elements do not belong to the isolate directive.\n\n if (\n newIsolateScopeDirective &&\n (newIsolateScopeDirective.template ||\n newIsolateScopeDirective.templateUrl === null)\n ) {\n scopeToChild = isolateScope;\n }\n\n if (\n childLinkFn &&\n linkNode &&\n linkNode.childNodes &&\n linkNode.childNodes.length\n ) {\n childLinkFn(\n scopeToChild,\n new NodeRef(linkNode.childNodes),\n boundTranscludeFn,\n );\n }\n\n // POSTLINKING\n for (i = postLinkFns.length - 1; i >= 0; i--) {\n const postLinkFn = /** @type {any} */ (postLinkFns[i]);\n\n const controllers =\n postLinkFn.require &&\n getControllers(\n postLinkFn.directiveName,\n postLinkFn.require,\n /** @type {Element} */ ($element.node),\n elementControllers,\n );\n\n // invoke link function\n try {\n if (postLinkFn.isolateScope) {\n setIsolateScope($element.element, isolateScope);\n }\n\n postLinkFn(\n postLinkFn.isolateScope ? isolateScope : scope,\n $element.node,\n attrs,\n controllers,\n transcludeFn,\n );\n } catch (err) {\n $exceptionHandler(err);\n }\n }\n\n if (elementControllers) {\n // Trigger $postLink lifecycle hooks\n Object.values(elementControllers).forEach((controller) => {\n const controllerInstance = controller.instance;\n\n if (isFunction(controllerInstance.$postLink)) {\n controllerInstance.$postLink();\n }\n });\n }\n\n // This is the function that is injected as `$transclude` or\n // the fifth parameter to the link function.\n // Example: function link (scope, element, attrs, ctrl, transclude) {}\n // Note: all arguments are optional!\n function controllersBoundTransclude(\n scopeParam,\n cloneAttachFn,\n futureParentElement,\n slotName,\n ) {\n let transcludeControllers;\n\n // No scope passed in:\n if (!isScope(scopeParam)) {\n slotName = futureParentElement;\n futureParentElement = cloneAttachFn;\n cloneAttachFn = scopeParam;\n scopeParam = undefined;\n }\n\n if (hasElementTranscludeDirective) {\n transcludeControllers = elementControllers;\n }\n\n if (!futureParentElement) {\n futureParentElement = hasElementTranscludeDirective\n ? $element.node.parentElement\n : $element.node;\n }\n\n if (slotName) {\n // slotTranscludeFn can be one of three things:\n // * a transclude function - a filled slot\n // * `null` - an optional slot that was not filled\n // * `undefined` - a slot that was not declared (i.e. invalid)\n const slotTranscludeFn = boundTranscludeFn.$$slots[slotName];\n\n if (slotTranscludeFn) {\n return slotTranscludeFn(\n scopeParam,\n cloneAttachFn,\n transcludeControllers,\n futureParentElement,\n scopeToChild,\n );\n }\n\n if (isUndefined(slotTranscludeFn)) {\n throw $compileMinErr(\n \"noslot\",\n 'No parent directive that requires a transclusion with slot name \"{0}\". ' +\n \"Element: {1}\",\n slotName,\n startingTag($element.element),\n );\n }\n\n return undefined;\n } else {\n return boundTranscludeFn(\n scopeParam,\n cloneAttachFn,\n transcludeControllers,\n futureParentElement,\n scopeToChild,\n );\n }\n }\n };\n\n // executes all directives on the current element\n for (let i = 0, ii = directives.length; i < ii; i++) {\n directive = directives[i];\n $template = undefined;\n\n if (terminalPriority > directive.priority) {\n break; // prevent further processing of directives\n }\n\n directiveValue = directive.scope;\n\n if (directiveValue) {\n // skip the check for directives with async templates, we'll check the derived sync\n // directive when the template arrives\n if (!directive.templateUrl) {\n if (isObject(directiveValue)) {\n // This directive is trying to add an isolated scope.\n // Check that there is no scope of any kind already\n assertNoDuplicate(\n \"new/isolated scope\",\n newIsolateScopeDirective || newScopeDirective,\n directive,\n compileNodeRef,\n );\n newIsolateScopeDirective = directive;\n } else {\n // This directive is trying to add a child scope.\n // Check that there is no isolated scope already\n assertNoDuplicate(\n \"new/isolated scope\",\n newIsolateScopeDirective,\n directive,\n compileNodeRef,\n );\n }\n }\n\n newScopeDirective = newScopeDirective || directive;\n }\n\n directiveName = directive.name;\n\n // If we encounter a condition that can result in transclusion on the directive,\n // then scan ahead in the remaining directives for others that may cause a multiple\n // transclusion error to be thrown during the compilation process. If a matching directive\n // is found, then we know that when we encounter a transcluded directive, we need to eagerly\n // compile the `transclude` function rather than doing it lazily in order to throw\n // exceptions at the correct time\n const hasReplacedTemplate =\n directive.replace &&\n (directive.templateUrl || directive.template);\n\n const shouldTransclude =\n directive.transclude &&\n !EXCLUDED_DIRECTIVES.includes(directive.name);\n\n if (\n !didScanForMultipleTransclusion &&\n (hasReplacedTemplate || shouldTransclude)\n ) {\n let candidateDirective;\n\n for (\n let scanningIndex = i + 1;\n (candidateDirective = directives[scanningIndex++]);\n\n ) {\n if (\n (candidateDirective.transclude &&\n !EXCLUDED_DIRECTIVES.includes(candidateDirective.name)) ||\n (candidateDirective.replace &&\n (candidateDirective.templateUrl ||\n candidateDirective.template))\n ) {\n mightHaveMultipleTransclusionError = true;\n break;\n }\n }\n\n didScanForMultipleTransclusion = true;\n }\n\n if (!directive.templateUrl && directive.controller) {\n controllerDirectives =\n controllerDirectives || Object.create(null);\n assertNoDuplicate(\n `'${directiveName}' controller`,\n controllerDirectives[directiveName],\n directive,\n compileNodeRef,\n );\n controllerDirectives[directiveName] = directive;\n }\n\n directiveValue = directive.transclude;\n\n if (directiveValue) {\n hasTranscludeDirective = true;\n\n // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.\n // This option should only be used by directives that know how to safely handle element transclusion,\n // where the transcluded nodes are added or replaced after linking.\n if (!EXCLUDED_DIRECTIVES.includes(directive.name)) {\n assertNoDuplicate(\n \"transclusion\",\n nonTlbTranscludeDirective,\n directive,\n compileNodeRef,\n );\n nonTlbTranscludeDirective = directive;\n }\n\n if (directiveValue === \"element\") {\n hasElementTranscludeDirective = true;\n terminalPriority = directive.priority;\n $template = compileNodeRef;\n compileNodeRef = new NodeRef(document.createComment(\"\"));\n templateAttrs.$nodeRef = compileNodeRef;\n compileNode = compileNodeRef.node;\n ctxNodeRef.node = compileNode;\n replaceWith(\n new NodeRef($template._getAny()),\n compileNode,\n index,\n );\n\n // @ts-ignore\n childTranscludeFn = compilationGenerator(\n mightHaveMultipleTransclusionError,\n $template._getAny(),\n transcludeFn,\n terminalPriority,\n replaceDirective && replaceDirective.name,\n {\n // Don't pass in:\n // - controllerDirectives - otherwise we'll create duplicates controllers\n // - newIsolateScopeDirective or templateDirective - combining templates with\n // element transclusion doesn't make sense.\n //\n // We need only nonTlbTranscludeDirective so that we prevent putting transclusion\n // on the same element more than once.\n nonTlbTranscludeDirective,\n },\n );\n } else {\n const slots = Object.create(null);\n\n if (!isObject(directiveValue)) {\n //\n // Clone childnodes before clearing contents on transcluded directives\n $template = compileNode.cloneNode(true).childNodes;\n } else {\n // We have transclusion slots,\n // collect them up, compile them and store their transclusion functions\n $template = document.createDocumentFragment();\n\n const slotMap = Object.create(null);\n\n const filledSlots = Object.create(null);\n\n // Parse the element selectors\n entries(directiveValue).forEach(\n ([slotName, elementSelector]) => {\n // If an element selector starts with a ? then it is optional\n const optional = elementSelector.charAt(0) === \"?\";\n\n elementSelector = optional\n ? elementSelector.substring(1)\n : elementSelector;\n\n slotMap[elementSelector] = slotName;\n\n // We explicitly assign `null` since this implies that a slot was defined but not filled.\n // Later when calling boundTransclusion functions with a slot name we only error if the\n // slot is `undefined`\n slots[slotName] = null;\n\n // filledSlots contains `true` for all slots that are either optional or have been\n // filled. This is used to check that we have not missed any required slots\n filledSlots[slotName] = optional;\n },\n );\n\n // Add the matching elements into their slot\n compileNodeRef.element.childNodes.forEach((node) => {\n const slotName =\n slotMap[\n directiveNormalize(\n getNodeName(/** @type {Element} */ (node)),\n )\n ];\n\n if (slotName) {\n filledSlots[slotName] = true;\n slots[slotName] =\n slots[slotName] || document.createDocumentFragment();\n slots[slotName].appendChild(node);\n } else {\n $template.appendChild(node);\n }\n });\n\n // Check for required slots that were not filled\n entries(filledSlots).forEach(([slotName, filled]) => {\n if (!filled) {\n throw $compileMinErr(\n \"reqslot\",\n \"Required transclusion slot `{0}` was not filled.\",\n slotName,\n );\n }\n });\n\n for (const slotName in slots) {\n if (slots[slotName]) {\n // Only define a transclusion function if the slot was filled\n const slotCompileNodes = slots[slotName].childNodes;\n\n slots[slotName] = compilationGenerator(\n mightHaveMultipleTransclusionError,\n slotCompileNodes,\n transcludeFn,\n );\n }\n }\n\n $template = $template.childNodes;\n }\n\n emptyElement(/** @type {Element} */ (compileNode)); // clear contents on transcluded directives\n\n // lazily compile transcluded template and generate a transcluded link function\n // @ts-ignore\n childTranscludeFn = compilationGenerator(\n mightHaveMultipleTransclusionError,\n $template,\n transcludeFn,\n undefined,\n undefined,\n {\n needsNewScope:\n directive.$$isolateScope || directive.$$newScope,\n },\n );\n childTranscludeFn.$$slots = slots;\n }\n }\n\n if (directive.template) {\n hasTemplate = true;\n assertNoDuplicate(\n \"template\",\n templateDirective,\n directive,\n compileNodeRef,\n );\n templateDirective = directive;\n\n directiveValue = isFunction(directive.template)\n ? directive.template(compileNodeRef.node, templateAttrs)\n : directive.template;\n\n directiveValue = denormalizeTemplate(directiveValue);\n\n if (directive.replace) {\n replaceDirective = directive;\n\n if (isTextNode(directiveValue)) {\n $template = [];\n } else {\n $template = removeComments(\n wrapTemplate(\n directive.templateNamespace,\n trim(directiveValue),\n ),\n );\n }\n\n if (isString($template)) {\n $template = Array.from(\n createNodelistFromHTML($template),\n ).filter((x) => x.nodeType === NodeType._ELEMENT_NODE);\n }\n compileNode = $template[0];\n\n if (\n $template.length !== 1 ||\n compileNode.nodeType !== NodeType._ELEMENT_NODE\n ) {\n throw $compileMinErr(\n \"tplrt\",\n \"Template for directive '{0}' must have exactly one root element. {1}\",\n directiveName,\n \"\",\n );\n }\n\n replaceWith(compileNodeRef, compileNode);\n\n if (parentNodeRef) {\n /** @type {NodeRef} */ (parentNodeRef)._setIndex(\n index,\n compileNode,\n );\n }\n\n const newTemplateAttrs = { $attr: {} };\n\n // combine directives from the original node and from the template:\n // - take the array of directives for this element\n // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed)\n // - collect directives from the template and sort them by priority\n // - combine directives as: processed + template + unprocessed\n const templateDirectives = collectDirectives(\n /** @type {Element} */ (compileNode),\n newTemplateAttrs,\n );\n\n const unprocessedDirectives = directives.splice(\n i + 1,\n directives.length - (i + 1),\n );\n\n if (newIsolateScopeDirective || newScopeDirective) {\n // The original directive caused the current element to be replaced but this element\n // also needs to have a new scope, so we need to tell the template directives\n // that they would need to get their scope from further up, if they require transclusion\n markDirectiveScope(\n templateDirectives,\n newIsolateScopeDirective,\n newScopeDirective,\n );\n }\n directives = directives\n .concat(templateDirectives)\n .concat(unprocessedDirectives);\n\n mergeTemplateAttributes(templateAttrs, newTemplateAttrs);\n\n ii = directives.length;\n } else {\n if (compileNodeRef._isElement()) {\n compileNodeRef.element.innerHTML = directiveValue;\n }\n }\n }\n\n if (directive.templateUrl) {\n hasTemplate = true;\n assertNoDuplicate(\n \"template\",\n templateDirective,\n directive,\n compileNodeRef,\n );\n templateDirective = directive;\n\n if (directive.replace) {\n replaceDirective = directive;\n }\n // @ts-ignore\n nodeLinkFn = compileTemplateUrl(\n directives.splice(i, directives.length - i),\n compileNodeRef,\n templateAttrs,\n /** @type {Element} */ (compileNode),\n hasTranscludeDirective && childTranscludeFn,\n preLinkFns,\n postLinkFns,\n {\n index,\n controllerDirectives,\n newScopeDirective:\n newScopeDirective !== directive && newScopeDirective,\n newIsolateScopeDirective,\n templateDirective,\n nonTlbTranscludeDirective,\n futureParentElement:\n previousCompileContext.futureParentElement,\n },\n );\n ii = directives.length;\n } else if (directive.compile) {\n try {\n /** @type {ng.PublicLinkFn} */\n const linkFn = directive.compile(\n compileNodeRef._getAny(),\n templateAttrs,\n childTranscludeFn,\n );\n\n const context = directive.$$originalDirective || directive;\n\n if (isFunction(linkFn)) {\n addLinkFns(null, bind(context, linkFn));\n } else if (linkFn) {\n addLinkFns(\n bind(context, linkFn.pre),\n bind(context, linkFn.post),\n );\n }\n } catch (err) {\n $exceptionHandler(err);\n }\n }\n\n if (directive.terminal) {\n terminal = true;\n terminalPriority = Math.max(terminalPriority, directive.priority);\n }\n }\n\n previousCompileContext.hasElementTranscludeDirective =\n hasElementTranscludeDirective;\n\n // might be normal or delayed nodeLinkFn depending on if templateUrl is present\n return {\n nodeLinkFn,\n terminal,\n transclude: childTranscludeFn,\n transcludeOnThisElement: hasTranscludeDirective,\n templateOnThisElement: hasTemplate,\n newScope: newScopeDirective && newScopeDirective.scope === true,\n };\n\n /// /////////////////\n function addLinkFns(pre, post) {\n if (pre) {\n pre.require = directive.require;\n pre.directiveName = directiveName;\n\n if (\n newIsolateScopeDirective === directive ||\n directive.$$isolateScope\n ) {\n pre = cloneAndAnnotateFn(pre, { isolateScope: true });\n }\n preLinkFns.push(pre);\n }\n\n if (post) {\n post.require = directive.require;\n post.directiveName = directiveName;\n\n if (\n newIsolateScopeDirective === directive ||\n directive.$$isolateScope\n ) {\n post = cloneAndAnnotateFn(post, { isolateScope: true });\n }\n postLinkFns.push(post);\n }\n }\n }\n\n /**\n *\n * @param {*} directiveName\n * @param {*} require\n * @param {Element} $element\n * @param {*} elementControllers\n * @returns\n */\n function getControllers(\n directiveName,\n require,\n $element,\n elementControllers,\n ) {\n let value;\n\n if (isString(require)) {\n const match = require.match(REQUIRE_PREFIX_REGEXP);\n\n const name = require.substring(match[0].length);\n\n const inheritType = match[1] || match[3];\n\n const optional = match[2] === \"?\";\n\n // If only parents then start at the parent element\n if (inheritType === \"^^\") {\n if ($element.parentElement) {\n $element = $element.parentElement;\n } else {\n $element = undefined;\n }\n // Otherwise attempt getting the controller from elementControllers in case\n // the element is transcluded (and has no data) and to avoid .data if possible\n } else {\n value = elementControllers && elementControllers[name];\n value = value && value.instance;\n }\n\n if (!value) {\n const dataName = `$${name}Controller`;\n\n if (\n inheritType === \"^^\" &&\n $element &&\n $element.nodeType === NodeType._DOCUMENT_NODE\n ) {\n // inheritedData() uses the documentElement when it finds the document, so we would\n // require from the element itself.\n value = null;\n } else {\n value = $element\n ? inheritType\n ? getInheritedData($element, dataName)\n : getCacheData($element, dataName)\n : undefined;\n }\n }\n\n if (!value && !optional) {\n throw $compileMinErr(\n \"ctreq\",\n \"Controller '{0}', required by directive '{1}', can't be found!\",\n name,\n directiveName,\n );\n }\n } else if (isArray(require)) {\n value = [];\n\n for (let i = 0, ii = require.length; i < ii; i++) {\n value[i] = getControllers(\n directiveName,\n require[i],\n $element,\n elementControllers,\n );\n }\n } else if (isObject(require)) {\n value = {};\n entries(require).forEach(([property, controller]) => {\n value[property] = getControllers(\n directiveName,\n controller,\n $element,\n elementControllers,\n );\n });\n }\n\n return value || null;\n }\n\n /**\n * @param {NodeRef} $element\n * @param attrs\n * @param transcludeFn\n * @param controllerDirectives\n * @param isolateScope\n * @param scope\n * @param newIsolateScopeDirective\n * @returns {any}\n */\n function setupControllers(\n $element,\n attrs,\n transcludeFn,\n controllerDirectives,\n isolateScope,\n scope,\n newIsolateScopeDirective,\n ) {\n const elementControllers = Object.create(null);\n\n for (const controllerKey in controllerDirectives) {\n const directive = controllerDirectives[controllerKey];\n\n const locals = {\n $scope:\n directive === newIsolateScopeDirective ||\n directive.$$isolateScope\n ? isolateScope\n : scope,\n $element: $element.node,\n $attrs: attrs,\n $transclude: transcludeFn,\n };\n\n let { controller } = directive;\n\n if (controller === \"@\") {\n controller = attrs[directive.name];\n }\n\n const controllerInstance = $controller(\n controller,\n locals,\n true,\n directive.controllerAs,\n );\n\n // For directives with element transclusion the element is a comment.\n // In this case .data will not attach any data.\n // Instead, we save the controllers for the element in a local hash and attach to .data\n // later, once we have the actual element.\n elementControllers[directive.name] = controllerInstance;\n\n if ($element._isElement()) {\n setCacheData(\n $element.element,\n `$${directive.name}Controller`,\n controllerInstance.instance,\n );\n }\n }\n\n return elementControllers;\n }\n\n // Depending upon the context in which a directive finds itself it might need to have a new isolated\n // or child scope created. For instance:\n // * if the directive has been pulled into a template because another directive with a higher priority\n // asked for element transclusion\n // * if the directive itself asks for transclusion but it is at the root of a template and the original\n // element was replaced. See https://github.com/angular/angular.js/issues/12936\n function markDirectiveScope(directives, isolateScope, newScope) {\n for (let j = 0, jj = directives.length; j < jj; j++) {\n directives[j] = inherit(directives[j], {\n $$isolateScope: isolateScope,\n $$newScope: newScope,\n });\n }\n }\n\n /**\n * looks up the directive and decorates it with exception handling and proper parameters. We\n * call this the boundDirective.\n *\n * @param {string} name name of the directive to look up.\n * @param {string} location The directive must be found in specific format.\n * String containing any of these characters:\n *\n * * `E`: element name\n * * `A': attribute\n * @returns {boolean} true if directive was added.\n */\n function addDirective(tDirectives, name, location, maxPriority) {\n let match = false;\n\n if (hasOwn(hasDirectives, name)) {\n for (\n let directive,\n directives = $injector.get(name + DirectiveSuffix),\n i = 0,\n ii = directives.length;\n i < ii;\n i++\n ) {\n directive = directives[i];\n\n if (\n (isUndefined(maxPriority) ||\n maxPriority > directive.priority) &&\n directive.restrict.indexOf(location) !== -1\n ) {\n if (!directive.$$bindings) {\n const bindings = (directive.$$bindings =\n parseDirectiveBindings(directive, directive.name));\n\n if (isObject(bindings.isolateScope)) {\n directive.$$isolateBindings = bindings.isolateScope;\n }\n }\n tDirectives.push(directive);\n match = directive;\n }\n }\n }\n\n return match;\n }\n\n /**\n * When the element is replaced with HTML template then the new attributes\n * on the template need to be merged with the existing attributes in the DOM.\n * The desired effect is to have both of the attributes present.\n *\n * @param {object} dst destination attributes (original DOM)\n * @param {object} src source attributes (from the directive template)\n */\n function mergeTemplateAttributes(dst, src) {\n const srcAttr = src.$attr;\n\n const dstAttr = dst.$attr;\n\n // reapply the old attributes to the new element\n entries(dst).forEach(([key, value]) => {\n if (key[0] !== \"$\" && key[0] !== \"_\") {\n if (src[key] && src[key] !== value) {\n if (value.length) {\n value += (key === \"style\" ? \";\" : \" \") + src[key];\n } else {\n value = src[key];\n }\n }\n dst.$set(key, value, true, srcAttr[key]);\n }\n });\n\n // copy the new attributes on the old attrs object\n entries(src).forEach(([key, value]) => {\n // Check if we already set this attribute in the loop above.\n // `dst` will never contain hasOwnProperty as DOM parser won't let it.\n // You will get an \"InvalidCharacterError: DOM Exception 5\" error if you\n // have an attribute like \"has-own-property\" or \"data-has-own-property\", etc.\n if (!hasOwn(dst, key) && key.charAt(0) !== \"$\") {\n dst[key] = value;\n\n if (key !== \"class\" && key !== \"style\") {\n dstAttr[key] = srcAttr[key];\n }\n }\n });\n }\n\n /**\n *\n * @param {import(\"../../interface.ts\").Directive[]} directives\n * @param {NodeRef} $compileNode\n * @param {Attributes} tAttrs\n * @param {Element} $rootElement\n * @param {*} childTranscludeFn\n * @param {Array} preLinkFns\n * @param {Array} postLinkFns\n * @param {*} previousCompileContext\n * @returns\n */\n function compileTemplateUrl(\n directives,\n $compileNode,\n tAttrs,\n $rootElement,\n childTranscludeFn,\n preLinkFns,\n postLinkFns,\n previousCompileContext,\n ) {\n let linkQueue = [];\n\n /** @type {any} */\n let afterTemplateNodeLinkFn;\n\n let afterTemplateChildLinkFn;\n\n let afterTemplateNodeLinkFnCtx;\n\n const beforeTemplateCompileNode = $compileNode._getAny();\n\n const origAsyncDirective = directives.shift();\n\n const derivedSyncDirective = inherit(origAsyncDirective, {\n templateUrl: null,\n transclude: null,\n replace: null,\n $$originalDirective: origAsyncDirective,\n });\n\n /** @type {string} */\n let templateUrl;\n\n if (isFunction(origAsyncDirective.templateUrl)) {\n templateUrl =\n /** @type { ((element: Element, tAttrs: Attributes) => string) } */ (\n origAsyncDirective.templateUrl\n )($compileNode.element, tAttrs);\n } else {\n // eslint-disable-next-line prefer-destructuring\n templateUrl = /** @type {string} */ (\n origAsyncDirective.templateUrl\n );\n }\n const { templateNamespace } = origAsyncDirective;\n\n emptyElement($compileNode.element);\n\n $templateRequest(templateUrl)\n .then((content) => {\n /** @type {Element} */\n let compileNode;\n\n let tempTemplateAttrs;\n\n let $template;\n\n let childBoundTranscludeFn;\n\n content = denormalizeTemplate(content);\n\n if (origAsyncDirective.replace) {\n if (isTextNode(content)) {\n $template = [];\n } else if (isString(content)) {\n $template = Array.from(\n createNodelistFromHTML(content),\n ).filter(\n (node) =>\n node.nodeType !== NodeType._COMMENT_NODE &&\n node.nodeType !== NodeType._TEXT_NODE,\n );\n } else {\n $template = removeComments(\n wrapTemplate(templateNamespace, trim(content)),\n );\n }\n compileNode = $template[0];\n\n if (\n $template.length !== 1 ||\n compileNode.nodeType !== NodeType._ELEMENT_NODE\n ) {\n throw $compileMinErr(\n \"tplrt\",\n \"Template for directive '{0}' must have exactly one root element. {1}\",\n origAsyncDirective.name,\n templateUrl,\n );\n }\n\n tempTemplateAttrs = { $attr: {} };\n\n replaceWith(\n $compileNode,\n compileNode,\n previousCompileContext.index,\n );\n\n const templateDirectives = collectDirectives(\n compileNode,\n tempTemplateAttrs,\n );\n\n if (isObject(origAsyncDirective.scope)) {\n // the original directive that caused the template to be loaded async required\n // an isolate scope\n markDirectiveScope(templateDirectives, true);\n }\n directives = templateDirectives.concat(directives);\n\n mergeTemplateAttributes(tAttrs, tempTemplateAttrs);\n } else {\n compileNode = /** @type {Element} */ (\n beforeTemplateCompileNode\n );\n $compileNode.element.innerHTML = content;\n }\n\n directives.unshift(derivedSyncDirective);\n afterTemplateNodeLinkFnCtx = applyDirectivesToNode(\n directives,\n compileNode,\n tAttrs,\n childTranscludeFn,\n origAsyncDirective,\n preLinkFns,\n postLinkFns,\n { ...previousCompileContext, ctxNodeRef: $compileNode },\n );\n\n afterTemplateNodeLinkFn = afterTemplateNodeLinkFnCtx?.nodeLinkFn;\n\n if ($rootElement) {\n entries($rootElement).forEach(([i, node]) => {\n if (node === compileNode) {\n $rootElement[i] = $compileNode;\n }\n });\n }\n afterTemplateChildLinkFn = compileNodes(\n new NodeRef($compileNode._getAny().childNodes),\n childTranscludeFn,\n );\n\n while (linkQueue.length) {\n const scope = linkQueue.shift();\n\n const beforeTemplateLinkNode = linkQueue.shift();\n\n const boundTranscludeFn = linkQueue.shift();\n\n let linkNode = $compileNode._getAny();\n\n if (scope.$$destroyed) {\n continue;\n }\n\n if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {\n const oldClasses = beforeTemplateLinkNode.className;\n\n if (\n !(\n previousCompileContext.hasElementTranscludeDirective &&\n origAsyncDirective.replace\n )\n ) {\n // it was cloned therefore we have to clone as well.\n linkNode = compileNode.cloneNode(true);\n beforeTemplateLinkNode.appendChild(linkNode);\n }\n\n // Copy in CSS classes from original node\n try {\n if (oldClasses !== \"\") {\n $compileNode.element.classList.forEach((cls) =>\n beforeTemplateLinkNode.classList.add(cls),\n );\n }\n } catch {\n // ignore, since it means that we are trying to set class on\n // SVG element, where class name is read-only.\n }\n }\n\n if (afterTemplateNodeLinkFnCtx.transcludeOnThisElement) {\n childBoundTranscludeFn = createBoundTranscludeFn(\n scope,\n afterTemplateNodeLinkFnCtx.transclude,\n boundTranscludeFn,\n );\n } else {\n childBoundTranscludeFn = boundTranscludeFn;\n }\n\n afterTemplateNodeLinkFn(\n afterTemplateChildLinkFn,\n scope,\n linkNode,\n childBoundTranscludeFn,\n );\n }\n linkQueue = null;\n })\n .catch((error) => {\n if (isError(error)) {\n $exceptionHandler(error);\n } else {\n $exceptionHandler(new Error(error));\n }\n });\n\n return function delayedNodeLinkFn(\n _ignoreChildLinkFn,\n scope,\n node,\n rootElement,\n boundTranscludeFn,\n ) {\n let childBoundTranscludeFn = boundTranscludeFn;\n\n if (scope.$$destroyed) {\n return;\n }\n\n if (linkQueue) {\n linkQueue.push(scope, node, rootElement);\n } else {\n if (afterTemplateNodeLinkFn.transcludeOnThisElement) {\n childBoundTranscludeFn = createBoundTranscludeFn(\n scope,\n afterTemplateNodeLinkFn.transclude,\n boundTranscludeFn,\n );\n }\n afterTemplateNodeLinkFn(\n afterTemplateChildLinkFn,\n scope,\n node,\n rootElement,\n childBoundTranscludeFn,\n );\n }\n };\n }\n\n /**\n * Sorting function for bound directives.\n */\n function byPriority(a, b) {\n const diff = b.priority - a.priority;\n\n if (diff !== 0) {\n return diff;\n }\n\n if (a.name !== b.name) {\n return a.name < b.name ? -1 : 1;\n }\n\n return a.index - b.index;\n }\n\n function assertNoDuplicate(\n what,\n previousDirective,\n directive,\n element,\n ) {\n if (previousDirective) {\n throw $compileMinErr(\n \"multidir\",\n \"Multiple directives [{0}, {1}] asking for {3} on: {4}\",\n previousDirective.name,\n directive.name,\n what,\n startingTag(/** @tupe {NodeRef} */ element._getAny()),\n );\n }\n }\n\n function addTextInterpolateDirective(directives, text) {\n const interpolateFn = $interpolate(text, true);\n\n if (interpolateFn) {\n directives.push({\n priority: 0,\n compile: () => (scope, node) => {\n interpolateFn.expressions.forEach((x) => {\n scope.$watch(x, () => {\n const res = interpolateFn(\n isProxy(scope) ? scope.$target : scope,\n );\n\n switch (node.nodeType) {\n case 1:\n node.innerHTML = res;\n break;\n default:\n node.nodeValue = res;\n }\n });\n });\n },\n });\n }\n }\n\n /**\n * @param {string} type\n * @param {string} template\n * @returns\n */\n function wrapTemplate(type, template) {\n type = (type || \"html\").toLowerCase();\n switch (type) {\n case \"svg\":\n case \"math\": {\n const wrapper =\n /** @type {HTMLDivElement} */ document.createElement(\"div\");\n\n wrapper.innerHTML = `<${type}>${template}</${type}>`;\n\n return wrapper.childNodes[0].childNodes;\n }\n default:\n return template;\n }\n }\n\n function getTrustedAttrContext(nodeName, attrNormalizedName) {\n if (attrNormalizedName === \"srcdoc\") {\n return $sce.HTML;\n }\n\n // All nodes with src attributes require a RESOURCE_URL value, except for\n // img and various html5 media nodes, which require the MEDIA_URL context.\n if (attrNormalizedName === \"src\" || attrNormalizedName === \"ngSrc\") {\n if (\n [\"img\", \"video\", \"audio\", \"source\", \"track\"].indexOf(nodeName) ===\n -1\n ) {\n return $sce.RESOURCE_URL;\n }\n\n return $sce.MEDIA_URL;\n }\n\n if (attrNormalizedName === \"xlinkHref\") {\n // Some xlink:href are okay, most aren't\n if (nodeName === \"image\") {\n return $sce.MEDIA_URL;\n }\n\n if (nodeName === \"a\") {\n return $sce.URL;\n }\n\n return $sce.RESOURCE_URL;\n }\n\n if (\n // Formaction\n (nodeName === \"form\" && attrNormalizedName === \"action\") ||\n // If relative URLs can go where they are not expected to, then\n // all sorts of trust issues can arise.\n (nodeName === \"base\" && attrNormalizedName === \"href\") ||\n // links can be stylesheets or imports, which can run script in the current origin\n (nodeName === \"link\" && attrNormalizedName === \"href\")\n ) {\n return $sce.RESOURCE_URL;\n }\n\n if (\n nodeName === \"a\" &&\n (attrNormalizedName === \"href\" || attrNormalizedName === \"ngHref\")\n ) {\n return $sce.URL;\n }\n\n return undefined;\n }\n\n function getTrustedPropContext(nodeName, propNormalizedName) {\n const prop = propNormalizedName.toLowerCase();\n\n return (\n PROP_CONTEXTS[`${nodeName}|${prop}`] || PROP_CONTEXTS[`*|${prop}`]\n );\n }\n\n function sanitizeSrcset(value, invokeType) {\n if (!value) {\n return value;\n }\n\n if (!isString(value)) {\n throw $compileMinErr(\n \"srcset\",\n 'Can\\'t pass trusted values to `{0}`: \"{1}\"',\n invokeType,\n value.toString(),\n );\n }\n\n // Such values are a bit too complex to handle automatically inside $sce.\n // Instead, we sanitize each of the URIs individually, which works, even dynamically.\n // It's not possible to work around this using `$sce.trustAsMediaUrl`.\n // If you want to programmatically set explicitly trusted unsafe URLs, you should use\n // `$sce.trustAsHtml` on the whole `img` tag and inject it into the DOM using the\n // `ng-bind-html` directive.\n let result = \"\";\n\n // first check if there are spaces because it's not the same pattern\n const trimmedSrcset = trim(value);\n\n // ( 999x ,| 999w ,| ,|, )\n const srcPattern = /(\\s+\\d+x\\s*,|\\s+\\d+w\\s*,|\\s+,|,\\s+)/;\n\n const pattern = /\\s/.test(trimmedSrcset) ? srcPattern : /(,)/;\n\n // split srcset into tuple of uri and descriptor except for the last item\n const rawUris = trimmedSrcset.split(pattern);\n\n // for each tuples\n const nbrUrisWith2parts = Math.floor(rawUris.length / 2);\n\n let i;\n\n for (i = 0; i < nbrUrisWith2parts; i++) {\n const innerIdx = i * 2;\n\n // sanitize the uri\n result += $sce.getTrustedMediaUrl(trim(rawUris[innerIdx]));\n // add the descriptor\n result += ` ${trim(rawUris[innerIdx + 1])}`;\n }\n\n // split the last item into uri and descriptor\n const lastTuple = trim(rawUris[i * 2]).split(/\\s/);\n\n // sanitize the last uri\n result += $sce.getTrustedMediaUrl(trim(lastTuple[0]));\n\n // and add the last descriptor if any\n if (lastTuple.length === 2) {\n result += ` ${trim(lastTuple[1])}`;\n }\n\n return result;\n }\n\n function addPropertyDirective(node, directives, attrName, propName) {\n if (EVENT_HANDLER_ATTR_REGEXP.test(propName)) {\n throw $compileMinErr(\n \"nodomevents\",\n \"Property bindings for HTML DOM event properties are disallowed\",\n );\n }\n\n const nodeName = getNodeName(node);\n\n const trustedContext = getTrustedPropContext(nodeName, propName);\n\n let sanitizer = (x) => x;\n\n // Sanitize img[srcset] + source[srcset] values.\n if (\n propName === \"srcset\" &&\n (nodeName === \"img\" || nodeName === \"source\")\n ) {\n sanitizer = (value) =>\n sanitizeSrcset($sce.valueOf(value), \"ng-prop-srcset\");\n } else if (trustedContext) {\n sanitizer = $sce.getTrusted.bind($sce, trustedContext);\n }\n\n directives.push({\n priority: 100,\n compile: function ngPropCompileFn(_, attr) {\n const ngPropGetter = $parse(attr[attrName]);\n\n return {\n pre: function ngPropPreLinkFn(scope, $element) {\n function applyPropValue() {\n const propValue = ngPropGetter(scope);\n\n $element[propName] = sanitizer(propValue);\n }\n\n applyPropValue();\n scope.$watch(propName, applyPropValue);\n scope.$watch(attr[attrName], (val) => {\n $sce.valueOf(val);\n applyPropValue();\n });\n },\n };\n },\n });\n }\n\n function addAttrInterpolateDirective(\n node,\n directives,\n value,\n name,\n isNgAttr,\n ) {\n const nodeName = getNodeName(node);\n\n const trustedContext = getTrustedAttrContext(nodeName, name);\n\n const mustHaveExpression = !isNgAttr;\n\n const allOrNothing = ALL_OR_NOTHING_ATTRS.includes(name) || isNgAttr;\n\n let interpolateFn = $interpolate(\n value,\n mustHaveExpression,\n trustedContext,\n allOrNothing,\n );\n\n // no interpolation found -> ignore\n if (!interpolateFn) {\n return;\n }\n\n if (name === \"multiple\" && nodeName === \"select\") {\n throw $compileMinErr(\n \"selmulti\",\n \"Binding to the 'multiple' attribute is not supported. Element: {0}\",\n startingTag(node.outerHTML),\n );\n }\n\n if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {\n throw $compileMinErr(\n \"nodomevents\",\n \"Interpolations for HTML DOM event attributes are disallowed\",\n );\n }\n\n directives.push({\n priority: 100,\n compile() {\n return {\n pre: function attrInterpolatePreLinkFn(scope, element, attr) {\n const $$observers =\n attr.$$observers ||\n (attr.$$observers = Object.create(null));\n\n // If the attribute has changed since last $interpolate()ed\n const newValue = attr[name];\n\n if (newValue !== value) {\n // we need to interpolate again since the attribute value has been updated\n // (e.g. by another directive's compile function)\n // ensure unset/empty values make interpolateFn falsy\n interpolateFn =\n newValue &&\n $interpolate(\n newValue,\n true,\n trustedContext,\n allOrNothing,\n );\n value = newValue;\n }\n\n // if attribute was updated so that there is no interpolation going on we don't want to\n // register any observers\n if (!interpolateFn) {\n return;\n }\n\n // initialize attr object so that it's ready in case we need the value for isolate\n // scope initialization, otherwise the value would not be available from isolate\n // directive's linking fn during linking phase\n attr[name] = interpolateFn(scope);\n\n ($$observers[name] || ($$observers[name] = [])).$$inter =\n true;\n interpolateFn.expressions.forEach((x) => {\n const targetScope =\n (attr.$$observers && attr.$$observers[name].$$scope) ||\n scope;\n\n targetScope.$watch(x, () => {\n const newInterpolatedValue = interpolateFn(scope);\n\n // special case for class attribute addition + removal\n // so that class changes can tap into the animation\n // hooks provided by the $animate service. Be sure to\n // skip animations when the first digest occurs (when\n // both the new and the old values are the same) since\n // the CSS classes are the non-interpolated values\n if (name === \"class\") {\n attr.$updateClass(\n newInterpolatedValue,\n attr.$$element.classList.value,\n );\n } else {\n attr.$set(\n name,\n name === \"srcset\"\n ? $sce.getTrustedMediaUrl(newInterpolatedValue)\n : newInterpolatedValue,\n );\n }\n });\n });\n\n if (interpolateFn.expressions.length === 0) {\n attr.$set(\n name,\n name === \"srcset\"\n ? $sce.getTrustedMediaUrl(newValue)\n : newValue,\n );\n }\n },\n };\n },\n });\n }\n\n /**\n *\n * @param {NodeRef} elementsToRemove The JQLite element which we are going to replace. We keep\n * the shell, but replace its DOM node reference.\n * @param {Node} newNode The new DOM node.\n * @param {number} [index] Parent node index.\n */\n function replaceWith(elementsToRemove, newNode, index) {\n const firstElementToRemove = elementsToRemove._getAny();\n\n // const removeCount = elementsToRemove.length;\n const parent = firstElementToRemove.parentNode;\n\n if (parent) {\n if (isDefined(index)) {\n const oldChild = parent.childNodes[index];\n\n if (oldChild) {\n parent.replaceChild(newNode, oldChild);\n }\n } else {\n parent.insertBefore(newNode, parent.firstChild);\n //parent.append(newNode);\n }\n }\n\n // Append all the `elementsToRemove` to a fragment. This will...\n // - remove them from the DOM\n // - allow them to still be traversed with .nextSibling\n // - allow a single fragment.qSA to fetch all elements being removed\n const fragment = document.createDocumentFragment();\n\n elementsToRemove._collection().forEach((element) => {\n fragment.appendChild(element);\n });\n\n elementsToRemove.node = newNode;\n }\n\n function cloneAndAnnotateFn(fn, annotation) {\n return extend(\n function () {\n return fn.apply(null, arguments);\n },\n fn,\n annotation,\n );\n }\n\n function strictBindingsCheck(attrName, directiveName) {\n if (strictComponentBindingsEnabled) {\n throw $compileMinErr(\n \"missingattr\",\n \"Attribute '{0}' of '{1}' is non-optional and must be set!\",\n attrName,\n directiveName,\n );\n }\n }\n\n // Set up $watches for isolate scope and controller bindings.\n /**\n *\n * @param {ng.Scope} scope\n * @param {*} attrs\n * @param {ng.Scope} destination - child scope or isolate scope\n * @param {*} bindings\n * @param {*} directive\n * @returns\n */\n function initializeDirectiveBindings(\n scope,\n attrs,\n destination,\n bindings,\n directive,\n ) {\n const removeWatchCollection = [];\n\n const initialChanges = {};\n\n let changes;\n\n if (bindings) {\n entries(bindings).forEach(([scopeName, definition]) => {\n const {\n attrName,\n optional,\n mode, // @, =, <, or &\n } = definition;\n\n let lastValue;\n\n let parentGet;\n\n let parentSet;\n\n let compare;\n\n let removeWatch;\n\n let firstCall = true;\n\n let firstChange = true;\n\n switch (mode) {\n case \"@\":\n if (!optional && !hasOwn(attrs, attrName)) {\n strictBindingsCheck(attrName, directive.name);\n destination[scopeName] = attrs[attrName] = undefined;\n }\n\n removeWatch = attrs.$observe(attrName, (value) => {\n if (isString(value) || isBoolean(value)) {\n recordChanges(scopeName, value, firstChange);\n\n destination[scopeName] = value;\n\n if (firstCall) {\n firstCall = false;\n } else {\n triggerOnChangesHook();\n firstChange = false;\n }\n }\n });\n attrs.$$observers[attrName].$$scope = scope;\n lastValue = attrs[attrName];\n\n if (isString(lastValue)) {\n // If the attribute has been provided then we trigger an interpolation to ensure\n // the value is there for use in the link fn\n destination[scopeName] = $interpolate(lastValue)(scope);\n } else if (isBoolean(lastValue)) {\n // If the attributes is one of the BOOLEAN_ATTR then AngularTS will have converted\n // the value to boolean rather than a string, so we special case this situation\n destination[scopeName] = lastValue;\n }\n\n /**\n * @type {import(\"./inteface.ts\").SimpleChange}\n */\n initialChanges[scopeName] = {\n currentValue: destination[scopeName],\n firstChange: true,\n };\n removeWatchCollection.push(removeWatch);\n break;\n\n case \"=\": {\n if (!hasOwn(attrs, attrName)) {\n if (optional) {\n break;\n }\n strictBindingsCheck(attrName, directive.name);\n attrs[attrName] = undefined;\n }\n\n if (optional && !attrs[attrName]) {\n break;\n }\n\n parentGet = $parse(attrs[attrName]);\n\n if (parentGet.literal) {\n compare = equals;\n } else {\n compare = simpleCompare;\n }\n\n parentSet =\n parentGet.assign ||\n function () {\n // reset the change, or we will throw this exception on every $digest\n lastValue = destination.$target[scopeName] =\n parentGet(scope);\n throw $compileMinErr(\n \"nonassign\",\n \"Expression '{0}' in attribute '{1}' used with directive '{2}' is non-assignable!\",\n attrs[attrName],\n attrName,\n directive.name,\n );\n };\n // store the value that the parent scope had after the last check:\n lastValue = destination.$target[scopeName] = parentGet(\n scope.$target,\n );\n const parentValueWatch = function parentValueWatch(\n parentValue,\n ) {\n if (!compare(parentValue, destination[scopeName])) {\n // we are out of sync and need to copy\n if (!compare(parentValue, lastValue)) {\n // parent changed and it has precedence\n destination[scopeName] = parentValue;\n } else {\n // if the parent can be assigned then do so\n parentSet(\n scope,\n (parentValue = destination[scopeName]),\n );\n }\n }\n lastValue = parentValue;\n\n return lastValue;\n };\n\n parentValueWatch.$stateful = true;\n\n if (definition.collection) {\n removeWatch = scope.$watch(\n attrs[attrName],\n parentValueWatch,\n );\n } else {\n if (attrs[attrName]) {\n const expr = attrs[attrName];\n\n // make it lazy as we dont want to trigger the two way data binding at this point\n scope.$watch(\n expr,\n (val) => {\n const res = $parse(attrs[attrName], parentValueWatch);\n\n if (val) {\n if (parentGet.literal) {\n scope.$target[attrName] = val;\n } else {\n scope[attrName] = val;\n }\n res(scope);\n } else {\n scope[attrName] = scope[attrs[attrName]];\n }\n },\n true,\n );\n }\n\n removeWatch = destination.$watch(\n attrName,\n (val) => {\n if (\n val === lastValue &&\n !isUndefined(attrs[attrName])\n ) {\n return;\n }\n\n if (\n (!!parentGet.inputs && !parentGet.literal) ||\n (isUndefined(attrs[attrName]) && isDefined(val))\n ) {\n destination.$target[attrName] = lastValue;\n throw $compileMinErr(\n \"nonassign\",\n \"Expression '{0}' in attribute '{1}' used with directive '{2}' is non-assignable!\",\n attrs[attrName],\n attrName,\n directive.name,\n );\n } else {\n // manually set the handler to avoid watch cycles\n if (isObject(val)) {\n entries(val).forEach(([key, value]) => {\n scope.$target[key] = value;\n });\n } else {\n parentSet(scope.$target, (lastValue = val));\n scope.$handler.watchers\n .get(attrs[attrName])\n ?.forEach((watchFn) => {\n watchFn.listenerFn(val, scope.$target);\n });\n }\n }\n },\n true,\n );\n }\n removeWatchCollection.push(removeWatch);\n break;\n }\n\n case \"<\":\n if (!hasOwn(attrs, attrName)) {\n if (optional) {\n break;\n }\n strictBindingsCheck(attrName, directive.name);\n attrs[attrName] = undefined;\n }\n\n if (optional && !attrs[attrName]) {\n break;\n }\n\n parentGet = $parse(attrs[attrName]);\n\n destination.$target[scopeName] = parentGet(scope.$target);\n /** @type {import(\"./inteface.ts\").SimpleChange} */\n initialChanges[scopeName] = {\n currentValue: destination.$target[scopeName],\n firstChange,\n };\n scope.$target.attrs = attrs;\n\n if (attrs[attrName]) {\n removeWatch = scope.$watch(\n attrs[attrName],\n (val) => {\n destination.$target[scopeName] = val;\n recordChanges(scopeName, val, firstChange);\n\n if (firstChange) {\n firstChange = false;\n }\n },\n true,\n );\n removeWatchCollection.push(removeWatch);\n }\n break;\n\n case \"&\":\n if (!optional && !hasOwn(attrs, attrName)) {\n strictBindingsCheck(attrName, directive.name);\n }\n // Don't assign Object.prototype method to scope\n parentGet = hasOwn(attrs, attrName)\n ? $parse(attrs[attrName])\n : () => {\n /* empty */\n };\n\n // Don't assign noop to destination if expression is not valid\n if (\n parentGet.toString() ===\n (() => {\n /* empty */\n }).toString() &&\n optional\n ) {\n break;\n }\n\n destination.$target[scopeName] = function (locals) {\n return parentGet(scope.$target, locals);\n };\n\n break;\n }\n });\n }\n\n function recordChanges(key, currentValue, initial) {\n if (isFunction(destination.$onChanges)) {\n // If we have not already scheduled the top level onChangesQueue handler then do so now\n if (!onChangesQueue) {\n scope.$postUpdate(flushOnChangesQueue);\n onChangesQueue = [];\n }\n\n // If we have not already queued a trigger of onChanges for this controller then do so now\n if (!changes) {\n changes = {};\n onChangesQueue.push(triggerOnChangesHook);\n }\n // Store this change\n changes[key] = {\n currentValue,\n firstChange: initial,\n };\n }\n }\n\n function triggerOnChangesHook() {\n destination.$onChanges &&\n changes &&\n destination.$onChanges(changes);\n // Now clear the changes so that we schedule onChanges when more changes arrive\n changes = undefined;\n }\n\n return {\n initialChanges,\n removeWatches:\n removeWatchCollection.length &&\n function removeWatches() {\n for (\n let i = 0, ii = removeWatchCollection.length;\n i < ii;\n ++i\n ) {\n removeWatchCollection[i]();\n }\n },\n };\n }\n },\n ];\n }\n}\n\nfunction removeComments(jqNodes) {\n let i = jqNodes.length;\n\n if (i <= 1) {\n return jqNodes;\n }\n\n while (i--) {\n const node = jqNodes[i];\n\n if (\n node.nodeType === NodeType._COMMENT_NODE ||\n (node.nodeType === NodeType._TEXT_NODE && node.nodeValue.trim() === \"\")\n ) {\n [].splice.call(jqNodes, i, 1);\n }\n }\n\n return jqNodes;\n}\n\n/**\n * @param {String} name\n * @returns {void}\n */\nfunction assertValidDirectiveName(name) {\n const letter = name.charAt(0);\n\n if (!letter || letter !== letter.toLowerCase()) {\n throw $compileMinErr(\n \"baddir\",\n \"Directive/Component name '{0}' is invalid. The first character must be a lowercase letter\",\n name,\n );\n }\n\n if (name !== name.trim()) {\n throw $compileMinErr(\n \"baddir\",\n \"Directive/Component name '{0}' is invalid. The name should not contain leading or trailing whitespaces\",\n name,\n );\n }\n}\n","import {\n arrayRemove,\n assertNotHasOwnProperty,\n extend,\n hasAnimate,\n isBoolean,\n isObjectEmpty,\n isProxy,\n isUndefined,\n shallowCopy,\n snakeCase,\n} from \"../../shared/utils.js\";\nimport {\n DIRTY_CLASS,\n INVALID_CLASS,\n PRISTINE_CLASS,\n VALID_CLASS,\n} from \"../../shared/constants.js\";\n\n/**\n * @type {{\n * $nonscope: boolean,\n * $addControl: Function,\n * $getControls: () => any[],\n * $$renameControl: Function,\n * $removeControl: Function,\n * $setValidity: Function | ((key: any, isValid: boolean, control: any) => any),\n * $setDirty: Function,\n * $setPristine: Function,\n * $setSubmitted: Function,\n * $$setSubmitted: Function\n * }}\n */\nexport const nullFormCtrl = {\n $nonscope: true,\n $addControl: () => {\n /* empty */\n },\n $getControls: () => [],\n $$renameControl: (control, name) => {\n control.$name = name;\n },\n $removeControl: () => {\n /* empty */\n },\n $setValidity: () => {\n /* empty */\n },\n $setDirty: () => {\n /* empty */\n },\n $setPristine: () => {\n /* empty */\n },\n $setSubmitted: () => {\n /* empty */\n },\n $$setSubmitted: () => {\n /* empty */\n },\n};\n\nexport const PENDING_CLASS = \"ng-pending\";\nconst SUBMITTED_CLASS = \"ng-submitted\";\n\n/**\n * @property {boolean} $dirty True if user has already interacted with the form.\n * @property {boolean} $valid True if all of the containing forms and controls are valid.\n * @property {boolean} $invalid True if at least one containing control or form is invalid.\n * @property {boolean} $submitted True if user has submitted the form even if its invalid.\n *\n * @property {Object} $pending An object hash, containing references to controls or forms with\n * pending validators, where:\n *\n * - keys are validations tokens (error names).\n * - values are arrays of controls or forms that have a pending validator for the given error name.\n *\n * See {@link form.FormController#$error $error} for a list of built-in validation tokens.\n *\n * @property {Object} $error An object hash, containing references to controls or forms with failing\n * validators, where:\n *\n * - keys are validation tokens (error names),\n * - values are arrays of controls or forms that have a failing validator for the given error name.\n *\n * Built-in validation tokens:\n * - `email`\n * - `max`\n * - `maxlength`\n * - `min`\n * - `minlength`\n * - `number`\n * - `pattern`\n * - `required`\n * - `url`\n * - `date`\n * - `datetimelocal`\n * - `time`\n * - `week`\n * - `month`\n *\n * @description\n * `FormController` keeps track of all its controls and nested forms as well as the state of them,\n * such as being valid/invalid or dirty/pristine.\n *\n * Each {@link ng.directive:form form} directive creates an instance\n * of `FormController`.\n *\n */\n// asks for $scope to fool the BC controller module\n\nexport class FormController {\n static $nonscope = true;\n /* @ignore */ static $inject = [\n \"$element\",\n \"$attrs\",\n \"$scope\",\n \"$animate\",\n \"$interpolate\",\n ];\n\n /**\n * @param {Element} $element\n * @param {ng.Attributes} $attrs\n * @param {ng.Scope} $scope\n * @param {ng.AnimateService} $animate\n * @param {*} $interpolate\n */\n constructor($element, $attrs, $scope, $animate, $interpolate) {\n this.$$controls = [];\n\n this.$name = $interpolate($attrs.name || $attrs.ngForm || \"\")($scope);\n\n /**\n * @property {boolean} $dirty True if user has already interacted with the form.\n */\n this.$dirty = false;\n\n /**\n * @propertys {boolean} $pristine - True if user has not interacted with the form yet.s\n */\n this.$pristine = true;\n this.$valid = true;\n this.$invalid = false;\n this.$submitted = false;\n /** @type {FormController|Object} */\n this.$$parentForm = nullFormCtrl;\n\n this.$$element = $element;\n this.$$animate = $animate;\n this.$error = {};\n this.$$success = {};\n this.$pending = undefined;\n this.$$classCache = {};\n const isValid = this.$$element.classList.contains(VALID_CLASS);\n\n this.$$classCache[VALID_CLASS] = isValid;\n this.$$classCache[INVALID_CLASS] = !isValid;\n }\n\n /**\n * Rollback all form controls pending updates to the `$modelValue`.\n *\n * Updates may be pending by a debounced event or because the input is waiting for a some future\n * event defined in `ng-model-options`. This method is typically needed by the reset button of\n * a form that uses `ng-model-options` to pend updates.\n */\n $rollbackViewValue() {\n this.$$controls.forEach((control) => {\n control.$rollbackViewValue();\n });\n }\n\n /**\n * Commit all form controls pending updates to the `$modelValue`.\n *\n * Updates may be pending by a debounced event or because the input is waiting for a some future\n * event defined in `ng-model-options`. This method is rarely needed as `NgModelController`\n * usually handles calling this in response to input events.\n */\n $commitViewValue() {\n this.$$controls.forEach((control) => {\n control.$commitViewValue();\n });\n }\n\n /**\n * Register a control with the form. Input elements using ngModelController do this automatically\n * when they are linked.\n *\n * Note that the current state of the control will not be reflected on the new parent form. This\n * is not an issue with normal use, as freshly compiled and linked controls are in a `$pristine`\n * state.\n *\n * However, if the method is used programmatically, for example by adding dynamically created controls,\n * or controls that have been previously removed without destroying their corresponding DOM element,\n * it's the developers responsibility to make sure the current state propagates to the parent form.\n *\n * For example, if an input control is added that is already `$dirty` and has `$error` properties,\n * calling `$setDirty()` and `$validate()` afterwards will propagate the state to the parent form.\n */\n $addControl(control) {\n // Breaking change - before, inputs whose name was \"hasOwnProperty\" were quietly ignored\n // and not added to the scope. Now we throw an error.\n assertNotHasOwnProperty(control.$name, \"input\");\n this.$$controls.push(control);\n\n if (control.$name) {\n this[control.$name] = control;\n }\n control.$target.$$parentForm = this;\n }\n\n /**\n * This method returns a **shallow copy** of the controls that are currently part of this form.\n * The controls can be instances of {@link form.FormController `FormController`}\n * ({@link ngForm \"child-forms\"}) and of {@link ngModel.NgModelController `NgModelController`}.\n * If you need access to the controls of child-forms, you have to call `$getControls()`\n * recursively on them.\n * This can be used for example to iterate over all controls to validate them.\n *\n * The controls can be accessed normally, but adding to, or removing controls from the array has\n * no effect on the form. Instead, use {@link form.FormController#$addControl `$addControl()`} and\n * {@link form.FormController#$removeControl `$removeControl()`} for this use-case.\n * Likewise, adding a control to, or removing a control from the form is not reflected\n * in the shallow copy. That means you should get a fresh copy from `$getControls()` every time\n * you need access to the controls.\n */\n $getControls() {\n return shallowCopy(this.$$controls);\n }\n\n // Private API: rename a form control\n $$renameControl(control, newName) {\n const oldName = control.$name;\n\n if (this[oldName] === control) {\n delete this[oldName];\n }\n this[newName] = control;\n control.$name = newName;\n }\n\n /**\n * Deregister a control from the form.\n *\n * Input elements using ngModelController do this automatically when they are destroyed.\n *\n * Note that only the removed control's validation state (`$errors`etc.) will be removed from the\n * form. `$dirty`, `$submitted` states will not be changed, because the expected behavior can be\n * different from case to case. For example, removing the only `$dirty` control from a form may or\n * may not mean that the form is still `$dirty`.\n */\n $removeControl(control) {\n if (control.$name && this[control.$name] === control) {\n delete this[control.$name];\n }\n this.$pending &&\n Object.keys(this.$pending).forEach((name) => {\n this.$setValidity(name, null, control);\n });\n this.$error &&\n Object.keys(this.$error).forEach((name) => {\n this.$setValidity(name, null, control);\n });\n this.$$success &&\n Object.keys(this.$$success).forEach((name) => {\n this.$setValidity(name, null, control);\n });\n\n arrayRemove(this.$$controls, control);\n\n control.$target.$$parentForm = nullFormCtrl;\n }\n\n /**\n * Sets the form to a dirty state.\n *\n * This method can be called to add the 'ng-dirty' class and set the form to a dirty\n * state (ng-dirty class). This method will also propagate to parent forms.\n */\n $setDirty() {\n if (hasAnimate(this.$$element)) {\n this.$$animate.removeClass(this.$$element, PRISTINE_CLASS);\n this.$$animate.addClass(this.$$element, DIRTY_CLASS);\n } else {\n // Fallback for non-animated environments\n this.$$element.classList.remove(PRISTINE_CLASS);\n this.$$element.classList.add(DIRTY_CLASS);\n }\n this.$dirty = true;\n this.$pristine = false;\n this.$$parentForm.$setDirty();\n }\n\n /**\n * Sets the form to its pristine state.\n *\n * This method sets the form's `$pristine` state to true, the `$dirty` state to false, removes\n * the `ng-dirty` class and adds the `ng-pristine` class. Additionally, it sets the `$submitted`\n * state to false.\n *\n * This method will also propagate to all the controls contained in this form.\n *\n * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after\n * saving or resetting it.\n */\n $setPristine() {\n if (hasAnimate(this.$$element)) {\n this.$$animate.setClass(\n this.$$element,\n PRISTINE_CLASS,\n `${DIRTY_CLASS} ${SUBMITTED_CLASS}`,\n );\n } else {\n // Fallback for non-animated environments\n this.$$element.classList.remove(DIRTY_CLASS, SUBMITTED_CLASS);\n this.$$element.classList.add(PRISTINE_CLASS);\n }\n\n this.$dirty = false;\n this.$pristine = true;\n this.$submitted = false;\n this.$$controls.forEach((control) => {\n control.$setPristine();\n });\n }\n\n /**\n * Sets the form to its untouched state.\n *\n * This method can be called to remove the 'ng-touched' class and set the form controls to their\n * untouched state (ng-untouched class).\n *\n * Setting a form controls back to their untouched state is often useful when setting the form\n * back to its pristine state.\n */\n $setUntouched() {\n this.$$controls.forEach((control) => {\n control.$setUntouched();\n });\n }\n\n /**\n * Sets the form to its `$submitted` state. This will also set `$submitted` on all child and\n * parent forms of the form.\n */\n $setSubmitted() {\n /** @type {FormController} */\n let rootForm = this;\n\n while (rootForm.$$parentForm && rootForm.$$parentForm !== nullFormCtrl) {\n rootForm = rootForm.$$parentForm;\n }\n rootForm.$$setSubmitted();\n }\n\n $$setSubmitted() {\n if (hasAnimate(this.$$element)) {\n this.$$animate.addClass(this.$$element, SUBMITTED_CLASS);\n } else {\n this.$$element.classList.add(SUBMITTED_CLASS);\n }\n this.$submitted = true;\n this.$$controls.forEach((control) => {\n if (control.$$setSubmitted) {\n control.$$setSubmitted();\n }\n });\n }\n\n set(object, property, controller) {\n const list = object[property];\n\n if (!list) {\n if (isProxy(object)) {\n object = object.$target;\n }\n object[property] = [controller];\n } else {\n const index = list.indexOf(controller);\n\n if (index === -1) {\n list.push(controller);\n }\n }\n }\n\n unset(object, property, controller) {\n const list = object[property];\n\n if (!list) {\n return;\n }\n const index = arrayRemove(list, controller);\n\n if (index === -1) {\n arrayRemove(list, controller.$target);\n }\n\n if (list.length === 0) {\n delete object[property];\n }\n }\n\n /**\n * Change the validity state of the form, and notify the parent form (if any).\n *\n * Application developers will rarely need to call this method directly. It is used internally, by\n * {@link ngModel.NgModelController#$setValidity NgModelController.$setValidity()}, to propagate a\n * control's validity state to the parent `FormController`.\n *\n * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be\n * assigned to either `$error[validationErrorKey]` or `$pending[validationErrorKey]` (for\n * unfulfilled `$asyncValidators`), so that it is available for data-binding. The\n * `validationErrorKey` should be in camelCase and will get converted into dash-case for\n * class name. Example: `myError` will result in `ng-valid-my-error` and\n * `ng-invalid-my-error` classes and can be bound to as `{{ someForm.$error.myError }}`.\n * @param {boolean} state Whether the current state is valid (true), invalid (false), pending\n * (undefined), or skipped (null). Pending is used for unfulfilled `$asyncValidators`.\n * Skipped is used by AngularTS when validators do not run because of parse errors and when\n * `$asyncValidators` do not run because any of the `$validators` failed.\n * @param {import(\"../model/model.js\").NgModelController | FormController} controller - The controller whose validity state is\n * triggering the change.\n */\n $setValidity(validationErrorKey, state, controller) {\n const that = this;\n\n if (isUndefined(state)) {\n createAndSet(this, \"$pending\", validationErrorKey, controller);\n } else {\n unsetAndCleanup(this, \"$pending\", validationErrorKey, controller);\n }\n\n if (!isBoolean(state)) {\n this.unset(this.$error, validationErrorKey, controller);\n this.unset(this.$$success, validationErrorKey, controller);\n } else if (state) {\n this.unset(this.$error, validationErrorKey, controller);\n this.set(this.$$success, validationErrorKey, controller);\n } else {\n this.set(this.$error, validationErrorKey, controller);\n this.unset(this.$$success, validationErrorKey, controller);\n }\n\n if (this.$pending) {\n cachedToggleClass(this, PENDING_CLASS, true);\n this.$valid = this.$invalid = undefined;\n toggleValidationCss(this, \"\", null);\n } else {\n cachedToggleClass(this, PENDING_CLASS, false);\n this.$valid = isObjectEmpty(this.$error);\n this.$invalid = !this.$valid;\n toggleValidationCss(this, \"\", this.$valid);\n }\n\n // re-read the state as the set/unset methods could have\n // combined state in this.$error[validationError] (used for forms),\n // where setting/unsetting only increments/decrements the value,\n // and does not replace it.\n let combinedState;\n\n if (this.$pending && this.$pending[validationErrorKey]) {\n combinedState = undefined;\n } else if (this.$error[validationErrorKey]) {\n combinedState = false;\n } else if (this.$$success[validationErrorKey]) {\n combinedState = true;\n } else {\n combinedState = null;\n }\n\n toggleValidationCss(this, validationErrorKey, combinedState);\n this.$$parentForm.$setValidity(validationErrorKey, combinedState, this);\n function createAndSet(ctrl, name, value, controllerParam) {\n if (!ctrl[name]) {\n ctrl[name] = {};\n }\n that.set(ctrl[name], value, controllerParam);\n }\n\n function unsetAndCleanup(ctrl, name, value, controllerParam) {\n if (ctrl[name]) {\n that.unset(ctrl[name], value, controllerParam);\n }\n\n if (isObjectEmpty(ctrl[name])) {\n ctrl[name] = undefined;\n }\n }\n\n function cachedToggleClass(ctrl, className, switchValue) {\n if (switchValue && !ctrl.$$classCache[className]) {\n ctrl.$$animate.addClass(ctrl.$$element, className);\n ctrl.$$classCache[className] = true;\n } else if (!switchValue && ctrl.$$classCache[className]) {\n ctrl.$$animate.removeClass(ctrl.$$element, className);\n ctrl.$$classCache[className] = false;\n }\n }\n\n function toggleValidationCss(ctrl, validationErrorKeyParam, isValid) {\n validationErrorKeyParam = validationErrorKeyParam\n ? `-${snakeCase(validationErrorKeyParam, \"-\")}`\n : \"\";\n\n cachedToggleClass(\n ctrl,\n VALID_CLASS + validationErrorKeyParam,\n isValid === true,\n );\n cachedToggleClass(\n ctrl,\n INVALID_CLASS + validationErrorKeyParam,\n isValid === false,\n );\n }\n }\n}\n\n/**\n * Helper directive that makes it possible to create control groups inside a\n * {@link ng.directive:form `form`} directive.\n * These \"child forms\" can be used, for example, to determine the validity of a sub-group of\n * controls.\n *\n * <div class=\"alert alert-danger\">\n * **Note**: `ngForm` cannot be used as a replacement for `<form>`, because it lacks its\n * [built-in HTML functionality](https://html.spec.whatwg.org/#the-form-element).\n * Specifically, you cannot submit `ngForm` like a `<form>` tag. That means,\n * you cannot send data to the server with `ngForm`, or integrate it with\n * {@link ng.directive:ngSubmit `ngSubmit`}.\n * </div>\n *\n * @param {string=} ngForm|name Name of the form. If specified, the form controller will\n * be published into the related scope, under this name.\n *\n */\n\n/**\n * Directive that instantiates\n * {@link form.FormController FormController}.\n *\n * If the `name` attribute is specified, the form controller is published onto the current scope under\n * this name.\n *\n * ## Alias: {@link ng.directive:ngForm `ngForm`}\n *\n * In AngularTS, forms can be nested. This means that the outer form is valid when all of the child\n * forms are valid as well. However, browsers do not allow nesting of `<form>` elements, so\n * AngularTS provides the {@link ng.directive:ngForm `ngForm`} directive, which behaves identically to\n * `form` but can be nested. Nested forms can be useful, for example, if the validity of a sub-group\n * of controls needs to be determined.\n *\n * ## CSS classes\n * - `ng-valid` is set if the form is valid.\n * - `ng-invalid` is set if the form is invalid.\n * - `ng-pending` is set if the form is pending.\n * - `ng-pristine` is set if the form is pristine.\n * - `ng-dirty` is set if the form is dirty.\n * - `ng-submitted` is set if the form was submitted.\n *\n * Keep in mind that ngAnimate can detect each of these classes when added and removed.\n *\n *\n * ## Submitting a form and preventing the default action\n *\n * Since the role of forms in client-side AngularTS applications is different than in classical\n * roundtrip apps, it is desirable for the browser not to translate the form submission into a full\n * page reload that sends the data to the server. Instead some javascript logic should be triggered\n * to handle the form submission in an application-specific way.\n *\n * For this reason, AngularTS prevents the default action (form submission to the server) unless the\n * `<form>` element has an `action` attribute specified.\n *\n * You can use one of the following two ways to specify what javascript method should be called when\n * a form is submitted:\n *\n * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element\n * - {@link ng.directive:ngClick ngClick} directive on the first\n * button or input field of type submit (input[type=submit])\n *\n * To prevent double execution of the handler, use only one of the {@link ng.directive:ngSubmit ngSubmit}\n * or {@link ng.directive:ngClick ngClick} directives.\n * This is because of the following form submission rules in the HTML specification:\n *\n * - If a form has only one input field then hitting enter in this field triggers form submit\n * (`ngSubmit`)\n * - if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter\n * doesn't trigger submit\n * - if a form has one or more input fields and one or more buttons or input[type=submit] then\n * hitting enter in any of the input fields will trigger the click handler on the *first* button or\n * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`)\n *\n * Any pending `ngModelOptions` changes will take place immediately when an enclosing form is\n * submitted. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`\n * to have access to the updated model.\n *\n * @animations\n * Animations in ngForm are triggered when any of the associated CSS classes are added and removed.\n * These classes are: `.ng-pristine`, `.ng-dirty`, `.ng-invalid` and `.ng-valid` as well as any\n * other validations that are performed within the form. Animations in ngForm are similar to how\n * they work in ngClass and animations can be hooked into using CSS transitions, keyframes as well\n * as JS animations.\n *\n * @param {string=} isNgForm Name of the form. If specified, the form controller will be published into\n * related scope, under this name.\n */\nconst formDirectiveFactory = function (isNgForm) {\n return [\n \"$parse\",\n function ($parse) {\n return {\n name: \"form\",\n restrict: isNgForm ? \"EA\" : \"E\",\n require: [\"form\", \"^^?form\"], // first is the form's own ctrl, second is an optional parent form\n controller: FormController,\n compile: function ngFormCompile(formElement, attr) {\n // Setup initial state of the control\n formElement.classList.add(PRISTINE_CLASS, VALID_CLASS);\n\n const nameAttr = attr.name\n ? \"name\"\n : isNgForm && attr.ngForm\n ? \"ngForm\"\n : false;\n\n return {\n pre: function ngFormPreLink(\n scope,\n formElementParam,\n attrParam,\n ctrls,\n ) {\n const controller = ctrls[0];\n\n // if `action` attr is not present on the form, prevent the default action (submission)\n if (!(\"action\" in attrParam)) {\n // we can't use jq events because if a form is destroyed during submission the default\n // action is not prevented. see #1238\n //\n // IE 9 is not affected because it doesn't fire a submit event and try to do a full\n // page reload if the form was destroyed by submission of the form via a click handler\n // on a button in the form. Looks like an IE9 specific bug.\n const handleFormSubmission = function (event) {\n controller.$commitViewValue();\n controller.$setSubmitted();\n event.preventDefault();\n };\n\n formElementParam.addEventListener(\n \"submit\",\n handleFormSubmission,\n );\n\n // unregister the preventDefault listener so that we don't not leak memory but in a\n // way that will achieve the prevention of the default action.\n formElementParam.addEventListener(\"$destroy\", () => {\n setTimeout(\n () => {\n formElementParam.removeEventListener(\n \"submit\",\n handleFormSubmission,\n );\n },\n 0,\n false,\n );\n });\n }\n\n const parentFormCtrl = ctrls[1] || controller.$$parentForm;\n\n parentFormCtrl.$addControl(controller);\n\n const setter = nameAttr\n ? getSetter(controller.$name)\n : () => {\n /* empty */\n };\n\n if (nameAttr) {\n setter(scope, controller);\n attrParam.$observe(nameAttr, (newValue) => {\n if (controller.$name === newValue) return;\n scope.$target[controller.$name] = undefined;\n controller.$$parentForm.$$renameControl(controller, newValue);\n\n if (\n scope.$target !== controller.$$parentForm &&\n controller.$$parentForm !== nullFormCtrl\n ) {\n // form moved\n } else {\n scope.$target[newValue] = controller;\n }\n });\n }\n formElementParam.addEventListener(\"$destroy\", () => {\n controller.$target.$$parentForm.$removeControl(controller);\n setter(scope, undefined);\n extend(controller, nullFormCtrl); // stop propagating child destruction handlers upwards\n });\n },\n };\n },\n };\n function getSetter(expression) {\n if (expression === \"\") {\n // create an assignable expression, so forms with an empty name can be renamed later\n return $parse('this[\"\"]').assign;\n }\n\n return (\n $parse(expression).assign ||\n (() => {\n /* empty */\n })\n );\n }\n },\n ];\n};\n\nexport const formDirective = formDirectiveFactory();\nexport const ngFormDirective = formDirectiveFactory(\"ngForm\");\n\n// helper methods\nexport function setupValidity(instance) {\n instance.$$classCache = {};\n instance.$$classCache[INVALID_CLASS] = !(instance.$$classCache[VALID_CLASS] =\n instance.$$element.classList.contains(VALID_CLASS));\n}\n","import { entries, isDefined, keys, trim } from \"../../shared/utils.js\";\n\nconst DEFAULT_REGEXP = /(\\s+|^)default(\\s+|$)/;\n\n/**\n * @typedef {Object} ModelOptionsConfig\n * @property {string} [updateOn] - A string specifying which events the input should be bound to. Multiple events can be set using a space-delimited list. The special event 'default' matches the default events belonging to the control.\n * @property {number|Object.<string, number>} [debounce] - An integer specifying the debounce time in milliseconds. A value of 0 triggers an immediate update. If an object is supplied, custom debounce values can be set for each event.\n * @property {boolean} [allowInvalid] - Indicates whether the model can be set with values that did not validate correctly. Defaults to false, which sets the model to undefined on validation failure.\n * @property {boolean} [getterSetter] - Determines whether to treat functions bound to `ngModel` as getters/setters. Defaults to false.\n * @property {boolean} [updateOnDefault]\n */\n\nclass NgModelOptionsController {\n static $nonscope = true;\n /* @ignore */ static $inject = [\"$attrs\", \"$scope\"];\n\n /**\n * @param {ng.Attributes} $attrs\n * @param {ng.Scope} $scope\n */\n constructor($attrs, $scope) {\n this.$$attrs = $attrs;\n this.$$scope = $scope;\n /** @type {NgModelOptionsController?} */\n this.parentCtrl;\n }\n\n $onInit() {\n const parentOptions = this.parentCtrl\n ? this.parentCtrl.$options\n : defaultModelOptions;\n\n const modelOptionsDefinition = this.$$scope.$eval(\n this.$$attrs.ngModelOptions,\n );\n\n this.$options = parentOptions.createChild(modelOptionsDefinition);\n }\n}\n\n/**\n * @description\n * A container for the options set by the {@link ngModelOptions} directive\n */\nclass ModelOptions {\n static $nonscope = true;\n\n /**\n * @param {ModelOptionsConfig} options\n */\n constructor(options) {\n /** @type {ModelOptionsConfig} */\n this.$$options = options;\n }\n\n /**\n * Returns the value of the given option\n * @param {string} name the name of the option to retrieve\n * @returns {string|boolean|number|Object.<string, number>} the value of the option *\n */\n getOption(name) {\n return this.$$options[name];\n }\n\n /**\n * @param {ModelOptionsConfig} options a hash of options for the new child that will override the parent's options\n * @return {ModelOptions} a new `ModelOptions` object initialized with the given options.\n */\n createChild(options) {\n let inheritAll = false;\n\n // make a shallow copy\n options = Object.assign({}, options);\n\n // Inherit options from the parent if specified by the value `\"$inherit\"`\n entries(options).forEach(([key, option]) => {\n if (option === \"$inherit\") {\n if (key === \"*\") {\n inheritAll = true;\n } else {\n options[key] = this.$$options[key];\n\n // `updateOn` is special so we must also inherit the `updateOnDefault` option\n if (key === \"updateOn\") {\n options.updateOnDefault = this.$$options.updateOnDefault;\n }\n }\n } else if (key === \"updateOn\") {\n // If the `updateOn` property contains the `default` event then we have to remove\n // it from the event list and set the `updateOnDefault` flag.\n options.updateOnDefault = false;\n options[key] = trim(\n /** @type {string} */ (option).replace(DEFAULT_REGEXP, () => {\n options.updateOnDefault = true;\n\n return \" \";\n }),\n );\n }\n }, this);\n\n if (inheritAll) {\n // We have a property of the form: `\"*\": \"$inherit\"`\n delete options[\"*\"];\n defaults(options, this.$$options);\n }\n\n // Finally add in any missing defaults\n defaults(options, defaultModelOptions.$$options);\n\n return new ModelOptions(options);\n }\n}\n\nexport const defaultModelOptions = new ModelOptions({\n updateOn: \"\",\n updateOnDefault: true,\n debounce: 0,\n getterSetter: false,\n allowInvalid: false,\n});\n\n/**\n * @returns {ng.Directive}\n */\nexport function ngModelOptionsDirective() {\n return {\n restrict: \"A\",\n // ngModelOptions needs to run before ngModel and input directives\n priority: 10,\n require: { parentCtrl: \"?^^ngModelOptions\" },\n bindToController: true,\n controller: NgModelOptionsController,\n };\n}\n\n// shallow copy over values from `src` that are not already specified on `dst`\nfunction defaults(dst, src) {\n keys(src).forEach((key) => {\n if (!isDefined(dst[key])) {\n dst[key] = src[key];\n }\n });\n}\n","import {\n DIRTY_CLASS,\n EMPTY_CLASS,\n INVALID_CLASS,\n NOT_EMPTY_CLASS,\n PRISTINE_CLASS,\n TOUCHED_CLASS,\n UNTOUCHED_CLASS,\n VALID_CLASS,\n} from \"../../shared/constants.js\";\nimport {\n entries,\n hasAnimate,\n isBoolean,\n isFunction,\n isNumber,\n isNumberNaN,\n isObjectEmpty,\n isPromiseLike,\n isProxy,\n isUndefined,\n keys,\n minErr,\n snakeCase,\n} from \"../../shared/utils.js\";\nimport { PENDING_CLASS, nullFormCtrl } from \"../form/form.js\";\nimport { defaultModelOptions } from \"../model-options/model-options.js\";\nimport { startingTag } from \"../../shared/dom.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n\nexport const ngModelMinErr = minErr(\"ngModel\");\n\n/**\n * \n * @property {*} $viewValue The actual value from the control's view.\n *\n * @property {*} $modelValue The value in the model that the control is bound to.\n * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever\n * the control updates the ngModelController with a new `$viewValue` from the DOM, usually via user input.\n *\n * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever\n the bound ngModel expression changes programmatically. The `$formatters` are not called when the\n value of the control is changed by user interaction.\n *\n * @property {Object.<string, (string, string) => boolean>} $validators A collection of validators that are applied whenever the model value changes. \n * The key value within the object refers to the name of the validator while the function refers to the validation operation. \n * The validation operation is provided with the model value as an argument and must return a true or false value depending on the response of that validation.\n *\n * @property {Object.<string, function(string, string) => Promise>} $asyncValidators A collection of validations that are expected to perform an asynchronous validation (e.g. a HTTP request).\n * The validation function that is provided is expected to return a promise when it is run during the model validation process\n *\n * @property {Array.<Function>} $viewChangeListeners Array of functions to execute whenever\n * a change to {@link ngModel.NgModelController#$viewValue `$viewValue`} has caused a change\n * to {@link ngModel.NgModelController#$modelValue `$modelValue`}.\n * It is called with no arguments, and its return value is ignored.\n * This can be used in place of additional $watches against the model value.\n *\n * @property {Object} $error An object hash with all failing validator ids as keys.\n * @property {Object} $pending An object hash with all pending validator ids as keys.\n *\n * @property {boolean} $untouched True if control has not lost focus yet.\n * @property {boolean} $touched True if control has lost focus.\n * @property {boolean} $pristine True if user has not interacted with the control yet.\n * @property {boolean} $dirty True if user has already interacted with the control.\n * @property {boolean} $valid True if there is no error.\n * @property {boolean} $invalid True if at least one error on the control.\n * @property {string} $name The name attribute of the control.\n */\n\nexport class NgModelController {\n static $nonscope = true;\n /* @ignore */ static $inject = [\n \"$scope\",\n $t.$exceptionHandler,\n \"$attrs\",\n \"$element\",\n $t.$parse,\n $t.$animate,\n $t.$interpolate,\n ];\n\n /**\n * @param {ng.Scope} $scope\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @param {ng.Attributes} $attr\n * @param {Element} $element\n * @param {ng.ParseService} $parse\n * @param {ng.AnimateService} $animate\n * @param {*} $interpolate\n */\n constructor(\n $scope,\n $exceptionHandler,\n $attr,\n $element,\n $parse,\n $animate,\n $interpolate,\n ) {\n /** @type {any} The actual value from the control's view */\n this.$viewValue = Number.NaN;\n\n /** @type {any} The value in the model that the control is bound to. */\n this.$modelValue = Number.NaN;\n /** @type {any} */\n this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity.\n\n /** @type {any} */\n this.$validators = {};\n\n /** @type {any} */\n this.$asyncValidators = {};\n\n /** @type {Array<any>} */\n this.$parsers = [];\n\n /** @type {Array<any>} */\n this.$formatters = [];\n\n /** @type {Array<any>} */\n this.$viewChangeListeners = [];\n\n /** @type {boolean} */\n this.$untouched = true;\n\n /** @type {boolean} */\n this.$touched = false;\n\n /** @type {boolean} */\n this.$pristine = true;\n\n /** @type {boolean} */\n this.$dirty = false;\n\n /** @type {boolean} */\n this.$valid = true;\n\n /** @type {boolean} */\n this.$invalid = false;\n\n this.$error = {}; // keep invalid keys here\n this.$$success = {}; // keep valid keys here\n this.$pending = undefined; // keep pending keys here\n this.$name = $interpolate($attr.name || \"\", false)($scope);\n this.$$parentForm = nullFormCtrl;\n this.$options = defaultModelOptions;\n this.$$updateEvents = \"\";\n // Attach the correct context to the event handler function for updateOn\n this.$$updateEventHandler = this.$$updateEventHandler.bind(this);\n\n this.$$parsedNgModel = $parse($attr.ngModel);\n this.$$parsedNgModelAssign = this.$$parsedNgModel.assign;\n\n /**\n * @type {import(\"../../core/parse/interface.ts\").CompiledExpression |\n * (function(ng.Scope): any)}\n */\n this.$$ngModelGet = this.$$parsedNgModel;\n this.$$ngModelSet = this.$$parsedNgModelAssign;\n this.$$pendingDebounce = null;\n this.$$parserValid = undefined;\n\n /** @type {string} */\n this.$$parserName = \"parse\";\n\n /** @type {number} */\n this.$$currentValidationRunId = 0;\n\n /** @type {ng.Scope} */\n this.$$scope = $scope; // attempt to bind to nearest controller if present\n this.$$attr = $attr;\n this.$$element = $element;\n this.$$animate = $animate;\n this.$$parse = $parse;\n this.$$exceptionHandler = $exceptionHandler;\n\n this.$$hasNativeValidators = false;\n\n this.$$classCache = {};\n const isValid = this.$$element.classList.contains(VALID_CLASS);\n\n this.$$classCache[VALID_CLASS] = isValid;\n this.$$classCache[INVALID_CLASS] = !isValid;\n\n this.$$eventRemovers = new Set();\n\n setupModelWatcher(this);\n }\n\n set(object, property) {\n object[property] = true;\n }\n\n unset(object, property) {\n delete object[property];\n }\n\n $setValidity(validationErrorKey, state) {\n const that = this;\n\n function createAndSet(ctrl, name, value) {\n if (!ctrl[name]) {\n ctrl[name] = {};\n }\n that.set(ctrl[name], value);\n }\n\n function unsetAndCleanup(ctrl, name, value) {\n if (ctrl[name]) {\n that.unset(ctrl[name], value);\n }\n\n if (isObjectEmpty(ctrl[name])) {\n ctrl[name] = undefined;\n }\n }\n\n function cachedToggleClass(ctrl, className, switchValue) {\n if (switchValue && !ctrl.$$classCache[className]) {\n if (hasAnimate(ctrl.$$element)) {\n ctrl.$$animate.addClass(ctrl.$$element, className);\n } else {\n ctrl.$$element.classList.add(className);\n }\n\n ctrl.$$classCache[className] = true;\n } else if (!switchValue && ctrl.$$classCache[className]) {\n if (hasAnimate(ctrl.$$element)) {\n ctrl.$$animate.removeClass(ctrl.$$element, className);\n } else {\n ctrl.$$element.classList.remove(className);\n }\n ctrl.$$classCache[className] = false;\n }\n }\n\n function toggleValidationCss(ctrl, validationErrorKeyParam, isValid) {\n validationErrorKeyParam = validationErrorKeyParam\n ? `-${snakeCase(validationErrorKeyParam, \"-\")}`\n : \"\";\n\n cachedToggleClass(\n ctrl,\n VALID_CLASS + validationErrorKeyParam,\n isValid === true,\n );\n cachedToggleClass(\n ctrl,\n INVALID_CLASS + validationErrorKeyParam,\n isValid === false,\n );\n }\n\n if (isUndefined(state)) {\n createAndSet(this, \"$pending\", validationErrorKey);\n } else {\n unsetAndCleanup(this, \"$pending\", validationErrorKey);\n }\n\n if (!isBoolean(state)) {\n delete this.$error[validationErrorKey];\n delete this.$$success[validationErrorKey];\n } else if (state) {\n delete this.$error[validationErrorKey];\n this.set(this.$$success, validationErrorKey);\n } else {\n this.set(this.$error, validationErrorKey);\n delete this.$$success[validationErrorKey];\n }\n\n if (this.$pending) {\n cachedToggleClass(this, PENDING_CLASS, true);\n this.$valid = this.$invalid = undefined;\n toggleValidationCss(this, \"\", null);\n } else {\n cachedToggleClass(this, PENDING_CLASS, false);\n this.$valid = isObjectEmpty(this.$error);\n this.$invalid = !this.$valid;\n toggleValidationCss(this, \"\", this.$valid);\n }\n\n // re-read the state as the set/unset methods could have\n // combined state in this.$error[validationError] (used for forms),\n // where setting/unsetting only increments/decrements the value,\n // and does not replace it.\n let combinedState;\n\n if (this.$pending && this.$pending[validationErrorKey]) {\n combinedState = undefined;\n } else if (this.$error[validationErrorKey]) {\n combinedState = false;\n } else if (this.$$success[validationErrorKey]) {\n combinedState = true;\n } else {\n combinedState = null;\n }\n\n toggleValidationCss(this, validationErrorKey, combinedState);\n this.$$parentForm.$setValidity(validationErrorKey, combinedState, this);\n }\n\n $$initGetterSetters() {\n if (this.$options.getOption(\"getterSetter\")) {\n const invokeModelGetter = this.$$parse(`${this.$$attr.ngModel}()`);\n\n const invokeModelSetter = this.$$parse(`${this.$$attr.ngModel}($$$p)`);\n\n this.$$ngModelGet = ($scope) => {\n let modelValue = this.$$parsedNgModel($scope);\n\n if (isFunction(modelValue)) {\n modelValue = invokeModelGetter($scope);\n }\n\n return modelValue;\n };\n this.$$ngModelSet = ($scope, newValue) => {\n if (isFunction(this.$$parsedNgModel($scope))) {\n invokeModelSetter($scope, { $$$p: newValue });\n } else {\n this.$$parsedNgModelAssign($scope, newValue);\n }\n };\n } else if (!this.$$parsedNgModel.assign) {\n throw ngModelMinErr(\n \"nonassign\",\n \"Expression '{0}' is non-assignable. Element: {1}\",\n this.$$attr.ngModel,\n startingTag(this.$$element),\n );\n }\n }\n\n /**\n * Called when the view needs to be updated. It is expected that the user of the ng-model\n * directive will implement this method.\n *\n * The `$render()` method is invoked in the following situations:\n *\n * * `$rollbackViewValue()` is called. If we are rolling back the view value to the last\n * committed value then `$render()` is called to update the input control.\n * * The value referenced by `ng-model` is changed programmatically and both the `$modelValue` and\n * the `$viewValue` are different from last time.\n *\n * Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of\n * `$modelValue` and `$viewValue` are actually different from their previous values. If `$modelValue`\n * or `$viewValue` are objects (rather than a string or number) then `$render()` will not be\n * invoked if you only change a property on the objects.\n */\n $render() {\n /* empty */\n }\n\n /**\n * This is called when we need to determine if the value of an input is empty.\n *\n * For instance, the required directive does this to work out if the input has data or not.\n *\n * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`.\n *\n * You can override this for input directives whose concept of being empty is different from the\n * default. The `checkboxInputType` directive does this because in its case a value of `false`\n * implies empty.\n *\n * @param {*} value The value of the input to check for emptiness.\n * @returns {boolean} True if `value` is \"empty\".\n */\n $isEmpty(value) {\n return (\n isUndefined(value) ||\n value === \"\" ||\n value === null ||\n Number.isNaN(value)\n );\n }\n\n $$updateEmptyClasses(value) {\n if (this.$isEmpty(value)) {\n if (hasAnimate(this.$$element)) {\n this.$$animate.removeClass(this.$$element, NOT_EMPTY_CLASS);\n this.$$animate.addClass(this.$$element, EMPTY_CLASS);\n } else {\n this.$$element.classList.remove(NOT_EMPTY_CLASS);\n this.$$element.classList.add(EMPTY_CLASS);\n }\n } else {\n if (hasAnimate(this.$$element)) {\n this.$$animate.removeClass(this.$$element, EMPTY_CLASS);\n this.$$animate.addClass(this.$$element, NOT_EMPTY_CLASS);\n } else {\n this.$$element.classList.remove(EMPTY_CLASS);\n this.$$element.classList.add(NOT_EMPTY_CLASS);\n }\n }\n }\n\n /**\n * Sets the control to its pristine state.\n *\n * This method can be called to remove the `ng-dirty` class and set the control to its pristine\n * state (`ng-pristine` class). A model is considered to be pristine when the control\n * has not been changed from when first compiled.\n */\n $setPristine() {\n this.$dirty = false;\n this.$pristine = true;\n\n if (!this.$$element) return;\n\n if (hasAnimate(this.$$element)) {\n this.$$animate.removeClass(this.$$element, EMPTY_CLASS);\n this.$$animate.addClass(this.$$element, PRISTINE_CLASS);\n } else {\n this.$$element.classList.remove(EMPTY_CLASS);\n this.$$element.classList.add(PRISTINE_CLASS);\n }\n }\n\n /**\n * Sets the control to its dirty state.\n *\n * This method can be called to remove the `ng-pristine` class and set the control to its dirty\n * state (`ng-dirty` class). A model is considered to be dirty when the control has been changed\n * from when first compiled.\n */\n $setDirty() {\n this.$dirty = true;\n this.$pristine = false;\n\n if (hasAnimate(this.$$element)) {\n this.$$animate.removeClass(this.$$element, PRISTINE_CLASS);\n this.$$animate.addClass(this.$$element, DIRTY_CLASS);\n } else {\n this.$$element.classList.remove(PRISTINE_CLASS);\n this.$$element.classList.add(DIRTY_CLASS);\n }\n this.$$parentForm.$setDirty();\n }\n\n /**\n * Sets the control to its untouched state.\n *\n * This method can be called to remove the `ng-touched` class and set the control to its\n * untouched state (`ng-untouched` class). Upon compilation, a model is set as untouched\n * by default, however this function can be used to restore that state if the model has\n * already been touched by the user.\n */\n $setUntouched() {\n this.$touched = false;\n this.$untouched = true;\n\n if (hasAnimate(this.$$element)) {\n this.$$animate.setClass(this.$$element, UNTOUCHED_CLASS, TOUCHED_CLASS);\n } else {\n this.$$element.classList.remove(TOUCHED_CLASS);\n this.$$element.classList.add(UNTOUCHED_CLASS);\n }\n }\n\n /**\n * Sets the control to its touched state.\n *\n * This method can be called to remove the `ng-untouched` class and set the control to its\n * touched state (`ng-touched` class). A model is considered to be touched when the user has\n * first focused the control element and then shifted focus away from the control (blur event).\n */\n $setTouched() {\n this.$touched = true;\n this.$untouched = false;\n\n if (hasAnimate(this.$$element)) {\n this.$$animate.setClass(this.$$element, TOUCHED_CLASS, UNTOUCHED_CLASS);\n } else {\n this.$$element.classList.remove(UNTOUCHED_CLASS);\n this.$$element.classList.add(TOUCHED_CLASS);\n }\n }\n\n /**\n * Cancel an update and reset the input element's value to prevent an update to the `$modelValue`,\n * which may be caused by a pending debounced event or because the input is waiting for some\n * future event.\n *\n * If you have an input that uses `ng-model-options` to set up debounced updates or updates that\n * depend on special events such as `blur`, there can be a period when the `$viewValue` is out of\n * sync with the ngModel's `$modelValue`.\n *\n * In this case, you can use `$rollbackViewValue()` to manually cancel the debounced / future update\n * and reset the input to the last committed view value.\n *\n * It is also possible that you run into difficulties if you try to update the ngModel's `$modelValue`\n * programmatically before these debounced/future events have resolved/occurred, because AngularTS's\n * dirty checking mechanism is not able to tell whether the model has actually changed or not.\n *\n * The `$rollbackViewValue()` method should be called before programmatically changing the model of an\n * input which may have such events pending. This is important in order to make sure that the\n * input field will be updated with the new model value and any pending operations are cancelled.\n *\n * @example\n * <example name=\"ng-model-cancel-update\" module=\"cancel-update-example\">\n * <file name=\"app.js\">\n * angular.module('cancel-update-example', [])\n *\n * .controller('CancelUpdateController', ['$scope', function($scope) {\n * $scope.model = {value1: '', value2: ''};\n *\n * $scope.setEmpty = function(e, value, rollback) {\n * if (e.keyCode === 27) {\n * e.preventDefault();\n * if (rollback) {\n * $scope.myForm[value].$rollbackViewValue();\n * }\n * $scope.model[value] = '';\n * }\n * };\n * }]);\n * </file>\n * <file name=\"index.html\">\n * <div ng-controller=\"CancelUpdateController\">\n * <p>Both of these inputs are only updated if they are blurred. Hitting escape should\n * empty them. Follow these steps and observe the difference:</p>\n * <ol>\n * <li>Type something in the input. You will see that the model is not yet updated</li>\n * <li>Press the Escape key.\n * <ol>\n * <li> In the first example, nothing happens, because the model is already '', and no\n * update is detected. If you blur the input, the model will be set to the current view.\n * </li>\n * <li> In the second example, the pending update is cancelled, and the input is set back\n * to the last committed view value (''). Blurring the input does nothing.\n * </li>\n * </ol>\n * </li>\n * </ol>\n *\n * <form name=\"myForm\" ng-model-options=\"{ updateOn: 'blur' }\">\n * <div>\n * <p id=\"inputDescription1\">Without $rollbackViewValue():</p>\n * <input name=\"value1\" aria-describedby=\"inputDescription1\" ng-model=\"model.value1\"\n * ng-keydown=\"setEmpty($event, 'value1')\">\n * value1: \"{{ model.value1 }}\"\n * </div>\n *\n * <div>\n * <p id=\"inputDescription2\">With $rollbackViewValue():</p>\n * <input name=\"value2\" aria-describedby=\"inputDescription2\" ng-model=\"model.value2\"\n * ng-keydown=\"setEmpty($event, 'value2', true)\">\n * value2: \"{{ model.value2 }}\"\n * </div>\n * </form>\n * </div>\n * </file>\n <file name=\"style.css\">\n div {\n display: table-cell;\n }\n div:nth-child(1) {\n padding-right: 30px;\n }\n\n </file>\n * </example>\n */\n $rollbackViewValue() {\n clearTimeout(this.$$pendingDebounce);\n this.$viewValue = this.$$lastCommittedViewValue;\n this.$render();\n }\n\n /**\n * Runs each of the registered validators (first synchronous validators and then\n * asynchronous validators).\n * If the validity changes to invalid, the model will be set to `undefined`,\n * unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`.\n * If the validity changes to valid, it will set the model to the last available valid\n * `$modelValue`, i.e. either the last parsed value or the last value set from the scope.\n */\n $validate() {\n // ignore $validate before model is initialized\n if (isNumberNaN(this.$modelValue)) {\n return;\n }\n\n const viewValue = this.$$lastCommittedViewValue;\n\n // Note: we use the $$rawModelValue as $modelValue might have been\n // set to undefined during a view -> model update that found validation\n // errors. We can't parse the view here, since that could change\n // the model although neither viewValue nor the model on the scope changed\n const modelValue = this.$$rawModelValue;\n\n const prevValid = this.$valid;\n\n const prevModelValue = this.$modelValue;\n\n const allowInvalid = this.$options.getOption(\"allowInvalid\");\n\n const that = this;\n\n this.$$runValidators(modelValue, viewValue, (allValid) => {\n // If there was no change in validity, don't update the model\n // This prevents changing an invalid modelValue to undefined\n if (!allowInvalid && prevValid !== allValid) {\n // Note: Don't check this.$valid here, as we could have\n // external validators (e.g. calculated on the server),\n // that just call $setValidity and need the model value\n // to calculate their validity.\n that.$modelValue = allValid ? modelValue : undefined;\n\n if (that.$modelValue !== prevModelValue) {\n that.$$writeModelToScope();\n }\n }\n });\n }\n\n $$runValidators(modelValue, viewValue, doneCallback) {\n this.$$currentValidationRunId++;\n const localValidationRunId = this.$$currentValidationRunId;\n\n const that = this;\n\n // check parser error\n if (!processParseErrors()) {\n validationDone(false);\n\n return;\n }\n\n if (!processSyncValidators()) {\n validationDone(false);\n\n return;\n }\n processAsyncValidators();\n\n function processParseErrors() {\n const errorKey = that.$$parserName;\n\n if (isUndefined(that.$$parserValid)) {\n setValidity(errorKey, null);\n } else {\n if (!that.$$parserValid) {\n keys(that.$validators).forEach((name) => {\n setValidity(name, null);\n });\n keys(that.$asyncValidators).forEach((name) => {\n setValidity(name, null);\n });\n }\n\n // Set the parse error last, to prevent unsetting it, should a $validators key == parserName\n setValidity(errorKey, that.$$parserValid);\n\n return that.$$parserValid;\n }\n\n return true;\n }\n\n function processSyncValidators() {\n let syncValidatorsValid = true;\n\n entries(that.$validators).forEach(([name, validator]) => {\n const result = Boolean(validator(modelValue, viewValue));\n\n syncValidatorsValid = syncValidatorsValid && result;\n setValidity(name, result);\n });\n\n if (!syncValidatorsValid) {\n keys(that.$asyncValidators).forEach((name) => {\n setValidity(name, null);\n });\n\n return false;\n }\n\n return true;\n }\n\n function processAsyncValidators() {\n const validatorPromises = [];\n\n let allValid = true;\n\n entries(that.$asyncValidators).forEach(([name, validator]) => {\n const promise = validator(modelValue, viewValue);\n\n if (!isPromiseLike(promise)) {\n throw ngModelMinErr(\n \"nopromise\",\n \"Expected asynchronous validator to return a promise but got '{0}' instead.\",\n promise,\n );\n }\n setValidity(name, undefined);\n validatorPromises.push(\n promise.then(\n () => {\n setValidity(name, true);\n },\n () => {\n allValid = false;\n setValidity(name, false);\n },\n ),\n );\n });\n\n if (!validatorPromises.length) {\n validationDone(true);\n } else {\n Promise.all(validatorPromises).then(\n () => {\n validationDone(allValid);\n },\n () => {\n /* empty */\n },\n );\n }\n }\n\n function setValidity(name, isValid) {\n if (localValidationRunId === that.$$currentValidationRunId) {\n that.$setValidity(name, isValid);\n }\n }\n\n function validationDone(allValid) {\n if (localValidationRunId === that.$$currentValidationRunId) {\n doneCallback(allValid);\n }\n }\n }\n\n /**\n * Commit a pending update to the `$modelValue`.\n *\n * Updates may be pending by a debounced event or because the input is waiting for a some future\n * event defined in `ng-model-options`. this method is rarely needed as `NgModelController`\n * usually handles calling this in response to input events.\n */\n $commitViewValue() {\n clearTimeout(this.$$pendingDebounce);\n\n // If the view value has not changed then we should just exit, except in the case where there is\n // a native validator on the element. In this case the validation state may have changed even though\n // the viewValue has stayed empty.\n if (\n this.$$lastCommittedViewValue === this.$viewValue &&\n (this.$viewValue !== \"\" || !this.$$hasNativeValidators)\n ) {\n return;\n }\n\n if (\n this.$$lastCommittedViewValue === undefined &&\n Number.isNaN(this.$viewValue)\n ) {\n return;\n }\n\n this.$$updateEmptyClasses(this.$viewValue);\n this.$$lastCommittedViewValue = this.$viewValue;\n\n // change to dirty\n if (this.$pristine) {\n this.$setDirty();\n }\n this.$$parseAndValidate();\n }\n\n $$parseAndValidate() {\n let modelValue = this.$$lastCommittedViewValue;\n\n const that = this;\n\n this.$$parserValid = isUndefined(modelValue) ? undefined : true;\n\n // Reset any previous parse error\n this.$setValidity(this.$$parserName, null);\n this.$$parserName = \"parse\";\n\n if (this.$$parserValid) {\n for (let i = 0; i < this.$parsers.length; i++) {\n modelValue = this.$parsers[i](modelValue);\n\n if (isUndefined(modelValue)) {\n this.$$parserValid = false;\n break;\n }\n }\n }\n\n if (isNumberNaN(this.$modelValue)) {\n // this.$modelValue has not been touched yet...\n // @ts-ignore\n this.$modelValue = this.$$ngModelGet(this.$$scope);\n }\n const prevModelValue = this.$modelValue;\n\n const allowInvalid = this.$options.getOption(\"allowInvalid\");\n\n this.$$rawModelValue = modelValue;\n\n if (allowInvalid) {\n this.$modelValue = modelValue;\n writeToModelIfNeeded();\n }\n\n // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date.\n // This can happen if e.g. $setViewValue is called from inside a parser\n this.$$runValidators(\n modelValue,\n this.$$lastCommittedViewValue,\n (allValid) => {\n if (!allowInvalid) {\n // Note: Don't check this.$valid here, as we could have\n // external validators (e.g. calculated on the server),\n // that just call $setValidity and need the model value\n // to calculate their validity.\n // if (that.$modelValue ?? that.$modelValue[isProxySymbol]) {\n // delete that.$modelValue;\n // }\n that.$modelValue = allValid ? modelValue : undefined;\n writeToModelIfNeeded();\n }\n },\n );\n\n function writeToModelIfNeeded() {\n // intentional loose equality\n // eslint-disable-next-line eqeqeq\n if (that.$modelValue != prevModelValue) {\n that.$$writeModelToScope();\n }\n }\n }\n\n $$writeModelToScope() {\n this.$$ngModelSet(this.$$scope, this.$modelValue);\n Object.values(this.$viewChangeListeners).forEach((listener) => {\n try {\n listener();\n } catch (err) {\n this.$$exceptionHandler(err);\n }\n }, this);\n }\n\n /**\n * Update the view value.\n *\n * This method should be called when a control wants to change the view value; typically,\n * this is done from within a DOM event handler. For example, the {@link ng.directive:input input}\n * directive calls it when the value of the input changes and {@link ng.directive:select select}\n * calls it when an option is selected.\n *\n * When `$setViewValue` is called, the new `value` will be staged for committing through the `$parsers`\n * and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged\n * value is sent directly for processing through the `$parsers` pipeline. After this, the `$validators` and\n * `$asyncValidators` are called and the value is applied to `$modelValue`.\n * Finally, the value is set to the **expression** specified in the `ng-model` attribute and\n * all the registered change listeners, in the `$viewChangeListeners` list are called.\n *\n * In case the {@link ng.directive:ngModelOptions ngModelOptions} directive is used with `updateOn`\n * and the `default` trigger is not listed, all those actions will remain pending until one of the\n * `updateOn` events is triggered on the DOM element.\n * All these actions will be debounced if the {@link ng.directive:ngModelOptions ngModelOptions}\n * directive is used with a custom debounce for this particular event.\n * Note that a `$digest` is only triggered once the `updateOn` events are fired, or if `debounce`\n * is specified, once the timer runs out.\n *\n * When used with standard inputs, the view value will always be a string (which is in some cases\n * parsed into another type, such as a `Date` object for `input[date]`.)\n * However, custom controls might also pass objects to this method. In this case, we should make\n * a copy of the object before passing it to `$setViewValue`. This is because `ngModel` does not\n * perform a deep watch of objects, it only looks for a change of identity. If you only change\n * the property of the object then ngModel will not realize that the object has changed and\n * will not invoke the `$parsers` and `$validators` pipelines. For this reason, you should\n * not change properties of the copy once it has been passed to `$setViewValue`.\n * Otherwise you may cause the model value on the scope to change incorrectly.\n *\n * <div class=\"alert alert-info\">\n * In any case, the value passed to the method should always reflect the current value\n * of the control. For example, if you are calling `$setViewValue` for an input element,\n * you should pass the input DOM value. Otherwise, the control and the scope model become\n * out of sync. It's also important to note that `$setViewValue` does not call `$render` or change\n * the control's DOM value in any way. If we want to change the control's DOM value\n * programmatically, we should update the `ngModel` scope expression. Its new value will be\n * picked up by the model controller, which will run it through the `$formatters`, `$render` it\n * to update the DOM, and finally call `$validate` on it.\n * </div>\n *\n * @param {*} value value from the view.\n * @param {string} [trigger] Event that triggered the update.\n */\n $setViewValue(value, trigger) {\n this.$viewValue = value;\n\n if (this.$options?.getOption(\"updateOnDefault\")) {\n this.$$debounceViewValueCommit(trigger);\n }\n }\n\n $$debounceViewValueCommit(trigger) {\n let debounceDelay = this.$options.getOption(\"debounce\");\n\n if (isNumber(debounceDelay[trigger])) {\n debounceDelay = debounceDelay[trigger];\n } else if (\n isNumber(\n /** @type {Object.<string, number>} */ (debounceDelay).default,\n ) &&\n /** @type {string} */ (this.$options.getOption(\"updateOn\")).indexOf(\n trigger,\n ) === -1\n ) {\n debounceDelay = /** @type {Object.<string, number>} */ (debounceDelay)\n .default;\n } else if (isNumber(debounceDelay[\"*\"])) {\n debounceDelay = debounceDelay[\"*\"];\n }\n\n clearTimeout(this.$$pendingDebounce);\n const that = this;\n\n if (/** @type {number} */ (debounceDelay) > 0) {\n // this fails if debounceDelay is an object\n this.$$pendingDebounce = setTimeout(() => {\n that.$commitViewValue();\n }, /** @type {number} */ (debounceDelay));\n } else {\n this.$commitViewValue();\n }\n }\n\n /**\n *\n * Override the current model options settings programmatically.\n *\n * The previous `ModelOptions` value will not be modified. Instead, a\n * new `ModelOptions` object will inherit from the previous one overriding\n * or inheriting settings that are defined in the given parameter.\n *\n * See {@link ngModelOptions} for information about what options can be specified\n * and how model option inheritance works.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** this function only affects the options set on the `ngModelController`,\n * and not the options on the {@link ngModelOptions} directive from which they might have been\n * obtained initially.\n * </div>\n *\n * <div class=\"alert alert-danger\">\n * **Note:** it is not possible to override the `getterSetter` option.\n * </div>\n *\n * @param {Object} options a hash of settings to override the previous options\n *\n */\n $overrideModelOptions(options) {\n this.$$removeAllEventListeners();\n this.$options = this.$options.createChild(options);\n this.$$updateEvents = this.$options.$$options.updateOn;\n this.$$setUpdateOnEvents();\n }\n\n /**\n * Runs the model -> view pipeline on the current\n * {@link ngModel.NgModelController#$modelValue $modelValue}.\n *\n * The following actions are performed by this method:\n *\n * - the `$modelValue` is run through the {@link ngModel.NgModelController#$formatters $formatters}\n * and the result is set to the {@link ngModel.NgModelController#$viewValue $viewValue}\n * - the `ng-empty` or `ng-not-empty` class is set on the element\n * - if the `$viewValue` has changed:\n * - {@link ngModel.NgModelController#$render $render} is called on the control\n * - the {@link ngModel.NgModelController#$validators $validators} are run and\n * the validation status is set.\n *\n * This method is called by ngModel internally when the bound scope value changes.\n * Application developers usually do not have to call this function themselves.\n *\n * This function can be used when the `$viewValue` or the rendered DOM value are not correctly\n * formatted and the `$modelValue` must be run through the `$formatters` again.\n *\n * @example\n * Consider a text input with an autocomplete list (for fruit), where the items are\n * objects with a name and an id.\n * A user enters `ap` and then selects `Apricot` from the list.\n * Based on this, the autocomplete widget will call `$setViewValue({name: 'Apricot', id: 443})`,\n * but the rendered value will still be `ap`.\n * The widget can then call `ctrl.$processModelValue()` to run the model -> view\n * pipeline again, which formats the object to the string `Apricot`,\n * then updates the `$viewValue`, and finally renders it in the DOM.\n *\n * <example module=\"inputExample\" name=\"ng-model-process\">\n <file name=\"index.html\">\n <div ng-controller=\"inputController\" style=\"display: flex;\">\n <div style=\"margin-right: 30px;\">\n Search Fruit:\n <basic-autocomplete items=\"items\" on-select=\"selectedFruit = item\"></basic-autocomplete>\n </div>\n <div>\n Model:<br>\n <pre>{{selectedFruit | json}}</pre>\n </div>\n </div>\n </file>\n <file name=\"app.js\">\n angular.module('inputExample', [])\n .controller('inputController', function($scope) {\n $scope.items = [\n {name: 'Apricot', id: 443},\n {name: 'Clementine', id: 972},\n {name: 'Durian', id: 169},\n {name: 'Jackfruit', id: 982},\n {name: 'Strawberry', id: 863}\n ];\n })\n .component('basicAutocomplete', {\n bindings: {\n items: '<',\n onSelect: '&'\n },\n templateUrl: 'autocomplete.html',\n controller: function($element, $scope) {\n let that = this;\n let ngModel;\n\n that.$postLink = function() {\n ngModel = $element.querySelectorAll('input').controller('ngModel');\n\n ngModel.$formatters.push(function(value) {\n return (value && value.name) || value;\n });\n\n ngModel.$parsers.push(function(value) {\n let match = value;\n for (let i = 0; i < that.items.length; i++) {\n if (that.items[i].name === value) {\n match = that.items[i];\n break;\n }\n }\n\n return match;\n });\n };\n\n that.selectItem = function(item) {\n ngModel.$setViewValue(item);\n ngModel.$processModelValue();\n that.onSelect({item: item});\n };\n }\n });\n </file>\n <file name=\"autocomplete.html\">\n <div>\n <input type=\"search\" ng-model=\"$ctrl.searchTerm\" />\n <ul>\n <li ng-repeat=\"item in $ctrl.items | filter:$ctrl.searchTerm\">\n <button ng-click=\"$ctrl.selectItem(item)\">{{ item.name }}</button>\n </li>\n </ul>\n </div>\n </file>\n * </example>\n *\n */\n $processModelValue() {\n const viewValue = this.$$format();\n\n if (this.$viewValue !== viewValue) {\n this.$$updateEmptyClasses(viewValue);\n this.$viewValue = this.$$lastCommittedViewValue = viewValue;\n this.$render();\n // It is possible that model and view value have been updated during render\n this.$$runValidators(this.$modelValue, this.$viewValue, () => {\n /* empty */\n });\n }\n }\n\n /**\n * This method is called internally to run the $formatters on the $modelValue\n */\n $$format() {\n const formatters = this.$formatters;\n\n let idx = formatters.length;\n\n let viewValue = this.$modelValue;\n\n while (idx--) {\n viewValue = formatters[idx](viewValue);\n }\n\n return viewValue;\n }\n\n /**\n * This method is called internally when the bound scope value changes.\n */\n $$setModelValue(modelValue) {\n this.$modelValue = this.$$rawModelValue = modelValue;\n this.$$parserValid = undefined;\n this.$processModelValue();\n }\n\n $$removeAllEventListeners() {\n this.$$eventRemovers.forEach((removeCallback) => removeCallback());\n this.$$eventRemovers.clear();\n }\n\n $$setUpdateOnEvents() {\n if (this.$$updateEvents) {\n this.$$updateEvents.split(\" \").forEach((ev) => {\n this.$$element.addEventListener(ev, this.$$updateEventHandler);\n this.$$eventRemovers.add(() =>\n this.$$element.removeEventListener(ev, this.$$updateEventHandler),\n );\n });\n }\n\n this.$$updateEvents = /** @type {string} */ (\n this.$options.getOption(\"updateOn\")\n );\n\n if (this.$$updateEvents) {\n this.$$updateEvents.split(\" \").forEach((ev) => {\n this.$$element.addEventListener(ev, this.$$updateEventHandler);\n this.$$eventRemovers.add(() =>\n this.$$element.removeEventListener(ev, this.$$updateEventHandler),\n );\n });\n }\n }\n\n $$updateEventHandler(ev) {\n this.$$debounceViewValueCommit(ev && ev.type);\n }\n}\n\nfunction setupModelWatcher(ctrl) {\n // model -> value\n // Note: we cannot use a normal scope.$watch as we want to detect the following:\n // 1. scope value is 'a'\n // 2. user enters 'b'\n // 3. ng-change kicks in and reverts scope value to 'a'\n // -> scope value did not change since the last digest as\n // ng-change executes in apply phase\n // 4. view should be changed back to 'a'\n ctrl.$$scope.$watch(\"value\", () => {\n const modelValue = ctrl.$$ngModelGet(ctrl.$$scope);\n\n // if scope model value and ngModel value are out of sync\n // This cannot be moved to the action function, because it would not catch the\n // case where the model is changed in the ngChange function or the model setter\n if (\n modelValue !== ctrl.$modelValue &&\n // checks for NaN is needed to allow setting the model to NaN when there's an asyncValidator\n\n (!Number.isNaN(ctrl.$modelValue) || !Number.isNaN(modelValue))\n ) {\n ctrl.$$setModelValue(modelValue);\n }\n });\n}\n\nexport function ngModelDirective() {\n return {\n restrict: \"A\",\n require: [\"ngModel\", \"^?form\", \"^?ngModelOptions\"],\n controller: NgModelController,\n // Prelink needs to run before any input directive\n // so that we can set the NgModelOptions in NgModelController\n // before anyone else uses it.\n priority: 1,\n compile:\n /** @param {Element} element */\n (element) => {\n // Setup initial state of the control\n element.classList.add(PRISTINE_CLASS, UNTOUCHED_CLASS, VALID_CLASS);\n\n return {\n pre: (scope, _element, attr, ctrls) => {\n const modelCtrl = ctrls[0];\n\n const formCtrl = ctrls[1] || modelCtrl.$$parentForm;\n\n const optionsCtrl = ctrls[2];\n\n if (optionsCtrl) {\n modelCtrl.$options = optionsCtrl.$options;\n }\n modelCtrl.$$initGetterSetters();\n\n // notify others, especially parent forms\n formCtrl.$addControl(modelCtrl);\n\n attr.$observe(\"name\", (newValue) => {\n if (modelCtrl.$name !== newValue) {\n modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue);\n }\n });\n const deregisterWatch = scope.$watch(attr.ngModel, (val) => {\n modelCtrl.$$setModelValue(isProxy(val) ? val.$target : val);\n });\n\n scope.$on(\"$destroy\", () => {\n modelCtrl.$$parentForm.$removeControl(modelCtrl);\n deregisterWatch();\n });\n },\n post: (scope, elementPost, _attr, ctrls) => {\n const modelCtrl = ctrls[0];\n\n modelCtrl.$$setUpdateOnEvents();\n\n function setTouched() {\n modelCtrl.$setTouched();\n }\n\n elementPost.addEventListener(\"blur\", () => {\n if (modelCtrl.$touched) return;\n setTouched();\n });\n\n modelCtrl.$viewChangeListeners.push(() =>\n scope.$eval(elementPost.dataset.change),\n );\n },\n };\n },\n };\n}\n","import {\n addDateMinutes,\n convertTimezoneToLocal,\n equals,\n isDate,\n isDefined,\n isNullOrUndefined,\n isNumber,\n isNumberNaN,\n isObject,\n isProxy,\n isString,\n isUndefined,\n nextUid,\n timezoneToOffset,\n trim,\n} from \"../../shared/utils.js\";\nimport { ngModelMinErr } from \"./../model/model.js\";\n\n// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231\nexport const ISO_DATE_REGEXP =\n /^\\d{4,}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+(?:[+-][0-2]\\d:[0-5]\\d|Z)$/;\n// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987)\n// Note: We are being more lenient, because browsers are too.\n// 1. Scheme\n// 2. Slashes\n// 3. Username\n// 4. Password\n// 5. Hostname\n// 6. Port\n// 7. Path\n// 8. Query\n// 9. Fragment\n// 1111111111111111 222 333333 44444 55555555555555555555555 666 77777777 8888888 999\nexport const URL_REGEXP =\n /^[a-z][a-z\\d.+-]*:\\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\\s:/?#]+|\\[[a-f\\d:]+])(?::\\d+)?(?:\\/[^?#]*)?(?:\\?[^#]*)?(?:#.*)?$/i;\n\nexport const EMAIL_REGEXP =\n /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;\nconst NUMBER_REGEXP = /^\\s*([-+])?(\\d+|(\\d*(\\.\\d*)))([eE][+-]?\\d+)?\\s*$/;\n\nconst DATE_REGEXP = /^(\\d{4,})-(\\d{2})-(\\d{2})$/;\n\nconst DATETIMELOCAL_REGEXP =\n /^(\\d{4,})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d)(?::(\\d\\d)(\\.\\d{1,3})?)?$/;\n\nconst WEEK_REGEXP = /^(\\d{4,})-W(\\d\\d)$/;\n\nconst MONTH_REGEXP = /^(\\d{4,})-(\\d\\d)$/;\n\nconst TIME_REGEXP = /^(\\d\\d):(\\d\\d)(?::(\\d\\d)(\\.\\d{1,3})?)?$/;\n\n// The name of a form control's ValidityState property.\n// This is used so that it's possible for internal tests to create mock ValidityStates.\nexport const VALIDITY_STATE_PROPERTY = \"validity\";\n\nconst PARTIAL_VALIDATION_EVENTS = \"keydown wheel mousedown\";\n\n/**\n * @type {Map<string, boolean>}\n */\nconst PARTIAL_VALIDATION_TYPES = new Map();\n\n\"date,datetime-local,month,time,week\".split(\",\").forEach((type) => {\n PARTIAL_VALIDATION_TYPES.set(type, true);\n});\n\nconst inputType = {\n text: textInputType,\n date: createDateInputType(\n \"date\",\n DATE_REGEXP,\n createDateParser(DATE_REGEXP, [\"yyyy\", \"MM\", \"dd\"]),\n ),\n \"datetime-local\": createDateInputType(\n \"datetimelocal\",\n DATETIMELOCAL_REGEXP,\n createDateParser(DATETIMELOCAL_REGEXP, [\n \"yyyy\",\n \"MM\",\n \"dd\",\n \"HH\",\n \"mm\",\n \"ss\",\n \"sss\",\n ]),\n ),\n time: createDateInputType(\n \"time\",\n TIME_REGEXP,\n createDateParser(TIME_REGEXP, [\"HH\", \"mm\", \"ss\", \"sss\"]),\n ),\n week: createDateInputType(\"week\", WEEK_REGEXP, weekParser),\n month: createDateInputType(\n \"month\",\n MONTH_REGEXP,\n createDateParser(MONTH_REGEXP, [\"yyyy\", \"MM\"]),\n ),\n number: numberInputType,\n url: urlInputType,\n email: emailInputType,\n radio: radioInputType,\n range: rangeInputType,\n checkbox: checkboxInputType,\n hidden: () => {\n /* empty */\n },\n button: () => {\n /* empty */\n },\n submit: () => {\n /* empty */\n },\n reset: () => {\n /* empty */\n },\n file: () => {\n /* empty */\n },\n};\n\nfunction stringBasedInputType(ctrl) {\n ctrl.$formatters.push((value) =>\n ctrl.$isEmpty(value) ? value : value.toString(),\n );\n}\n\nfunction textInputType(scope, element, attr, ctrl) {\n baseInputType(scope, element, attr, ctrl);\n stringBasedInputType(ctrl);\n}\n\nfunction baseInputType(_, element, attr, ctrl) {\n const type = element.type.toLowerCase();\n\n let composing = false;\n\n // In composition mode, users are still inputting intermediate text buffer,\n // hold the listener until composition is done.\n // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent\n element.addEventListener(\"compositionstart\", () => {\n composing = true;\n });\n\n element.addEventListener(\"compositionend\", () => {\n composing = false;\n listener();\n });\n\n let timeout;\n\n const listener = function (ev) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n\n if (composing) return;\n let { value } = element;\n\n const event = ev && ev.type;\n\n // By default we will trim the value\n // If the attribute ng-trim exists we will avoid trimming\n // If input type is 'password', the value is never trimmed\n if (type !== \"password\" && (!attr.ngTrim || attr.ngTrim !== \"false\")) {\n value = trim(value);\n }\n\n // If a control is suffering from bad input (due to native validators), browsers discard its\n // value, so it may be necessary to revalidate (by calling $setViewValue again) even if the\n // control's value is the same empty value twice in a row.\n if (\n ctrl.$viewValue !== value ||\n (value === \"\" && ctrl.$$hasNativeValidators)\n ) {\n ctrl.$target.$setViewValue(value, event);\n }\n };\n\n [\"input\", \"change\", \"paste\", \"drop\", \"cut\"].forEach((event) => {\n element.addEventListener(event, listener);\n });\n\n // Some native input types (date-family) have the ability to change validity without\n // firing any input/change events.\n // For these event types, when native validators are present and the browser supports the type,\n // check for validity changes on various DOM events.\n if (\n PARTIAL_VALIDATION_TYPES[type] &&\n ctrl.$$hasNativeValidators &&\n type === attr.type\n ) {\n element.addEventListener(PARTIAL_VALIDATION_EVENTS, (ev) => {\n if (!timeout) {\n // eslint-disable-next-line no-invalid-this\n const validity = this[VALIDITY_STATE_PROPERTY];\n\n const origBadInput = validity.badInput;\n\n const origTypeMismatch = validity.typeMismatch;\n\n timeout = setTimeout(() => {\n timeout = null;\n\n if (\n validity.badInput !== origBadInput ||\n validity.typeMismatch !== origTypeMismatch\n ) {\n listener(ev);\n }\n });\n }\n });\n }\n\n ctrl.$render = function () {\n // Workaround for Firefox validation #12102.\n const value = ctrl.$isEmpty(ctrl.$viewValue) ? \"\" : ctrl.$viewValue;\n\n if (element.value !== value) {\n element.value = value;\n }\n };\n}\n\nexport function weekParser(isoWeek, existingDate) {\n if (isDate(isoWeek)) {\n return isoWeek;\n }\n\n function getFirstThursdayOfYear(year) {\n // 0 = index of January\n const dayOfWeekOnFirst = new Date(year, 0, 1).getDay();\n\n // 4 = index of Thursday (+1 to account for 1st = 5)\n // 11 = index of *next* Thursday (+1 account for 1st = 12)\n return new Date(\n year,\n 0,\n // eslint-disable-next-line no-magic-numbers\n (dayOfWeekOnFirst <= 4 ? 5 : 12) - dayOfWeekOnFirst,\n );\n }\n\n if (isString(isoWeek)) {\n WEEK_REGEXP.lastIndex = 0;\n const parts = WEEK_REGEXP.exec(isoWeek);\n\n if (parts) {\n const year = +parts[1];\n\n const week = +parts[2];\n\n let hours = 0;\n\n let minutes = 0;\n\n let seconds = 0;\n\n let milliseconds = 0;\n\n const firstThurs = getFirstThursdayOfYear(year);\n\n const DAYS = 7;\n\n const addDays = (week - 1) * DAYS;\n\n if (existingDate) {\n hours = existingDate.getHours();\n minutes = existingDate.getMinutes();\n seconds = existingDate.getSeconds();\n milliseconds = existingDate.getMilliseconds();\n }\n\n return new Date(\n year,\n 0,\n firstThurs.getDate() + addDays,\n hours,\n minutes,\n seconds,\n milliseconds,\n );\n }\n }\n\n return NaN;\n}\n\nexport function createDateParser(regexp, mapping) {\n return function (iso, previousDate) {\n let parts;\n\n let map;\n\n if (isDate(iso)) {\n return iso;\n }\n\n if (isString(iso)) {\n // When a date is JSON'ified to wraps itself inside of an extra\n // set of double quotes. This makes the date parsing code unable\n // to match the date string and parse it as a date.\n if (iso.charAt(0) === '\"' && iso.charAt(iso.length - 1) === '\"') {\n iso = iso.substring(1, iso.length - 1);\n }\n\n if (ISO_DATE_REGEXP.test(iso)) {\n return new Date(iso);\n }\n regexp.lastIndex = 0;\n parts = regexp.exec(iso);\n\n if (parts) {\n parts.shift();\n\n if (previousDate) {\n map = {\n yyyy: previousDate.getFullYear(),\n MM: previousDate.getMonth() + 1,\n dd: previousDate.getDate(),\n HH: previousDate.getHours(),\n mm: previousDate.getMinutes(),\n ss: previousDate.getSeconds(),\n sss: previousDate.getMilliseconds() / 1000,\n };\n } else {\n map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, sss: 0 };\n }\n\n Object.entries(parts).forEach(([index, part]) => {\n if (index < mapping.length) {\n map[mapping[index]] = +part;\n }\n });\n\n const date = new Date(\n map.yyyy,\n map.MM - 1,\n map.dd,\n map.HH,\n map.mm,\n map.ss || 0,\n map.sss * 1000 || 0,\n );\n\n if (map.yyyy < 100) {\n // In the constructor, 2-digit years map to 1900-1999.\n // Use `setFullYear()` to set the correct year.\n date.setFullYear(map.yyyy);\n }\n\n return date;\n }\n }\n\n return NaN;\n };\n}\n\nconst MONTH_INPUT_FORMAT = /\\b\\d{4}-(0[1-9]|1[0-2])\\b/;\n\nexport function createDateInputType(type, regexp, parseDate) {\n return function dynamicDateInputType(\n scope,\n element,\n attr,\n ctrl,\n $filter,\n $parse,\n ) {\n badInputChecker(scope, element, attr, ctrl, type);\n baseInputType(scope, element, attr, ctrl);\n let previousDate;\n\n let previousTimezone;\n\n ctrl.$parsers.push((value) => {\n if (ctrl.$isEmpty(value)) return null;\n\n if (regexp.test(value)) {\n // Do not convert for native HTML\n if ([\"month\", \"week\", \"datetimelocal\", \"time\", \"date\"].includes(type)) {\n return value;\n }\n\n // Note: We cannot read ctrl.$modelValue, as there might be a different\n // parser/formatter in the processing chain so that the model\n // contains some different data format!\n return parseDateAndConvertTimeZoneToLocal(value, previousDate);\n }\n ctrl.$$parserName = type;\n\n return undefined;\n });\n\n ctrl.$formatters.push(function (value) {\n if (value && !isString(value)) {\n throw ngModelMinErr(\"datefmt\", \"Expected `{0}` to be a String\", value);\n }\n\n if (type === \"month\") {\n if (isNullOrUndefined(value)) {\n return \"\";\n }\n\n if (!MONTH_INPUT_FORMAT.test(value)) {\n throw ngModelMinErr(\n \"datefmt\",\n \"Expected month `{0}` to be a 'YYYY-DD'\",\n value,\n );\n }\n }\n\n if (type === \"week\") {\n if (isNullOrUndefined(value)) {\n return \"\";\n }\n\n if (!WEEK_REGEXP.test(value)) {\n throw ngModelMinErr(\n \"datefmt\",\n \"Expected week `{0}` to be a 'yyyy-Www'\",\n value,\n );\n }\n }\n\n if (type === \"datetimelocal\") {\n if (isNullOrUndefined(value)) {\n return \"\";\n }\n\n if (!DATETIMELOCAL_REGEXP.test(value)) {\n throw ngModelMinErr(\n \"datefmt\",\n \"Expected week `{0}` to be a in date time format. See: https://developer.mozilla.org/en-US/docs/Web/HTML/Date_and_time_formats#local_date_and_time_strings\",\n value,\n );\n }\n }\n\n return value;\n\n // if (isValidDate(value)) {\n // previousDate = value;\n // const timezone = ctrl.$options.getOption(\"timezone\");\n\n // if (timezone) {\n // previousTimezone = timezone;\n // previousDate = convertTimezoneToLocal(previousDate, timezone, true);\n // }\n\n // return value;\n // }\n // previousDate = null;\n // previousTimezone = null;\n // return \"\";\n });\n\n if (isDefined(attr.min) || attr.ngMin) {\n let minVal = attr.min || $parse(attr.ngMin)(scope);\n\n let parsedMinVal = parseObservedDateValue(\n isProxy(minVal) ? minVal.$target : minVal,\n );\n\n ctrl.$validators.min = function (value) {\n if (type === \"month\") {\n return (\n isUndefined(parsedMinVal) ||\n parseDate(value) >= parseDate(parsedMinVal)\n );\n }\n\n return (\n !isValidDate(value) ||\n isUndefined(parsedMinVal) ||\n parseDate(value) >= parsedMinVal\n );\n };\n attr.$observe(\"min\", (val) => {\n if (val !== minVal) {\n parsedMinVal = parseObservedDateValue(val);\n minVal = val;\n ctrl.$validate();\n }\n });\n }\n\n if (isDefined(attr.max) || attr.ngMax) {\n let maxVal = attr.max || $parse(attr.ngMax)(scope);\n\n let parsedMaxVal = parseObservedDateValue(\n isProxy(maxVal) ? maxVal.$target : maxVal,\n );\n\n ctrl.$validators.max = function (value) {\n if (type === \"month\") {\n return (\n isUndefined(parsedMaxVal) ||\n parseDate(value) <= parseDate(parsedMaxVal)\n );\n }\n\n return (\n !isValidDate(value) ||\n isUndefined(parsedMaxVal) ||\n parseDate(value) <= parsedMaxVal\n );\n };\n attr.$observe(\"max\", (val) => {\n if (val !== maxVal) {\n parsedMaxVal = parseObservedDateValue(val);\n maxVal = val;\n ctrl.$validate();\n }\n });\n }\n\n function isValidDate(value) {\n // Invalid Date: getTime() returns NaN\n return value && !(value.getTime && Number.isNaN(value.getTime()));\n }\n\n function parseObservedDateValue(val) {\n return isDefined(val) && !isDate(val)\n ? parseDateAndConvertTimeZoneToLocal(val) || undefined\n : val;\n }\n\n function parseDateAndConvertTimeZoneToLocal(value, previousDateParam) {\n const timezone = ctrl.$options.getOption(\"timezone\");\n\n if (previousTimezone && previousTimezone !== timezone) {\n // If the timezone has changed, adjust the previousDate to the default timezone\n // so that the new date is converted with the correct timezone offset\n previousDateParam = addDateMinutes(\n previousDateParam,\n timezoneToOffset(previousTimezone),\n );\n }\n\n let parsedDate = parseDate(value, previousDateParam);\n\n if (!Number.isNaN(parsedDate) && timezone) {\n parsedDate = convertTimezoneToLocal(parsedDate, timezone);\n }\n\n return parsedDate;\n }\n };\n}\n\nexport function badInputChecker(scope, element, attr, ctrl, parserName) {\n const nativeValidation = (ctrl.$$hasNativeValidators = isObject(\n element.validity,\n ));\n\n if (nativeValidation) {\n ctrl.$parsers.push((value) => {\n const validity = element[VALIDITY_STATE_PROPERTY] || {};\n\n if (validity.badInput || validity.typeMismatch) {\n ctrl.$$parserName = parserName;\n\n return undefined;\n }\n\n return value;\n });\n }\n}\n\nexport function numberFormatterParser(ctrl) {\n ctrl.$parsers.push((value) => {\n if (ctrl.$isEmpty(value)) return null;\n\n if (NUMBER_REGEXP.test(value)) return parseFloat(value);\n\n ctrl.$$parserName = \"number\";\n\n return undefined;\n });\n\n ctrl.$formatters.push((value) => {\n if (!ctrl.$isEmpty(value)) {\n if (!isNumber(value)) {\n throw ngModelMinErr(\"numfmt\", \"Expected `{0}` to be a number\", value);\n }\n value = value.toString();\n }\n\n return value;\n });\n}\n\nfunction parseNumberAttrVal(val) {\n if (isDefined(val) && !isNumber(val)) {\n val = parseFloat(val);\n }\n\n return !isNumberNaN(val) ? val : undefined;\n}\n\nexport function isNumberInteger(num) {\n // See http://stackoverflow.com/questions/14636536/how-to-check-if-a-variable-is-an-integer-in-javascript#14794066\n // (minus the assumption that `num` is a number)\n\n return (num | 0) === num;\n}\n\nexport function countDecimals(num) {\n const numString = num.toString();\n\n const decimalSymbolIndex = numString.indexOf(\".\");\n\n if (decimalSymbolIndex === -1) {\n if (num > -1 && num < 1) {\n // It may be in the exponential notation format (`1e-X`)\n const match = /e-(\\d+)$/.exec(numString);\n\n if (match) {\n return Number(match[1]);\n }\n }\n\n return 0;\n }\n\n return numString.length - decimalSymbolIndex - 1;\n}\n\nexport function isValidForStep(viewValue, stepBase, step) {\n // At this point `stepBase` and `step` are expected to be non-NaN values\n // and `viewValue` is expected to be a valid stringified number.\n let value = Number(viewValue);\n\n const isNonIntegerValue = !isNumberInteger(value);\n\n const isNonIntegerStepBase = !isNumberInteger(stepBase);\n\n const isNonIntegerStep = !isNumberInteger(step);\n\n // Due to limitations in Floating Point Arithmetic (e.g. `0.3 - 0.2 !== 0.1` or\n // `0.5 % 0.1 !== 0`), we need to convert all numbers to integers.\n if (isNonIntegerValue || isNonIntegerStepBase || isNonIntegerStep) {\n const valueDecimals = isNonIntegerValue ? countDecimals(value) : 0;\n\n const stepBaseDecimals = isNonIntegerStepBase ? countDecimals(stepBase) : 0;\n\n const stepDecimals = isNonIntegerStep ? countDecimals(step) : 0;\n\n const decimalCount = Math.max(\n valueDecimals,\n stepBaseDecimals,\n stepDecimals,\n );\n\n const multiplier = 10 ** decimalCount;\n\n value *= multiplier;\n stepBase *= multiplier;\n step *= multiplier;\n\n if (isNonIntegerValue) value = Math.round(value);\n\n if (isNonIntegerStepBase) stepBase = Math.round(stepBase);\n\n if (isNonIntegerStep) step = Math.round(step);\n }\n\n return (value - stepBase) % step === 0;\n}\n\nexport function numberInputType(scope, element, attr, ctrl, $filter, $parse) {\n badInputChecker(scope, element, attr, ctrl, \"number\");\n numberFormatterParser(ctrl);\n baseInputType(scope, element, attr, ctrl);\n\n let parsedMinVal;\n\n if (isDefined(attr.min) || attr.ngMin) {\n let minVal = attr.min || $parse(attr.ngMin)(scope);\n\n parsedMinVal = parseNumberAttrVal(minVal);\n\n ctrl.$validators.min = function (modelValue, viewValue) {\n return (\n ctrl.$isEmpty(viewValue) ||\n isUndefined(parsedMinVal) ||\n viewValue >= parsedMinVal\n );\n };\n\n attr.$observe(\"min\", (val) => {\n if (val !== minVal) {\n parsedMinVal = parseNumberAttrVal(val);\n minVal = val;\n // TODO(matsko): implement validateLater to reduce number of validations\n ctrl.$validate();\n }\n });\n }\n\n if (isDefined(attr.max) || attr.ngMax) {\n let maxVal = attr.max || $parse(attr.ngMax)(scope);\n\n let parsedMaxVal = parseNumberAttrVal(maxVal);\n\n ctrl.$validators.max = function (modelValue, viewValue) {\n return (\n ctrl.$isEmpty(viewValue) ||\n isUndefined(parsedMaxVal) ||\n viewValue <= parsedMaxVal\n );\n };\n\n attr.$observe(\"max\", (val) => {\n if (val !== maxVal) {\n parsedMaxVal = parseNumberAttrVal(val);\n maxVal = val;\n // TODO(matsko): implement validateLater to reduce number of validations\n ctrl.$validate();\n }\n });\n }\n\n if (isDefined(attr.step) || attr.ngStep) {\n let stepVal = attr.step || $parse(attr.ngStep)(scope);\n\n let parsedStepVal = parseNumberAttrVal(stepVal);\n\n ctrl.$validators.step = function (modelValue, viewValue) {\n return (\n ctrl.$isEmpty(viewValue) ||\n isUndefined(parsedStepVal) ||\n isValidForStep(viewValue, parsedMinVal || 0, parsedStepVal)\n );\n };\n\n attr.$observe(\"step\", (val) => {\n // TODO(matsko): implement validateLater to reduce number of validations\n if (val !== stepVal) {\n parsedStepVal = parseNumberAttrVal(val);\n stepVal = val;\n ctrl.$validate();\n }\n });\n }\n}\n\nexport function rangeInputType(scope, element, attr, ctrl) {\n badInputChecker(scope, element, attr, ctrl, \"range\");\n numberFormatterParser(ctrl);\n baseInputType(scope, element, attr, ctrl);\n\n const supportsRange = ctrl.$$hasNativeValidators && element.type === \"range\";\n\n let minVal = supportsRange ? 0 : undefined;\n\n let maxVal = supportsRange ? 100 : undefined;\n\n let stepVal = supportsRange ? 1 : undefined;\n\n const { validity } = element;\n\n const hasMinAttr = isDefined(attr.min);\n\n const hasMaxAttr = isDefined(attr.max);\n\n const hasStepAttr = isDefined(attr.step);\n\n const originalRender = ctrl.$render;\n\n ctrl.$render =\n supportsRange &&\n isDefined(validity.rangeUnderflow) &&\n isDefined(validity.rangeOverflow)\n ? // Browsers that implement range will set these values automatically, but reading the adjusted values after\n // $render would cause the min / max validators to be applied with the wrong value\n function rangeRender() {\n originalRender();\n ctrl.$setViewValue(element.value);\n }\n : originalRender;\n\n if (hasMinAttr) {\n minVal = parseNumberAttrVal(attr.min);\n\n ctrl.$validators.min = supportsRange\n ? // Since all browsers set the input to a valid value, we don't need to check validity\n function noopMinValidator() {\n return true;\n }\n : // non-support browsers validate the min val\n function minValidator(modelValue, viewValue) {\n return (\n ctrl.$isEmpty(viewValue) ||\n isUndefined(minVal) ||\n viewValue >= minVal\n );\n };\n\n setInitialValueAndObserver(\"min\", minChange);\n }\n\n if (hasMaxAttr) {\n maxVal = parseNumberAttrVal(attr.max);\n\n ctrl.$validators.max = supportsRange\n ? // Since all browsers set the input to a valid value, we don't need to check validity\n function noopMaxValidator() {\n return true;\n }\n : // non-support browsers validate the max val\n function maxValidator(modelValue, viewValue) {\n return (\n ctrl.$isEmpty(viewValue) ||\n isUndefined(maxVal) ||\n viewValue <= maxVal\n );\n };\n\n setInitialValueAndObserver(\"max\", maxChange);\n }\n\n if (hasStepAttr) {\n stepVal = parseNumberAttrVal(attr.step);\n\n ctrl.$validators.step = supportsRange\n ? function nativeStepValidator() {\n // Currently, only FF implements the spec on step change correctly (i.e. adjusting the\n // input element value to a valid value). It's possible that other browsers set the stepMismatch\n // validity error instead, so we can at least report an error in that case.\n return !validity.stepMismatch;\n }\n : // ngStep doesn't set the setp attr, so the browser doesn't adjust the input value as setting step would\n function stepValidator(modelValue, viewValue) {\n return (\n ctrl.$isEmpty(viewValue) ||\n isUndefined(stepVal) ||\n isValidForStep(viewValue, minVal || 0, stepVal)\n );\n };\n\n setInitialValueAndObserver(\"step\", stepChange);\n }\n\n function setInitialValueAndObserver(htmlAttrName, changeFn) {\n // interpolated attributes set the attribute value only after a digest, but we need the\n // attribute value when the input is first rendered, so that the browser can adjust the\n // input value based on the min/max value\n element.setAttribute(htmlAttrName, attr[htmlAttrName]);\n let oldVal = attr[htmlAttrName];\n\n attr.$observe(htmlAttrName, (val) => {\n if (val !== oldVal) {\n oldVal = val;\n changeFn(val);\n }\n });\n }\n\n function minChange(val) {\n minVal = parseNumberAttrVal(val);\n\n // ignore changes before model is initialized\n if (isNumberNaN(ctrl.$modelValue)) {\n return;\n }\n\n if (supportsRange) {\n let elVal = element.value;\n\n // IE11 doesn't set the el val correctly if the minVal is greater than the element value\n if (minVal > elVal) {\n elVal = minVal;\n element.value = elVal;\n }\n ctrl.$setViewValue(elVal);\n } else {\n // TODO(matsko): implement validateLater to reduce number of validations\n ctrl.$validate();\n }\n }\n\n function maxChange(val) {\n maxVal = parseNumberAttrVal(val);\n\n // ignore changes before model is initialized\n if (isNumberNaN(ctrl.$modelValue)) {\n return;\n }\n\n if (supportsRange) {\n let elVal = element.value;\n\n // IE11 doesn't set the el val correctly if the maxVal is less than the element value\n if (maxVal < elVal) {\n element.value = maxVal;\n // IE11 and Chrome don't set the value to the minVal when max < min\n elVal = maxVal < minVal ? minVal : maxVal;\n }\n ctrl.$setViewValue(elVal);\n } else {\n // TODO(matsko): implement validateLater to reduce number of validations\n ctrl.$validate();\n }\n }\n\n function stepChange(val) {\n stepVal = parseNumberAttrVal(val);\n\n // ignore changes before model is initialized\n if (isNumberNaN(ctrl.$modelValue)) {\n return;\n }\n\n // Some browsers don't adjust the input value correctly, but set the stepMismatch error\n if (!supportsRange) {\n // TODO(matsko): implement validateLater to reduce number of validations\n ctrl.$validate();\n } else if (ctrl.$viewValue !== element.value) {\n ctrl.$setViewValue(element.value);\n }\n }\n}\n\nfunction urlInputType(scope, element, attr, ctrl) {\n // Note: no badInputChecker here by purpose as `url` is only a validation\n // in browsers, i.e. we can always read out input.value even if it is not valid!\n baseInputType(scope, element, attr, ctrl);\n stringBasedInputType(ctrl);\n\n ctrl.$validators.url = function (modelValue, viewValue) {\n const value = modelValue || viewValue;\n\n return ctrl.$isEmpty(value) || URL_REGEXP.test(value);\n };\n}\n\nfunction emailInputType(scope, element, attr, ctrl) {\n // Note: no badInputChecker here by purpose as `url` is only a validation\n // in browsers, i.e. we can always read out input.value even if it is not valid!\n baseInputType(scope, element, attr, ctrl);\n stringBasedInputType(ctrl);\n\n ctrl.$validators.email = function (modelValue, viewValue) {\n const value = modelValue || viewValue;\n\n return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value);\n };\n}\n\nfunction radioInputType(scope, element, attr, ctrl) {\n const doTrim = !attr.ngTrim || trim(attr.ngTrim) !== \"false\";\n\n // make the name unique, if not defined\n if (isUndefined(attr.name)) {\n element.setAttribute(\"name\", nextUid());\n }\n\n const listener = function (ev) {\n if (element.checked) {\n let { value } = attr;\n\n if (doTrim) {\n value = trim(value);\n }\n ctrl.$setViewValue(value, ev && ev.type);\n }\n };\n\n element.addEventListener(\"change\", listener);\n // NgModelController call\n ctrl.$render = function () {\n let { value } = attr;\n\n if (doTrim) {\n value = trim(value);\n }\n const deproxy = isProxy(ctrl.$viewValue)\n ? ctrl.$viewValue.$target\n : ctrl.$viewValue;\n\n // the proxy may reach down two levels\n element.checked =\n (isProxy(value) ? value.$target : value) ===\n (isProxy(deproxy) ? deproxy.$target : deproxy);\n };\n\n attr.$observe(\"value\", ctrl.$render);\n}\n\nfunction parseConstantExpr($parse, context, name, expression, fallback) {\n let parseFn;\n\n if (isDefined(expression)) {\n parseFn = $parse(expression);\n\n if (!parseFn.constant) {\n throw ngModelMinErr(\n \"constexpr\",\n \"Expected constant expression for `{0}`, but saw \" + \"`{1}`.\",\n name,\n expression,\n );\n }\n\n return parseFn(context);\n }\n\n return fallback;\n}\n\nfunction checkboxInputType(scope, element, attr, ctrl, $filter, $parse) {\n const trueValue = parseConstantExpr(\n $parse,\n scope,\n \"ngTrueValue\",\n attr.ngTrueValue,\n true,\n );\n\n const falseValue = parseConstantExpr(\n $parse,\n scope,\n \"ngFalseValue\",\n attr.ngFalseValue,\n false,\n );\n\n const listener = function (ev) {\n ctrl.$setViewValue(element.checked, ev && ev.type);\n };\n\n element.addEventListener(\"change\", listener);\n\n ctrl.$render = function () {\n element.checked = ctrl.$viewValue;\n };\n\n // Override the standard `$isEmpty` because the $viewValue of an empty checkbox is always set to `false`\n // This is because of the parser below, which compares the `$modelValue` with `trueValue` to convert\n // it to a boolean.\n ctrl.$isEmpty = function (value) {\n return value === false;\n };\n\n ctrl.$formatters.push((value) => equals(value, trueValue));\n\n ctrl.$parsers.push((value) => (value ? trueValue : falseValue));\n}\n\ninputDirective.$inject = [\"$filter\", \"$parse\"];\n\n/**\n * @param {ng.FilterFactory} $filter\n * @param {ng.ParseService} $parse\n * @returns {ng.Directive}\n */\nexport function inputDirective($filter, $parse) {\n return {\n restrict: \"E\",\n require: [\"?ngModel\"],\n link: {\n pre(scope, element, attr, ctrls) {\n if (ctrls[0]) {\n (inputType[attr.type?.toLowerCase()] || inputType.text)(\n scope,\n element,\n attr,\n ctrls[0],\n $filter,\n $parse,\n );\n }\n },\n },\n };\n}\n\n/**\n * @returns {ng.Directive}\n */\nexport function hiddenInputBrowserCacheDirective() {\n const valueProperty = {\n configurable: true,\n enumerable: false,\n get() {\n return this.getAttribute(\"value\") || \"\";\n },\n set(val) {\n this.setAttribute(\"value\", val);\n },\n };\n\n return {\n restrict: \"E\",\n priority: 200,\n compile(_, attr) {\n if (attr.type?.toLowerCase() !== \"hidden\") {\n return undefined;\n }\n\n const res = {\n pre(_scope, element) {\n const node = element;\n\n // Support: Edge\n // Moving the DOM around prevents autofillling\n if (node.parentNode) {\n node.parentNode.insertBefore(node, node.nextSibling);\n }\n\n // Support: FF, IE\n // Avoiding direct assignment to .value prevents autofillling\n if (Object.defineProperty) {\n Object.defineProperty(node, \"value\", valueProperty);\n }\n\n return undefined;\n },\n };\n\n return res;\n },\n };\n}\n\nconst CONSTANT_VALUE_REGEXP = /^(true|false|\\d+)$/;\n\n/**\n * @returns {ng.Directive}\n */\nexport function ngValueDirective() {\n /**\n * inputs use the value attribute as their default value if the value property is not set.\n * Once the value property has been set (by adding input), it will not react to changes to\n * the value attribute anymore. Setting both attribute and property fixes this behavior, and\n * makes it possible to use ngValue as a sort of one-way bind.\n */\n function updateElementValue(element, attr, value) {\n // TODO REMOVE IS SUPPORT\n // Support: IE9 only\n // In IE9 values are converted to string (e.g. `input.value = null` results in `input.value === 'null'`).\n element.value = isDefined(value)\n ? isProxy(value)\n ? value.$target\n : value\n : null;\n attr.$set(\"value\", value);\n }\n\n return {\n restrict: \"A\",\n priority: 100,\n compile(_, tplAttr) {\n if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {\n return function (scope, elm, attr) {\n const value = scope.$eval(attr.ngValue);\n\n updateElementValue(elm, attr, value);\n };\n }\n\n return function (scope, elm, attr) {\n scope.$watch(attr.ngValue, (value) => {\n updateElementValue(elm, attr, value);\n });\n };\n },\n };\n}\n","scriptDirective.$inject = [\"$templateCache\"];\n\n/**\n * @param {ng.TemplateCacheService} $templateCache\n * @returns {import('../../interface.ts').Directive}\n */\nexport function scriptDirective($templateCache) {\n return {\n restrict: \"E\",\n terminal: true,\n compile(element, attr) {\n if (attr.type === \"text/ng-template\") {\n $templateCache.set(attr.id, element.innerText);\n }\n },\n };\n}\n","import { getCacheData } from \"../../shared/dom.js\";\nimport { NodeType } from \"../../shared/node.js\";\nimport {\n assertNotHasOwnProperty,\n equals,\n hashKey,\n includes,\n isDefined,\n isNullOrUndefined,\n isUndefined,\n shallowCopy,\n} from \"../../shared/utils.js\";\n\n/**\n * The controller for the {@link ng.select select} directive.\n * The controller exposes a few utility methods that can be used to augment\n * the behavior of a regular or an {@link ng.ngOptions ngOptions} select element.\n */\nclass SelectController {\n static $nonscope = [\n \"ngModelCtrl\",\n \"selectValueMap\",\n \"emptyOption\",\n \"optionsMap\",\n \"$scope\",\n \"$element\",\n ];\n\n /**\n * @type {Array<string>}\n */\n /* @ignore */ static $inject = [\"$element\", \"$scope\"];\n\n /**\n * @param {HTMLSelectElement} $element\n * @param {ng.Scope} $scope\n */\n constructor($element, $scope) {\n /** @type {HTMLSelectElement} */\n this.$element = $element;\n\n /** @type {ng.Scope} */\n this.$scope = $scope;\n\n /** @type {Object<string, any>} */\n this.selectValueMap = {};\n\n /** @type {any} */\n this.ngModelCtrl = {};\n\n /** @type {boolean} */\n this.multiple = false;\n\n /** @type {HTMLOptionElement} */\n this.unknownOption = document.createElement(\"option\");\n\n /** @type {boolean} */\n this.hasEmptyOption = false;\n\n /** @type {HTMLOptionElement|undefined} */\n this.emptyOption = undefined;\n\n /** @type {Map<any, number>} */\n this.optionsMap = new Map();\n\n /** @type {boolean} */\n this.renderScheduled = false;\n\n /** @type {boolean} */\n this.updateScheduled = false;\n\n $scope.$on(\"$destroy\", () => {\n // disable unknown option so that we don't do work when the whole select is being destroyed\n this.renderUnknownOption = () => {\n /* empty */\n };\n });\n }\n\n /**\n * Render the unknown option when the viewValue doesn't match any options.\n * @param {*} val\n */\n renderUnknownOption(val) {\n const unknownVal = this.generateUnknownOptionValue(val);\n\n this.unknownOption.value = unknownVal;\n this.$element.prepend(this.unknownOption);\n this.unknownOption.selected = true;\n this.unknownOption.setAttribute(\"selected\", \"selected\");\n this.$element.value = unknownVal;\n }\n\n /**\n * Update the unknown option if it's already rendered.\n * @param {*} val\n */\n updateUnknownOption(val) {\n const unknownVal = this.generateUnknownOptionValue(val);\n\n this.unknownOption.value = unknownVal;\n this.unknownOption.selected = true;\n this.unknownOption.setAttribute(\"selected\", \"selected\");\n this.$element.value = unknownVal;\n }\n\n /**\n * Generate a special value used for unknown options.\n * @param {*} val\n * @returns {string}\n */\n generateUnknownOptionValue(val) {\n if (isUndefined(val)) {\n return `? undefined:undefined ?`;\n }\n\n return `? ${hashKey(val)} ?`;\n }\n\n /**\n * Remove the unknown option from the select element if it exists.\n */\n removeUnknownOption() {\n if (this.unknownOption.parentElement) this.unknownOption.remove();\n }\n\n /**\n * Select the empty option (value=\"\") if it exists.\n */\n selectEmptyOption() {\n if (this.emptyOption) {\n this.$element.value = \"\";\n this.emptyOption.selected = true;\n this.emptyOption.setAttribute(\"selected\", \"selected\");\n }\n }\n\n /**\n * Unselect the empty option if present.\n */\n unselectEmptyOption() {\n if (this.hasEmptyOption) {\n this.emptyOption.selected = false;\n }\n }\n\n /**\n * Read the current value from the select element.\n * @returns {*|null}\n */\n readValue() {\n const val = this.$element.value;\n\n const realVal = val in this.selectValueMap ? this.selectValueMap[val] : val;\n\n return this.hasOption(realVal) ? realVal : null;\n }\n\n /**\n * Write a value to the select control.\n * @param {*} value\n */\n writeValue(value) {\n const currentlySelectedOption =\n this.$element.options[this.$element.selectedIndex];\n\n if (currentlySelectedOption) currentlySelectedOption.selected = false;\n\n if (this.hasOption(value)) {\n this.removeUnknownOption();\n\n const hashedVal = hashKey(value);\n\n this.$element.value =\n hashedVal in this.selectValueMap ? hashedVal : value;\n const selectedOption = this.$element.options[this.$element.selectedIndex];\n\n if (!selectedOption) {\n this.selectUnknownOrEmptyOption(value);\n } else {\n selectedOption.selected = true;\n }\n } else {\n this.selectUnknownOrEmptyOption(value);\n }\n }\n\n /**\n * Register a new option with the controller.\n * @param {*} value\n * @param {HTMLOptionElement} element\n */\n addOption(value, element) {\n if (element.nodeType === NodeType._COMMENT_NODE) return;\n\n assertNotHasOwnProperty(value, '\"option value\"');\n\n if (value === \"\") {\n this.hasEmptyOption = true;\n this.emptyOption = element;\n }\n const count = this.optionsMap.get(value) || 0;\n\n this.optionsMap.set(value, count + 1);\n this.scheduleRender();\n }\n\n /**\n * Remove an option from the controller.\n * @param {*} value\n */\n removeOption(value) {\n const count = this.optionsMap.get(value);\n\n if (count) {\n if (count === 1) {\n this.optionsMap.delete(value);\n\n if (value === \"\") {\n this.hasEmptyOption = false;\n this.emptyOption = undefined;\n }\n } else {\n this.optionsMap.set(value, count - 1);\n }\n }\n }\n\n /**\n * Check if an option exists for the given value.\n * @param {*} value\n * @returns {boolean}\n */\n hasOption(value) {\n return !!this.optionsMap.get(value);\n }\n\n /**\n * @returns {boolean} Whether the select element currently has an empty option.\n */\n $hasEmptyOption() {\n return this.hasEmptyOption;\n }\n\n /**\n * @returns {boolean} Whether the unknown option is currently selected.\n */\n $isUnknownOptionSelected() {\n return this.$element.options[0] === this.unknownOption;\n }\n\n /**\n * @returns {boolean} Whether the empty option is selected.\n */\n $isEmptyOptionSelected() {\n return (\n this.hasEmptyOption &&\n this.$element.options[this.$element.selectedIndex] === this.emptyOption\n );\n }\n\n /**\n * Select unknown or empty option depending on the value.\n * @param {*} value\n */\n selectUnknownOrEmptyOption(value) {\n if (isNullOrUndefined(value) && this.emptyOption) {\n this.removeUnknownOption();\n this.selectEmptyOption();\n } else if (this.unknownOption.parentElement) {\n this.updateUnknownOption(value);\n } else {\n this.renderUnknownOption(value);\n }\n }\n\n /**\n * Schedule a render at the end of the digest cycle.\n */\n scheduleRender() {\n if (this.renderScheduled) return;\n this.renderScheduled = true;\n this.$scope.$postUpdate(() => {\n this.renderScheduled = false;\n this.ngModelCtrl.$render();\n });\n }\n\n /**\n * Schedule a view value update at the end of the digest cycle.\n * @param {boolean} [renderAfter=false]\n */\n scheduleViewValueUpdate(renderAfter = false) {\n if (this.updateScheduled) return;\n\n this.updateScheduled = true;\n\n this.$scope.$postUpdate(() => {\n if (this.$scope.$$destroyed) return;\n\n this.updateScheduled = false;\n this.ngModelCtrl.$setViewValue(this.readValue());\n\n if (renderAfter) this.ngModelCtrl.$render();\n });\n }\n\n /**\n * Register an option with interpolation or dynamic value/text.\n * @param {any} optionScope\n * @param {HTMLOptionElement} optionElement\n * @param {any} optionAttrs\n * @param {Function} [interpolateValueFn]\n * @param {Function} [interpolateTextFn]\n */\n registerOption(\n optionScope,\n optionElement,\n optionAttrs,\n interpolateValueFn,\n interpolateTextFn,\n ) {\n let oldVal;\n\n let hashedVal;\n\n if (optionAttrs.$attr.ngValue) {\n optionAttrs.$observe(\"value\", (newVal) => {\n let removal;\n\n const previouslySelected = optionElement.selected;\n\n if (isDefined(hashedVal)) {\n this.removeOption(oldVal);\n delete this.selectValueMap[hashedVal];\n removal = true;\n }\n\n hashedVal = hashKey(newVal);\n oldVal = newVal;\n this.selectValueMap[hashedVal] = newVal;\n this.addOption(newVal, optionElement);\n optionElement.setAttribute(\"value\", hashedVal);\n\n if (removal && previouslySelected) {\n this.scheduleViewValueUpdate();\n }\n });\n } else if (interpolateValueFn) {\n optionAttrs.$observe(\"value\", (newVal) => {\n this.readValue();\n let removal;\n\n const previouslySelected = optionElement.selected;\n\n if (isDefined(oldVal)) {\n this.removeOption(oldVal);\n removal = true;\n }\n oldVal = newVal;\n this.addOption(newVal, optionElement);\n\n if (removal && previouslySelected) {\n this.scheduleViewValueUpdate();\n }\n });\n } else if (interpolateTextFn) {\n optionScope.value = interpolateTextFn(optionScope);\n\n if (!optionAttrs.value) {\n optionAttrs.$set(\"value\", optionScope.value);\n this.addOption(optionScope.value, optionElement);\n }\n\n optionScope.$watch(\"value\", () => {\n const newVal = interpolateTextFn(optionScope);\n\n if (!optionAttrs.value) {\n optionAttrs.$set(\"value\", newVal);\n }\n const previouslySelected = optionElement.selected;\n\n if (oldVal !== newVal) {\n this.removeOption(oldVal);\n oldVal = newVal;\n }\n this.addOption(newVal, optionElement);\n\n if (oldVal && previouslySelected) {\n this.scheduleViewValueUpdate();\n }\n });\n } else {\n this.addOption(optionAttrs.value, optionElement);\n }\n\n optionAttrs.$observe(\"disabled\", (newVal) => {\n if (newVal === \"true\" || (newVal && optionElement.selected)) {\n if (this.multiple) {\n this.scheduleViewValueUpdate(true);\n } else {\n this.ngModelCtrl.$setViewValue(null);\n this.ngModelCtrl.$render();\n }\n }\n });\n\n optionElement.addEventListener(\"$destroy\", () => {\n const currentValue = this.readValue();\n\n const removeValue = optionAttrs.value;\n\n this.removeOption(removeValue);\n this.scheduleRender();\n\n if (\n (this.multiple &&\n currentValue &&\n currentValue.indexOf(removeValue) !== -1) ||\n currentValue === removeValue\n ) {\n this.scheduleViewValueUpdate(true);\n }\n });\n }\n}\n\n/**\n * @returns {import('../../interface.ts').Directive}\n */\nexport function selectDirective() {\n return {\n restrict: \"E\",\n require: [\"select\", \"?ngModel\"],\n controller: SelectController,\n priority: 1,\n link: {\n pre: selectPreLink,\n post: selectPostLink,\n },\n };\n\n function selectPreLink(_scope, element, attr, ctrls) {\n /** @type {SelectController} */\n const selectCtrl = ctrls[0];\n\n /** @type {import(\"../model/model.js\").NgModelController} */\n const ngModelCtrl = ctrls[1];\n\n // if ngModel is not defined, we don't need to do anything but set the registerOption\n // function to noop, so options don't get added internally\n if (!ngModelCtrl) {\n selectCtrl.registerOption = () => {\n /* empty */\n };\n\n return;\n }\n selectCtrl.ngModelCtrl = ngModelCtrl;\n\n // When the selected item(s) changes we delegate getting the value of the select control\n // to the `readValue` method, which can be changed if the select can have multiple\n // selected values or if the options are being generated by `ngOptions`\n element.addEventListener(\"change\", () => {\n selectCtrl.removeUnknownOption();\n const viewValue = selectCtrl.readValue();\n\n ngModelCtrl.$setViewValue(viewValue);\n });\n\n // If the select allows multiple values then we need to modify how we read and write\n // values from and to the control; also what it means for the value to be empty and\n // we have to add an extra watch since ngModel doesn't work well with arrays - it\n // doesn't trigger rendering if only an item in the array changes.\n if (attr.multiple) {\n selectCtrl.multiple = true;\n\n // Read value now needs to check each option to see if it is selected\n selectCtrl.readValue = function () {\n const array = [];\n\n /**\n * @type {HTMLCollection}\n */\n const options = element.getElementsByTagName(\"option\");\n\n Array.from(options).forEach(\n /**\n * @param {HTMLOptionElement} option\n */\n (option) => {\n if (option.selected && !option.disabled) {\n const val = option.value;\n\n array.push(\n val in selectCtrl.selectValueMap\n ? selectCtrl.selectValueMap[val]\n : val,\n );\n }\n },\n );\n\n return array;\n };\n\n // Write value now needs to set the selected property of each matching option\n selectCtrl.writeValue = function (value) {\n /**\n * @type {HTMLCollection}\n */\n const options = element.getElementsByTagName(\"option\");\n\n Array.from(options).forEach(\n /**\n * @param {HTMLOptionElement} option\n */\n (option) => {\n const shouldBeSelected =\n !!value &&\n (includes(value, option.value) ||\n includes(value, selectCtrl.selectValueMap[option.value]));\n\n const currentlySelected = option.selected;\n\n // Support: IE 9-11 only, Edge 12-15+\n // In IE and Edge adding options to the selection via shift+click/UP/DOWN\n // will de-select already selected options if \"selected\" on those options was set\n // more than once (i.e. when the options were already selected)\n // So we only modify the selected property if necessary.\n // Note: this behavior cannot be replicated via unit tests because it only shows in the\n // actual user interface.\n if (shouldBeSelected !== currentlySelected) {\n option.selected = shouldBeSelected;\n }\n },\n );\n };\n\n // we have to do it on each watch since ngModel watches reference, but\n // we need to work of an array, so we need to see if anything was inserted/removed\n let lastView;\n\n let lastViewRef = NaN;\n\n if (\n lastViewRef === ngModelCtrl.$viewValue &&\n !equals(lastView, ngModelCtrl.$viewValue)\n ) {\n lastView = shallowCopy(ngModelCtrl.$viewValue);\n ngModelCtrl.$render();\n }\n lastViewRef = ngModelCtrl.$viewValue;\n\n // If we are a multiple select then value is now a collection\n // so the meaning of $isEmpty changes\n ngModelCtrl.$isEmpty = function (value) {\n return !value || value.length === 0;\n };\n }\n }\n\n function selectPostLink(_scope, _element, _attrs, ctrls) {\n // if ngModel is not defined, we don't need to do anything\n const ngModelCtrl = ctrls[1];\n\n if (!ngModelCtrl) return;\n\n const selectCtrl = ctrls[0];\n\n // We delegate rendering to the `writeValue` method, which can be changed\n // if the select can have multiple selected values or if the options are being\n // generated by `ngOptions`.\n // This must be done in the postLink fn to prevent $render to be called before\n // all nodes have been linked correctly.\n ngModelCtrl.$render = function () {\n selectCtrl.writeValue(ngModelCtrl.$viewValue);\n };\n }\n}\n\n// The option directive is purely designed to communicate the existence (or lack of)\n// of dynamically created (and destroyed) option elements to their containing select\n// directive via its controller.\n/**\n * @returns {import('../../interface.ts').Directive}\n */\noptionDirective.$inject = [\"$interpolate\"];\nexport function optionDirective($interpolate) {\n return {\n restrict: \"E\",\n priority: 100,\n compile(element, attr) {\n let interpolateValueFn;\n\n let interpolateTextFn;\n\n if (isDefined(attr.ngValue)) {\n // Will be handled by registerOption\n } else if (isDefined(attr.value)) {\n // If the value attribute is defined, check if it contains an interpolation\n interpolateValueFn = $interpolate(attr.value, true);\n } else {\n // If the value attribute is not defined then we fall back to the\n // text content of the option element, which may be interpolated\n interpolateTextFn = $interpolate(element.textContent, true);\n\n if (!interpolateTextFn) {\n attr.$set(\"value\", element.textContent);\n }\n }\n\n return function (scope, elemParam, attrParam) {\n // This is an optimization over using ^^ since we don't want to have to search\n // all the way to the root of the DOM for every single option element\n const selectCtrlName = \"$selectController\";\n\n const parent = elemParam.parentElement;\n\n const selectCtrl =\n getCacheData(parent, selectCtrlName) ||\n getCacheData(parent.parentElement, selectCtrlName); // in case we are in optgroup\n\n if (selectCtrl) {\n selectCtrl.registerOption(\n scope,\n elemParam,\n attrParam,\n interpolateValueFn,\n interpolateTextFn,\n );\n }\n };\n },\n };\n}\n","import {\n isDefined,\n isNull,\n isProxy,\n isUndefined,\n stringify,\n} from \"../../shared/utils.js\";\nimport { $injectTokens } from \"../../injection-tokens.js\";\n\n/**\n * @returns {ng.Directive}\n */\nexport function ngBindDirective() {\n return {\n /**\n * @param {ng.Scope} scope\n * @param {Element} element\n * @param {ng.Attributes} attr\n */\n link(scope, element, attr) {\n scope.$watch(\n attr.ngBind,\n (value) => {\n element.textContent = stringify(\n isProxy(value) ? value.$target : value,\n );\n },\n isDefined(attr.lazy),\n );\n },\n };\n}\n\n/**\n * @returns {import('../../interface.ts').Directive}\n */\nexport function ngBindTemplateDirective() {\n return {\n /**\n * @param {ng.Scope} _scope\n * @param {Element} element\n * @param {import('../../core/compile/attributes.js').Attributes} attr\n */\n link(_scope, element, attr) {\n attr.$observe(\"ngBindTemplate\", (value) => {\n element.textContent = isUndefined(value) ? \"\" : value;\n });\n },\n };\n}\n\nngBindHtmlDirective.$inject = [$injectTokens.$parse];\n/**\n * @param {import('../../core/parse/interface.ts').ParseService} $parse\n * @returns {import('../../interface.ts').Directive}\n */\nexport function ngBindHtmlDirective($parse) {\n return {\n restrict: \"A\",\n compile(_tElement, tAttrs) {\n $parse(tAttrs.ngBindHtml); // checks for interpolation errors\n\n return (\n /**\n * @param {ng.Scope} scope\n * @param {Element} element\n */\n (scope, element) => {\n scope.$watch(tAttrs.ngBindHtml, (val) => {\n if (isUndefined(val) || isNull(val)) {\n val = \"\";\n }\n element.innerHTML = val;\n });\n }\n );\n },\n };\n}\n","import { getCacheData, setCacheData } from \"../../shared/dom.js\";\nimport {\n hasAnimate,\n isArray,\n isObject,\n isString,\n keys,\n} from \"../../shared/utils.js\";\n\n/**\n * @param {string} name\n * @param {boolean|number} selector\n * @returns {ng.DirectiveFactory}\n */\nfunction classDirective(name, selector) {\n name = `ngClass${name}`;\n\n /**\n * @returns {ng.Directive}\n */\n return function () {\n return {\n /**\n * @param {ng.Scope} scope\n * @param {HTMLElement} element\n * @param {ng.Attributes} attr\n */\n link(scope, element, attr) {\n let classCounts = getCacheData(element, \"$classCounts\");\n\n let oldModulo = true;\n\n /** @type {string|undefined} */\n let oldClassString;\n\n if (!classCounts) {\n // Use Object.create(null) to prevent class assumptions involving property\n // names in Object.prototype\n classCounts = Object.create(null);\n setCacheData(element, \"$classCounts\", classCounts);\n }\n\n if (name !== \"ngClass\") {\n scope.$watch(\"$index\", () => {\n ngClassIndexWatchAction(scope.$index & 1);\n });\n }\n scope.$watch(attr[name], (val) => {\n ngClassWatchAction(toClassString(val));\n });\n\n /**\n * @param {string} classString\n */\n function addClasses(classString) {\n classString = digestClassCounts(split(classString), 1);\n\n if (hasAnimate(element)) {\n attr.$addClass(classString);\n } else {\n scope.$postUpdate(() => {\n if (classString !== \"\") {\n element.classList.add(...classString.trim().split(\" \"));\n }\n });\n }\n }\n\n /**\n * @param {string} classString\n */\n function removeClasses(classString) {\n classString = digestClassCounts(split(classString), -1);\n\n if (hasAnimate(element)) {\n attr.$removeClass(classString);\n } else {\n scope.$postUpdate(() => {\n if (classString !== \"\") {\n element.classList.remove(...classString.trim().split(\" \"));\n }\n });\n }\n }\n\n /**\n * @param {string} oldClassStringParam\n * @param {string} newClassStringParam\n */\n function updateClasses(oldClassStringParam, newClassStringParam) {\n const oldClassArray = split(oldClassStringParam);\n\n const newClassArray = split(newClassStringParam);\n\n const toRemoveArray = arrayDifference(oldClassArray, newClassArray);\n\n const toAddArray = arrayDifference(newClassArray, oldClassArray);\n\n const toRemoveString = digestClassCounts(toRemoveArray, -1);\n\n const toAddString = digestClassCounts(toAddArray, 1);\n\n if (hasAnimate(element)) {\n attr.$addClass(toAddString);\n attr.$removeClass(toRemoveString);\n } else {\n if (toAddString !== \"\") {\n element.classList.add(...toAddString.trim().split(\" \"));\n }\n\n if (toRemoveString !== \"\") {\n element.classList.remove(...toRemoveString.trim().split(\" \"));\n }\n }\n }\n\n function digestClassCounts(classArray, count) {\n const classesToUpdate = [];\n\n if (classArray) {\n classArray.forEach((className) => {\n if (count > 0 || classCounts[className]) {\n classCounts[className] = (classCounts[className] || 0) + count;\n\n if (classCounts[className] === +(count > 0)) {\n classesToUpdate.push(className);\n }\n }\n });\n }\n\n return classesToUpdate.join(\" \");\n }\n\n function ngClassIndexWatchAction(newModulo) {\n // This watch-action should run before the `ngClassWatchAction()`, thus it\n // adds/removes `oldClassString`. If the `ngClass` expression has changed as well, the\n // `ngClassWatchAction()` will update the classes.\n if (newModulo === selector) {\n addClasses(oldClassString);\n } else {\n removeClasses(oldClassString);\n }\n\n oldModulo = newModulo;\n }\n\n /**\n * @param {string} newClassString\n */\n function ngClassWatchAction(newClassString) {\n if (oldModulo === selector) {\n updateClasses(oldClassString, newClassString);\n }\n\n oldClassString = newClassString;\n }\n },\n };\n };\n}\n\n// Helpers\nfunction arrayDifference(tokens1, tokens2) {\n if (!tokens1 || !tokens1.length) return [];\n\n if (!tokens2 || !tokens2.length) return tokens1;\n\n const values = [];\n\n outer: for (let i = 0; i < tokens1.length; i++) {\n const token = tokens1[i];\n\n for (let j = 0; j < tokens2.length; j++) {\n if (token === tokens2[j]) continue outer;\n }\n values.push(token);\n }\n\n return values;\n}\n\nfunction split(classString) {\n return classString && classString.split(\" \");\n}\n\nfunction toClassString(classValue) {\n if (!classValue) return classValue;\n\n let classString = classValue;\n\n if (isArray(classValue)) {\n classString = classValue.map(toClassString).join(\" \");\n } else if (isObject(classValue)) {\n classString = keys(classValue)\n .filter((key) => classValue[key])\n .join(\" \");\n } else if (!isString(classValue)) {\n classString = `${classValue}`;\n }\n\n return classString;\n}\n\nexport const ngClassDirective = classDirective(\"\", true);\nexport const ngClassOddDirective = classDirective(\"Odd\", 0);\nexport const ngClassEvenDirective = classDirective(\"Even\", 1);\n","/**\n * @returns {ng.Directive}\n */\nexport function ngCloakDirective() {\n return {\n compile(_, attr) {\n attr.$set(\"ngCloak\", undefined);\n },\n };\n}\n","/**\n * @returns {import(\"../../interface.ts\").Directive}\n */\nexport function ngControllerDirective() {\n return {\n restrict: \"A\",\n scope: true,\n controller: \"@\",\n priority: 500,\n };\n}\n","import { hasAnimate } from \"../../shared/utils.js\";\n\nconst NG_HIDE_CLASS = \"ng-hide\";\n\nconst NG_HIDE_IN_PROGRESS_CLASS = \"ng-hide-animate\";\n\nngShowDirective.$inject = [\"$animate\"];\n/**\n * @param {ng.AnimateService} $animate\n * @returns {ng.Directive}\n */\nexport function ngShowDirective($animate) {\n return {\n restrict: \"A\",\n /**\n * @param scope\n * @param {Element} element\n * @param $attr\n */\n link(scope, element, $attr) {\n scope.$watch($attr.ngShow, (value) => {\n // we're adding a temporary, animation-specific class for ng-hide since this way\n // we can control when the element is actually displayed on screen without having\n // to have a global/greedy CSS selector that breaks when other animations are run.\n // Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845\n if (hasAnimate(element)) {\n $animate[value ? \"removeClass\" : \"addClass\"](element, NG_HIDE_CLASS, {\n tempClasses: NG_HIDE_IN_PROGRESS_CLASS,\n });\n } else {\n if (value) {\n element.classList.remove(NG_HIDE_CLASS);\n } else {\n element.classList.add(NG_HIDE_CLASS);\n }\n }\n });\n },\n };\n}\n\nngHideDirective.$inject = [\"$animate\"];\n/**\n * @returns {import('../../interface.ts').Directive}\n */\nexport function ngHideDirective($animate) {\n return {\n restrict: \"A\",\n link(scope, element, attr) {\n scope.$watch(attr.ngHide, (value) => {\n // The comment inside of the ngShowDirective explains why we add and\n // remove a temporary class for the show/hide animation\n if (hasAnimate(element)) {\n $animate[value ? \"addClass\" : \"removeClass\"](element, NG_HIDE_CLASS, {\n tempClasses: NG_HIDE_IN_PROGRESS_CLASS,\n });\n } else {\n if (value) {\n element.classList.add(NG_HIDE_CLASS);\n } else {\n element.classList.remove(NG_HIDE_CLASS);\n }\n }\n });\n },\n };\n}\n","import { removeElement } from \"../../shared/dom.js\";\nimport { hasAnimate } from \"../../shared/utils.js\";\n\nngIfDirective.$inject = [\"$animate\"];\n/**\n * @param {ng.AnimateService} $animate\n * @returns {ng.Directive}\n */\nexport function ngIfDirective($animate) {\n return {\n transclude: \"element\",\n priority: 600,\n terminal: true,\n restrict: \"A\",\n /**\n *\n * @param {ng.Scope} $scope\n * @param {Element} $element\n * @param {ng.Attributes} $attr\n * @param {*} _ctrl\n * @param {*} $transclude\n */\n link($scope, $element, $attr, _ctrl, $transclude) {\n /** @type {Element} */\n let block;\n\n /** @type {ng.Scope} */\n let childScope;\n\n let previousElements;\n\n $scope.$watch($attr.ngIf, (value) => {\n if (value) {\n if (!childScope) {\n $transclude((clone, newScope) => {\n childScope = newScope;\n // Note: We only need the first/last node of the cloned nodes.\n // However, we need to keep the reference to the dom wrapper as it might be changed later\n // by a directive with templateUrl when its template arrives.\n block = clone;\n\n if (hasAnimate(clone)) {\n $animate.enter(clone, $element.parentElement, $element);\n } else {\n $element.after(clone);\n }\n });\n }\n } else {\n if (previousElements) {\n removeElement(previousElements);\n previousElements = null;\n }\n\n if (childScope) {\n childScope.$destroy();\n childScope = null;\n }\n\n if (block) {\n previousElements = block;\n\n if (hasAnimate(previousElements)) {\n $animate.leave(previousElements).done((response) => {\n if (response !== false) previousElements = null;\n });\n } else {\n $element.nextElementSibling.remove();\n }\n block = null;\n }\n }\n });\n },\n };\n}\n","import { isDefined, hasAnimate } from \"../../shared/utils.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n\nngIncludeDirective.$inject = [\n $t.$templateRequest,\n $t.$anchorScroll,\n $t.$animate,\n $t.$exceptionHandler,\n];\n\n/**\n *\n * @param {ng.TemplateRequestService} $templateRequest\n * @param {import(\"../../services/anchor-scroll/anchor-scroll.js\").AnchorScrollFunction} $anchorScroll\n * @param {ng.AnimateService} $animate\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @returns {ng.Directive}\n */\nexport function ngIncludeDirective(\n $templateRequest,\n $anchorScroll,\n $animate,\n $exceptionHandler,\n) {\n return {\n priority: 400,\n terminal: true,\n transclude: \"element\",\n controller: () => {\n /* empty */\n },\n compile(_element, attr) {\n const srcExp = attr.ngInclude || attr.src;\n\n const onloadExp = attr.onload || \"\";\n\n const autoScrollExp = attr.autoscroll;\n\n return (scope, $element, _$attr, ctrl, $transclude) => {\n function maybeScroll() {\n if (\n isDefined(autoScrollExp) &&\n (!autoScrollExp || scope.$eval(autoScrollExp))\n ) {\n $anchorScroll();\n }\n }\n\n let changeCounter = 0;\n\n let currentScope;\n\n let previousElement;\n\n let currentElement;\n\n const cleanupLastIncludeContent = () => {\n if (previousElement) {\n previousElement.remove();\n previousElement = null;\n }\n\n if (currentScope) {\n currentScope.$destroy();\n currentScope = null;\n }\n\n if (currentElement) {\n if (hasAnimate(currentElement)) {\n $animate.leave(currentElement).done((response) => {\n if (response !== false) previousElement = null;\n });\n } else {\n currentElement.remove();\n }\n\n previousElement = currentElement;\n currentElement = null;\n }\n };\n\n scope.$watch(srcExp, async (src) => {\n const afterAnimation = function (response) {\n response !== false && maybeScroll();\n };\n\n const thisChangeId = ++changeCounter;\n\n if (src) {\n // set the 2nd param to true to ignore the template request error so that the inner\n // contents and scope can be cleaned up.\n await $templateRequest(src, true).then(\n (response) => {\n if (scope.$$destroyed) return;\n\n if (thisChangeId !== changeCounter) return;\n const newScope = scope.$new();\n\n ctrl.template = response;\n\n // Note: This will also link all children of ng-include that were contained in the original\n // html. If that content contains controllers, ... they could pollute/change the scope.\n // However, using ng-include on an element with additional content does not make sense...\n // Note: We can't remove them in the cloneAttchFn of $transclude as that\n // function is called before linking the content, which would apply child\n // directives to non existing elements.\n const clone = $transclude(newScope, (cloneParam) => {\n cleanupLastIncludeContent();\n\n if (hasAnimate(cloneParam)) {\n $animate\n .enter(cloneParam, null, $element)\n .done(afterAnimation);\n } else {\n $element.after(cloneParam);\n maybeScroll();\n }\n });\n\n currentScope = newScope;\n currentElement = clone;\n currentScope.$emit(\"$includeContentLoaded\", src);\n scope.$eval(onloadExp);\n },\n (err) => {\n if (scope.$$destroyed) return;\n\n if (thisChangeId === changeCounter) {\n cleanupLastIncludeContent();\n scope.$emit(\"$includeContentError\", src);\n }\n $exceptionHandler(new Error(err));\n },\n );\n scope.$emit(\"$includeContentRequested\", src);\n } else {\n cleanupLastIncludeContent();\n ctrl.template = null;\n }\n });\n };\n },\n };\n}\n\n// This directive is called during the $transclude call of the first `ngInclude` directive.\n// It will replace and compile the content of the element with the loaded template.\n// We need this directive so that the element content is already filled when\n// the link function of another directive on the same element as ngInclude\n// is called.\nngIncludeFillContentDirective.$inject = [$t.$compile];\n\n/**\n * @param {ng.CompileService} $compile\n * @returns {import(\"../../interface.ts\").Directive}\n */\nexport function ngIncludeFillContentDirective($compile) {\n return {\n priority: -400,\n require: \"ngInclude\",\n link(scope, $element, _$attr, ctrl) {\n $element.innerHTML = ctrl.template;\n $compile($element.childNodes)(scope);\n },\n };\n}\n","import { getController } from \"../../shared/dom.js\";\n\n/**\n * @returns {import('../../interface.ts').Directive}\n */\nexport function ngInitDirective() {\n return {\n priority: 450,\n compile() {\n return {\n pre(scope, element, attrs) {\n const controller = getController(element);\n\n if (controller) {\n controller.$eval(attrs.ngInit);\n } else {\n scope.$eval(attrs.ngInit);\n }\n },\n };\n },\n };\n}\n","/**\n * @returns {import('../../interface.ts').Directive}\n */\nexport function ngNonBindableDirective() {\n return {\n terminal: true,\n priority: 1000,\n };\n}\n","import {\n directiveNormalize,\n getNodeName,\n hasOwn,\n minErr,\n} from \"../../shared/utils.js\";\nimport { getCacheData } from \"../../shared/dom.js\";\n\n/**\n * The `ngRef` attribute tells AngularTS to assign the controller of a component (or a directive)\n * to the given property in the current scope.\n *\n * If the element with `ngRef` is destroyed `null` is assigned to the property.\n *\n * Note that if you want to assign from a child into the parent scope, you must initialize the\n * target property on the parent scope, otherwise `ngRef` will assign on the child scope.\n * This commonly happens when assigning elements or components wrapped in {@link ngIf} or\n * {@link ngRepeat}. See the second example below.\n *\n *\n * @element ANY\n * @param {string} ngRef property name - A valid AngularTS expression identifier to which the\n * controller or dom-wrapped DOM element will be bound.\n * @param {string=} ngRefRead read value - The name of a directive (or component) on this element,\n * or the special string `$element`. If a name is provided, `ngRef` will\n * assign the matching controller. If `$element` is provided, the element\n * itself is assigned (even if a controller is available).\n */\n\nconst ngRefMinErr = minErr(\"ngRef\");\n\nngRefDirective.$inject = [\"$parse\"];\nexport function ngRefDirective($parse) {\n return {\n priority: -1, // Needed for compatibility with element transclusion on the same element\n restrict: \"A\",\n compile(tElement, tAttrs) {\n // Get the expected controller name, converts <data-some-thing> into \"someThing\"\n const controllerName = directiveNormalize(getNodeName(tElement));\n\n // Get the expression for value binding\n const getter = $parse(tAttrs.ngRef);\n\n const setter =\n getter.assign ||\n function () {\n throw ngRefMinErr(\n \"nonassign\",\n 'Expression in ngRef=\"{0}\" is non-assignable!',\n tAttrs.ngRef,\n );\n };\n\n return (scope, element, attrs) => {\n let refValue;\n\n if (hasOwn(attrs, \"ngRefRead\")) {\n if (attrs.ngRefRead === \"$element\") {\n refValue = element;\n } else {\n refValue = getCacheData(element, `$${attrs.ngRefRead}Controller`);\n\n if (!refValue) {\n throw ngRefMinErr(\n \"noctrl\",\n 'The controller for ngRefRead=\"{0}\" could not be found on ngRef=\"{1}\"',\n attrs.ngRefRead,\n tAttrs.ngRef,\n );\n }\n }\n } else {\n refValue = getCacheData(element, `$${controllerName}Controller`);\n }\n\n refValue = refValue || element;\n\n setter(scope, refValue);\n\n // when the element is removed, remove it (nullify it)\n element.addEventListener(\"$destroy\", () => {\n // only remove it if value has not changed,\n // because animations (and other procedures) may duplicate elements\n if (getter(scope) === refValue) {\n setter(scope, null);\n }\n });\n };\n },\n };\n}\n","import {\n callBackOnce,\n hasOwn,\n hashKey,\n isArrayLike,\n isDefined,\n minErr,\n} from \"../../shared/utils.js\";\nimport { getBlockNodes, removeElement } from \"../../shared/dom.js\";\nimport { $injectTokens } from \"../../injection-tokens.js\";\n\nconst NG_REMOVED = \"$$NG_REMOVED\";\n\nconst ngRepeatMinErr = minErr(\"ngRepeat\");\n\n/**\n * Regular expression to match either:\n * 1. A single variable name (optionally preceded by whitespace), e.g. \"foo\", \" $bar\"\n * 2. A pair of variable names inside parentheses separated by a comma (with optional whitespace), e.g. \"(x, y)\", \"($foo, _bar123)\"\n *\n * Capturing groups:\n * - Group 1: The single variable name (if present)\n * - Group 2: The first variable in the tuple (if present)\n * - Group 3: The second variable in the tuple (if present)\n *\n * Examples:\n * - Matches: \"foo\", \" $var\", \"(x, y)\", \"($a, $b)\"\n * - Does NOT match: \"x,y\", \"(x)\", \"(x y)\", \"\"\n *\n * @constant {RegExp}\n */\nconst VAR_OR_TUPLE_REGEX =\n /^(?:(\\s*[$\\w]+)|\\(\\s*([$\\w]+)\\s*,\\s*([$\\w]+)\\s*\\))$/;\n\nngRepeatDirective.$inject = [$injectTokens.$animate];\n\n/**\n * TODO // Add type for animate service\n * @param {*} $animate\n * @returns {import(\"../../interface.ts\").Directive}\n */\nexport function ngRepeatDirective($animate) {\n function updateScope(\n scope,\n index,\n valueIdentifier,\n value,\n keyIdentifier,\n key,\n arrayLength,\n ) {\n // TODO(perf): generate setters to shave off ~40ms or 1-1.5%\n if (scope[valueIdentifier] !== value) {\n scope[valueIdentifier] = value;\n }\n\n if (keyIdentifier) scope[keyIdentifier] = key;\n\n if (value) {\n scope.$target.$$hashKey = value.$$hashKey;\n }\n scope.$index = index;\n scope.$first = index === 0;\n scope.$last = index === arrayLength - 1;\n scope.$middle = !(scope.$first || scope.$last);\n scope.$odd = !(scope.$even = (index & 1) === 0);\n }\n\n function getBlockStart(block) {\n return block.clone;\n }\n\n function getBlockEnd(block) {\n return block.clone;\n }\n\n function trackByIdArrayFn(_$scope, _key, value) {\n return hashKey(value);\n }\n\n function trackByIdObjFn(_$scope, key) {\n return key;\n }\n\n return {\n restrict: \"A\",\n transclude: \"element\",\n priority: 1000,\n terminal: true,\n compile: (_$element, $attr) => {\n const expression = $attr.ngRepeat;\n\n const hasAnimate = !!$attr.animate;\n\n let match = expression.match(\n /^\\s*([\\s\\S]+?)\\s+in\\s+([\\s\\S]+?)(?:\\s+as\\s+([\\s\\S]+?))?(?:\\s+track\\s+by\\s+([\\s\\S]+?))?\\s*$/,\n );\n\n if (!match) {\n throw ngRepeatMinErr(\n \"iexp\",\n \"Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.\",\n expression,\n );\n }\n\n const lhs = match[1];\n\n const rhs = match[2];\n\n const aliasAs = match[3];\n\n match = lhs.match(VAR_OR_TUPLE_REGEX);\n\n if (!match) {\n throw ngRepeatMinErr(\n \"iidexp\",\n \"'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.\",\n lhs,\n );\n }\n const valueIdentifier = match[3] || match[1];\n\n const keyIdentifier = match[2];\n\n if (\n aliasAs &&\n (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) ||\n /^(null|undefined|this|\\$index|\\$first|\\$middle|\\$last|\\$even|\\$odd|\\$parent|\\$root|\\$id)$/.test(\n aliasAs,\n ))\n ) {\n throw ngRepeatMinErr(\n \"badident\",\n \"alias '{0}' is invalid --- must be a valid JS identifier which is not a reserved name.\",\n aliasAs,\n );\n }\n\n let trackByIdExpFn;\n\n const swap = callBackOnce(() => {\n if (isDefined($attr.lazy) && isDefined($attr.swap)) {\n document\n .querySelectorAll($attr.swap)\n .forEach((x) => removeElement(x));\n }\n });\n\n return function ngRepeatLink($scope, $element, attr, ctrl, $transclude) {\n // Store a list of elements from previous run. This is a hash where key is the item from the\n // iterator, and the value is objects with following properties.\n // - scope: bound scope\n // - clone: previous element.\n // - index: position\n //\n // We are using no-proto object so that we don't need to guard against inherited props via\n // hasOwnProperty.\n let lastBlockMap = Object.create(null);\n\n // watch props\n $scope.$watch(\n rhs,\n (collection) => {\n swap();\n let index,\n previousNode = $element, // node that cloned nodes should be inserted after\n // initialized to the comment node anchor\n nextNode;\n\n const // Same as lastBlockMap but it has the current state. It will become the\n // lastBlockMap on the next iteration.\n nextBlockMap = Object.create(null);\n\n let key,\n value, // key/value of iteration\n trackById,\n trackByIdFn,\n collectionKeys,\n block, // last object information {scope, element, id}\n elementsToRemove;\n\n if (aliasAs) {\n $scope[aliasAs] = collection;\n }\n\n if (isArrayLike(collection)) {\n collectionKeys = collection;\n trackByIdFn = trackByIdExpFn || trackByIdArrayFn;\n } else {\n trackByIdFn = trackByIdExpFn || trackByIdObjFn;\n // if object, extract keys, in enumeration order, unsorted\n collectionKeys = [];\n\n for (const itemKey in collection) {\n if (hasOwn(collection, itemKey) && itemKey.charAt(0) !== \"$\") {\n collectionKeys.push(itemKey);\n }\n }\n }\n\n const collectionLength = collectionKeys.length;\n\n const nextBlockOrder = new Array(collectionLength);\n\n // locate existing items\n for (index = 0; index < collectionLength; index++) {\n key =\n collection === collectionKeys ? index : collectionKeys[index];\n value = collection[key];\n trackById = trackByIdFn($scope, key, value);\n\n if (lastBlockMap[trackById]) {\n // found previously seen block\n block = lastBlockMap[trackById];\n delete lastBlockMap[trackById];\n nextBlockMap[trackById] = block;\n nextBlockOrder[index] = block;\n } else if (nextBlockMap[trackById]) {\n // if collision detected. restore lastBlockMap and throw an error\n Object.values(nextBlockOrder).forEach((x) => {\n if (x && x.scope) lastBlockMap[x.id] = block;\n });\n throw ngRepeatMinErr(\n \"dupes\",\n \"Duplicates keys in a repeater are not allowed. Repeater: {0}, Duplicate key: {1} for value: {2}\",\n expression,\n trackById,\n value,\n );\n } else {\n // new never before seen block\n nextBlockOrder[index] = {\n id: trackById,\n scope: undefined,\n clone: undefined,\n };\n nextBlockMap[trackById] = true;\n }\n }\n\n // remove leftover items\n for (const blockKey in lastBlockMap) {\n block = lastBlockMap[blockKey];\n elementsToRemove = block.clone;\n\n if (hasAnimate) {\n $animate.leave(elementsToRemove);\n } else {\n elementsToRemove.remove();\n }\n\n if (elementsToRemove.parentNode) {\n // if the element was not removed yet because of pending animation, mark it as deleted\n // so that we can ignore it later\n for (let i = 0, j = elementsToRemove.length; i < j; i++) {\n elementsToRemove[i][NG_REMOVED] = true;\n }\n }\n block.scope.$destroy();\n }\n\n for (index = 0; index < collectionLength; index++) {\n key =\n collection === collectionKeys ? index : collectionKeys[index];\n value = collection[key];\n block = nextBlockOrder[index];\n\n if (block.scope) {\n // if we have already seen this object, then we need to reuse the\n // associated scope/element\n\n nextNode = previousNode;\n\n // skip nodes that are already pending removal via leave animation\n do {\n nextNode = nextNode.nextSibling;\n } while (nextNode && nextNode[NG_REMOVED]);\n\n if (getBlockStart(block) !== nextNode) {\n // existing item which got moved\n $animate.move(getBlockNodes(block.clone), null, previousNode);\n }\n previousNode = getBlockEnd(block);\n updateScope(\n block.scope,\n index,\n valueIdentifier,\n value,\n keyIdentifier,\n key,\n collectionLength,\n );\n } else {\n // new item which we don't know about\n $transclude(\n /**\n * Clone attach function\n * @param {Array<NodeList>} clone\n * @param {ng.Scope} scope\n */\n\n (clone, scope) => {\n block.scope = scope;\n const endNode = clone;\n\n if (hasAnimate) {\n $animate.enter(clone, null, previousNode);\n } else {\n // @ts-ignore\n previousNode.after(clone);\n }\n\n // @ts-ignore\n previousNode = endNode;\n // Note: We only need the first/last node of the cloned nodes.\n // However, we need to keep the reference to the dom wrapper as it might be changed later\n // by a directive with templateUrl when its template arrives.\n block.clone = clone;\n nextBlockMap[block.id] = block;\n updateScope(\n block.scope,\n index,\n valueIdentifier,\n value,\n keyIdentifier,\n key,\n collectionLength,\n );\n },\n );\n }\n }\n lastBlockMap = nextBlockMap;\n },\n isDefined(attr.lazy),\n );\n };\n },\n };\n}\n","/**\n * @returns {ng.Directive}\n */\nexport function ngStyleDirective() {\n return {\n restrict: \"A\",\n link(scope, element, attr) {\n let oldStyles = null;\n\n scope.$watch(attr.ngStyle, (newStyles) => {\n const target = newStyles?.$target || newStyles;\n\n if (oldStyles) {\n for (const key in oldStyles) {\n element.style.removeProperty(key);\n }\n }\n\n if (target) {\n oldStyles = {};\n\n for (const key in target) {\n const value = target[key];\n\n element.style.setProperty(key, value);\n oldStyles[key] = value;\n }\n } else {\n oldStyles = null;\n }\n });\n },\n };\n}\n","import { domInsert, getBlockNodes } from \"../../shared/dom.js\";\nimport { hasAnimate } from \"../../shared/utils.js\";\n\nngSwitchDirective.$inject = [\"$animate\"];\n\n/**\n * @param {ng.AnimateService} $animate\n * @returns {ng.Directive}\n */\nexport function ngSwitchDirective($animate) {\n return {\n require: \"ngSwitch\",\n\n // asks for $scope to fool the BC controller module\n controller: [\n \"$scope\",\n class {\n constructor() {\n this.cases = {};\n }\n },\n ],\n link(scope, _element, attr, ngSwitchController) {\n const watchExpr = attr.ngSwitch || attr.on;\n\n let selectedTranscludes = [];\n\n const selectedElements = [];\n\n const previousLeaveAnimations = [];\n\n const selectedScopes = [];\n\n const spliceFactory = function (array, index) {\n return function (response) {\n if (response !== false) array.splice(index, 1);\n };\n };\n\n scope.$watch(watchExpr, (value) => {\n let i;\n\n let ii;\n\n // Start with the last, in case the array is modified during the loop\n while (previousLeaveAnimations.length) {\n $animate.cancel(previousLeaveAnimations.pop());\n }\n\n for (i = 0, ii = selectedScopes.length; i < ii; ++i) {\n const selected = getBlockNodes(selectedElements[i].clone);\n\n selectedScopes[i].$destroy();\n\n if (hasAnimate(selected)) {\n const runner = (previousLeaveAnimations[i] =\n $animate.leave(selected));\n\n runner.done(spliceFactory(previousLeaveAnimations, i));\n } else {\n selected.remove();\n }\n }\n\n selectedElements.length = 0;\n selectedScopes.length = 0;\n\n if (\n (selectedTranscludes =\n ngSwitchController.cases[`!${value}`] ||\n ngSwitchController.cases[\"?\"])\n ) {\n Object.values(selectedTranscludes).forEach((selectedTransclude) => {\n selectedTransclude.transclude((caseElement, selectedScope) => {\n selectedScopes.push(selectedScope);\n const anchor = selectedTransclude.element;\n\n // TODO removing this breaks repeater test\n const block = {\n clone: caseElement,\n comment: document.createComment(\"\"),\n };\n\n selectedElements.push(block);\n\n if (hasAnimate(caseElement)) {\n $animate.enter(caseElement, anchor.parentElement, anchor);\n } else {\n domInsert(caseElement, anchor.parentElement, anchor);\n }\n });\n });\n }\n });\n },\n };\n}\n\n/**\n * @returns {import('../../interface.ts').Directive}\n */\nexport function ngSwitchWhenDirective() {\n return {\n transclude: \"element\",\n terminal: true,\n priority: 1200,\n\n require: \"^ngSwitch\",\n link(scope, element, attrs, ctrl, $transclude) {\n const cases = attrs.ngSwitchWhen\n .split(attrs.ngSwitchWhenSeparator)\n .sort()\n .filter(\n // Filter duplicate cases\n (elementParam, index, array) => array[index - 1] !== elementParam,\n );\n\n cases.forEach((whenCase) => {\n ctrl.cases[`!${whenCase}`] = ctrl.cases[`!${whenCase}`] || [];\n ctrl.cases[`!${whenCase}`].push({\n transclude: $transclude,\n element,\n });\n });\n },\n };\n}\n\n/**\n * @returns {import('../../interface.ts').Directive}\n */\nexport function ngSwitchDefaultDirective() {\n return {\n transclude: \"element\",\n terminal: true,\n priority: 1200,\n require: \"^ngSwitch\",\n link(_scope, element, _attr, ctrl, $transclude) {\n ctrl.cases[\"?\"] = ctrl.cases[\"?\"] || [];\n ctrl.cases[\"?\"].push({ transclude: $transclude, element });\n },\n };\n}\n","import { emptyElement, removeElement, startingTag } from \"../../shared/dom.js\";\nimport { NodeType } from \"../../shared/node.js\";\nimport {\n equals,\n hasOwn,\n hashKey,\n includes,\n isArrayLike,\n isDefined,\n minErr,\n} from \"../../shared/utils.js\";\n\nconst ngOptionsMinErr = minErr(\"ngOptions\");\n\n/** @type {HTMLOptionElement} */\nconst optionTemplate = document.createElement(\"option\");\n\n/** @type {HTMLOptGroupElement} */\nconst optGroupTemplate = document.createElement(\"optgroup\");\n\nconst NG_OPTIONS_REGEXP =\n /^\\s*([\\s\\S]+?)(?:\\s+as\\s+([\\s\\S]+?))?(?:\\s+group\\s+by\\s+([\\s\\S]+?))?(?:\\s+disable\\s+when\\s+([\\s\\S]+?))?\\s+for\\s+(?:([$\\w][$\\w]*)|(?:\\(\\s*([$\\w][$\\w]*)\\s*,\\s*([$\\w][$\\w]*)\\s*\\)))\\s+in\\s+([\\s\\S]+?)(?:\\s+track\\s+by\\s+([\\s\\S]+?))?$/;\n\n// 1: value expression (valueFn)\n// 2: label expression (displayFn)\n// 3: group by expression (groupByFn)\n// 4: disable when expression (disableWhenFn)\n// 5: array item variable name\n// 6: object item key variable name\n// 7: object item value variable name\n// 8: collection expression\n// 9: track by expression\n\nngOptionsDirective.$inject = [\"$compile\", \"$parse\"];\n/**\n *\n * @param {ng.CompileService} $compile\n * @param {ng.ParseService} $parse\n * @returns {ng.Directive}\n */\nexport function ngOptionsDirective($compile, $parse) {\n /**\n * @param {import('../../interface.ts').Expression} optionsExp\n * @param {HTMLSelectElement} selectElement\n * @param {ng.Scope} scope\n * @returns\n */\n function parseOptionsExpression(optionsExp, selectElement, scope) {\n const match = optionsExp.match(NG_OPTIONS_REGEXP);\n\n if (!match) {\n throw ngOptionsMinErr(\n \"iexp\",\n \"Expected expression in form of \" +\n \"'_select_ (as _label_)? for (_key_,)?_value_ in _collection_'\" +\n \" but got '{0}'. Element: {1}\",\n optionsExp,\n startingTag(selectElement),\n );\n }\n // Extract the parts from the ngOptions expression\n\n // The variable name for the value of the item in the collection\n const valueName = match[5] || match[7];\n\n // The variable name for the key of the item in the collection\n const keyName = match[6];\n\n // An expression that generates the viewValue for an option if there is a label expression\n const selectAs = / as /.test(match[0]) && match[1];\n\n // An expression that is used to track the id of each object in the options collection\n const trackBy = match[9];\n\n // An expression that generates the viewValue for an option if there is no label expression\n const valueFn = $parse(match[2] ? match[1] : valueName);\n\n const selectAsFn = selectAs && $parse(selectAs);\n\n const viewValueFn = selectAsFn || valueFn;\n\n const trackByFn = trackBy && $parse(trackBy);\n\n // Get the value by which we are going to track the option\n // if we have a trackFn then use that (passing scope and locals)\n // otherwise just hash the given viewValue\n const getTrackByValueFn = trackBy\n ? function (value, locals) {\n return trackByFn(scope, locals);\n }\n : function getHashOfValue(value) {\n return hashKey(value);\n };\n\n const getTrackByValue = function (value, key) {\n return getTrackByValueFn(value, getLocals(value, key));\n };\n\n const displayFn = $parse(match[2] || match[1]);\n\n const groupByFn = $parse(match[3] || \"\");\n\n const disableWhenFn = $parse(match[4] || \"\");\n\n const valuesFn = $parse(match[8]);\n\n const locals = {};\n\n const getLocals = keyName\n ? function (value, key) {\n locals[keyName] = key;\n locals[valueName] = value;\n\n return locals;\n }\n : function (value) {\n locals[valueName] = value;\n\n return locals;\n };\n\n class Option {\n constructor(selectValue, viewValue, label, group, disabled) {\n this.selectValue = selectValue;\n this.viewValue = viewValue;\n this.label = label;\n this.group = group;\n this.disabled = disabled;\n }\n }\n\n function getOptionValuesKeys(optionValues) {\n let optionValuesKeys;\n\n if (!keyName && isArrayLike(optionValues)) {\n optionValuesKeys = optionValues;\n } else {\n // if object, extract keys, in enumeration order, unsorted\n optionValuesKeys = [];\n\n for (const itemKey in optionValues) {\n if (hasOwn(optionValues, itemKey) && itemKey.charAt(0) !== \"$\") {\n optionValuesKeys.push(itemKey);\n }\n }\n }\n\n return optionValuesKeys;\n }\n\n return {\n trackBy,\n getTrackByValue,\n getWatchables: $parse(valuesFn, (optionValues) => {\n // Create a collection of things that we would like to watch (watchedArray)\n // so that they can all be watched using a single $watchCollection\n // that only runs the handler once if anything changes\n const watchedArray = [];\n\n optionValues = optionValues || [];\n\n const optionValuesKeys = getOptionValuesKeys(optionValues);\n\n const optionValuesLength = optionValuesKeys.length;\n\n for (let index = 0; index < optionValuesLength; index++) {\n const key =\n optionValues === optionValuesKeys ? index : optionValuesKeys[index];\n\n const value = optionValues[key];\n\n const updatedLocals = getLocals(value, key);\n\n const selectValue = getTrackByValueFn(value, updatedLocals);\n\n watchedArray.push(selectValue);\n\n // Only need to watch the displayFn if there is a specific label expression\n if (match[2] || match[1]) {\n const label = displayFn(scope, updatedLocals);\n\n watchedArray.push(label);\n }\n\n // Only need to watch the disableWhenFn if there is a specific disable expression\n if (match[4]) {\n const disableWhen = disableWhenFn(scope, updatedLocals);\n\n watchedArray.push(disableWhen);\n }\n }\n\n return watchedArray;\n }),\n\n getOptions() {\n /** @type {Option[]} */\n const optionItems = [];\n\n /** @type {Object.<string, Option>} */\n const selectValueMap = {};\n\n // The option values were already computed in the `getWatchables` fn,\n // which must have been called to trigger `getOptions`\n const optionValues = valuesFn(scope) || [];\n\n const optionValuesKeys = getOptionValuesKeys(optionValues);\n\n const optionValuesLength = optionValuesKeys.length;\n\n for (let index = 0; index < optionValuesLength; index++) {\n const key =\n optionValues === optionValuesKeys ? index : optionValuesKeys[index];\n\n const value = optionValues[key];\n\n const updatedLocals = getLocals(value, key);\n\n const viewValue = viewValueFn(scope, updatedLocals);\n\n const selectValue = getTrackByValueFn(viewValue, updatedLocals);\n\n const label = displayFn(scope, updatedLocals);\n\n const group = groupByFn(scope, updatedLocals);\n\n const disabled = disableWhenFn(scope, updatedLocals);\n\n const optionItem = new Option(\n selectValue,\n viewValue,\n label,\n group,\n disabled,\n );\n\n optionItems.push(optionItem);\n selectValueMap[selectValue] = optionItem;\n }\n\n return {\n items: optionItems,\n selectValueMap,\n getOptionFromViewValue(value) {\n return selectValueMap[getTrackByValue(value)];\n },\n getViewValueFromOption(option) {\n // If the viewValue could be an object that may be mutated by the application,\n // we need to make a copy and not return the reference to the value on the option.\n return trackBy\n ? structuredClone(option.viewValue)\n : option.viewValue;\n },\n };\n },\n };\n }\n\n /**\n *\n * @param {ng.Scope} scope\n * @param {HTMLSelectElement} selectElement\n * @param {ng.Attributes} attr\n * @param {*} ctrls\n */\n function ngOptionsPostLink(scope, selectElement, attr, ctrls) {\n const selectCtrl = ctrls[0];\n\n const ngModelCtrl = ctrls[1];\n\n const { multiple } = attr;\n\n // The emptyOption allows the application developer to provide their own custom \"empty\"\n // option when the viewValue does not match any of the option values.\n for (\n let i = 0, children = selectElement.childNodes, ii = children.length;\n i < ii;\n i++\n ) {\n if (/** @type {HTMLOptionElement} */ (children[i]).value === \"\") {\n selectCtrl.hasEmptyOption = true;\n selectCtrl.emptyOption = children[i];\n break;\n }\n }\n\n // The empty option will be compiled and rendered before we first generate the options\n emptyElement(selectElement);\n\n const providedEmptyOption = !!selectCtrl.emptyOption;\n\n const unknownOption = optionTemplate.cloneNode(false);\n\n // TODO double check\n unknownOption.nodeValue = \"?\";\n\n let options;\n\n const ngOptions = parseOptionsExpression(\n attr.ngOptions,\n selectElement,\n scope,\n );\n\n // This stores the newly created options before they are appended to the select.\n // Since the contents are removed from the fragment when it is appended,\n // we only need to create it once.\n const listFragment = document.createDocumentFragment();\n\n // Overwrite the implementation. ngOptions doesn't use hashes\n selectCtrl.generateUnknownOptionValue = () => \"?\";\n\n // Update the controller methods for multiple selectable options\n if (!multiple) {\n selectCtrl.writeValue = function writeNgOptionsValue(value) {\n // The options might not be defined yet when ngModel tries to render\n if (!options) return;\n\n const selectedOption =\n selectElement.options[selectElement.selectedIndex];\n\n const option = options.getOptionFromViewValue(value);\n\n // Make sure to remove the selected attribute from the previously selected option\n // Otherwise, screen readers might get confused\n if (selectedOption) selectedOption.removeAttribute(\"selected\");\n\n if (option) {\n // Don't update the option when it is already selected.\n // For example, the browser will select the first option by default. In that case,\n // most properties are set automatically - except the `selected` attribute, which we\n // set always\n\n if (selectElement.value !== option.selectValue) {\n selectCtrl.removeUnknownOption();\n\n selectElement.value = option.selectValue;\n option.element.selected = true;\n }\n\n option.element.setAttribute(\"selected\", \"selected\");\n } else {\n selectCtrl.selectUnknownOrEmptyOption(value);\n }\n };\n\n selectCtrl.readValue = function readNgOptionsValue() {\n const selectedOption = options.selectValueMap[selectElement.value];\n\n if (selectedOption && !selectedOption.disabled) {\n selectCtrl.unselectEmptyOption();\n selectCtrl.removeUnknownOption();\n\n return options.getViewValueFromOption(selectedOption);\n }\n\n return null;\n };\n\n // If we are using `track by` then we must watch the tracked value on the model\n // since ngModel only watches for object identity change\n // FIXME: When a user selects an option, this watch will fire needlessly\n if (ngOptions.trackBy) {\n scope.$watch(ngOptions.getTrackByValue(ngModelCtrl.$viewValue), () => {\n ngModelCtrl.$render();\n });\n }\n } else {\n selectCtrl.writeValue = function writeNgOptionsMultiple(values) {\n // The options might not be defined yet when ngModel tries to render\n if (!options) return;\n\n // Only set `<option>.selected` if necessary, in order to prevent some browsers from\n // scrolling to `<option>` elements that are outside the `<select>` element's viewport.\n const selectedOptions =\n (values && values.map(getAndUpdateSelectedOption)) || [];\n\n options.items.forEach((option) => {\n if (option.element.selected && !includes(selectedOptions, option)) {\n option.element.selected = false;\n }\n });\n };\n\n selectCtrl.readValue = function readNgOptionsMultiple() {\n const selectedValues = selectElement.value || [];\n\n const selections = [];\n\n // @ts-ignore\n selectedValues.forEach((value) => {\n const option = options.selectValueMap[value];\n\n if (option && !option.disabled)\n selections.push(options.getViewValueFromOption(option));\n });\n\n return selections;\n };\n\n // If we are using `track by` then we must watch these tracked values on the model\n // since ngModel only watches for object identity change\n // if (ngOptions.trackBy) {\n // scope.$watchCollection(\n // () => {\n // if (isArray(ngModelCtrl.$viewValue)) {\n // return ngModelCtrl.$viewValue.map((value) =>\n // ngOptions.getTrackByValue(value),\n // );\n // }\n // },\n // () => {\n // ngModelCtrl.$render();\n // },\n // );\n // }\n }\n\n if (providedEmptyOption) {\n // compile the element since there might be bindings in it\n const linkFn = $compile(selectCtrl.emptyOption);\n\n selectElement.prepend(selectCtrl.emptyOption);\n linkFn(scope);\n\n if (selectCtrl.emptyOption.nodeType === NodeType._COMMENT_NODE) {\n // This means the empty option has currently no actual DOM node, probably because\n // it has been modified by a transclusion directive.\n selectCtrl.hasEmptyOption = false;\n\n // Redefine the registerOption function, which will catch\n // options that are added by ngIf etc. (rendering of the node is async because of\n // lazy transclusion)\n selectCtrl.registerOption = function (optionScope, optionEl) {\n if (optionEl.value === \"\") {\n selectCtrl.hasEmptyOption = true;\n selectCtrl.emptyOption = optionEl;\n // This ensures the new empty option is selected if previously no option was selected\n ngModelCtrl.$render();\n\n optionEl.addEventListener(\"$destroy\", () => {\n const needsRerender = selectCtrl.$isEmptyOptionSelected();\n\n selectCtrl.hasEmptyOption = false;\n selectCtrl.emptyOption = undefined;\n\n if (needsRerender) ngModelCtrl.$render();\n });\n }\n };\n }\n }\n\n // We will re-render the option elements if the option values or labels change\n\n // let watchables = ngOptions.getWatchables();\n // watchables.forEach((i) => {\n // scope.$watch(i, updateOptions);\n // });\n scope.$watch(\n ngOptions.getWatchables.decoratedNode.body[0].expression.name,\n updateOptions,\n );\n\n // ------------------------------------------------------------------ //\n\n function addOptionElement(option, parent) {\n /**\n * @type {HTMLOptionElement}\n */\n const optionElement = /** @type {HTMLOptionElement} */ (\n optionTemplate.cloneNode(false)\n );\n\n parent.appendChild(optionElement);\n updateOptionElement(option, optionElement);\n }\n\n function getAndUpdateSelectedOption(viewValue) {\n const option = options.getOptionFromViewValue(viewValue);\n\n const element = option && option.element;\n\n if (element && !element.selected) element.selected = true;\n\n return option;\n }\n\n function updateOptionElement(option, element) {\n option.element = element;\n element.disabled = option.disabled;\n\n // Support: IE 11 only, Edge 12-13 only\n // NOTE: The label must be set before the value, otherwise IE 11 & Edge create unresponsive\n // selects in certain circumstances when multiple selects are next to each other and display\n // the option list in listbox style, i.e. the select is [multiple], or specifies a [size].\n // See https://github.com/angular/angular.js/issues/11314 for more info.\n // This is unfortunately untestable with unit / e2e tests\n if (option.label !== element.label) {\n element.label = option.label;\n element.textContent = option.label;\n }\n element.value = option.selectValue;\n }\n\n function updateOptions() {\n const previousValue = options && selectCtrl.readValue();\n\n // We must remove all current options, but cannot simply set innerHTML = null\n // since the providedEmptyOption might have an ngIf on it that inserts comments which we\n // must preserve.\n // Instead, iterate over the current option elements and remove them or their optgroup\n // parents\n if (options) {\n for (let i = options.items.length - 1; i >= 0; i--) {\n const option = options.items[i];\n\n if (isDefined(option.group)) {\n removeElement(option.element.parentNode);\n } else {\n removeElement(option.element);\n }\n }\n }\n\n options = ngOptions.getOptions();\n\n const groupElementMap = {};\n\n options.items.forEach((option) => {\n let groupElement;\n\n if (isDefined(option.group)) {\n // This option is to live in a group\n // See if we have already created this group\n groupElement = groupElementMap[option.group];\n\n if (!groupElement) {\n groupElement = optGroupTemplate.cloneNode(false);\n listFragment.appendChild(groupElement);\n\n // Update the label on the group element\n // \"null\" is special cased because of Safari\n /** @type {HTMLOptGroupElement} */\n (groupElement).label =\n option.group === null ? \"null\" : option.group;\n\n // Store it for use later\n groupElementMap[option.group] = groupElement;\n }\n\n addOptionElement(option, groupElement);\n } else {\n // This option is not in a group\n addOptionElement(option, listFragment);\n }\n });\n\n selectElement.appendChild(listFragment);\n\n ngModelCtrl.$render();\n\n // Check to see if the value has changed due to the update to the options\n if (!ngModelCtrl.$isEmpty(previousValue)) {\n const nextValue = selectCtrl.readValue();\n\n const isNotPrimitive = ngOptions.trackBy || multiple;\n\n if (\n isNotPrimitive\n ? !equals(previousValue, nextValue)\n : previousValue !== nextValue\n ) {\n ngModelCtrl.$setViewValue(nextValue);\n ngModelCtrl.$render();\n }\n }\n }\n }\n\n return {\n restrict: \"A\",\n terminal: true,\n require: [\"select\", \"ngModel\"],\n link: {\n pre: function ngOptionsPreLink(scope, selectElement, attr, ctrls) {\n // Deactivate the SelectController.register method to prevent\n // option directives from accidentally registering themselves\n // (and unwanted $destroy handlers etc.)\n ctrls[0].registerOption = () => {\n /* empty */\n };\n },\n post: ngOptionsPostLink,\n },\n };\n}\n","import { minErr } from \"../../shared/utils.js\";\nimport { emptyElement, startingTag } from \"../../shared/dom.js\";\nimport { NodeType } from \"../../shared/node.js\";\n\n/**\n * Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.\n *\n * You can specify that you want to insert a named transclusion slot, instead of the default slot, by providing the slot name\n * as the value of the `ng-transclude` or `ng-transclude-slot` attribute.\n *\n * If the transcluded content is not empty (i.e. contains one or more DOM nodes, including whitespace text nodes), any existing\n * content of this element will be removed before the transcluded content is inserted.\n * If the transcluded content is empty (or only whitespace), the existing content is left intact. This lets you provide fallback\n * content in the case that no transcluded content is provided.\n *\n * @element ANY\n *\n * @param {string} ngTransclude|ngTranscludeSlot the name of the slot to insert at this point. If this is not provided, is empty\n * or its value is the same as the name of the attribute then the default slot is used.\n */\nconst ngTranscludeMinErr = minErr(\"ngTransclude\");\n\nngTranscludeDirective.$inject = [\"$compile\"];\n/**\n * @param {ng.CompileService} $compile\n * @returns {ng.Directive}\n */\nexport function ngTranscludeDirective($compile) {\n return {\n compile: function ngTranscludeCompile(tElement) {\n // Remove and cache any original content to act as a fallback\n const fallbackLinkFn = $compile(tElement.childNodes);\n\n emptyElement(tElement);\n\n /**\n *\n * @param {ng.Scope} $scope\n * @param {Element} $element\n * @param {ng.Attributes} $attrs\n * @param {*} _controller\n * @param {*} $transclude\n */\n function ngTranscludePostLink(\n $scope,\n $element,\n $attrs,\n _controller,\n $transclude,\n ) {\n if (!$transclude) {\n throw ngTranscludeMinErr(\n \"orphan\",\n \"Illegal use of ngTransclude directive in the template! \" +\n \"No parent directive that requires a transclusion found. \" +\n \"Element: {0}\",\n startingTag($element),\n );\n }\n\n // If the attribute is of the form: `ng-transclude=\"ng-transclude\"` then treat it like the default\n if ($attrs.ngTransclude === $attrs.$attr.ngTransclude) {\n $attrs.ngTransclude = \"\";\n }\n const slotName = $attrs.ngTransclude || $attrs.ngTranscludeSlot;\n\n // If the slot is required and no transclusion content is provided then this call will throw an error\n $transclude(ngTranscludeCloneAttachFn, null, slotName);\n\n // If the slot is optional and no transclusion content is provided then use the fallback content\n if (slotName && !$transclude.isSlotFilled(slotName)) {\n useFallbackContent();\n }\n\n /**\n * @param {NodeList | Node} clone\n * @param {ng.Scope} transcludedScope\n */\n function ngTranscludeCloneAttachFn(clone, transcludedScope) {\n if (notWhitespace(clone)) {\n if (clone instanceof NodeList) {\n Array.from(clone).forEach((el) => {\n $element.append(el);\n });\n } else {\n $element.append(/** @type {Node} */ (clone));\n }\n } else {\n useFallbackContent();\n // There is nothing linked against the transcluded scope since no content was available,\n // so it should be safe to clean up the generated scope.\n transcludedScope.$destroy();\n }\n }\n\n function useFallbackContent() {\n // Since this is the fallback content rather than the transcluded content,\n // we link against the scope of this directive rather than the transcluded scope\n fallbackLinkFn(\n $scope,\n\n (clone) => {\n // @ts-ignore\n $element.append(clone);\n },\n );\n }\n\n function notWhitespace(node) {\n if (node instanceof Array) {\n return false;\n } else if (\n node.nodeType !== NodeType._TEXT_NODE ||\n node.nodeValue.trim()\n ) {\n return true;\n }\n\n return false;\n }\n }\n\n return ngTranscludePostLink;\n },\n };\n}\n","import { BOOLEAN_ATTR } from \"../../shared/dom.js\";\nimport { directiveNormalize, entries } from \"../../shared/utils.js\";\nimport { ALIASED_ATTR } from \"../../shared/constants.js\";\nimport { $injectTokens } from \"../../injection-tokens.js\";\n\nexport const REGEX_STRING_REGEXP = /^\\/(.+)\\/([a-z]*)$/;\n\n/**\n * @type {Record<string, import(\"../../interface.ts\").DirectiveFactory>}\n */\nexport const ngAttributeAliasDirectives = {};\n\n// boolean attrs are evaluated\nBOOLEAN_ATTR.forEach((i) => {\n // binding to multiple is not supported\n if (i === \"multiple\") return;\n\n function defaultLinkFn(scope, _element, attr) {\n scope.$watch(attr[normalized], (value) => {\n attr.$set(i, !!value);\n });\n }\n\n const normalized = directiveNormalize(`ng-${i}`);\n\n let linkFn = defaultLinkFn;\n\n if (i === \"checked\") {\n linkFn = function (scope, element, attr) {\n // ensuring ngChecked doesn't interfere with ngModel when both are set on the same input\n if (attr.ngModel !== attr[normalized]) {\n defaultLinkFn(scope, element, attr);\n }\n };\n }\n\n ngAttributeAliasDirectives[normalized] = function () {\n return {\n restrict: \"A\",\n priority: 100,\n link: linkFn,\n };\n };\n});\n\n// aliased input attrs are evaluated\nentries(ALIASED_ATTR).forEach(([ngAttr]) => {\n ngAttributeAliasDirectives[ngAttr] = function () {\n return {\n priority: 100,\n link(scope, element, attr) {\n // special case ngPattern when a literal regular expression value\n // is used as the expression (this way we don't have to watch anything).\n if (ngAttr === \"ngPattern\" && attr.ngPattern.charAt(0) === \"/\") {\n const match = attr.ngPattern.match(REGEX_STRING_REGEXP);\n\n if (match) {\n attr.$set(\"ngPattern\", new RegExp(match[1], match[2]).toString());\n\n return;\n }\n }\n\n scope.$watch(attr[ngAttr], (value) => {\n attr.$set(ngAttr, value);\n });\n },\n };\n };\n});\n\n// ng-src, ng-srcset, ng-href are interpolated\n[\"src\", \"srcset\", \"href\"].forEach((attrName) => {\n const normalized = directiveNormalize(`ng-${attrName}`);\n\n ngAttributeAliasDirectives[normalized] = [\n $injectTokens.$sce,\n function ($sce) {\n return {\n priority: 99, // it needs to run after the attributes are interpolated\n link(_scope, element, attr) {\n let name = attrName;\n\n if (\n attrName === \"href\" &&\n toString.call(/** @type {HTMLLinkElement} */ (element).href) ===\n \"[object SVGAnimatedString]\"\n ) {\n name = \"xlinkHref\";\n attr.$attr[name] = \"href\";\n }\n\n // We need to sanitize the url at least once, in case it is a constant\n // non-interpolated attribute.\n attr.$set(normalized, $sce.getTrustedMediaUrl(attr[normalized]));\n\n attr.$observe(normalized, (value) => {\n if (!value) {\n if (attrName === \"href\") {\n attr.$set(name, null);\n }\n\n return;\n }\n\n attr.$set(name, value);\n });\n },\n };\n },\n ];\n});\n","import {\n hasOwn,\n isNumberNaN,\n isProxy,\n isString,\n isUndefined,\n minErr,\n} from \"../../shared/utils.js\";\nimport { REGEX_STRING_REGEXP } from \"./../attrs/attrs.js\";\nimport { startingTag } from \"../../shared/dom.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n\n/**\n *\n * @param {string} ngRequired AngularTS expression. If it evaluates to `true`, it sets the\n * `required` attribute to the element and adds the `required`\n * {@link ngModel.NgModelController#$validators `validator`}.\n *\n *\n * ngRequired adds the required {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for {@link input `input`} and {@link select `select`} controls, but can also be\n * applied to custom controls.\n *\n * The directive sets the `required` attribute on the element if the AngularTS expression inside\n * `ngRequired` evaluates to true. A special directive for setting `required` is necessary because we\n * cannot use interpolation inside `required`. See the {@link guide/interpolation interpolation guide}\n * for more info.\n *\n * The validator will set the `required` error key to true if the `required` attribute is set and\n * calling {@link ngModel.NgModelController#$isEmpty `NgModelController.$isEmpty`} with the\n * {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`} returns `true`. For example, the\n * `$isEmpty()` implementation for `input[text]` checks the length of the `$viewValue`. When developing\n * custom controls, `$isEmpty()` can be overwritten to account for a $viewValue that is not string-based.\n *\n */\nexport const requiredDirective = [\n $t.$parse,\n /**\n * @param {import(\"../../core/parse/interface.ts\").ParseService} $parse\n * @returns {import(\"../../interface.ts\").Directive}\n */\n ($parse) => ({\n restrict: \"A\",\n require: \"?ngModel\",\n link:\n /**\n * @param {ng.Scope} scope\n * @param {Element} _elm\n * @param {ng.Attributes} attr\n * @param {ng.NgModelController} ctrl\n * @returns\n */\n (scope, _elm, attr, ctrl) => {\n if (!ctrl) return;\n // For boolean attributes like required, presence means true\n let value = hasOwn(attr, \"required\") || $parse(attr.ngRequired)(scope);\n\n if (!attr.ngRequired) {\n // force truthy in case we are on non input element\n // (input elements do this automatically for boolean attributes like required)\n attr.required = true;\n }\n\n ctrl.$validators.required = (_modelValue, viewValue) => {\n return !value || !ctrl.$isEmpty(viewValue);\n };\n\n attr.$observe(\"required\", (newVal) => {\n if (value !== newVal) {\n value = newVal;\n ctrl.$validate();\n }\n });\n },\n }),\n];\n\n/**\n * @param {String|RegExp} ngPattern AngularTS expression that must evaluate to a `RegExp` or a `String`\n * parsable into a `RegExp`, or a `RegExp` literal. See above for\n * more details.\n *\n * @description\n *\n * ngPattern adds the pattern {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.\n *\n * The validator sets the `pattern` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}\n * does not match a RegExp which is obtained from the `ngPattern` attribute value:\n * - the value is an AngularTS expression:\n * - If the expression evaluates to a RegExp object, then this is used directly.\n * - If the expression evaluates to a string, then it will be converted to a RegExp after wrapping it\n * in `^` and `$` characters. For instance, `\"abc\"` will be converted to `new RegExp('^abc$')`.\n * - If the value is a RegExp literal, e.g. `ngPattern=\"/^\\d+$/\"`, it is used directly.\n *\n * <div class=\"alert alert-info\">\n * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n * start at the index of the last search's match, thus not taking the whole input value into\n * account.\n * </div>\n *\n * <div class=\"alert alert-info\">\n * **Note:** This directive is also added when the plain `pattern` attribute is used, with two\n * differences:\n * <ol>\n * <li>\n * `ngPattern` does not set the `pattern` attribute and therefore HTML5 constraint validation is\n * not available.\n * </li>\n * <li>\n * The `ngPattern` attribute must be an expression, while the `pattern` value must be\n * interpolated.\n * </li>\n * </ol>\n * </div>\n */\nexport const patternDirective = [\n $t.$parse,\n /**\n * @param {import(\"../../core/parse/interface.ts\").ParseService} $parse\n * @returns {import(\"../../interface.ts\").Directive}\n */\n ($parse) => ({\n restrict: \"A\",\n require: \"?ngModel\",\n compile: (_Elm, tAttr) => {\n let patternExp;\n\n let parseFn;\n\n if (tAttr.ngPattern) {\n patternExp = tAttr.ngPattern;\n\n // ngPattern might be a scope expression, or an inlined regex, which is not parsable.\n // We get value of the attribute here, so we can compare the old and the new value\n // in the observer to avoid unnecessary validations\n if (\n tAttr.ngPattern.charAt(0) === \"/\" &&\n REGEX_STRING_REGEXP.test(tAttr.ngPattern)\n ) {\n parseFn = function () {\n return tAttr.ngPattern;\n };\n } else {\n parseFn = $parse(tAttr.ngPattern);\n }\n }\n\n return function (scope, elm, attr, ctrl) {\n if (!ctrl) return;\n let attrVal = attr.pattern;\n\n if (attr.ngPattern) {\n attrVal = parseFn(scope);\n } else {\n patternExp = attr.pattern;\n }\n\n let regexp = parsePatternAttr(attrVal, patternExp, elm);\n\n attr.$observe(\"pattern\", (newVal) => {\n const oldRegexp = regexp;\n\n regexp = parsePatternAttr(newVal, patternExp, elm);\n\n if (\n (oldRegexp && oldRegexp.toString()) !==\n (regexp && regexp.toString())\n ) {\n ctrl.$validate();\n }\n });\n\n ctrl.$validators.pattern = (_modelValue, viewValue) => {\n // HTML5 pattern constraint validates the input value, so we validate the viewValue\n return (\n ctrl.$isEmpty(viewValue) ||\n isUndefined(regexp) ||\n regexp.test(viewValue)\n );\n };\n };\n },\n }),\n];\n\n/**\n * @param {string} ngMaxlength AngularTS expression that must evaluate to a `Number` or `String`\n * parsable into a `Number`. Used as value for the `maxlength`\n * {@link ngModel.NgModelController#$validators validator}.\n *\n * @description\n *\n * ngMaxlength adds the maxlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.\n *\n * The validator sets the `maxlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}\n * is longer than the integer obtained by evaluating the AngularTS expression given in the\n * `ngMaxlength` attribute value.\n *\n * <div class=\"alert alert-info\">\n * **Note:** This directive is also added when the plain `maxlength` attribute is used, with two\n * differences:\n * <ol>\n * <li>\n * `ngMaxlength` does not set the `maxlength` attribute and therefore HTML5 constraint\n * validation is not available.\n * </li>\n * <li>\n * The `ngMaxlength` attribute must be an expression, while the `maxlength` value must be\n * interpolated.\n * </li>\n * </ol>\n * </div>\n *\n */\nexport const maxlengthDirective = [\n $t.$parse,\n /**\n * @param {ng.ParseService} $parse\n * @returns {ng.Directive}\n */\n ($parse) => ({\n restrict: \"A\",\n require: \"?ngModel\",\n link:\n /**\n * @param {ng.Scope} scope\n * @param {Element} _elm\n * @param {ng.Attributes} attr\n * @param {ng.NgModelController} ctrl\n * @returns\n */\n (scope, _elm, attr, ctrl) => {\n if (!ctrl) return;\n\n let maxlength = attr.maxlength || $parse(attr.ngMaxlength)(scope);\n\n let maxlengthParsed = parseLength(maxlength);\n\n attr.$observe(\"maxlength\", (value) => {\n if (maxlength !== value) {\n maxlengthParsed = parseLength(value);\n maxlength = value;\n ctrl.$validate();\n }\n });\n ctrl.$validators.maxlength = function (_modelValue, viewValue) {\n return (\n maxlengthParsed < 0 ||\n ctrl.$isEmpty(viewValue) ||\n viewValue.length <= maxlengthParsed\n );\n };\n },\n }),\n];\n\n/**\n *\n * @param {string} ngMinlength AngularTS expression that must evaluate to a `Number` or `String`\n * parsable into a `Number`. Used as value for the `minlength`\n * {@link ngModel.NgModelController#$validators validator}.\n *\n * @description\n *\n * ngMinlength adds the minlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.\n *\n * The validator sets the `minlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}\n * is shorter than the integer obtained by evaluating the AngularTS expression given in the\n * `ngMinlength` attribute value.\n *\n * <div class=\"alert alert-info\">\n * **Note:** This directive is also added when the plain `minlength` attribute is used, with two\n * differences:\n * <ol>\n * <li>\n * `ngMinlength` does not set the `minlength` attribute and therefore HTML5 constraint\n * validation is not available.\n * </li>\n * <li>\n * The `ngMinlength` value must be an expression, while the `minlength` value must be\n * interpolated.\n * </li>\n * </ol>\n * </div>\n *\n */\nexport const minlengthDirective = [\n $t.$parse,\n ($parse) => ({\n restrict: \"A\",\n require: \"?ngModel\",\n link(scope, elm, attr, ctrl) {\n if (!ctrl) return;\n\n let minlength = attr.minlength || $parse(attr.ngMinlength)(scope);\n\n let minlengthParsed = parseLength(minlength) || -1;\n\n attr.$observe(\"minlength\", (value) => {\n if (minlength !== value) {\n minlengthParsed = parseLength(value) || -1;\n minlength = value;\n ctrl.$validate();\n }\n });\n ctrl.$validators.minlength = function (modelValue, viewValue) {\n return ctrl.$isEmpty(viewValue) || viewValue.length >= minlengthParsed;\n };\n },\n }),\n];\n\nfunction parsePatternAttr(regex, patternExp, elm) {\n if (!regex) return undefined;\n\n if (isProxy(regex)) {\n regex = regex.$target;\n }\n\n if (isString(regex)) {\n const match = regex.match(/^\\/(.*)\\/([gimsuy]*)$/);\n\n if (match) {\n regex = new RegExp(match[1], match[2]);\n } else {\n regex = new RegExp(`^${regex}$`);\n }\n }\n\n if (!regex.test) {\n throw minErr(\"ngPattern\")(\n \"noregexp\",\n \"Expected {0} to be a RegExp but was {1}. Element: {2}\",\n patternExp,\n regex,\n startingTag(elm),\n );\n }\n\n return regex;\n}\n\nfunction parseLength(val) {\n const intVal = parseInt(val, 10);\n\n return isNumberNaN(intVal) ? -1 : intVal;\n}\n","import {\n getNodeName,\n isFunction,\n isNumber,\n isString,\n} from \"../../shared/utils.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n\n/**\n * @typedef {Object} AnchorScrollObject\n * @property {number|function|Element} yOffset\n */\n\n/**\n * @typedef {(string) => void} AnchorScrollFunction\n */\n\n/**\n * @typedef {AnchorScrollFunction | AnchorScrollObject} AnchorScrollService\n */\n\nexport class AnchorScrollProvider {\n constructor() {\n this.autoScrollingEnabled = true;\n }\n\n $get = [\n $t.$location,\n $t.$rootScope,\n /**\n *\n * @param {import('../../services/location/location.js').Location} $location\n * @param {ng.Scope} $rootScope\n * @returns\n */\n ($location, $rootScope) => {\n // Helper function to get first anchor from a NodeList\n // (using `Array#some()` instead of `angular#forEach()` since it's more performant\n // and working in all supported browsers.)\n function getFirstAnchor(list) {\n let result = null;\n\n Array.prototype.some.call(list, (element) => {\n if (getNodeName(element) === \"a\") {\n result = element;\n\n return true;\n }\n\n return false;\n });\n\n return result;\n }\n\n function getYOffset() {\n // Figure out a better way to configure this other than bolting on a property onto a function\n let offset = /** @type {AnchorScrollObject} */ (scroll).yOffset;\n\n if (isFunction(offset)) {\n offset = /** @type {Function} */ (offset)();\n } else if (offset instanceof Element) {\n const elem = offset[0];\n\n const style = window.getComputedStyle(elem);\n\n if (style.position !== \"fixed\") {\n offset = 0;\n } else {\n offset = elem.getBoundingClientRect().bottom;\n }\n } else if (!isNumber(offset)) {\n offset = 0;\n }\n\n return offset;\n }\n\n function scrollTo(elem) {\n if (elem) {\n elem.scrollIntoView();\n\n const offset = getYOffset();\n\n if (offset) {\n // `offset` is the number of pixels we should scroll UP in order to align `elem` properly.\n // This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the\n // top of the viewport.\n //\n // IF the number of pixels from the top of `elem` to the end of the page's content is less\n // than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some\n // way down the page.\n //\n // This is often the case for elements near the bottom of the page.\n //\n // In such cases we do not need to scroll the whole `offset` up, just the difference between\n // the top of the element and the offset, which is enough to align the top of `elem` at the\n // desired position.\n const elemTop = elem.getBoundingClientRect().top;\n\n window.scrollBy(0, elemTop - /** @type {number} */ (offset));\n }\n } else {\n window.scrollTo(0, 0);\n }\n }\n\n /** @type {AnchorScrollService} */\n const scroll = function (hash) {\n // Allow numeric hashes\n hash = isString(hash)\n ? hash\n : isNumber(hash)\n ? hash.toString()\n : $location.getHash();\n let elm;\n\n // empty hash, scroll to the top of the page\n if (!hash) {\n scrollTo(null);\n }\n // element with given id\n else if ((elm = document.getElementById(hash))) scrollTo(elm);\n // first anchor with given name :-D\n else if ((elm = getFirstAnchor(document.getElementsByName(hash))))\n scrollTo(elm);\n // no element and hash === 'top', scroll to the top of the page\n else if (hash === \"top\") scrollTo(null);\n };\n\n // does not scroll when user clicks on anchor link that is currently on\n // (no url change, no $location.getHash() change), browser native does scroll\n if (this.autoScrollingEnabled) {\n $rootScope.$location = $location;\n $rootScope.$watch(\"$location.$$hash\", (newVal, oldVal) => {\n // skip the initial scroll if $location.hash is empty\n if (newVal === oldVal && newVal === \"\") return;\n\n const action = () => scroll(newVal);\n\n if (document.readyState === \"complete\") {\n // Force the action to be run async for consistent behavior\n // from the action's point of view\n // i.e. it will definitely not be in a $apply\n queueMicrotask(() => action());\n } else {\n window.addEventListener(\"load\", () => action());\n }\n });\n }\n\n return scroll;\n },\n ];\n}\n","import {\n extend,\n hasAnimate,\n isFunction,\n isObject,\n mergeClasses,\n minErr,\n} from \"../shared/utils.js\";\nimport { animatedomInsert, removeElement } from \"../shared/dom.js\";\nimport { NG_ANIMATE_CLASSNAME } from \"./shared.js\";\nimport { $injectTokens } from \"../injection-tokens\";\n\nconst $animateMinErr = minErr(\"$animate\");\n\n// if any other type of options value besides an Object value is\n// passed into the $animate.method() animation then this helper code\n// will be run which will ignore it. While this patch is not the\n// greatest solution to this, a lot of existing plugins depend on\n// $animate to either call the callback (< 1.2) or return a promise\n// that can be changed. This helper function ensures that the options\n// are wiped clean incase a callback function is provided.\nfunction prepareAnimateOptions(options) {\n return isObject(options) ? options : {};\n}\n\nAnimateProvider.$inject = [\"$provide\"];\n\n/** @param {ng.ProvideService} $provide */\nexport function AnimateProvider($provide) {\n const provider = this;\n\n let classNameFilter = null;\n\n let customFilter = null;\n\n this.$$registeredAnimations = Object.create(null);\n\n /**\n * Registers a new injectable animation factory function. The factory function produces the\n * animation object which contains callback functions for each event that is expected to be\n * animated.\n *\n * * `eventFn`: `function(element, ... , doneFunction, options)`\n * The element to animate, the `doneFunction` and the options fed into the animation. Depending\n * on the type of animation additional arguments will be injected into the animation function. The\n * list below explains the function signatures for the different animation methods:\n *\n * - setClass: function(element, addedClasses, removedClasses, doneFunction, options)\n * - addClass: function(element, addedClasses, doneFunction, options)\n * - removeClass: function(element, removedClasses, doneFunction, options)\n * - enter, leave, move: function(element, doneFunction, options)\n * - animate: function(element, fromStyles, toStyles, doneFunction, options)\n *\n * Make sure to trigger the `doneFunction` once the animation is fully complete.\n *\n * ```js\n * return {\n * //enter, leave, move signature\n * eventFn : function(element, done, options) {\n * //code to run the animation\n * //once complete, then run done()\n * return function endFunction(wasCancelled) {\n * //code to cancel the animation\n * }\n * }\n * }\n * ```\n *\n * @param {string} name The name of the animation (this is what the class-based CSS value will be compared to).\n * @param {import(\"../interface.ts\").Injectable<any>} factory The factory function that will be executed to return the animation\n * object.\n */\n this.register = function (name, factory) {\n if (name && name.charAt(0) !== \".\") {\n throw $animateMinErr(\n \"notcsel\",\n \"Expecting class selector starting with '.' got '{0}'.\",\n name,\n );\n }\n\n const key = `${name}-animation`;\n\n provider.$$registeredAnimations[name.substring(1)] = key;\n $provide.factory(key, factory);\n };\n\n /**\n * Sets and/or returns the custom filter function that is used to \"filter\" animations, i.e.\n * determine if an animation is allowed or not. When no filter is specified (the default), no\n * animation will be blocked. Setting the `customFilter` value will only allow animations for\n * which the filter function's return value is truthy.\n *\n * This allows to easily create arbitrarily complex rules for filtering animations, such as\n * allowing specific events only, or enabling animations on specific subtrees of the DOM, etc.\n * Filtering animations can also boost performance for low-powered devices, as well as\n * applications containing a lot of structural operations.\n *\n * <div class=\"alert alert-success\">\n * **Best Practice:**\n * Keep the filtering function as lean as possible, because it will be called for each DOM\n * action (e.g. insertion, removal, class change) performed by \"animation-aware\" directives.\n * See {@link guide/animations#which-directives-support-animations- here} for a list of built-in\n * directives that support animations.\n * Performing computationally expensive or time-consuming operations on each call of the\n * filtering function can make your animations sluggish.\n * </div>\n *\n * **Note:** If present, `customFilter` will be checked before\n * {@link $animateProvider#classNameFilter classNameFilter}.\n *\n * @param {Function=} filterFn - The filter function which will be used to filter all animations.\n * If a falsy value is returned, no animation will be performed. The function will be called\n * with the following arguments:\n * - **node** `{Element}` - The DOM element to be animated.\n * - **event** `{String}` - The name of the animation event (e.g. `enter`, `leave`, `addClass`\n * etc).\n * - **options** `{Object}` - A collection of options/styles used for the animation.\n * @return {Function} The current filter function or `null` if there is none set.\n */\n this.customFilter = function (filterFn) {\n if (arguments.length === 1) {\n customFilter = isFunction(filterFn) ? filterFn : null;\n }\n\n return customFilter;\n };\n\n /**\n * Sets and/or returns the CSS class regular expression that is checked when performing\n * an animation. Upon bootstrap the classNameFilter value is not set at all and will\n * therefore enable $animate to attempt to perform an animation on any element that is triggered.\n * When setting the `classNameFilter` value, animations will only be performed on elements\n * that successfully match the filter expression. This in turn can boost performance\n * for low-powered devices as well as applications containing a lot of structural operations.\n *\n * **Note:** If present, `classNameFilter` will be checked after\n * {@link $animateProvider#customFilter customFilter}. If `customFilter` is present and returns\n * false, `classNameFilter` will not be checked.\n *\n * @param {RegExp=} expression The className expression which will be checked against all animations\n * @return {RegExp} The current CSS className expression value. If null then there is no expression value\n */\n this.classNameFilter = function (expression) {\n if (arguments.length === 1) {\n classNameFilter = expression instanceof RegExp ? expression : null;\n\n if (classNameFilter) {\n const reservedRegex = new RegExp(\n `[(\\\\s|\\\\/)]${NG_ANIMATE_CLASSNAME}[(\\\\s|\\\\/)]`,\n );\n\n if (reservedRegex.test(classNameFilter.toString())) {\n classNameFilter = null;\n throw $animateMinErr(\n \"nongcls\",\n '$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the \"{0}\" CSS class.',\n NG_ANIMATE_CLASSNAME,\n );\n }\n }\n }\n\n return classNameFilter;\n };\n\n this.$get = [\n $injectTokens.$$animateQueue,\n /**\n * @param {import(\"./queue/interface.ts\").AnimateQueueService} $$animateQueue\n * @returns {ng.AnimateService}\n */\n function ($$animateQueue) {\n /**\n * The $animate service exposes a series of DOM utility methods that provide support\n * for animation hooks. The default behavior is the application of DOM operations, however,\n * when an animation is detected (and animations are enabled), $animate will do the heavy lifting\n * to ensure that animation runs with the triggered DOM operation.\n *\n * By default $animate doesn't trigger any animations. This is because the `ngAnimate` module isn't\n * included and only when it is active then the animation hooks that `$animate` triggers will be\n * functional. Once active then all structural `ng-` directives will trigger animations as they perform\n * their DOM-related operations (enter, leave and move). Other directives such as `ngClass`,\n * `ngShow`, `ngHide` and `ngMessages` also provide support for animations.\n *\n * It is recommended that the`$animate` service is always used when executing DOM-related procedures within directives.\n */\n return {\n /**\n *\n * Sets up an event listener to fire whenever the animation event (enter, leave, move, etc...)\n * has fired on the given element or among any of its children. Once the listener is fired, the provided callback\n * is fired with the following params:\n *\n * ```js\n * $animate.on('enter', container,\n * function callback(element, phase) {\n * // cool we detected an enter animation within the container\n * }\n * );\n * ```\n *\n * <div class=\"alert alert-warning\">\n * **Note**: Generally, the events that are fired correspond 1:1 to `$animate` method names,\n * e.g. {@link ng.$animate#addClass addClass()} will fire `addClass`, and {@link ng.ngClass}\n * will fire `addClass` if classes are added, and `removeClass` if classes are removed.\n * However, there are two exceptions:\n *\n * <ul>\n * <li>if both an {@link ng.$animate#addClass addClass()} and a\n * {@link ng.$animate#removeClass removeClass()} action are performed during the same\n * animation, the event fired will be `setClass`. This is true even for `ngClass`.</li>\n * <li>an {@link ng.$animate#animate animate()} call that adds and removes classes will fire\n * the `setClass` event, but if it either removes or adds classes,\n * it will fire `animate` instead.</li>\n * </ul>\n *\n * </div>\n *\n * @param {string} event the animation event that will be captured (e.g. enter, leave, move, addClass, removeClass, etc...)\n * @param {Element} container the container element that will capture each of the animation events that are fired on itself\n * as well as among its children\n * @param {Function} callback the callback function that will be fired when the listener is triggered.\n *\n * The arguments present in the callback function are:\n * * `element` - The captured DOM element that the animation was fired on.\n * * `phase` - The phase of the animation. The two possible phases are **start** (when the animation starts) and **close** (when it ends).\n * * `data` - an object with these properties:\n * * addClass - `{string|null}` - space-separated CSS classes to add to the element\n * * removeClass - `{string|null}` - space-separated CSS classes to remove from the element\n * * from - `{Object|null}` - CSS properties & values at the beginning of the animation\n * * to - `{Object|null}` - CSS properties & values at the end of the animation\n *\n * Note that the callback does not trigger a scope digest. Wrap your call into a\n * {@link $rootScope.Scope#$apply scope.$apply} to propagate changes to the scope.\n */\n on: $$animateQueue.on,\n\n /**\n * Deregisters an event listener based on the event which has been associated with the provided element. This method\n * can be used in three different ways depending on the arguments:\n *\n * ```js\n * // remove all the animation event listeners listening for `enter`\n * $animate.off('enter');\n *\n * // remove listeners for all animation events from the container element\n * $animate.off(container);\n *\n * // remove all the animation event listeners listening for `enter` on the given element and its children\n * $animate.off('enter', container);\n *\n * // remove the event listener function provided by `callback` that is set\n * // to listen for `enter` on the given `container` as well as its children\n * $animate.off('enter', container, callback);\n * ```\n *\n * @param {string|Element} event|container the animation event (e.g. enter, leave, move,\n * addClass, removeClass, etc...), or the container element. If it is the element, all other\n * arguments are ignored.\n * @param {Element=} container the container element the event listener was placed on\n * @param {Function=} callback the callback function that was registered as the listener\n */\n off: $$animateQueue.off,\n\n /**\n * Associates the provided element with a host parent element to allow the element to be animated even if it exists\n * outside of the DOM structure of the AngularTS application. By doing so, any animation triggered via `$animate` can be issued on the\n * element despite being outside the realm of the application or within another application. Say for example if the application\n * was bootstrapped on an element that is somewhere inside of the `<body>` tag, but we wanted to allow for an element to be situated\n * as a direct child of `document.body`, then this can be achieved by pinning the element via `$animate.pin(element)`. Keep in mind\n * that calling `$animate.pin(element, parentElement)` will not actually insert into the DOM anywhere; it will just create the association.\n *\n * Note that this feature is only active when the `ngAnimate` module is used.\n *\n * @param {Element} element the external element that will be pinned\n * @param {Element} parentElement the host parent element that will be associated with the external element\n */\n pin: $$animateQueue.pin,\n\n /**\n * Used to get and set whether animations are enabled or not on the entire application or on an element and its children. This\n * function can be called in four ways:\n *\n * ```js\n * // returns true or false\n * $animate.enabled();\n *\n * // changes the enabled state for all animations\n * $animate.enabled(false);\n * $animate.enabled(true);\n *\n * // returns true or false if animations are enabled for an element\n * $animate.enabled(element);\n *\n * // changes the enabled state for an element and its children\n * $animate.enabled(element, true);\n * $animate.enabled(element, false);\n * ```\n *\n * @param {Element=} element the element that will be considered for checking/setting the enabled state\n * @param {boolean=} enabled whether or not the animations will be enabled for the element\n *\n * @return {boolean} whether or not animations are enabled\n */\n enabled: (element, enabled) => {\n if (enabled !== undefined) {\n return hasAnimate(element);\n } else {\n element.setAttribute(\"animate\", `${enabled}`);\n }\n\n return true;\n },\n\n /**\n * Cancels the provided animation and applies the end state of the animation.\n * Note that this does not cancel the underlying operation, e.g. the setting of classes or\n * adding the element to the DOM.\n *\n * @param {import('./runner/animate-runner.js').AnimateRunner} runner An animation runner returned by an $animate function.\n */\n cancel(runner) {\n if (runner.cancel) {\n runner.cancel();\n }\n },\n\n /**\n * Inserts the element into the DOM either after the `after` element (if provided) or\n * as the first child within the `parent` element and then triggers an animation.\n * A promise is returned that will be resolved during the next digest once the animation\n * has completed.\n *\n * @param {Element} element - the element which will be inserted into the DOM\n * @param {Element} parent - the parent element which will append the element as a child (so long as the after element is not present)\n * @param {Element} [after] - after the sibling element after which the element will be appended\n * @param {import(\"./interface.ts\").AnimationOptions} [options] - an optional collection of options/styles that will be applied to the element.\n * @returns {import('./runner/animate-runner.js').AnimateRunner} the animation runner\n */\n enter(element, parent, after, options) {\n parent = parent || after.parentElement;\n animatedomInsert(element, parent, after);\n\n return $$animateQueue.push(\n element,\n \"enter\",\n prepareAnimateOptions(options),\n );\n },\n\n /**\n * Inserts (moves) the element into its new position in the DOM either after\n * the `after` element (if provided) or as the first child within the `parent` element\n * and then triggers an animation. A promise is returned that will be resolved\n * during the next digest once the animation has completed.\n *\n * @param {Element} element - the element which will be inserted into the DOM\n * @param {Element} parent - the parent element which will append the element as a child (so long as the after element is not present)\n * @param {Element} after - after the sibling element after which the element will be appended\n * @param {import(\"./interface.ts\").AnimationOptions} [options] - an optional collection of options/styles that will be applied to the element.\n * @returns {import('./runner/animate-runner.js').AnimateRunner} the animation runner\n */\n move(element, parent, after, options) {\n parent = parent || after.parentElement;\n animatedomInsert(element, parent, after);\n\n return $$animateQueue.push(\n element,\n \"move\",\n prepareAnimateOptions(options),\n );\n },\n\n /**\n * Triggers an animation and then removes the element from the DOM.\n * When the function is called a promise is returned that will be resolved during the next\n * digest once the animation has completed.\n *\n * @param {Element} element the element which will be removed from the DOM\n * @param {import(\"./interface.ts\").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.\n * @returns {import('./runner/animate-runner.js').AnimateRunner} the animation runner\n */\n leave(element, options) {\n return $$animateQueue.push(\n element,\n \"leave\",\n prepareAnimateOptions(options),\n () => {\n removeElement(element);\n },\n );\n },\n\n /**\n * Triggers an addClass animation surrounding the addition of the provided CSS class(es). Upon\n * execution, the addClass operation will only be handled after the next digest and it will not trigger an\n * animation if element already contains the CSS class or if the class is removed at a later step.\n * Note that class-based animations are treated differently compared to structural animations\n * (like enter, move and leave) since the CSS classes may be added/removed at different points\n * depending if CSS or JavaScript animations are used.\n *\n * @param {Element} element the element which the CSS classes will be applied to\n * @param {string} className the CSS class(es) that will be added (multiple classes are separated via spaces)\n * @param {import(\"./interface\").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.\n * @return {import('./runner/animate-runner.js').AnimateRunner}} animationRunner the animation runner\n */\n addClass(element, className, options) {\n options = prepareAnimateOptions(options);\n options.addClass = mergeClasses(options.addClass, className);\n\n return $$animateQueue.push(element, \"addClass\", options);\n },\n\n /**\n * Triggers a removeClass animation surrounding the removal of the provided CSS class(es). Upon\n * execution, the removeClass operation will only be handled after the next digest and it will not trigger an\n * animation if element does not contain the CSS class or if the class is added at a later step.\n * Note that class-based animations are treated differently compared to structural animations\n * (like enter, move and leave) since the CSS classes may be added/removed at different points\n * depending if CSS or JavaScript animations are used.\n *\n * @param {Element} element the element which the CSS classes will be applied to\n * @param {string} className the CSS class(es) that will be removed (multiple classes are separated via spaces)\n * @param {import(\"./interface\").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element. *\n * @return {import('./runner/animate-runner.js').AnimateRunner} animationRunner the animation runner\n */\n removeClass(element, className, options) {\n options = prepareAnimateOptions(options);\n options.removeClass = mergeClasses(options.removeClass, className);\n\n return $$animateQueue.push(element, \"removeClass\", options);\n },\n\n /**\n * Performs both the addition and removal of a CSS classes on an element and (during the process)\n * triggers an animation surrounding the class addition/removal. Much like `$animate.addClass` and\n * `$animate.removeClass`, `setClass` will only evaluate the classes being added/removed once a digest has\n * passed. Note that class-based animations are treated differently compared to structural animations\n * (like enter, move and leave) since the CSS classes may be added/removed at different points\n * depending if CSS or JavaScript animations are used.\n *\n * @param {Element} element the element which the CSS classes will be applied to\n * @param {string} add the CSS class(es) that will be added (multiple classes are separated via spaces)\n * @param {string} remove the CSS class(es) that will be removed (multiple classes are separated via spaces)\n * @param {object=} options an optional collection of options/styles that will be applied to the element.\n *\n * @return {import('./runner/animate-runner.js').AnimateRunner} the animation runner\n */\n setClass(element, add, remove, options) {\n options = prepareAnimateOptions(options);\n options.addClass = mergeClasses(options.addClass, add);\n options.removeClass = mergeClasses(options.removeClass, remove);\n\n return $$animateQueue.push(element, \"setClass\", options);\n },\n\n /**\n * Performs an inline animation on the element which applies the provided to and from CSS styles to the element.\n * If any detected CSS transition, keyframe or JavaScript matches the provided className value, then the animation will take\n * on the provided styles. For example, if a transition animation is set for the given className, then the provided `from` and\n * `to` styles will be applied alongside the given transition. If the CSS style provided in `from` does not have a corresponding\n * style in `to`, the style in `from` is applied immediately, and no animation is run.\n * If a JavaScript animation is detected then the provided styles will be given in as function parameters into the `animate`\n * method (or as part of the `options` parameter):\n *\n * ```js\n * ngModule.animation('.my-inline-animation', function() {\n * return {\n * animate : function(element, from, to, done, options) {\n * //animation\n * done();\n * }\n * }\n * });\n * ```\n * @return {import('./runner/animate-runner.js').AnimateRunner} the animation runner\n */\n animate(element, from, to, className, options) {\n options = prepareAnimateOptions(options);\n options.from = options.from ? extend(options.from, from) : from;\n options.to = options.to ? extend(options.to, to) : to;\n\n className = className || \"ng-inline-animate\";\n options.tempClasses = mergeClasses(options.tempClasses, className);\n\n return $$animateQueue.push(element, \"animate\", options);\n },\n };\n },\n ];\n}\n","/**\n * Provides an instance of a cache that can be used to store and retrieve template content.\n */\nexport class TemplateCacheProvider {\n constructor() {\n /** @type {ng.TemplateCacheService} */\n this.cache = new Map();\n }\n\n /**\n * @returns {ng.TemplateCacheService}\n */\n $get() {\n return this.cache;\n }\n}\n","/**\n * Unified exception handler used throughout AngularTS.\n *\n * This service receives uncaught exceptions from both synchronous and asynchronous operations.\n * Its purpose is to provide a central point through which the framework\n * processes errors.\n *\n * By default, `$exceptionHandler` simply rethrows the exception. This ensures fail-fast\n * behavior, making errors visible immediately in development and in unit tests.\n * Applications may override this service to introduce custom error handling.\n *\n * ### Example: Custom `$exceptionHandler`\n *\n * ```js\n * angular\n * .module('app')\n * .factory('$exceptionHandler', function(myLogger) {\n * return function handleError(error) {\n * myLogger.capture(error);\n * // Rethrow to preserve fail-fast behavior:\n * throw error;\n * };\n * });\n * ```\n *\n * IMPORTANT: custom implementation should always rethrow the error as the framework assumes that `$exceptionHandler` always does the throwing.\n *\n * ### Manual Invocation\n *\n * You can invoke the exception handler directly when catching errors in your own code:\n *\n * ```js\n * try {\n * riskyOperation();\n * } catch (err) {\n * $exceptionHandler(err);\n * }\n * ```\n *\n * @see {@link ng.ExceptionHandlerService} ExceptionHandlerService\n */\n\n/**\n * Provider for the `$exceptionHandler` service.\n *\n * The default implementation rethrows exceptions, enabling strict fail-fast behavior.\n * Applications may replace the handler via by setting `errorHandler`property or by providing their own\n * `$exceptionHandler` factory.\n */\nexport class ExceptionHandlerProvider {\n constructor() {\n /** @type {ng.ExceptionHandlerService} */\n this.handler = (exception) => {\n throw exception;\n };\n }\n\n /**\n * @returns {ng.ExceptionHandlerService}\n */\n $get() {\n return (exception) => this.handler(exception);\n }\n}\n","import {\n equals,\n hasCustomToString,\n isArray,\n isArrayLike,\n isFunction,\n isNullOrUndefined,\n isObject,\n isUndefined,\n minErr,\n} from \"../shared/utils.js\";\n\n/**\n * @returns {ng.FilterFn}\n */\nexport function filterFilter() {\n /**\n * @param {Array} array The source array.\n * @param {string|Object|function(any, number, []):[]} expression The predicate to be used for selecting items from `array`.\n * @param {function(any, any):boolean|boolean} [comparator] Comparator which is used in determining if values retrieved using `expression`\n * (when it is not a function) should be considered a match based on the expected value (from the filter expression) and actual value (from the object in the array).\n * @param {string} [anyPropertyKey] The special property name that matches against any property.\n * @return {Array} Filtered array\n */\n return function (array, expression, comparator, anyPropertyKey) {\n if (!isArrayLike(array)) {\n if (isNullOrUndefined(array)) {\n return array;\n }\n throw minErr(\"filter\")(\n \"notarray\",\n \"Expected array but received: {0}\",\n array,\n );\n }\n\n anyPropertyKey = anyPropertyKey || \"$\";\n let predicateFn;\n\n let matchAgainstAnyProp = false;\n\n switch (getTypeForFilter(expression)) {\n case \"function\":\n predicateFn = expression;\n break;\n case \"boolean\":\n case \"null\":\n case \"number\":\n case \"string\":\n matchAgainstAnyProp = true;\n // falls through\n case \"object\":\n predicateFn = createPredicateFn(\n expression,\n comparator,\n anyPropertyKey,\n matchAgainstAnyProp,\n );\n break;\n default:\n return array;\n }\n\n return Array.prototype.filter.call(array, predicateFn);\n };\n}\n\n// Helper functions for `filterFilter`\nfunction createPredicateFn(\n expression,\n comparator,\n anyPropertyKey,\n matchAgainstAnyProp,\n) {\n const shouldMatchPrimitives =\n isObject(expression) && anyPropertyKey in expression;\n\n if (comparator === true) {\n comparator = equals;\n } else if (!isFunction(comparator)) {\n comparator = function (actual, expected) {\n if (isUndefined(actual)) {\n // No substring matching against `undefined`\n return false;\n }\n\n if (actual === null || expected === null) {\n // No substring matching against `null`; only match against `null`\n return actual === expected;\n }\n\n if (\n isObject(expected) ||\n (isObject(actual) && !hasCustomToString(actual))\n ) {\n // Should not compare primitives against objects, unless they have custom `toString` method\n return false;\n }\n\n actual = `${actual}`.toLowerCase();\n expected = `${expected}`.toLowerCase();\n\n return actual.indexOf(expected) !== -1;\n };\n }\n\n const predicateFn = function (item) {\n if (shouldMatchPrimitives && !isObject(item)) {\n return deepCompare(\n item,\n expression[anyPropertyKey],\n comparator,\n anyPropertyKey,\n false,\n );\n }\n\n return deepCompare(\n item,\n expression,\n comparator,\n anyPropertyKey,\n matchAgainstAnyProp,\n );\n };\n\n return predicateFn;\n}\n\nfunction deepCompare(\n actual,\n expected,\n comparator,\n anyPropertyKey,\n matchAgainstAnyProp,\n dontMatchWholeObject,\n) {\n const actualType = getTypeForFilter(actual);\n\n const expectedType = getTypeForFilter(expected);\n\n if (expectedType === \"string\" && expected.charAt(0) === \"!\") {\n return !deepCompare(\n actual,\n expected.substring(1),\n comparator,\n anyPropertyKey,\n matchAgainstAnyProp,\n );\n }\n\n if (isArray(actual)) {\n // In case `actual` is an array, consider it a match\n // if ANY of it's items matches `expected`\n return actual.some((item) =>\n deepCompare(\n item,\n expected,\n comparator,\n anyPropertyKey,\n matchAgainstAnyProp,\n ),\n );\n }\n\n switch (actualType) {\n case \"object\":\n if (matchAgainstAnyProp) {\n for (const key in actual) {\n // Under certain, rare, circumstances, key may not be a string and `charAt` will be undefined\n // See: https://github.com/angular/angular.js/issues/15644\n if (\n key.charAt &&\n key.charAt(0) !== \"$\" &&\n deepCompare(actual[key], expected, comparator, anyPropertyKey, true)\n ) {\n return true;\n }\n }\n\n return dontMatchWholeObject\n ? false\n : deepCompare(actual, expected, comparator, anyPropertyKey, false);\n }\n\n if (expectedType === \"object\") {\n for (const key in expected) {\n const expectedVal = expected[key];\n\n if (isFunction(expectedVal) || isUndefined(expectedVal)) {\n continue;\n }\n\n const matchAnyProperty = key === anyPropertyKey;\n\n const actualVal = matchAnyProperty ? actual : actual[key];\n\n if (\n !deepCompare(\n actualVal,\n expectedVal,\n comparator,\n anyPropertyKey,\n matchAnyProperty,\n matchAnyProperty,\n )\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n return comparator(actual, expected);\n\n case \"function\":\n return false;\n default:\n return comparator(actual, expected);\n }\n}\n\n// Used for easily differentiating between `null` and actual `object`\nfunction getTypeForFilter(val) {\n return val === null ? \"null\" : typeof val;\n}\n","import { isNumber, isString, isUndefined, toJson } from \"../shared/utils.js\";\n\nconst MAX_DIGITS = 22;\n\nconst DECIMAL_SEP = \".\";\n\nconst ZERO_CHAR = \"0\";\n\n/**\n * Parse a number (as a string) into three components that can be used\n * for formatting the number.\n *\n * (Significant bits of this parse algorithm came from https://github.com/MikeMcl/big.js/)\n *\n * @param {string} numStr The number to parse\n * @return {object} An object describing this number, containing the following keys:\n * - d : an array of digits containing leading zeros as necessary\n * - i : the number of the digits in `d` that are to the left of the decimal point\n * - e : the exponent for numbers that would need more than `MAX_DIGITS` digits in `d`\n *\n */\nfunction parse(numStr) {\n let exponent = 0;\n\n let digits;\n\n let numberOfIntegerDigits;\n\n let i;\n\n let j;\n\n let zeros;\n\n // Decimal point?\n if ((numberOfIntegerDigits = numStr.indexOf(DECIMAL_SEP)) > -1) {\n numStr = numStr.replace(DECIMAL_SEP, \"\");\n }\n\n // Exponential form?\n if ((i = numStr.search(/e/i)) > 0) {\n // Work out the exponent.\n if (numberOfIntegerDigits < 0) numberOfIntegerDigits = i;\n numberOfIntegerDigits += +numStr.slice(i + 1);\n numStr = numStr.substring(0, i);\n } else if (numberOfIntegerDigits < 0) {\n // There was no decimal point or exponent so it is an integer.\n numberOfIntegerDigits = numStr.length;\n }\n\n // Count the number of leading zeros.\n for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) {\n /* empty */\n }\n\n if (i === (zeros = numStr.length)) {\n // The digits are all zero.\n digits = [0];\n numberOfIntegerDigits = 1;\n } else {\n // Count the number of trailing zeros\n zeros--;\n\n while (numStr.charAt(zeros) === ZERO_CHAR) zeros--;\n\n // Trailing zeros are insignificant so ignore them\n numberOfIntegerDigits -= i;\n digits = [];\n\n // Convert string to array of digits without leading/trailing zeros.\n for (j = 0; i <= zeros; i++, j++) {\n digits[j] = +numStr.charAt(i);\n }\n }\n\n // If the number overflows the maximum allowed digits then use an exponent.\n if (numberOfIntegerDigits > MAX_DIGITS) {\n digits = digits.splice(0, MAX_DIGITS - 1);\n exponent = numberOfIntegerDigits - 1;\n numberOfIntegerDigits = 1;\n }\n\n // eslint-disable-next-line id-length\n return { d: digits, e: exponent, i: numberOfIntegerDigits };\n}\n\n/**\n * Round the parsed number to the specified number of decimal places\n * This function changed the parsedNumber in-place\n */\nfunction roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {\n const digits = parsedNumber.d;\n\n let fractionLen = digits.length - parsedNumber.i;\n\n // determine fractionSize if it is not specified; `+fractionSize` converts it to a number\n fractionSize = isUndefined(fractionSize)\n ? Math.min(Math.max(minFrac, fractionLen), maxFrac)\n : +fractionSize;\n\n // The index of the digit to where rounding is to occur\n let roundAt = fractionSize + parsedNumber.i;\n\n const digit = digits[roundAt];\n\n if (roundAt > 0) {\n // Drop fractional digits beyond `roundAt`\n digits.splice(Math.max(parsedNumber.i, roundAt));\n\n // Set non-fractional digits beyond `roundAt` to 0\n for (let j = roundAt; j < digits.length; j++) {\n digits[j] = 0;\n }\n } else {\n // We rounded to zero so reset the parsedNumber\n fractionLen = Math.max(0, fractionLen);\n parsedNumber.i = 1;\n digits.length = Math.max(1, (roundAt = fractionSize + 1));\n digits[0] = 0;\n\n for (let i = 1; i < roundAt; i++) digits[i] = 0;\n }\n\n if (digit >= 5) {\n if (roundAt - 1 < 0) {\n for (let k = 0; k > roundAt; k--) {\n digits.unshift(0);\n parsedNumber.i++;\n }\n digits.unshift(1);\n parsedNumber.i++;\n } else {\n digits[roundAt - 1]++;\n }\n }\n\n // Pad out with zeros to get the required fraction length\n for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);\n\n // Do any carrying, e.g. a digit was rounded up to 10\n const carry = digits.reduceRight((x, y, i, digitsParam) => {\n y += x;\n digitsParam[i] = y % 10;\n\n return Math.floor(y / 10);\n }, 0);\n\n if (carry) {\n digits.unshift(carry);\n parsedNumber.i++;\n }\n}\n\n/**\n * Format a number into a string\n * @param {number} number The number to format\n * @param {{\n * minFrac, // the minimum number of digits required in the fraction part of the number\n * maxFrac, // the maximum number of digits required in the fraction part of the number\n * gSize, // number of digits in each group of separated digits\n * lgSize, // number of digits in the last group of digits before the decimal separator\n * negPre, // the string to go in front of a negative number (e.g. `-` or `(`))\n * posPre, // the string to go in front of a positive number\n * negSuf, // the string to go after a negative number (e.g. `)`)\n * posSuf // the string to go after a positive number\n * }} pattern\n * @param {string} groupSep The string to separate groups of number (e.g. `,`)\n * @param {string} decimalSep The string to act as the decimal separator (e.g. `.`)\n * @param {any} fractionSize The size of the fractional part of the number\n * @return {string} The number formatted as a string\n */\n\nexport function formatNumber(\n number,\n pattern,\n groupSep,\n decimalSep,\n fractionSize,\n) {\n if (!(isString(number) || isNumber(number)) || Number.isNaN(number))\n return \"\";\n\n const isInfinity = !Number.isFinite(number);\n\n let isZero = false;\n\n const numStr = `${Math.abs(number)}`;\n\n let formattedText = \"\";\n\n let parsedNumber;\n\n if (isInfinity) {\n formattedText = \"\\u221e\";\n } else {\n parsedNumber = parse(numStr);\n\n roundNumber(parsedNumber, fractionSize, pattern.minFrac, pattern.maxFrac);\n\n let digits = parsedNumber.d;\n\n let integerLen = parsedNumber.i;\n\n const exponent = parsedNumber.e;\n\n let decimals = [];\n\n isZero = digits.reduce((x, y) => x && !y, true);\n\n // pad zeros for small numbers\n while (integerLen < 0) {\n digits.unshift(0);\n integerLen++;\n }\n\n // extract decimals digits\n if (integerLen > 0) {\n decimals = digits.splice(integerLen, digits.length);\n } else {\n decimals = digits;\n digits = [0];\n }\n\n // format the integer digits with grouping separators\n const groups = [];\n\n if (digits.length >= pattern.lgSize) {\n groups.unshift(digits.splice(-pattern.lgSize, digits.length).join(\"\"));\n }\n\n while (digits.length > pattern.gSize) {\n groups.unshift(digits.splice(-pattern.gSize, digits.length).join(\"\"));\n }\n\n if (digits.length) {\n groups.unshift(digits.join(\"\"));\n }\n formattedText = groups.join(groupSep);\n\n // append the decimal digits\n if (decimals.length) {\n formattedText += decimalSep + decimals.join(\"\");\n }\n\n if (exponent) {\n formattedText += `e+${exponent}`;\n }\n }\n\n if (number < 0 && !isZero) {\n return pattern.negPre + formattedText + pattern.negSuf;\n }\n\n return pattern.posPre + formattedText + pattern.posSuf;\n}\n\n/**\n * @returns {ng.FilterFn}\n */\nexport function jsonFilter() {\n return function (object, spacing) {\n if (isUndefined(spacing)) {\n spacing = 2;\n }\n\n return toJson(object, spacing);\n };\n}\n","import {\n isArrayLike,\n isFunction,\n isNumber,\n isNumberNaN,\n isString,\n} from \"../shared/utils.js\";\n\n/**\n * @returns {ng.FilterFn}\n */\nexport function limitToFilter() {\n /**\n * @param {Array|ArrayLike|string|number|Function} input Array/array-like, string, or number to be limited.\n * @param {string|number} limit The length of the returned array or string.\n * @param {string|number} [begin] Index at which to begin limitation. As a negative index, `begin` indicates an offset from the end of `input`. Defaults to `0`.\n */\n return function (input, limit, begin) {\n if (isFunction(input)) {\n input = /** @type {Function} */ (input)();\n }\n\n if (Math.abs(Number(limit)) === Infinity) {\n limit = Number(limit);\n } else {\n limit = parseInt(/** @type {string} */ (limit), 10);\n }\n\n if (isNumberNaN(limit)) return input;\n\n if (isNumber(input)) input = input.toString();\n\n if (!isArrayLike(input)) return input;\n\n begin =\n !begin || isNaN(/** @type {any} */ (begin))\n ? 0\n : parseInt(/** @type {string} */ (begin), 10);\n begin =\n begin < 0 ? Math.max(0, /** @type {[]} */ (input).length + begin) : begin;\n\n if (limit >= 0) {\n return sliceFn(input, begin, begin + limit);\n } else {\n if (begin === 0) {\n return sliceFn(input, limit, /** @type {[]} */ (input).length);\n } else {\n return sliceFn(input, Math.max(0, begin + limit), begin);\n }\n }\n };\n}\n\nfunction sliceFn(input, begin, end) {\n if (isString(input)) return input.slice(begin, end);\n\n return [].slice.call(input, begin, end);\n}\n","import {\n hasCustomToString,\n isArray,\n isArrayLike,\n isFunction,\n isNullOrUndefined,\n isObject,\n isString,\n minErr,\n} from \"../shared/utils.js\";\nimport { $injectTokens } from \"../injection-tokens.js\";\n\norderByFilter.$inject = [$injectTokens.$parse];\n\n/**\n * @returns {ng.FilterFn}\n */\nexport function orderByFilter($parse) {\n return function (array, sortPredicate, reverseOrder, compareFn) {\n if (isNullOrUndefined(array)) return array;\n\n if (isFunction(array)) return array();\n\n if (!isArrayLike(array)) {\n throw minErr(\"orderBy\")(\n \"notarray\",\n \"Expected array but received: {0}\",\n array,\n );\n }\n\n if (!isArray(sortPredicate)) {\n sortPredicate = [sortPredicate];\n }\n\n if (sortPredicate.length === 0) {\n sortPredicate = [\"+\"];\n }\n\n const predicates = processPredicates(sortPredicate);\n\n const descending = reverseOrder ? -1 : 1;\n\n // Define the `compare()` function. Use a default comparator if none is specified.\n const compare = isFunction(compareFn) ? compareFn : defaultCompare;\n\n // The next three lines are a version of a Swartzian Transform idiom from Perl\n // (sometimes called the Decorate-Sort-Undecorate idiom)\n // See https://en.wikipedia.org/wiki/Schwartzian_transform\n const compareValues = Array.prototype.map.call(array, getComparisonObject);\n\n compareValues.sort(doComparison);\n array = compareValues.map((item) => item.value);\n\n return array;\n\n function getComparisonObject(value, index) {\n // NOTE: We are adding an extra `tieBreaker` value based on the element's index.\n // This will be used to keep the sort stable when none of the input predicates can\n // distinguish between two elements.\n return {\n value,\n tieBreaker: { value: index, type: \"number\", index },\n predicateValues: predicates.map((predicate) =>\n getPredicateValue(predicate.get(value), index),\n ),\n };\n }\n\n function doComparison(v1, v2) {\n for (let i = 0, ii = predicates.length; i < ii; i++) {\n const result = compare(v1.predicateValues[i], v2.predicateValues[i]);\n\n if (result) {\n return result * predicates[i].descending * descending;\n }\n }\n\n return (\n (compare(v1.tieBreaker, v2.tieBreaker) ||\n defaultCompare(v1.tieBreaker, v2.tieBreaker)) * descending\n );\n }\n };\n\n function processPredicates(sortPredicates) {\n return sortPredicates.map((predicate) => {\n let descending = 1;\n\n let get = (x) => x;\n\n if (isFunction(predicate)) {\n get = predicate;\n } else if (isString(predicate)) {\n if (predicate.charAt(0) === \"+\" || predicate.charAt(0) === \"-\") {\n descending = predicate.charAt(0) === \"-\" ? -1 : 1;\n predicate = predicate.substring(1);\n }\n\n if (predicate !== \"\") {\n const parsed = $parse(predicate);\n\n if (parsed.constant) {\n const key = parsed();\n\n get = (value) => value[key];\n } else {\n get = parsed;\n }\n }\n }\n\n return { get, descending };\n });\n }\n\n function isPrimitive(value) {\n switch (typeof value) {\n case \"number\": /* falls through */\n case \"boolean\": /* falls through */\n case \"string\":\n return true;\n default:\n return false;\n }\n }\n\n function objectValue(value) {\n // If `valueOf` is a valid function use that\n if (isFunction(value.valueOf)) {\n value = value.valueOf();\n\n if (isPrimitive(value)) return value;\n }\n\n // If `toString` is a valid function and not the one from `Object.prototype` use that\n if (hasCustomToString(value)) {\n value = value.toString();\n\n if (isPrimitive(value)) return value;\n }\n\n return value;\n }\n\n function getPredicateValue(value, index) {\n /** @type {String} */ let type = typeof value;\n\n if (value === null) {\n type = \"null\";\n } else if (type === \"object\") {\n value = objectValue(value);\n }\n\n return { value, type, index };\n }\n\n function defaultCompare(v1, v2) {\n let result = 0;\n\n const type1 = v1.type;\n\n const type2 = v2.type;\n\n if (type1 === type2) {\n let value1 = v1.value;\n\n let value2 = v2.value;\n\n if (type1 === \"string\") {\n // Compare strings case-insensitively\n value1 = value1.toLowerCase();\n value2 = value2.toLowerCase();\n } else if (type1 === \"object\") {\n // For basic objects, use the position of the object\n // in the collection instead of the value\n if (isObject(value1)) value1 = v1.index;\n\n if (isObject(value2)) value2 = v2.index;\n }\n\n if (value1 !== value2) {\n result = value1 < value2 ? -1 : 1;\n }\n } else {\n result =\n type1 === \"undefined\"\n ? 1\n : type2 === \"undefined\"\n ? -1\n : type1 === \"null\"\n ? 1\n : type2 === \"null\"\n ? -1\n : type1 < type2\n ? -1\n : 1;\n }\n\n return result;\n }\n}\n","import { $injectTokens as $t } from \"../injection-tokens.js\";\n\n$IsStateFilter.$inject = [$t.$state];\n\n/**\n * `isState` Filter: truthy if the current state is the parameter\n *\n * Translates to [[StateService.is]] `$state.is(\"stateName\")`.\n *\n * #### Example:\n * ```html\n * <div ng-if=\"'stateName' | isState\">show if state is 'stateName'</div>\n * ```\n *\n * @param {import('./state/state-service.js').StateProvider} $state\n * @returns {ng.FilterFn}\n */\nexport function $IsStateFilter($state) {\n const isFilter = (state, params, options) =>\n $state.is(state, params, options);\n\n isFilter.$stateful = true;\n\n return isFilter;\n}\n\n$IncludedByStateFilter.$inject = [$t.$state];\n\n/**\n * `includedByState` Filter: truthy if the current state includes the parameter\n *\n * Translates to [[StateService.includes]]` $state.is(\"fullOrPartialStateName\")`.\n *\n * #### Example:\n * ```html\n * <div ng-if=\"'fullOrPartialStateName' | includedByState\">show if state includes 'fullOrPartialStateName'</div>\n * ```\n *\n * @param {import('./state/state-service.js').StateProvider} $state\n * @returns {ng.FilterFn}\n */\nexport function $IncludedByStateFilter($state) {\n const includesFilter = function (state, params, options) {\n return $state.includes(state, params, options);\n };\n\n includesFilter.$stateful = true;\n\n return includesFilter;\n}\n","import { $injectTokens as $t } from \"../../injection-tokens.js\";\nimport { filterFilter } from \"../../filters/filter.js\";\nimport { jsonFilter } from \"../../filters/filters.js\";\nimport { limitToFilter } from \"../../filters/limit-to.js\";\nimport { orderByFilter } from \"../../filters/order-by.js\";\nimport {\n $IncludedByStateFilter,\n $IsStateFilter,\n} from \"../../router/state-filters.js\";\nimport { assert, entries, isDefined, isFunction } from \"../../shared/utils.js\";\nimport { validate, validateIsString } from \"../../shared/validate.js\";\n\n/* @ignore */\nconst SUFFIX = \"Filter\";\n\n/**\n * $filterProvider - $filter - provider in module ng\n *\n * Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To achieve this a filter definition consists of a factory function which is annotated with dependencies and is responsible for creating a filter function.\n * @extends {ng.ServiceProvider}\n */\nexport class FilterProvider {\n /* @ignore */ static $inject = [$t.$provide];\n\n /**\n * @param {ng.ProvideService} $provide\n */\n constructor($provide) {\n assert(isDefined($provide));\n this._$provide = $provide;\n entries({\n filter: filterFilter,\n json: jsonFilter,\n limitTo: limitToFilter,\n orderBy: orderByFilter,\n isState: $IsStateFilter,\n includedByState: $IncludedByStateFilter,\n }).forEach(([k, v]) =>\n this.register(k, /** @type {ng.FilterFactory} */ (v)),\n );\n }\n\n /**\n * Register a filter a config phase;\n * @param {string} name\n * @param {ng.FilterFactory} factory\n * @return {ng.FilterProvider}\n */\n register(name, factory) {\n validateIsString(name, \"name\");\n validate(isFunction, factory, \"factory\");\n this._$provide.factory(name + SUFFIX, factory);\n\n return this;\n }\n\n $get = [\n $t.$injector,\n /**\n * @param {ng.InjectorService} $injector\n * @returns {ng.FilterService}\n */\n ($injector) => (name) => {\n validateIsString(name, \"name\");\n\n return $injector.get(name + SUFFIX);\n },\n ];\n}\n","import {\n entries,\n isDefined,\n isFunction,\n isNullOrUndefined,\n isObject,\n isProxy,\n} from \"../../shared/utils.js\";\nimport { ASTType } from \"./ast-type.js\";\n\nexport const PURITY_ABSOLUTE = 1;\nexport const PURITY_RELATIVE = 2;\n\nexport class ASTInterpreter {\n /**\n * @param {function(any):any} $filter\n */\n constructor($filter) {\n this.$filter = $filter;\n }\n\n /**\n * Compiles the AST into a function.\n * @param {import(\"./ast/ast\").ASTNode} ast - The AST to compile.\n * @returns {import(\"./interface.ts\").CompiledExpression}\n */\n compile(ast) {\n const decoratedNode = findConstantAndWatchExpressions(ast, this.$filter);\n\n /** @type {import(\"./ast/ast\").ASTNode} */\n let assignable;\n\n /** @type {import(\"./interface.ts\").CompiledExpression} */\n let assign;\n\n if ((assignable = assignableAST(decoratedNode))) {\n assign = /** @type {import(\"./interface.ts\").CompiledExpression} */ (\n this.#recurse(assignable)\n );\n }\n const toWatch = getInputs(decoratedNode.body);\n\n let inputs;\n\n if (toWatch) {\n inputs = [];\n\n for (const [key, watch] of entries(toWatch)) {\n const input =\n /** @type {import(\"./interface.ts\").CompiledExpression} */ (\n this.#recurse(watch)\n );\n\n input.isPure = watch.isPure;\n watch.input = input;\n inputs.push(input);\n watch.watchId = key;\n }\n }\n const expressions = [];\n\n decoratedNode.body.forEach((expression) => {\n expressions.push(this.#recurse(expression.expression));\n });\n\n /** @type {import(\"./interface.ts\").CompiledExpression} */\n const fn =\n decoratedNode.body.length === 0\n ? () => {\n /* empty */\n }\n : decoratedNode.body.length === 1\n ? expressions[0]\n : function (scope, locals) {\n let lastValue;\n\n expressions.forEach((exp) => {\n lastValue = exp(scope, locals);\n });\n\n return lastValue;\n };\n\n if (assign) {\n fn.assign = (scope, value, locals) => assign(scope, locals, value);\n }\n\n if (inputs) {\n fn.inputs = inputs;\n }\n fn.decoratedNode = decoratedNode;\n\n return fn;\n }\n\n /**\n * Recurses the AST nodes.\n * @param {import(\"./ast/ast\").ASTNode} ast - The AST node.\n * @param {Object} [context] - The context.\n * @param {boolean|1} [create] - The create flag.\n * @returns {import(\"./interface.ts\").CompiledExpressionFunction} The recursive function.\n */\n #recurse(ast, context, create) {\n let left;\n\n let right;\n\n const self = this;\n\n let args;\n\n switch (ast.type) {\n case ASTType._Literal:\n return this.value(ast.value, context);\n case ASTType._UnaryExpression:\n right = this.#recurse(ast.argument);\n\n return this[`unary${ast.operator}`](right, context);\n case ASTType._BinaryExpression:\n left = this.#recurse(ast.left);\n right = this.#recurse(ast.right);\n\n return this[`binary${ast.operator}`](left, right, context);\n case ASTType._LogicalExpression:\n left = this.#recurse(ast.left);\n right = this.#recurse(ast.right);\n\n return this[`binary${ast.operator}`](left, right, context);\n case ASTType._ConditionalExpression:\n return /** @type {import(\"./interface.ts\").CompiledExpressionFunction} */ (\n this[\"ternary?:\"](\n this.#recurse(ast.test),\n this.#recurse(ast.alternate),\n this.#recurse(ast.consequent),\n context,\n )\n );\n case ASTType._Identifier:\n return self.identifier(ast.name, context, create);\n case ASTType._MemberExpression:\n left = this.#recurse(ast.object, false, !!create);\n\n if (!ast.computed) {\n right = ast.property.name;\n }\n\n if (ast.computed) right = this.#recurse(ast.property);\n\n return /** @type {import(\"./interface.ts\").CompiledExpressionFunction} */ (\n ast.computed\n ? this.#computedMember(\n left,\n /** @type {function } */ (right),\n context,\n create,\n )\n : this.nonComputedMember(\n left,\n /** @type {string } */ (right),\n context,\n create,\n )\n );\n case ASTType._CallExpression:\n args = [];\n ast.arguments.forEach((expr) => {\n args.push(self.#recurse(expr));\n });\n\n if (ast.filter) right = this.$filter(ast.callee.name);\n\n if (!ast.filter) right = this.#recurse(ast.callee, true);\n\n return ast.filter\n ? (scope, locals, assign) => {\n const values = [];\n\n for (let i = 0; i < args.length; ++i) {\n const res = args[i](\n scope && scope.$target ? scope.$target : scope,\n locals,\n assign,\n );\n\n values.push(res);\n }\n const value = () => {\n return right.apply(undefined, values);\n };\n\n return context\n ? { context: undefined, name: undefined, value }\n : value;\n }\n : (scope, locals, assign) => {\n const rhs = right(\n scope.$target ? scope.$target : scope,\n locals,\n assign,\n );\n\n let value;\n\n if (!isNullOrUndefined(rhs.value) && isFunction(rhs.value)) {\n const values = [];\n\n for (let i = 0; i < args.length; ++i) {\n const res = args[i](scope, locals, assign);\n\n values.push(isFunction(res) ? res() : res);\n }\n value = rhs.value.apply(rhs.context, values);\n }\n\n return context ? { value } : value;\n };\n case ASTType._AssignmentExpression:\n left = this.#recurse(ast.left, true, 1);\n right = this.#recurse(ast.right);\n\n return (scope, locals, assign) => {\n const lhs = left(scope, locals, assign);\n\n const rhs = right(scope, locals, assign);\n\n // lhs.context[lhs.name] = rhs;\n const ctx = isProxy(lhs.context)\n ? lhs.context\n : (lhs.context.$proxy ?? lhs.context);\n\n ctx[lhs.name] = rhs;\n\n return context ? { value: rhs } : rhs;\n };\n case ASTType._ArrayExpression:\n args = [];\n ast.elements.forEach((expr) => {\n args.push(self.#recurse(expr));\n });\n\n return (scope, locals, assign) => {\n const value = [];\n\n for (let i = 0; i < args.length; ++i) {\n value.push(args[i](scope, locals, assign));\n }\n\n return context ? { value } : value;\n };\n case ASTType._ObjectExpression:\n args = [];\n ast.properties.forEach((property) => {\n if (property.computed) {\n args.push({\n key: self.#recurse(property.key),\n computed: true,\n value: self.#recurse(property.value),\n });\n } else {\n args.push({\n key:\n property.key.type === ASTType._Identifier\n ? property.key.name\n : `${property.key.value}`,\n computed: false,\n value: self.#recurse(property.value),\n });\n }\n });\n\n return (scope, locals, assign) => {\n const value = {};\n\n for (let i = 0; i < args.length; ++i) {\n if (args[i].computed) {\n value[args[i].key(scope, locals, assign)] = args[i].value(\n scope,\n locals,\n assign,\n );\n } else {\n value[args[i].key] = args[i].value(scope, locals, assign);\n }\n }\n\n return context ? { value } : value;\n };\n case ASTType._ThisExpression:\n return (scope) => (context ? { value: scope } : scope.$proxy);\n case ASTType._LocalsExpression:\n return (scope, locals) => (context ? { value: locals } : locals);\n case ASTType.NGValueParameter:\n return (scope, locals, assign) =>\n context ? { value: assign } : assign;\n }\n\n return undefined;\n }\n\n /**\n * Unary plus operation.\n * @param {function} argument - The argument function.\n * @param {Object} [context] - The context.\n * @returns {function} The unary plus function.\n */\n \"unary+\"(argument, context) {\n return (scope, locals, assign) => {\n let arg = argument(scope, locals, assign);\n\n if (isDefined(arg)) {\n arg = +arg;\n } else {\n arg = 0;\n }\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Unary minus operation.\n * @param {function} argument - The argument function.\n * @param {Object} [context] - The context.\n * @returns {function} The unary minus function.\n */\n \"unary-\"(argument, context) {\n return (scope, locals, assign) => {\n let arg = argument(scope, locals, assign);\n\n if (isDefined(arg)) {\n arg = -arg;\n } else {\n arg = -0;\n }\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Unary negation operation.\n * @param {function} argument - The argument function.\n * @param {Object} [context] - The context.\n * @returns {function} The unary negation function.\n */\n \"unary!\"(argument, context) {\n return (scope, locals, assign) => {\n const arg = !argument(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary plus operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary plus function.\n */\n \"binary+\"(left, right, context) {\n return (scope, locals, assign) => {\n const lhs = left(scope, locals, assign);\n\n const rhs = right(scope, locals, assign);\n\n const arg = plusFn(lhs, rhs);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary minus operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary minus function.\n */\n \"binary-\"(left, right, context) {\n return (scope, locals, assign) => {\n const lhs = left(scope, locals, assign);\n\n const rhs = right(scope, locals, assign);\n\n const arg = (isDefined(lhs) ? lhs : 0) - (isDefined(rhs) ? rhs : 0);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary multiplication operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary multiplication function.\n */\n \"binary*\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) * right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n \"binary/\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) / right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary division operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary division function.\n */\n \"binary%\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) % right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary strict equality operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary strict equality function.\n */\n \"binary===\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) === right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary strict inequality operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary strict inequality function.\n */\n \"binary!==\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) !== right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary equality operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary equality function.\n */\n \"binary==\"(left, right, context) {\n return (scope, locals, assign) => {\n // eslint-disable-next-line eqeqeq\n const arg = left(scope, locals, assign) == right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary inequality operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary inequality function.\n */\n \"binary!=\"(left, right, context) {\n return (scope, locals, assign) => {\n // eslint-disable-next-line eqeqeq\n const arg = left(scope, locals, assign) != right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary less-than operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary less-than function.\n */\n \"binary<\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) < right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary greater-than operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary greater-than function.\n */\n \"binary>\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) > right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary less-than-or-equal-to operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary less-than-or-equal-to function.\n */\n \"binary<=\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) <= right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary greater-than-or-equal-to operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary greater-than-or-equal-to function.\n */\n \"binary>=\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) >= right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary logical AND operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary logical AND function.\n */\n \"binary&&\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) && right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Binary logical OR operation.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @returns {function} The binary logical OR function.\n */\n \"binary||\"(left, right, context) {\n return (scope, locals, assign) => {\n const arg = left(scope, locals, assign) || right(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Ternary conditional operation.\n * @param {function} test - The test function.\n * @param {function} alternate - The alternate function.\n * @param {function} consequent - The consequent function.\n * @param {Object} [context] - The context.\n * @returns {function} The ternary conditional function.\n */\n \"ternary?:\"(test, alternate, consequent, context) {\n return (scope, locals, assign) => {\n const arg = test(scope, locals, assign)\n ? alternate(scope, locals, assign)\n : consequent(scope, locals, assign);\n\n return context ? { value: arg } : arg;\n };\n }\n\n /**\n * Returns the value of a literal.\n * @param {*} value - The literal value.\n * @param {Object} [context] - The context.\n * @returns {import(\"./interface.ts\").CompiledExpressionFunction} The function returning the literal value.\n */\n value(value, context) {\n return () =>\n context ? { context: undefined, name: undefined, value } : value;\n }\n\n /**\n * Returns the value of an identifier.\n * @param {string} name - The identifier name.\n * @param {Object} [context] - The context.\n * @param {boolean|1} [create] - Whether to create the identifier if it does not exist.\n * @returns {import(\"./interface.ts\").CompiledExpressionFunction} The function returning the identifier value.\n */\n identifier(name, context, create) {\n return (scope, locals) => {\n const base =\n locals && name in locals ? locals : ((scope && scope.$proxy) ?? scope);\n\n if (create && create !== 1 && base && isNullOrUndefined(base[name])) {\n base[name] = {};\n }\n let value = undefined;\n\n if (base) {\n value = base.$target ? base.$target[name] : base[name];\n }\n\n if (context) {\n return { context: base, name, value };\n }\n\n return value;\n };\n }\n\n /**\n * Returns the value of a computed member expression.\n * @param {function} left - The left operand function.\n * @param {function} right - The right operand function.\n * @param {Object} [context] - The context.\n * @param {boolean|1} [create] - Whether to create the member if it does not exist.\n * @returns {function} The function returning the computed member value.\n */\n #computedMember(left, right, context, create) {\n return (scope, locals, assign) => {\n const lhs = left(scope, locals, assign);\n\n let rhs;\n\n let value;\n\n if (!isNullOrUndefined(lhs)) {\n rhs = right(scope, locals, assign);\n rhs = getStringValue(rhs);\n\n if (create && create !== 1) {\n if (lhs && !lhs[rhs]) {\n lhs[rhs] = {};\n }\n }\n value = lhs[rhs];\n }\n\n if (context) {\n return { context: lhs, name: rhs, value };\n }\n\n return value;\n };\n }\n\n /**\n * Returns the value of a non-computed member expression.\n * @param {function} left - The left operand function.\n * @param {string} right - The right operand function.\n * @param {Object} [context] - The context.\n * @param {boolean|1} [create] - Whether to create the member if it does not exist.\n * @returns {function} The function returning the non-computed member value.\n */\n nonComputedMember(left, right, context, create) {\n return (scope, locals, assign) => {\n const lhs = left(scope, locals, assign);\n\n if (create && create !== 1) {\n if (lhs && isNullOrUndefined(lhs[right])) {\n lhs[right] = {};\n }\n }\n const value = !isNullOrUndefined(lhs) ? lhs[right] : undefined;\n\n if (context) {\n return { context: lhs, name: right, value };\n }\n\n return value;\n };\n }\n}\n\n/**\n * @typedef {import(\"./ast/ast\").ASTNode & {\n * isPure: boolean|number,\n * constant: boolean,\n * toWatch: Array,\n * }} DecoratedASTNode\n */\n\n/**\n * Decorates AST with constant, toWatch, and isPure properties\n * @param {import(\"./ast/ast\").ASTNode} ast\n * @param {function(any):any} $filter\n * @param {boolean|1|2} [parentIsPure]\n * @returns {DecoratedASTNode}\n */\nfunction findConstantAndWatchExpressions(ast, $filter, parentIsPure) {\n let allConstants;\n\n let argsToWatch;\n\n let isStatelessFilter;\n\n const decoratedNode = /** @type {DecoratedASTNode} */ (ast);\n\n let decoratedLeft,\n decoratedRight,\n decoratedTest,\n decoratedAlternate,\n decoratedConsequent,\n decoratedObject,\n decoratedProperty,\n decoratedKey;\n\n // @ts-ignore\n const astIsPure = (decoratedNode.isPure = isPure(ast, parentIsPure));\n\n switch (ast.type) {\n case ASTType._Program:\n allConstants = true;\n decoratedNode.body.forEach((expr) => {\n const decorated = findConstantAndWatchExpressions(\n expr.expression,\n $filter,\n astIsPure,\n );\n\n allConstants = allConstants && decorated.constant;\n });\n decoratedNode.constant = allConstants;\n\n return decoratedNode;\n case ASTType._Literal:\n decoratedNode.constant = true;\n decoratedNode.toWatch = [];\n\n return decoratedNode;\n case ASTType._UnaryExpression:\n // eslint-disable-next-line no-var\n var decorated = findConstantAndWatchExpressions(\n decoratedNode.argument,\n $filter,\n astIsPure,\n );\n\n decoratedNode.constant = decorated.constant;\n decoratedNode.toWatch = decorated.toWatch;\n\n return decoratedNode;\n case ASTType._BinaryExpression:\n decoratedLeft = findConstantAndWatchExpressions(\n decoratedNode.left,\n $filter,\n astIsPure,\n );\n decoratedRight = findConstantAndWatchExpressions(\n decoratedNode.right,\n $filter,\n astIsPure,\n );\n decoratedNode.constant =\n decoratedLeft.constant && decoratedRight.constant;\n decoratedNode.toWatch = decoratedLeft.toWatch.concat(\n decoratedRight.toWatch,\n );\n\n return decoratedNode;\n case ASTType._LogicalExpression:\n decoratedLeft = findConstantAndWatchExpressions(\n decoratedNode.left,\n $filter,\n astIsPure,\n );\n decoratedRight = findConstantAndWatchExpressions(\n decoratedNode.right,\n $filter,\n astIsPure,\n );\n decoratedNode.constant =\n decoratedLeft.constant && decoratedRight.constant;\n decoratedNode.toWatch = decoratedNode.constant ? [] : [ast];\n\n return decoratedNode;\n case ASTType._ConditionalExpression:\n decoratedTest = findConstantAndWatchExpressions(\n ast.test,\n $filter,\n astIsPure,\n );\n decoratedAlternate = findConstantAndWatchExpressions(\n ast.alternate,\n $filter,\n astIsPure,\n );\n decoratedConsequent = findConstantAndWatchExpressions(\n ast.consequent,\n $filter,\n astIsPure,\n );\n decoratedNode.constant =\n decoratedTest.constant &&\n decoratedAlternate.constant &&\n decoratedConsequent.constant;\n decoratedNode.toWatch = decoratedNode.constant ? [] : [ast];\n\n return decoratedNode;\n case ASTType._Identifier:\n decoratedNode.constant = false;\n decoratedNode.toWatch = [ast];\n\n return decoratedNode;\n case ASTType._MemberExpression:\n decoratedObject = findConstantAndWatchExpressions(\n ast.object,\n $filter,\n astIsPure,\n );\n\n if (ast.computed) {\n decoratedProperty = findConstantAndWatchExpressions(\n ast.property,\n $filter,\n astIsPure,\n );\n }\n decoratedNode.constant =\n decoratedObject.constant &&\n (!decoratedNode.computed || decoratedProperty.constant);\n decoratedNode.toWatch = decoratedNode.constant ? [] : [ast];\n\n return decoratedNode;\n case ASTType._CallExpression:\n isStatelessFilter = ast.filter\n ? isStateless($filter, ast.callee.name)\n : false;\n allConstants = isStatelessFilter;\n argsToWatch = [];\n ast.arguments.forEach((expr) => {\n decorated = findConstantAndWatchExpressions(expr, $filter, astIsPure);\n allConstants = allConstants && decorated.constant;\n argsToWatch.push.apply(argsToWatch, decorated.toWatch);\n });\n decoratedNode.constant = allConstants;\n decoratedNode.toWatch = isStatelessFilter ? argsToWatch : [decoratedNode];\n\n return decoratedNode;\n case ASTType._AssignmentExpression:\n decoratedLeft = findConstantAndWatchExpressions(\n ast.left,\n $filter,\n astIsPure,\n );\n decoratedRight = findConstantAndWatchExpressions(\n ast.right,\n $filter,\n astIsPure,\n );\n decoratedNode.constant =\n decoratedLeft.constant && decoratedRight.constant;\n decoratedNode.toWatch = [decoratedNode];\n\n return decoratedNode;\n case ASTType._ArrayExpression:\n allConstants = true;\n argsToWatch = [];\n ast.elements.forEach((expr) => {\n decorated = findConstantAndWatchExpressions(expr, $filter, astIsPure);\n allConstants = allConstants && decorated.constant;\n argsToWatch.push.apply(argsToWatch, decorated.toWatch);\n });\n decoratedNode.constant = allConstants;\n decoratedNode.toWatch = argsToWatch;\n\n return decoratedNode;\n case ASTType._ObjectExpression:\n allConstants = true;\n argsToWatch = [];\n ast.properties.forEach((property) => {\n decorated = findConstantAndWatchExpressions(\n property.value,\n $filter,\n astIsPure,\n );\n allConstants = allConstants && decorated.constant;\n argsToWatch.push.apply(argsToWatch, decorated.toWatch);\n\n if (property.computed) {\n // `{[key]: value}` implicitly does `key.toString()` which may be non-pure\n decoratedKey = findConstantAndWatchExpressions(\n property.key,\n $filter,\n false,\n );\n allConstants = allConstants && decoratedKey.constant;\n argsToWatch.push.apply(argsToWatch, decoratedKey.toWatch);\n }\n });\n decoratedNode.constant = allConstants;\n decoratedNode.toWatch = argsToWatch;\n\n return decoratedNode;\n case ASTType._ThisExpression:\n decoratedNode.constant = false;\n decoratedNode.toWatch = [];\n\n return decoratedNode;\n case ASTType._LocalsExpression:\n decoratedNode.constant = false;\n decoratedNode.toWatch = [];\n\n return decoratedNode;\n }\n\n return undefined;\n}\n\n/**\n * Converts a single expression AST node into an assignment expression if the expression is assignable.\n *\n * @param {import(\"./ast/ast\").ASTNode} ast\n * @returns {import(\"./ast/ast\").ASTNode}\n */\nfunction assignableAST(ast) {\n if (ast.body.length === 1 && isAssignable(ast.body[0].expression)) {\n return {\n type: ASTType._AssignmentExpression,\n left: ast.body[0].expression,\n right: { type: ASTType.NGValueParameter },\n operator: \"=\",\n };\n }\n\n return undefined;\n}\n\nfunction plusFn(left, right) {\n if (typeof left === \"undefined\" || isObject(left)) return right;\n\n if (typeof right === \"undefined\" || isObject(right)) return left;\n\n return left + right;\n}\n\n/**\n *\n * @param {import(\"./ast/ast\").ASTNode[]} body\n * @returns {any}\n */\nfunction getInputs(body) {\n if (body.length !== 1) return undefined;\n const lastExpression = /** @type {DecoratedASTNode} */ (body[0].expression);\n\n const candidate = lastExpression.toWatch;\n\n if (candidate.length !== 1) return candidate;\n\n return candidate[0] !== lastExpression ? candidate : undefined;\n}\n\n/**\n * Detect nodes which could depend on non-shallow state of objects\n * @param {import(\"./ast/ast\").ASTNode} node\n * @param {boolean|PURITY_ABSOLUTE|PURITY_RELATIVE} parentIsPure\n * @returns {boolean|PURITY_ABSOLUTE|PURITY_RELATIVE}\n */\nfunction isPure(node, parentIsPure) {\n switch (node.type) {\n // Computed members might invoke a stateful toString()\n case ASTType._MemberExpression:\n if (node.computed) {\n return false;\n }\n break;\n\n // Unary always convert to primitive\n case ASTType._UnaryExpression:\n return PURITY_ABSOLUTE;\n\n // The binary + operator can invoke a stateful toString().\n case ASTType._BinaryExpression:\n return node.operator !== \"+\" ? PURITY_ABSOLUTE : false;\n\n // Functions / filters probably read state from within objects\n case ASTType._CallExpression:\n return false;\n }\n\n return undefined === parentIsPure ? PURITY_RELATIVE : parentIsPure;\n}\n\nfunction isStateless($filter, filterName) {\n const fn = $filter(filterName);\n\n return !fn.$stateful;\n}\n\n/**\n * Converts parameter to strings property name for use as keys in an object.\n * Any non-string object, including a number, is typecasted into a string via the toString method.\n * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors#Property_names}\n *\n * @param {!any} name\n * @returns {string}\n */\nfunction getStringValue(name) {\n return `${name}`;\n}\n\n/**\n * @param {import(\"./ast/ast\").ASTNode} ast\n * @returns {boolean}\n */\nexport function isAssignable(ast) {\n return (\n ast.type === ASTType._Identifier || ast.type === ASTType._MemberExpression\n );\n}\n","/* eslint-disable id-length */\n/* eslint-disable no-magic-numbers */\nimport { isDefined, minErr } from \"../../../shared/utils.js\";\n\n/**\n * @typedef {import(\"./token.ts\").Token} Token\n */\n\nconst $parseMinErr = minErr(\"$parse\");\n\nconst ESCAPE = {\n n: \"\\n\",\n f: \"\\f\",\n r: \"\\r\",\n t: \"\\t\",\n v: \"\\v\",\n \"'\": \"'\",\n '\"': '\"',\n};\n\nconst OPERATORS = new Set(\n \"+ - * / % === !== == != < > <= >= && || ! = |\".split(\" \"),\n);\n\n/**\n * @typedef {Object} LexerOptions\n * @property {(ch: string, codePoint: number) => boolean} [isIdentifierStart] - Custom function to determine if a character is a valid identifier start.\n * @property {(ch: string, codePoint: number) => boolean} [isIdentifierContinue] - Custom function to determine if a character is a valid identifier continuation.\n */\n\n/**\n * Represents a lexer that tokenizes input text. The Lexer takes the original expression string and returns an array of tokens parsed from that string.\n * For example, the string \"a + b\" would result in tokens for a, +, and b.\n */\nexport class Lexer {\n /**\n * Creates an instance of Lexer.\n * @param {LexerOptions} options - Lexer options.\n */\n constructor(options) {\n /** @type {LexerOptions} */\n this._options = options;\n }\n\n /**\n * Tokenizes the input text.\n * @param {string} text Input text to lex.\n * @returns {Array<Token>} Array of tokens.\n */\n _lex(text) {\n this._text = text;\n this._index = 0;\n /** @type {Array<Token>} */\n this._tokens = [];\n\n while (this._index < this._text.length) {\n const ch = this._text.charAt(this._index);\n\n if (ch === '\"' || ch === \"'\") {\n this._readString(ch);\n } else if (\n this._isNumber(ch) ||\n (ch === \".\" && this._isNumber(/** @type {string} */ (this._peek())))\n ) {\n this._readNumber();\n } else if (\n this._isIdentifierStart &&\n this._isIdentifierStart(this._peekMultichar())\n ) {\n this._readIdent();\n } else if (this._is(ch, \"(){}[].,;:?\")) {\n this._tokens.push({ index: this._index, text: ch });\n this._index++;\n } else if (this._isWhitespace(ch)) {\n this._index++;\n } else {\n const ch2 = ch + this._peek();\n\n const ch3 = ch2 + this._peek(2);\n\n const op1 = OPERATORS.has(ch);\n\n const op2 = OPERATORS.has(ch2);\n\n const op3 = OPERATORS.has(ch3);\n\n if (op1 || op2 || op3) {\n const token = op3 ? ch3 : op2 ? ch2 : ch;\n\n this._tokens.push({\n index: this._index,\n text: token,\n operator: true,\n });\n this._index += token.length;\n } else {\n this._throwError(\n \"Unexpected next character \",\n this._index,\n this._index + 1,\n );\n }\n }\n }\n\n return this._tokens;\n }\n\n /**\n * Checks if a character is contained in a set of characters.\n * @param {string} ch Character to check.\n * @param {string} chars Set of characters.\n * @returns {boolean} True if character is in the set, false otherwise.\n */\n _is(ch, chars) {\n return chars.indexOf(ch) !== -1;\n }\n\n /**\n * Peeks at the next character in the text.\n * @param {number} [i=1] Number of characters to peek.\n * @returns {string|false} Next character or false if end of text.\n */\n _peek(i) {\n const num = i || 1;\n\n return this._index + num < this._text.length\n ? this._text.charAt(this._index + num)\n : false;\n }\n\n /**\n * Checks if a character is a number.\n * @param {string} ch Character to check.\n * @returns {boolean} True if character is a number, false otherwise.\n */\n _isNumber(ch) {\n return ch >= \"0\" && ch <= \"9\" && typeof ch === \"string\";\n }\n\n /**\n * Checks if a character is whitespace.\n * @param {string} ch Character to check.\n * @returns {boolean} True if character is whitespace, false otherwise.\n */\n _isWhitespace(ch) {\n return (\n ch === \" \" || ch === \"\\r\" || ch === \"\\t\" || ch === \"\\n\" || ch === \"\\v\"\n );\n }\n\n /**\n * Checks if a character is a valid identifier start.\n * @param {string} ch Character to check.\n * @returns {boolean} True if character is a valid identifier start, false otherwise.\n */\n _isIdentifierStart(ch) {\n return this._options.isIdentifierStart\n ? this._options.isIdentifierStart(ch, this._codePointAt(ch))\n : (ch >= \"a\" && ch <= \"z\") ||\n (ch >= \"A\" && ch <= \"Z\") ||\n ch === \"_\" ||\n ch === \"$\";\n }\n\n /**\n * Checks if a character is a valid identifier continuation.\n * @param {string} ch Character to check.\n * @returns {boolean} True if character is a valid identifier continuation, false otherwise.\n */\n _isIdentifierContinue(ch) {\n return this._options.isIdentifierContinue\n ? this._options.isIdentifierContinue(ch, this._codePointAt(ch))\n : (ch >= \"a\" && ch <= \"z\") ||\n (ch >= \"A\" && ch <= \"Z\") ||\n ch === \"_\" ||\n ch === \"$\" ||\n (ch >= \"0\" && ch <= \"9\");\n }\n\n /**\n * Converts a character to its Unicode code point.\n * @param {string} ch Character to convert.\n * @returns {number} Unicode code point.\n */\n _codePointAt(ch) {\n if (ch.length === 1) return ch.charCodeAt(0);\n\n return (ch.charCodeAt(0) << 10) + ch.charCodeAt(1) - 0x35fdc00;\n }\n\n /**\n * Peeks at the next multicharacter sequence in the text.\n * @returns {string} Next multicharacter sequence.\n */\n _peekMultichar() {\n const ch = this._text.charAt(this._index);\n\n const peek = this._peek();\n\n if (!peek) {\n return ch;\n }\n const cp1 = ch.charCodeAt(0);\n\n const cp2 = peek.charCodeAt(0);\n\n if (cp1 >= 0xd800 && cp1 <= 0xdbff && cp2 >= 0xdc00 && cp2 <= 0xdfff) {\n return ch + peek;\n }\n\n return ch;\n }\n\n /**\n * Checks if a character is an exponent operator.\n * @param {string} ch Character to check.\n * @returns {boolean} True if character is an exponent operator, false otherwise.\n */\n _isExpOperator(ch) {\n return ch === \"-\" || ch === \"+\" || this._isNumber(ch);\n }\n\n /**\n * Throws a lexer error.\n * @param {string} error Error message.\n * @param {number} [start] Start index.\n * @param {number} [end] End index.\n * @throws {Error} Lexer error.\n */\n _throwError(error, start, end) {\n end = end || this._index;\n const colStr = isDefined(start)\n ? `s ${start}-${this._index} [${this._text.substring(start, end)}]`\n : ` ${end}`;\n\n throw $parseMinErr(\n \"lexerr\",\n `Lexer Error: ${error} at column${colStr} in expression [${this._text}].`,\n );\n }\n\n /**\n * Reads and tokenizes a number from the text.\n * @return {void}\n */\n _readNumber() {\n let number = \"\";\n\n const start = this._index;\n\n while (this._index < this._text.length) {\n const ch = this._text.charAt(this._index).toLowerCase();\n\n if (ch === \".\" || this._isNumber(ch)) {\n number += ch;\n } else {\n const peekCh = this._peek();\n\n if (ch === \"e\" && this._isExpOperator(/** @type {string} */ (peekCh))) {\n number += ch;\n } else if (\n this._isExpOperator(ch) &&\n peekCh &&\n this._isNumber(peekCh) &&\n number.charAt(number.length - 1) === \"e\"\n ) {\n number += ch;\n } else if (\n this._isExpOperator(ch) &&\n (!peekCh || !this._isNumber(peekCh)) &&\n number.charAt(number.length - 1) === \"e\"\n ) {\n this._throwError(\"Invalid exponent\");\n } else {\n break;\n }\n }\n this._index++;\n }\n this._tokens.push({\n index: start,\n text: number,\n constant: true,\n value: Number(number),\n });\n }\n\n /**\n * Reads and tokenizes an identifier from the text.\n */\n _readIdent() {\n const start = this._index;\n\n this._index += this._peekMultichar().length;\n\n while (this._index < this._text.length) {\n const ch = this._peekMultichar();\n\n if (this._isIdentifierContinue && !this._isIdentifierContinue(ch)) {\n break;\n }\n this._index += ch.length;\n }\n this._tokens.push({\n index: start,\n text: this._text.slice(start, this._index),\n identifier: true,\n });\n }\n\n /**\n * Reads and tokenizes a string from the text.\n * @param {string} quote Quote character used for the string.\n */\n _readString(quote) {\n const start = this._index;\n\n let string = \"\";\n\n let escape = false;\n\n this._index++; // Skip opening quote\n\n while (this._index < this._text.length) {\n const ch = this._text[this._index];\n\n if (escape) {\n if (ch === \"u\") {\n // Handle unicode escapes\n // Simplified for brevity\n string += this._handleUnicodeEscape();\n } else {\n string += ESCAPE[ch] || ch;\n }\n escape = false;\n } else if (ch === \"\\\\\") {\n escape = true;\n } else if (ch === quote) {\n this._tokens.push({\n index: start,\n text: this._text.slice(start, this._index + 1),\n constant: true,\n value: string,\n });\n this._index++; // Skip closing quote\n\n return;\n } else {\n string += ch;\n }\n\n this._index++;\n }\n\n this._throwError(\"Unterminated quote\", start);\n }\n\n /**\n * @returns {string}\n */\n _handleUnicodeEscape() {\n const hex = this._text.substring(this._index + 1, this._index + 5);\n\n if (!hex.match(/[\\da-f]{4}/i)) {\n this._throwError(`Invalid unicode escape [\\\\u${hex}]`);\n }\n this._index += 4; // Move index past the four hexadecimal digits\n\n return String.fromCharCode(parseInt(hex, 16));\n }\n}\n","import { isAssignable } from \"../interpreter.js\";\nimport { ASTType } from \"../ast-type.js\";\nimport { hasOwn, minErr } from \"../../../shared/utils.js\";\n\n/**\n * @typedef {import(\"./ast-node.ts\").ASTNode} ASTNode\n * @typedef {import(\"../lexer/token.js\").Token} Token\n */\n\nconst $parseMinErr = minErr(\"$parse\");\n\nconst literals = {\n true: true,\n false: false,\n null: null,\n undefined,\n};\n\n/**\n * @class\n */\nexport class AST {\n /**\n * @param {import('../lexer/lexer.js').Lexer} lexer - The lexer instance for tokenizing input\n */\n constructor(lexer) {\n /** @type {import('../lexer/lexer.js').Lexer} */\n this._lexer = lexer;\n this._selfReferential = {\n this: { type: ASTType._ThisExpression },\n $locals: { type: ASTType._LocalsExpression },\n };\n this._index = 0;\n }\n\n /**\n * Parses the input text and generates an AST.\n * @param {string} text - The input text to parse.\n * @returns {ASTNode} The root node of the AST.\n */\n _ast(text) {\n this._text = text;\n this._tokens = this._lexer._lex(text);\n\n const value = this._program();\n\n if (this._tokens.length > this._index) {\n this._throwError(\"is an unexpected token\", this._tokens[this._index]);\n }\n\n return value;\n }\n\n /**\n * Parses a program.\n * @returns {ASTNode} The program node.\n */\n _program() {\n const body = [];\n\n let hasMore = true;\n\n while (hasMore) {\n if (this._tokens.length > this._index && !this._peek(\"}\", \")\", \";\", \"]\"))\n body.push(this._expressionStatement());\n\n if (!this._expect(\";\")) {\n hasMore = false;\n }\n }\n\n return { type: ASTType._Program, body };\n }\n\n /**\n * Parses an expression statement.\n * @returns {ASTNode} The expression statement node.\n */\n _expressionStatement() {\n return {\n type: ASTType._ExpressionStatement,\n expression: this._filterChain(),\n };\n }\n\n /**\n * Parses a filter chain.\n * @returns {ASTNode} The filter chain node.\n */\n _filterChain() {\n let left = this._assignment();\n\n while (this._expect(\"|\")) {\n left = this._filter(left);\n }\n\n return left;\n }\n\n /**\n * Parses an assignment expression.\n * @returns {ASTNode} The assignment expression node.\n */\n _assignment() {\n let result = this._ternary();\n\n if (this._expect(\"=\")) {\n if (!isAssignable(result)) {\n throw $parseMinErr(\"lval\", \"Trying to assign a value to a non l-value\");\n }\n\n result = {\n type: ASTType._AssignmentExpression,\n left: result,\n right: this._assignment(),\n operator: \"=\",\n };\n }\n\n return result;\n }\n\n /**\n * Parses a ternary expression.\n * @returns {ASTNode} The ternary expression node.\n */\n _ternary() {\n const test = this._logicalOR();\n\n let alternate;\n\n let consequent;\n\n if (this._expect(\"?\")) {\n alternate = this._assignment();\n\n if (this._consume(\":\")) {\n consequent = this._assignment();\n\n return {\n type: ASTType._ConditionalExpression,\n test,\n alternate,\n consequent,\n };\n }\n }\n\n return test;\n }\n\n /**\n * Parses a logical OR expression.\n * @returns {ASTNode} The logical OR expression node.\n */\n _logicalOR() {\n let left = this._logicalAND();\n\n while (this._expect(\"||\")) {\n left = {\n type: ASTType._LogicalExpression,\n operator: \"||\",\n left,\n right: this._logicalAND(),\n };\n }\n\n return left;\n }\n\n /**\n * Parses a logical AND expression.\n * @returns {ASTNode} The logical AND expression node.\n */\n _logicalAND() {\n let left = this._equality();\n\n while (this._expect(\"&&\")) {\n left = {\n type: ASTType._LogicalExpression,\n operator: \"&&\",\n left,\n right: this._equality(),\n };\n }\n\n return left;\n }\n\n /**\n * Parses an equality expression.\n * @returns {ASTNode} The equality expression node.\n */\n _equality() {\n let left = this._relational();\n\n let token;\n\n while ((token = this._expect(\"==\", \"!=\", \"===\", \"!==\"))) {\n left = {\n type: ASTType._BinaryExpression,\n operator: /** @type {Token} */ (token).text,\n left,\n right: this._relational(),\n };\n }\n\n return left;\n }\n\n /**\n * Parses a relational expression.\n * @returns {ASTNode} The relational expression node.\n */\n _relational() {\n let left = this._additive();\n\n let token;\n\n while ((token = this._expect(\"<\", \">\", \"<=\", \">=\"))) {\n left = {\n type: ASTType._BinaryExpression,\n operator: /** @type {Token} */ (token).text,\n left,\n right: this._additive(),\n };\n }\n\n return left;\n }\n\n /**\n * Parses an additive expression.\n * @returns {ASTNode} The additive expression node.\n */\n _additive() {\n let left = this._multiplicative();\n\n let token;\n\n while ((token = this._expect(\"+\", \"-\"))) {\n left = {\n type: ASTType._BinaryExpression,\n operator: /** @type {Token} */ (token).text,\n left,\n right: this._multiplicative(),\n };\n }\n\n return left;\n }\n\n /**\n * Parses a multiplicative expression.\n * @returns {ASTNode} The multiplicative expression node.\n */\n _multiplicative() {\n let left = this._unary();\n\n let token;\n\n while ((token = this._expect(\"*\", \"/\", \"%\"))) {\n left = {\n type: ASTType._BinaryExpression,\n operator: /** @type {import(\"../lexer/lexer.js\").Token} */ (token).text,\n left,\n right: this._unary(),\n };\n }\n\n return left;\n }\n\n /**\n * Parses a unary expression.\n * @returns {ASTNode} The unary expression node.\n */\n _unary() {\n let token;\n\n if ((token = this._expect(\"+\", \"-\", \"!\"))) {\n return {\n type: ASTType._UnaryExpression,\n operator: /** @type {import(\"../lexer/lexer.js\").Token} */ (token).text,\n prefix: true,\n argument: this._unary(),\n };\n }\n\n return this._primary();\n }\n\n /**\n * Parses a primary expression.\n * @returns {ASTNode} The primary expression node.\n */\n _primary() {\n let primary;\n\n if (this._expect(\"(\")) {\n primary = this._filterChain();\n this._consume(\")\");\n } else if (this._expect(\"[\")) {\n primary = this._arrayDeclaration();\n } else if (this._expect(\"{\")) {\n primary = this._object();\n } else if (\n hasOwn(\n this._selfReferential,\n /** @type {import(\"../lexer/lexer.js\").Token} */ (this._peek()).text,\n )\n ) {\n primary = structuredClone(this._selfReferential[this._consume().text]);\n } else if (\n hasOwn(\n literals,\n /** @type {import(\"../lexer/lexer.js\").Token} */ (this._peek()).text,\n )\n ) {\n primary = {\n type: ASTType._Literal,\n value: literals[this._consume().text],\n };\n } else if (\n /** @type {import(\"../lexer/lexer.js\").Token} */ (this._peek()).identifier\n ) {\n primary = this._identifier();\n } else if (\n /** @type {import(\"../lexer/lexer.js\").Token} */ (this._peek()).constant\n ) {\n primary = this._constant();\n } else {\n this._throwError(\n \"not a primary expression\",\n /** @type {import(\"../lexer/lexer.js\").Token} */ (this._peek()),\n );\n }\n\n let next;\n\n while ((next = this._expect(\"(\", \"[\", \".\"))) {\n if (\n /** @type {import(\"../lexer/lexer.js\").Token} */ (next).text === \"(\"\n ) {\n primary = {\n type: ASTType._CallExpression,\n callee: primary,\n arguments: this._parseArguments(),\n };\n this._consume(\")\");\n } else if (\n /** @type {import(\"../lexer/lexer.js\").Token} */ (next).text === \"[\"\n ) {\n primary = {\n type: ASTType._MemberExpression,\n object: primary,\n property: this._assignment(),\n computed: true,\n };\n this._consume(\"]\");\n } else if (\n /** @type {import(\"../lexer/lexer.js\").Token} */ (next).text === \".\"\n ) {\n primary = {\n type: ASTType._MemberExpression,\n object: primary,\n property: this._identifier(),\n computed: false,\n };\n } else {\n this._throwError(\"IMPOSSIBLE\");\n }\n }\n\n return primary;\n }\n\n /**\n * Parses a filter.\n * @param {ASTNode} baseExpression - The base expression to apply the filter to.\n * @returns {ASTNode} The filter node.\n */\n _filter(baseExpression) {\n /** @type {ASTNode[]} */\n const args = [baseExpression];\n\n const result = {\n type: ASTType._CallExpression,\n callee: this._identifier(),\n arguments: args,\n filter: true,\n };\n\n while (this._expect(\":\")) {\n args.push(this._assignment());\n }\n\n return result;\n }\n\n /**\n * Parses function arguments.\n * @returns {ASTNode[]} The arguments array.\n */\n _parseArguments() {\n /** @type {ASTNode[]} */\n const args = [];\n\n if (this._peekToken().text !== \")\") {\n do {\n args.push(this._filterChain());\n } while (this._expect(\",\"));\n }\n\n return args;\n }\n\n /**\n * Parses an identifier.\n * @returns {ASTNode} The identifier node.\n */\n _identifier() {\n const token = this._consume();\n\n if (!token.identifier) {\n this._throwError(\"is not a valid identifier\", token);\n }\n\n return { type: ASTType._Identifier, name: token.text };\n }\n\n /**\n * Parses a constant.\n * @returns {ASTNode} The constant node.\n */\n _constant() {\n // TODO check that it is a constant\n return { type: ASTType._Literal, value: this._consume().value };\n }\n\n /**\n * Parses an array declaration.\n * @returns {ASTNode} The array declaration node.\n */\n _arrayDeclaration() {\n /** @type {ASTNode[]} */\n const elements = [];\n\n if (this._peekToken().text !== \"]\") {\n do {\n if (this._peek(\"]\")) {\n // Support trailing commas per ES5.1.\n break;\n }\n elements.push(this._assignment());\n } while (this._expect(\",\"));\n }\n this._consume(\"]\");\n\n return { type: ASTType._ArrayExpression, elements };\n }\n\n /**\n * Parses an object.\n * @returns {ASTNode} The object node.\n */\n _object() {\n /** @type {ASTNode[]} */\n const properties = [];\n\n /** @type {ASTNode} */\n let property;\n\n if (this._peekToken().text !== \"}\") {\n do {\n if (this._peek(\"}\")) {\n // Support trailing commas per ES5.1.\n break;\n }\n property = { type: ASTType._Property, kind: \"init\" };\n\n if (\n /** @type {import(\"../lexer/lexer.js\").Token} */ (this._peek())\n .constant\n ) {\n property.key = this._constant();\n property.computed = false;\n this._consume(\":\");\n property.value = this._assignment();\n } else if (\n /** @type {import(\"../lexer/lexer.js\").Token} */ (this._peek())\n .identifier\n ) {\n property.key = this._identifier();\n property.computed = false;\n\n if (this._peek(\":\")) {\n this._consume(\":\");\n property.value = this._assignment();\n } else {\n property.value = property.key;\n }\n } else if (this._peek(\"[\")) {\n this._consume(\"[\");\n property.key = this._assignment();\n this._consume(\"]\");\n property.computed = true;\n this._consume(\":\");\n property.value = this._assignment();\n } else {\n this._throwError(\n \"invalid key\",\n /** @type {import(\"../lexer/lexer.js\").Token} */ (this._peek()),\n );\n }\n properties.push(property);\n } while (this._expect(\",\"));\n }\n this._consume(\"}\");\n\n return { type: ASTType._ObjectExpression, properties };\n }\n\n /**\n * Throws a syntax error.\n * @param {string} msg - The error message.\n * @param {import(\"../lexer/lexer.js\").Token} [token] - The token that caused the error.\n */\n _throwError(msg, token) {\n throw $parseMinErr(\n \"syntax\",\n \"Syntax Error: Token '{0}' {1} at column {2} of the expression [{3}] starting at [{4}].\",\n token.text,\n msg,\n token.index + 1,\n this._text,\n this._text.substring(token.index),\n );\n }\n\n /**\n * Consumes a token if it matches the expected type.\n * @param {string} [e1] - The expected token type.\n * @returns {import(\"../lexer/lexer.js\").Token} The consumed token.\n */\n _consume(e1) {\n if (this._tokens.length === this._index) {\n throw $parseMinErr(\n \"ueoe\",\n \"Unexpected end of expression: {0}\",\n this._text,\n );\n }\n\n const token = this._expect(e1);\n\n if (!token) {\n this._throwError(\n `is unexpected, expecting [${e1}]`,\n /** @type {import(\"../lexer/lexer.js\").Token} */ (this._peek()),\n );\n } else {\n return /** @type {import(\"../lexer/lexer.js\").Token} */ (token);\n }\n\n return undefined;\n }\n\n /**\n * Returns the next token without consuming it.\n * @returns {import(\"../lexer/lexer.js\").Token} The next token.\n */\n _peekToken() {\n if (this._tokens.length === this._index) {\n throw $parseMinErr(\n \"ueoe\",\n \"Unexpected end of expression: {0}\",\n this._text,\n );\n }\n\n return this._tokens[this._index];\n }\n\n /**\n * Checks if the next token matches any of the expected types.\n * @param {...string} [expected] - The expected token types.\n * @returns {import('../lexer/lexer.js').Token|boolean} The next token if it matches, otherwise false.\n */\n _peek(...expected) {\n const token = this._tokens[this._index];\n\n const j = expected.length;\n\n if (!token || !j) return token;\n\n const txt = token.text;\n\n for (let i = 0; i < j; i++) {\n if (expected[i] === txt || !expected[i]) return token;\n }\n\n return false;\n }\n\n /**\n * Consumes the next token if it matches any of the expected types.\n * @param {...string} [expected] - The expected token types.\n * @returns {import(\"../lexer/lexer.js\").Token|boolean} The consumed token if it matches, otherwise false.\n */\n _expect(...expected) {\n const token = this._peek(...expected);\n\n if (token) {\n this._index++;\n\n return token;\n }\n\n return false;\n }\n}\n","import { AST } from \"../ast/ast.js\";\nimport { ASTType } from \"../ast-type.js\";\nimport { ASTInterpreter } from \"../interpreter.js\";\n\n/**\n * @typedef {Object} ParsedAST\n * @property {import(\"../ast/ast-node.d.ts\").ASTNode} ast - AST representation of expression\n */\n\n/**\n * @constructor\n */\nexport class Parser {\n /**\n *\n * @param {import('../lexer/lexer.js').Lexer} lexer\n * @param {function(any):any} $filter\n */\n constructor(lexer, $filter) {\n /** @type {AST} */\n this._ast = new AST(lexer);\n\n /** @type {ASTInterpreter} */\n this._astCompiler = new ASTInterpreter($filter);\n }\n\n /**\n * @param {string} exp - Expression to be parsed\n * @returns {import(\"../interface.ts\").CompiledExpression}\n */\n _parse(exp) {\n const { ast } = this.#getAst(exp);\n\n const fn = this._astCompiler.compile(ast);\n\n fn.literal = isLiteral(ast);\n fn.constant = isConstant(ast);\n\n return fn;\n }\n\n /**\n * @param {string} exp - Expression to be parsed\n * @returns {ParsedAST}\n */\n #getAst(exp) {\n exp = exp.trim();\n\n return {\n ast: this._ast._ast(exp),\n };\n }\n}\n\nfunction isLiteral(ast) {\n return (\n ast.body.length === 0 ||\n (ast.body.length === 1 &&\n (ast.body[0].expression.type === ASTType._Literal ||\n ast.body[0].expression.type === ASTType._ArrayExpression ||\n ast.body[0].expression.type === ASTType._ObjectExpression))\n );\n}\n\nfunction isConstant(ast) {\n return ast.constant;\n}\n","import { isFunction, isNullOrUndefined, isProxy } from \"../../shared/utils.js\";\nimport { PURITY_RELATIVE } from \"./interpreter.js\";\nimport { Lexer } from \"./lexer/lexer.js\";\nimport { Parser } from \"./parser/parser.js\";\n\nexport class ParseProvider {\n constructor() {\n const cache = Object.create(null);\n\n /** @type {function(any):boolean?} */\n let identStart;\n\n /** @type {function(any):boolean?} */\n let identContinue;\n\n /**\n * Allows defining the set of characters that are allowed in AngularTS expressions. The function\n * `identifierStart` will get called to know if a given character is a valid character to be the\n * first character for an identifier. The function `identifierContinue` will get called to know if\n * a given character is a valid character to be a follow-up identifier character. The functions\n * `identifierStart` and `identifierContinue` will receive as arguments the single character to be\n * identifier and the character code point. These arguments will be `string` and `numeric`. Keep in\n * mind that the `string` parameter can be two characters long depending on the character\n * representation. It is expected for the function to return `true` or `false`, whether that\n * character is allowed or not.\n *\n * Since this function will be called extensively, keep the implementation of these functions fast,\n * as the performance of these functions have a direct impact on the expressions parsing speed.\n *\n * @param {function(any):boolean} [identifierStart] The function that will decide whether the given character is\n * a valid identifier start character.\n * @param {function(any):boolean} [identifierContinue] The function that will decide whether the given character is\n * a valid identifier continue character.\n * @returns {ParseProvider}\n */\n this.setIdentifierFns = function (identifierStart, identifierContinue) {\n identStart = identifierStart;\n identContinue = identifierContinue;\n\n return this;\n };\n\n this.$get = [\n \"$filter\",\n /**\n *\n * @param {(any) => any} $filter\n * @returns {import('./interface').ParseService}\n */\n function ($filter) {\n /** @type {import(\"./lexer/lexer.js\").LexerOptions} */\n const $lexerOptions = {\n isIdentifierStart: isFunction(identStart) && identStart,\n isIdentifierContinue: isFunction(identContinue) && identContinue,\n };\n\n return $parse;\n\n /**\n * @param {string} exp\n * @param interceptorFn\n * @returns any\n */\n function $parse(exp, interceptorFn) {\n let parsedExpression, cacheKey;\n\n switch (typeof exp) {\n case \"string\":\n exp = exp.trim();\n cacheKey = exp;\n\n parsedExpression = cache[cacheKey];\n\n if (!parsedExpression) {\n const lexer = new Lexer($lexerOptions);\n\n const parser = new Parser(lexer, $filter);\n\n parsedExpression = parser._parse(exp);\n\n cache[cacheKey] = addWatchDelegate(parsedExpression);\n }\n\n return addInterceptor(parsedExpression, interceptorFn);\n\n case \"function\":\n return addInterceptor(exp, interceptorFn);\n\n default:\n return addInterceptor(() => {\n /* empty */\n }, interceptorFn);\n }\n }\n\n /**\n * @param {Function} parsedExpression\n * @param interceptorFn\n * @returns {import('./interface').CompiledExpression|*}\n */\n function addInterceptor(parsedExpression, interceptorFn) {\n if (!interceptorFn) {\n return parsedExpression;\n }\n\n // Extract any existing interceptors out of the parsedExpression\n // to ensure the original parsedExpression is always the $$intercepted\n // @ts-ignore\n if (parsedExpression.$$interceptor) {\n interceptorFn = chainInterceptors(\n // @ts-ignore\n parsedExpression.$$interceptor,\n interceptorFn,\n );\n // @ts-ignore\n parsedExpression = parsedExpression.$$intercepted;\n }\n\n let useInputs = false;\n\n const fn = function interceptedExpression(\n scope,\n locals,\n assign,\n inputs,\n ) {\n const value =\n useInputs && inputs\n ? inputs[0]\n : parsedExpression(scope, locals, assign, inputs);\n\n // Do not invoke for getters\n if (scope?.getter) {\n return undefined;\n }\n const res = isFunction(value) ? value() : value;\n\n return interceptorFn(isProxy(res) ? res.$target : res);\n };\n\n // Maintain references to the interceptor/intercepted\n fn.$$intercepted = parsedExpression;\n fn.$$interceptor = interceptorFn;\n\n // Propagate the literal/oneTime/constant attributes\n // @ts-ignore\n fn.literal = parsedExpression.literal;\n // @ts-ignore\n fn.oneTime = parsedExpression.oneTime;\n // @ts-ignore\n fn.constant = parsedExpression.constant;\n // @ts-ignore\n fn.decoratedNode = parsedExpression.decoratedNode;\n\n // Treat the interceptor like filters.\n // If it is not $stateful then only watch its inputs.\n // If the expression itself has no inputs then use the full expression as an input.\n if (!interceptorFn.$stateful) {\n // @ts-ignore\n useInputs = !parsedExpression.inputs;\n // @ts-ignore\n fn.inputs = parsedExpression.inputs\n ? // @ts-ignore\n parsedExpression.inputs\n : [parsedExpression];\n\n if (!interceptorFn.$$pure) {\n fn.inputs = fn.inputs.map(function (input) {\n // Remove the isPure flag of inputs when it is not absolute because they are now wrapped in a\n // non-pure interceptor function.\n if (input.isPure === PURITY_RELATIVE) {\n return function depurifier(x) {\n return input(x);\n };\n }\n\n return input;\n });\n }\n }\n\n return addWatchDelegate(fn);\n }\n },\n ];\n }\n}\n\nexport function constantWatchDelegate(\n scope,\n listener,\n objectEquality,\n parsedExpression,\n) {\n const unwatch = scope.$watch(\n () => {\n unwatch();\n\n return parsedExpression(scope);\n },\n listener,\n objectEquality,\n );\n\n return unwatch;\n}\n\n/**\n *\n * @param {import('./interface.ts').CompiledExpression} parsedExpression\n * @returns {import('./interface.ts').CompiledExpression}\n */\nfunction addWatchDelegate(parsedExpression) {\n if (parsedExpression.constant) {\n parsedExpression.$$watchDelegate = constantWatchDelegate;\n } else if (parsedExpression.inputs) {\n parsedExpression.$$watchDelegate = inputsWatchDelegate;\n }\n\n return parsedExpression;\n}\n\n/**\n *\n * @param {ng.Scope} scope\n * @param {Function} listener\n * @param {*} objectEquality\n * @param {import('./interface').CompiledExpression} parsedExpression\n * @returns {any}\n */\nfunction inputsWatchDelegate(\n scope,\n listener,\n objectEquality,\n parsedExpression,\n) {\n const inputExpressions = /** @type {Function} */ (parsedExpression.inputs);\n\n let lastResult;\n\n if (inputExpressions.length === 1) {\n let oldInputValueOf = expressionInputDirtyCheck; // init to something unique so that equals check fails\n\n const inputExpression = inputExpressions[0];\n\n return scope.$watch(\n // @ts-ignore\n ($scope) => {\n const newInputValue = inputExpression($scope);\n\n if (\n !expressionInputDirtyCheck(\n newInputValue,\n oldInputValueOf,\n inputExpression.isPure,\n )\n ) {\n lastResult = parsedExpression($scope, undefined, [newInputValue]);\n oldInputValueOf = newInputValue && getValueOf(newInputValue);\n }\n\n return lastResult;\n },\n listener,\n objectEquality,\n );\n } else {\n const oldInputValueOfValues = [];\n\n const oldInputValues = [];\n\n for (let i = 0, ii = inputExpressions.length; i < ii; i++) {\n oldInputValueOfValues[i] = expressionInputDirtyCheck; // init to something unique so that equals check fails\n oldInputValues[i] = null;\n }\n\n // return scope.$watch(\n // // @ts-ignore\n // (scope) => {\n // debugger\n // let changed = false;\n\n // for (let i = 0, ii = inputExpressions.length; i < ii; i++) {\n // const newInputValue = inputExpressions[i](scope);\n\n // if (\n // changed ||\n // (changed = !expressionInputDirtyCheck(\n // newInputValue,\n // oldInputValueOfValues[i],\n // inputExpressions[i].isPure,\n // ))\n // ) {\n // oldInputValues[i] = newInputValue;\n // oldInputValueOfValues[i] =\n // newInputValue && getValueOf(newInputValue);\n // }\n // }\n\n // if (changed) {\n // lastResult = parsedExpression(scope, undefined, oldInputValues);\n // }\n\n // return lastResult;\n // },\n // listener,\n // objectEquality,\n // );\n return undefined;\n }\n}\n\nfunction chainInterceptors(first, second) {\n function chainedInterceptor(value) {\n return second(first(value));\n }\n chainedInterceptor.$stateful = first.$stateful || second.$stateful;\n chainedInterceptor.$$pure = first.$$pure && second.$$pure;\n\n return chainedInterceptor;\n}\n\nfunction expressionInputDirtyCheck(\n newValue,\n oldValueOfValue,\n compareObjectIdentity,\n) {\n if (isNullOrUndefined(newValue) || isNullOrUndefined(oldValueOfValue)) {\n // null/undefined\n return newValue === oldValueOfValue;\n }\n\n if (typeof newValue === \"object\") {\n // attempt to convert the value to a primitive type\n // TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can\n // be cheaply dirty-checked\n newValue = getValueOf(newValue);\n\n if (typeof newValue === \"object\" && !compareObjectIdentity) {\n // objects/arrays are not supported - deep-watching them would be too expensive\n return false;\n }\n\n // fall-through to the primitive equality check\n }\n\n // Primitive or NaN\n\n return (\n newValue === oldValueOfValue ||\n (Number.isNaN(newValue) && Number.isNaN(oldValueOfValue))\n );\n}\n\nfunction getValueOf(value) {\n return isFunction(value.valueOf)\n ? value.valueOf()\n : {}.constructor.prototype.valueOf.call(value);\n}\n","import {\n extend,\n isDefined,\n isUndefined,\n minErr,\n stringify,\n} from \"../../shared/utils.js\";\nimport { constantWatchDelegate } from \"../parse/parse.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n\nconst $interpolateMinErr = minErr(\"$interpolate\");\n\nfunction throwNoconcat(text) {\n throw $interpolateMinErr(\n \"noconcat\",\n \"Error while interpolating: {0}\\nStrict Contextual Escaping disallows \" +\n \"interpolations that concatenate multiple expressions when a trusted value is \" +\n \"required. See http://docs.angularjs.org/api/ng.$sce\",\n text,\n );\n}\n\nfunction interr(text, err) {\n throw $interpolateMinErr(\n \"interr\",\n \"Can't interpolate: {0}\\n{1}\",\n text,\n err.toString(),\n );\n}\n\n/**\n *\n * Used for configuring the interpolation markup. Defaults to `{{` and `}}`.\n *\n * <div class=\"alert alert-danger\">\n * This feature is sometimes used to mix different markup languages, e.g. to wrap an AngularTS\n * template within a Python Jinja template (or any other template language). Mixing templating\n * languages is **very dangerous**. The embedding template language will not safely escape AngularTS\n * expressions, so any user-controlled values in the template will cause Cross Site Scripting (XSS)\n * security bugs!\n * </div>\n */\nexport class InterpolateProvider {\n constructor() {\n /**\n * @type {string} Symbol to denote start of expression in the interpolated string. Defaults to `{{`.\n */\n this.startSymbol = \"{{\";\n\n /**\n * @type {string} Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.\n */\n this.endSymbol = \"}}\";\n }\n\n $get = [\n $t.$parse,\n $t.$sce,\n /**\n *\n * @param {ng.ParseService} $parse\n * @param {*} $sce\n * @returns {ng.InterpolateService}\n */\n ($parse, $sce) => {\n /** @type {InterpolateProvider} */\n const provider = this;\n\n const startSymbolLength = provider.startSymbol.length;\n\n const endSymbolLength = provider.endSymbol.length;\n\n const escapedStartRegexp = new RegExp(\n provider.startSymbol.replace(/./g, escape),\n \"g\",\n );\n\n const escapedEndRegexp = new RegExp(\n provider.endSymbol.replace(/./g, escape),\n \"g\",\n );\n\n function escape(ch) {\n return `\\\\\\\\\\\\${ch}`;\n }\n\n function unescapeText(text) {\n return text\n .replace(escapedStartRegexp, provider.startSymbol)\n .replace(escapedEndRegexp, provider.endSymbol);\n }\n\n /**\n *\n * Compiles a string with markup into an interpolation function. This service is used by the\n * HTML {@link ng.$compile $compile} service for data binding. See\n * {@link ng.$interpolateProvider $interpolateProvider} for configuring the\n * interpolation markup.\n *\n *\n * ```js\n * let $interpolate = ...; // injected\n * let exp = $interpolate('Hello {{name | uppercase}}!');\n * expect(exp({name:'AngularTS'})).toEqual('Hello ANGULARJS!');\n * ```\n *\n * `$interpolate` takes an optional fourth argument, `allOrNothing`. If `allOrNothing` is\n * `true`, the interpolation function will return `undefined` unless all embedded expressions\n * evaluate to a value other than `undefined`.\n *\n * ```js\n * let $interpolate = ...; // injected\n * let context = {greeting: 'Hello', name: undefined };\n *\n * // default \"forgiving\" mode\n * let exp = $interpolate('{{greeting}} {{name}}!');\n * expect(exp(context)).toEqual('Hello !');\n *\n * // \"allOrNothing\" mode\n * exp = $interpolate('{{greeting}} {{name}}!', false, null, true);\n * expect(exp(context)).toBeUndefined();\n * context.name = 'AngularTS';\n * expect(exp(context)).toEqual('Hello AngularTS!');\n * ```\n *\n * `allOrNothing` is useful for interpolating URLs. `ngSrc` and `ngSrcset` use this behavior.\n *\n * #### Escaped Interpolation\n * $interpolate provides a mechanism for escaping interpolation markers. Start and end markers\n * can be escaped by preceding each of their characters with a REVERSE SOLIDUS U+005C (backslash).\n * It will be rendered as a regular start/end marker, and will not be interpreted as an expression\n * or binding.\n *\n * This enables web-servers to prevent script injection attacks and defacing attacks, to some\n * degree, while also enabling code examples to work without relying on the\n * {@link ng.directive:ngNonBindable ngNonBindable} directive.\n *\n * **For security purposes, it is strongly encouraged that web servers escape user-supplied data,\n * replacing angle brackets (<, >) with &lt; and &gt; respectively, and replacing all\n * interpolation start/end markers with their escaped counterparts.**\n *\n * Escaped interpolation markers are only replaced with the actual interpolation markers in rendered\n * output when the $interpolate service processes the text. So, for HTML elements interpolated\n * by {@link ng.$compile $compile}, or otherwise interpolated with the `mustHaveExpression` parameter\n * set to `true`, the interpolated text must contain an unescaped interpolation expression. As such,\n * this is typically useful only when user-data is used in rendering a template from the server, or\n * when otherwise untrusted data is used by a directive.\n *\n * <example name=\"interpolation\">\n * <file name=\"index.html\">\n * <div ng-init=\"username='A user'\">\n * <p ng-init=\"apptitle='Escaping demo'\">{{apptitle}}: \\{\\{ username = \"defaced value\"; \\}\\}\n * </p>\n * <p><strong>{{username}}</strong> attempts to inject code which will deface the\n * application, but fails to accomplish their task, because the server has correctly\n * escaped the interpolation start/end markers with REVERSE SOLIDUS U+005C (backslash)\n * characters.</p>\n * <p>Instead, the result of the attempted script injection is visible, and can be removed\n * from the database by an administrator.</p>\n * </div>\n * </file>\n * </example>\n *\n * @knownIssue\n * It is currently not possible for an interpolated expression to contain the interpolation end\n * symbol. For example, `{{ '}}' }}` will be incorrectly interpreted as `{{ ' }}` + `' }}`, i.e.\n * an interpolated expression consisting of a single-quote (`'`) and the `' }}` string.\n *\n * @knownIssue\n * All directives and components must use the standard `{{` `}}` interpolation symbols\n * in their templates. If you change the application interpolation symbols the {@link $compile}\n * service will attempt to denormalize the standard symbols to the custom symbols.\n * The denormalization process is not clever enough to know not to replace instances of the standard\n * symbols where they would not normally be treated as interpolation symbols. For example in the following\n * code snippet the closing braces of the literal object will get incorrectly denormalized:\n *\n * ```\n * <div data-context='{\"context\":{\"id\":3,\"type\":\"page\"}}\">\n * ```\n *\n * The workaround is to ensure that such instances are separated by whitespace:\n * ```\n * <div data-context='{\"context\":{\"id\":3,\"type\":\"page\"} }\">\n * ```\n *\n * See https://github.com/angular/angular.js/pull/14610#issuecomment-219401099 for more information.\n *\n * @param {string} text The text with markup to interpolate.\n * @param {boolean=} mustHaveExpression if set to true then the interpolation string must have\n * embedded expression in order to return an interpolation function. Strings with no\n * embedded expression will return null for the interpolation function.\n * @param {string=} trustedContext when provided, the returned function passes the interpolated\n * result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult,\n * trustedContext)} before returning it. Refer to the {@link ng.$sce $sce} service that\n * provides Strict Contextual Escaping for details.\n * @param {boolean=} allOrNothing if `true`, then the returned function returns undefined\n * unless all embedded expressions evaluate to a value other than `undefined`.\n * @returns {Function} an interpolation function which is used to compute the\n * interpolated string. The function has these parameters:\n *\n * - `context`: evaluation context for all expressions embedded in the interpolated text\n */\n function $interpolate(\n text,\n mustHaveExpression,\n trustedContext,\n allOrNothing,\n ) {\n const contextAllowsConcatenation =\n trustedContext === $sce.URL || trustedContext === $sce.MEDIA_URL;\n\n // Provide a quick exit and simplified result function for text with no interpolation\n if (!text.length || text.indexOf(provider.startSymbol) === -1) {\n if (mustHaveExpression) return undefined;\n\n let unescapedText = unescapeText(text);\n\n if (contextAllowsConcatenation) {\n unescapedText = $sce.getTrusted(trustedContext, unescapedText);\n }\n\n /**\n * @type {any}\n */\n const constantInterp = () => unescapedText;\n\n constantInterp.exp = text;\n constantInterp.expressions = [];\n constantInterp.$$watchDelegate = constantWatchDelegate;\n\n return constantInterp;\n }\n\n allOrNothing = !!allOrNothing;\n let startIndex;\n\n let endIndex;\n\n let index = 0;\n\n const expressions = [];\n\n const textLength = text.length;\n\n let exp;\n\n const concat = [];\n\n const expressionPositions = [];\n\n while (index < textLength) {\n if (\n (startIndex = text.indexOf(provider.startSymbol, index)) !== -1 &&\n (endIndex = text.indexOf(\n provider.endSymbol,\n startIndex + startSymbolLength,\n )) !== -1\n ) {\n if (index !== startIndex) {\n concat.push(unescapeText(text.substring(index, startIndex)));\n }\n exp = text.substring(startIndex + startSymbolLength, endIndex);\n expressions.push(exp);\n index = endIndex + endSymbolLength;\n expressionPositions.push(concat.length);\n concat.push(\"\"); // Placeholder that will get replaced with the evaluated expression.\n } else {\n // we did not find an interpolation, so we have to add the remainder to the separators array\n if (index !== textLength) {\n concat.push(unescapeText(text.substring(index)));\n }\n break;\n }\n }\n\n const singleExpression =\n concat.length === 1 && expressionPositions.length === 1;\n\n // Intercept expression if we need to stringify concatenated inputs, which may be SCE trusted\n // objects rather than simple strings\n // (we don't modify the expression if the input consists of only a single trusted input)\n const interceptor =\n contextAllowsConcatenation && singleExpression\n ? undefined\n : parseStringifyInterceptor;\n\n const parseFns = expressions.map((x) => $parse(x, interceptor));\n\n // Concatenating expressions makes it hard to reason about whether some combination of\n // concatenated values are unsafe to use and could easily lead to XSS. By requiring that a\n // single expression be used for some $sce-managed secure contexts (RESOURCE_URLs mostly),\n // we ensure that the value that's used is assigned or constructed by some JS code somewhere\n // that is more testable or make it obvious that you bound the value to some user controlled\n // value. This helps reduce the load when auditing for XSS issues.\n\n // Note that URL and MEDIA_URL $sce contexts do not need this, since `$sce` can sanitize the values\n // passed to it. In that case, `$sce.getTrusted` will be called on either the single expression\n // or on the overall concatenated string (losing trusted types used in the mix, by design).\n // Both these methods will sanitize plain strings. Also, HTML could be included, but since it's\n // only used in srcdoc attributes, this would not be very useful.\n\n if (!mustHaveExpression || expressions.length) {\n const compute = function (values) {\n for (let i = 0, ii = expressions.length; i < ii; i++) {\n if (allOrNothing && isUndefined(values[i])) return undefined;\n concat[expressionPositions[i]] = values[i];\n }\n\n if (contextAllowsConcatenation) {\n // If `singleExpression` then `concat[0]` might be a \"trusted\" value or `null`, rather than a string\n return $sce.getTrusted(\n trustedContext,\n singleExpression ? concat[0] : concat.join(\"\"),\n );\n }\n\n if (trustedContext && concat.length > 1) {\n // This context does not allow more than one part, e.g. expr + string or exp + exp.\n throwNoconcat(text);\n }\n\n // In an unprivileged context or only one part: just concatenate and return.\n return concat.join(\"\");\n };\n\n return /**@type {import(\"./interface.ts\").InterpolationFunction} */ extend(\n (context, cb) => {\n let i = 0;\n\n const ii = expressions.length;\n\n const values = new Array(ii);\n\n try {\n for (; i < ii; i++) {\n if (cb) {\n const watchProp = expressions[i].trim();\n\n context.$watch(watchProp, () => {\n const vals = new Array(ii);\n\n let j = 0;\n\n for (; j < ii; j++) {\n const fn = parseFns[j];\n\n vals[j] = fn(context);\n }\n cb(compute(vals));\n });\n }\n\n values[i] = parseFns[i](context);\n }\n\n return compute(values);\n } catch (err) {\n return interr(text, err);\n }\n },\n {\n // Most likely we would need to register watches during interpolation\n // all of these properties are undocumented for now\n exp: text, // just for compatibility with regular watchers created via $watch\n expressions,\n $$watchDelegate(scope, listener) {\n let lastValue;\n\n return scope.$watch(\n parseFns,\n function interpolateFnWatcher(values, oldValues) {\n const currValue = compute(values);\n\n listener.call(\n provider,\n currValue,\n values !== oldValues ? lastValue : currValue,\n scope,\n );\n lastValue = currValue;\n },\n );\n },\n },\n );\n }\n\n function parseStringifyInterceptor(value) {\n try {\n // In concatenable contexts, getTrusted comes at the end, to avoid sanitizing individual\n // parts of a full URL. We don't care about losing the trustedness here.\n // In non-concatenable contexts, where there is only one expression, this interceptor is\n // not applied to the expression.\n value =\n trustedContext && !contextAllowsConcatenation\n ? $sce.getTrusted(trustedContext, value)\n : $sce.valueOf(value);\n\n return allOrNothing && !isDefined(value) ? value : stringify(value);\n } catch (err) {\n return interr(text, err);\n }\n }\n\n return undefined;\n }\n\n /**\n * Symbol to denote the start of expression in the interpolated string. Defaults to `{{`.\n *\n * Use {@link ng.$interpolateProvider#startSymbol `$interpolateProvider.startSymbol`} to change\n * the symbol.\n *\n * @returns {string} start symbol.\n */\n $interpolate.startSymbol = function () {\n return provider.startSymbol;\n };\n\n /**\n * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.\n *\n * Use {@link ng.$interpolateProvider#endSymbol `$interpolateProvider.endSymbol`} to change\n * the symbol.\n *\n * @returns {string} end symbol.\n */\n $interpolate.endSymbol = function () {\n return provider.endSymbol;\n };\n\n // @ts-ignore\n return $interpolate;\n },\n ];\n}\n","import { trimEmptyHash, urlResolve } from \"../../shared/url-utils/url-utils.js\";\nimport {\n encodeUriSegment,\n entries,\n equals,\n isDefined,\n isNull,\n isNumber,\n isObject,\n isString,\n isUndefined,\n minErr,\n parseKeyValue,\n startsWith,\n toKeyValue,\n} from \"../../shared/utils.js\";\nimport { getBaseHref } from \"../../shared/dom.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n\nconst PATH_MATCH = /^([^?#]*)(\\?([^#]*))?(#(.*))?$/;\n\nconst $locationMinErr = minErr(\"$location\");\n\nlet urlUpdatedByLocation = false;\n\n/**\n * @ignore\n * The pathname, beginning with \"/\"\n * @type {string}\n */\nlet $$path;\n\n/**\n * @type {Object.<string,boolean|Array>}\n */\nlet $$search;\n\n/**\n * @ignore\n * The hash string, minus the hash symbol\n * @type {string}\n */\nlet $$hash;\n\nexport class Location {\n /**\n * @param {string} appBase application base URL\n * @param {string} appBaseNoFile application base URL stripped of any filename\n * @param {boolean} [html5] Defaults to true\n * @param {string} [prefix] URL path prefix for html5 mode or hash prefix for hashbang mode\n */\n constructor(appBase, appBaseNoFile, html5 = true, prefix) {\n /** @type {string} */\n this.appBase = appBase;\n\n /** @type {string} */\n this.appBaseNoFile = appBaseNoFile;\n\n /** @type {boolean} */\n this.html5 = html5;\n\n /** @type {string | undefined} */\n this.basePrefix = html5 ? prefix || \"\" : undefined;\n\n /** @type {string | undefined} */\n this.hashPrefix = html5 ? undefined : prefix;\n\n /**\n * An absolute URL is the full URL, including protocol (http/https ), the optional subdomain (e.g. www ), domain (example.com), and path (which includes the directory and slug)\n * with all segments encoded according to rules specified in [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).\n * @type {string}\n */\n this.absUrl = \"\";\n\n /**\n * @ignore\n * Current url\n * @type {string}\n */\n this.$$url = undefined;\n\n /**\n * @ignore\n * Callback to update browser url\n * @type {Function}\n */\n this.$$updateBrowser = undefined;\n }\n\n /**\n * Change path, search and hash, when called with parameter and return `$location`.\n *\n * @param {string} url New URL without base prefix (e.g. `/path?a=b#hash`)\n * @return {Location} url\n */\n setUrl(url) {\n const match = PATH_MATCH.exec(url);\n\n if (match[1] !== undefined || url === \"\") {\n this.setPath(match[1] || \"\");\n }\n\n if (match[2] !== undefined || match[1] !== undefined || url === \"\") {\n this.setSearch(match[3] || \"\");\n }\n\n this.setHash(match[5] || \"\");\n\n return this;\n }\n\n /**\n * Return URL (e.g. `/path?a=b#hash`) when called without any parameter.\n *\n * @return {string} url\n */\n getUrl() {\n return this.$$url;\n }\n\n /**\n * Change path parameter and return `$location`.\n *\n * @param {(string|number)} path New path\n * @return {Location}\n */\n setPath(path) {\n const newPath = path !== null ? path.toString() : \"\";\n\n $$path = newPath.charAt(0) === \"/\" ? newPath : `/${newPath}`;\n this.$$compose();\n\n return this;\n }\n\n /**\n *\n * Return path of current URL\n *\n * @return {string}\n */\n getPath() {\n return $$path;\n }\n\n /**\n * Changes the hash fragment when called with a parameter and returns `$location`.\n * @param {(string|number)} hash New hash fragment\n * @return {Location} hash\n */\n setHash(hash) {\n $$hash = hash !== null ? hash.toString() : \"\";\n this.$$compose();\n\n return this;\n }\n\n /**\n * Returns the hash fragment when called without any parameters.\n * @return {string} hash\n */\n getHash() {\n return $$hash;\n }\n\n /**\n * Sets the search part (as object) of current URL\n *\n * @param {string|Object} search New search params - string or hash object.\n * @param {(string|number|Array<string>|boolean)=} paramValue If search is a string or number, then paramValue will override only a single search property.\n * @returns {Object} Search object or Location object\n */\n setSearch(search, paramValue) {\n switch (arguments.length) {\n case 1:\n if (isString(search) || isNumber(search)) {\n search = search.toString();\n $$search = parseKeyValue(search);\n } else if (isObject(search)) {\n search = structuredClone(search, {});\n // remove object undefined or null properties\n entries(search).forEach(([key, value]) => {\n if (isNull(value)) delete search[key];\n });\n\n $$search = search;\n } else {\n throw $locationMinErr(\n \"isrcharg\",\n \"The first argument of the `$location#search()` call must be a string or an object.\",\n );\n }\n break;\n default:\n if (isUndefined(paramValue) || paramValue === null) {\n delete $$search[search];\n } else {\n // @ts-ignore\n $$search[search] = paramValue;\n }\n }\n\n this.$$compose();\n\n return this;\n }\n\n /**\n * Returns the search part (as object) of current URL\n *\n * @returns {Object} Search object or Location object\n */\n getSearch() {\n return $$search;\n }\n\n /**\n * @private\n * Compose url and update `url` and `absUrl` property\n */\n $$compose() {\n this.$$url = normalizePath($$path, $$search, $$hash);\n this.absUrl = this.html5\n ? this.appBaseNoFile + this.$$url.substring(1)\n : this.appBase + (this.$$url ? this.hashPrefix + this.$$url : \"\");\n urlUpdatedByLocation = true;\n setTimeout(() => this.$$updateBrowser && this.$$updateBrowser());\n }\n\n /**\n * Change the history state object when called with one parameter and return `$location`.\n * The state object is later passed to `pushState` or `replaceState`.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/History/pushState#state|History.state}\n *\n * NOTE: This method is supported only in HTML5 mode and only in browsers supporting\n * the HTML5 History API (i.e. methods `pushState` and `replaceState`). If you need to support\n * older browsers (like IE9 or Android < 4.0), don't use this method.\n * @param {any} state\n * @returns {Location}\n */\n setState(state) {\n if (!this.html5) {\n throw $locationMinErr(\n \"nostate\",\n \"History API state support is available only in HTML5 mode\",\n );\n }\n // The user might modify `stateObject` after invoking `$location.setState(stateObject)`\n // but we're changing the $$state reference to $browser.state() during the $digest\n // so the modification window is narrow.\n this.$$state = isUndefined(state) ? null : state;\n urlUpdatedByLocation = true;\n\n return this;\n }\n\n /**\n * Return the history state object\n * @returns {any}\n */\n getState() {\n return this.$$state;\n }\n\n /**\n * @param {string} url\n * @param {string} relHref\n * @returns {boolean}\n */\n parseLinkUrl(url, relHref) {\n if (this.html5) {\n if (relHref && relHref[0] === \"#\") {\n // special case for links to hash fragments:\n // keep the old url and only replace the hash fragment\n this.setHash(relHref.slice(1));\n\n return true;\n }\n let appUrl;\n\n let prevAppUrl;\n\n let rewrittenUrl;\n\n if (isDefined((appUrl = stripBaseUrl(this.appBase, url)))) {\n prevAppUrl = appUrl;\n\n if (\n this.basePrefix &&\n isDefined((appUrl = stripBaseUrl(this.basePrefix, appUrl)))\n ) {\n rewrittenUrl =\n this.appBaseNoFile + (stripBaseUrl(\"/\", appUrl) || appUrl);\n } else {\n rewrittenUrl = this.appBase + prevAppUrl;\n }\n } else if (isDefined((appUrl = stripBaseUrl(this.appBaseNoFile, url)))) {\n rewrittenUrl = this.appBaseNoFile + appUrl;\n } else if (this.appBaseNoFile === `${url}/`) {\n rewrittenUrl = this.appBaseNoFile;\n }\n\n if (rewrittenUrl) {\n this.parse(rewrittenUrl);\n }\n\n return !!rewrittenUrl;\n } else {\n if (stripHash(this.appBase) === stripHash(url)) {\n this.parse(url);\n\n return true;\n }\n\n return false;\n }\n }\n\n /**\n * Parse given HTML5 (regular) URL string into properties\n * @param {string} url HTML5 URL\n */\n parse(url) {\n if (this.html5) {\n const pathUrl = stripBaseUrl(this.appBaseNoFile, url);\n\n if (!isString(pathUrl)) {\n throw $locationMinErr(\n \"ipthprfx\",\n 'Invalid url \"{0}\", missing path prefix \"{1}\".',\n url,\n this.appBaseNoFile,\n );\n }\n\n parseAppUrl(pathUrl, true);\n\n if (!$$path) {\n $$path = \"/\";\n }\n\n this.$$compose();\n } else {\n const withoutBaseUrl =\n stripBaseUrl(this.appBase, url) ||\n stripBaseUrl(this.appBaseNoFile, url);\n\n let withoutHashUrl;\n\n if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === \"#\") {\n // The rest of the URL starts with a hash so we have\n // got either a hashbang path or a plain hash fragment\n withoutHashUrl = stripBaseUrl(this.hashPrefix, withoutBaseUrl);\n\n if (isUndefined(withoutHashUrl)) {\n // There was no hashbang prefix so we just have a hash fragment\n withoutHashUrl = withoutBaseUrl;\n }\n } else {\n // There was no hashbang path nor hash fragment:\n // If we are in HTML5 mode we use what is left as the path;\n // Otherwise we ignore what is left\n if (this.html5) {\n withoutHashUrl = withoutBaseUrl;\n } else {\n withoutHashUrl = \"\";\n\n if (isUndefined(withoutBaseUrl)) {\n this.appBase = url;\n }\n }\n }\n\n parseAppUrl(withoutHashUrl, false);\n\n $$path = removeWindowsDriveName($$path, withoutHashUrl, this.appBase);\n\n this.$$compose();\n\n /*\n * In Windows, on an anchor node on documents loaded from\n * the filesystem, the browser will return a pathname\n * prefixed with the drive name ('/C:/path') when a\n * pathname without a drive is set:\n * * a.setAttribute('href', '/foo')\n * * a.pathname === '/C:/foo' //true\n *\n * Inside of AngularTS, we're always using pathnames that\n * do not include drive names for routing.\n */\n function removeWindowsDriveName(path, urlParam, base) {\n /*\n Matches paths for file protocol on windows,\n such as /C:/foo/bar, and captures only /foo/bar.\n */\n const windowsFilePathExp = /^\\/[A-Z]:(\\/.*)/;\n\n // Get the relative path from the input URL.\n if (startsWith(urlParam, base)) {\n urlParam = urlParam.replace(base, \"\");\n }\n\n // The input URL intentionally contains a first path segment that ends with a colon.\n if (windowsFilePathExp.exec(urlParam)) {\n return path;\n }\n\n const firstPathSegmentMatch = windowsFilePathExp.exec(path);\n\n return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;\n }\n }\n }\n}\n\nexport class LocationProvider {\n constructor() {\n /** @type {string} */\n this.hashPrefixConf = \"!\";\n\n /** @type {import(\"./interface.ts\").Html5Mode} */\n this.html5ModeConf = {\n enabled: true,\n requireBase: false,\n rewriteLinks: true,\n };\n\n /** @type {Array<import(\"./interface.ts\").UrlChangeListener>} */\n this.urlChangeListeners = [];\n this.urlChangeInit = false;\n\n /** @type {History['state']} */\n this.cachedState = null;\n /** @type {History['state']} */\n this.lastHistoryState = null;\n /** @type {string} */\n this.lastBrowserUrl = window.location.href;\n this.cacheState();\n }\n\n /// ///////////////////////////////////////////////////////////\n // URL API\n /// ///////////////////////////////////////////////////////////\n\n /**\n * Updates the browser's current URL and history state.\n *\n * @param {string|undefined} url - The target URL to navigate to.\n * @param {*} [state=null] - Optional history state object to associate with the new URL.\n * @returns {LocationProvider}\n */\n setUrl(url, state) {\n if (state === undefined) {\n state = null;\n }\n\n if (url) {\n url = new URL(url).href;\n\n if (this.lastBrowserUrl === url && this.lastHistoryState === state) {\n return this;\n }\n\n this.lastBrowserUrl = url;\n this.lastHistoryState = state;\n history.pushState(state, \"\", url);\n this.cacheState();\n }\n\n return this;\n }\n\n /**\n * Returns the current URL with any empty hash (`#`) removed.\n * @return {string}\n */\n getBrowserUrl() {\n return trimEmptyHash(window.location.href);\n }\n\n /**\n * Returns the cached state.\n * @returns {History['state']} The cached state.\n */\n state() {\n return this.cachedState;\n }\n\n /**\n * Caches the current state.\n *\n * @private\n */\n cacheState() {\n const currentState = history.state ?? null;\n\n if (!equals(currentState, this.lastCachedState)) {\n this.cachedState = currentState;\n this.lastCachedState = currentState;\n this.lastHistoryState = currentState;\n }\n }\n\n /**\n * Fires the state or URL change event.\n */\n #fireStateOrUrlChange() {\n const prevLastHistoryState = this.lastHistoryState;\n\n this.cacheState();\n\n if (\n this.lastBrowserUrl === this.getBrowserUrl() &&\n prevLastHistoryState === this.cachedState\n ) {\n return;\n }\n this.lastBrowserUrl = this.getBrowserUrl();\n this.lastHistoryState = this.cachedState;\n this.urlChangeListeners.forEach((listener) => {\n listener(trimEmptyHash(window.location.href), this.cachedState);\n });\n }\n\n /**\n * Registers a callback to be called when the URL changes.\n *\n * @param {import(\"./interface.ts\").UrlChangeListener} callback - The callback function to register.\n * @returns void\n */\n #onUrlChange(callback) {\n if (!this.urlChangeInit) {\n window.addEventListener(\n \"popstate\",\n this.#fireStateOrUrlChange.bind(this),\n );\n window.addEventListener(\n \"hashchange\",\n this.#fireStateOrUrlChange.bind(this),\n );\n this.urlChangeInit = true;\n }\n this.urlChangeListeners.push(callback);\n }\n\n $get = [\n $t.$rootScope,\n $t.$rootElement,\n $t.$exceptionHandler,\n /**\n *\n * @param {ng.Scope} $rootScope\n * @param {Element} $rootElement\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @returns {Location}\n */\n ($rootScope, $rootElement, $exceptionHandler) => {\n const baseHref = getBaseHref(); // if base[href] is undefined, it defaults to ''\n\n const initialUrl = trimEmptyHash(window.location.href);\n\n let appBase;\n\n if (this.html5ModeConf.enabled) {\n if (!baseHref && this.html5ModeConf.requireBase) {\n throw $locationMinErr(\n \"nobase\",\n \"$location in HTML5 mode requires a <base> tag to be present!\",\n );\n }\n appBase = serverBase(initialUrl) + (baseHref || \"/\");\n } else {\n appBase = stripHash(initialUrl);\n }\n const appBaseNoFile = stripFile(appBase);\n\n const $location = new Location(\n appBase,\n appBaseNoFile,\n this.html5ModeConf.enabled,\n `#${this.hashPrefixConf}`,\n );\n\n $location.parseLinkUrl(initialUrl, initialUrl);\n\n $location.$$state = this.state();\n\n const IGNORE_URI_REGEXP = /^\\s*(javascript|mailto):/i;\n\n const setBrowserUrlWithFallback = (url, state) => {\n const oldUrl = $location.getUrl();\n\n const oldState = $location.$$state;\n\n try {\n this.setUrl(url, state);\n\n // Make sure $location.getState() returns referentially identical (not just deeply equal)\n // state object; this makes possible quick checking if the state changed in the digest\n // loop. Checking deep equality would be too expensive.\n $location.$$state = this.state();\n } catch (err) {\n // Restore old values if pushState fails\n $location.setUrl(/** @type {string} */ (oldUrl));\n $location.$$state = oldState;\n $exceptionHandler(err);\n }\n };\n\n $rootElement.addEventListener(\n \"click\",\n /** @param {MouseEvent} event */\n (event) => {\n const { rewriteLinks } = this.html5ModeConf;\n // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)\n // currently we open nice url link and redirect then\n\n if (\n !rewriteLinks ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey ||\n event.button === 2\n ) {\n return;\n }\n let elm = /** @type {HTMLAnchorElement} */ (event.target);\n\n // traverse the DOM up to find first A tag\n while (elm.nodeName.toLowerCase() !== \"a\") {\n // ignore rewriting if no A tag (reached root element, or no parent - removed from document)\n // @ts-ignore\n if (elm === $rootElement || !(elm = elm.parentElement)) return;\n }\n\n if (\n isString(rewriteLinks) &&\n isUndefined(elm.getAttribute(/** @type {string} */ (rewriteLinks)))\n ) {\n return;\n }\n\n let absHref = elm.href;\n\n // get the actual href attribute - see\n // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx\n const relHref =\n elm.getAttribute(\"href\") || elm.getAttribute(\"xlink:href\");\n\n if (\n isObject(absHref) &&\n absHref.toString() === \"[object SVGAnimatedString]\"\n ) {\n // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during\n // an animation.\n\n const scvAnimatedString = /** @type {unknown} */ (absHref);\n\n absHref = new URL(\n /** @type {SVGAnimatedString } */ (scvAnimatedString).animVal,\n ).href;\n }\n\n // Ignore when url is started with javascript: or mailto:\n if (IGNORE_URI_REGEXP.test(absHref)) return;\n\n if (\n absHref &&\n !elm.getAttribute(\"target\") &&\n !event.defaultPrevented\n ) {\n if ($location.parseLinkUrl(absHref, relHref)) {\n // We do a preventDefault for all urls that are part of the AngularTS application,\n // in html5mode and also without, so that we are able to abort navigation without\n // getting double entries in the location history.\n event.preventDefault();\n }\n }\n },\n );\n\n // rewrite hashbang url <> html5 url\n if ($location.absUrl !== initialUrl) {\n this.setUrl($location.absUrl, true);\n }\n\n let initializing = true;\n\n // update $location when $browser url changes\n this.#onUrlChange((newUrl, newState) => {\n if (!startsWith(newUrl, appBaseNoFile)) {\n // If we are navigating outside of the app then force a reload\n window.location.href = newUrl;\n\n return;\n }\n\n queueMicrotask(() => {\n const oldUrl = $location.absUrl;\n\n const oldState = $location.$$state;\n\n $location.parse(newUrl);\n $location.$$state = newState;\n\n const { defaultPrevented } = $rootScope.$broadcast(\n \"$locationChangeStart\",\n newUrl,\n oldUrl,\n newState,\n oldState,\n );\n\n // if the location was changed by a `$locationChangeStart` handler then stop\n // processing this location change\n if ($location.absUrl !== newUrl) return;\n\n if (defaultPrevented) {\n $location.parse(oldUrl);\n $location.$$state = oldState;\n setBrowserUrlWithFallback(oldUrl, oldState);\n } else {\n initializing = false;\n afterLocationChange(oldUrl, oldState);\n }\n });\n });\n\n // update browser\n const updateBrowser = () => {\n if (initializing || urlUpdatedByLocation) {\n urlUpdatedByLocation = false;\n\n const oldUrl = /** @type {string} */ (this.getBrowserUrl());\n\n let newUrl = $location.absUrl;\n\n const oldState = this.state();\n\n const urlOrStateChanged =\n !urlsEqual(oldUrl, newUrl) ||\n ($location.html5 && oldState !== $location.$$state);\n\n if (initializing || urlOrStateChanged) {\n initializing = false;\n\n setTimeout(() => {\n newUrl = $location.absUrl;\n\n const { defaultPrevented } = $rootScope.$broadcast(\n \"$locationChangeStart\",\n $location.absUrl,\n oldUrl,\n $location.$$state,\n oldState,\n );\n\n // if the location was changed by a `$locationChangeStart` handler then stop\n // processing this location change\n if ($location.absUrl !== newUrl) return;\n\n if (defaultPrevented) {\n $location.parse(oldUrl);\n $location.$$state = oldState;\n } else {\n if (urlOrStateChanged) {\n setBrowserUrlWithFallback(\n newUrl,\n oldState === $location.$$state ? null : $location.$$state,\n );\n }\n afterLocationChange(oldUrl, oldState);\n }\n });\n }\n }\n };\n\n $location.$$updateBrowser = updateBrowser;\n updateBrowser();\n $rootScope.$on(\"$updateBrowser\", updateBrowser);\n\n return $location;\n\n function afterLocationChange(oldUrl, oldState) {\n $rootScope.$broadcast(\n \"$locationChangeSuccess\",\n $location.absUrl,\n oldUrl,\n $location.$$state,\n oldState,\n );\n }\n },\n ];\n}\n\n/**\n * ///////////////////////////\n * PRIVATE HELPERS\n * ///////////////////////////\n */\n\n/**\n * @ignore\n * Encodes a URL path by encoding each path segment individually using `encodeUriSegment`,\n * while preserving forward slashes (`/`) as segment separators.\n *\n * This function first decodes any existing percent-encodings (such as `%20` or `%2F`)\n * in each segment to prevent double encoding, except for encoded forward slashes (`%2F`),\n * which are replaced with literal slashes before decoding to keep path boundaries intact.\n *\n * After decoding, each segment is re-encoded with `encodeUriSegment` according to RFC 3986,\n * encoding only characters that must be encoded in a path segment.\n *\n * The encoded segments are then rejoined with `/` to form the encoded path.\n *\n * @param {string} path - The URL path string to encode. May contain multiple segments separated by `/`.\n * @returns {string} The encoded path, where each segment is encoded, but forward slashes are preserved.\n *\n * @example\n * encodePath(\"user profile/images/pic 1.jpg\")\n * // returns \"user%20profile/images/pic%201.jpg\"\n *\n * @example\n * encodePath(\"folder1%2Fsub/folder2\")\n * // returns \"folder1%2Fsub/folder2\"\n */\nexport function encodePath(path) {\n const segments = path.split(\"/\");\n\n let i = segments.length;\n\n while (i--) {\n // Decode any existing encodings (e.g. %20, %2F) to prevent double-encoding\n // But keep slashes intact (they were split on)\n const decodedSegment = decodeURIComponent(\n segments[i].replace(/%2F/gi, \"/\"),\n );\n\n segments[i] = encodeUriSegment(decodedSegment);\n }\n\n return segments.join(\"/\");\n}\n\n/**\n * @ignore\n * Decodes each segment of a URL path.\n *\n * Splits the input path by \"/\", decodes each segment using decodeURIComponent,\n * and if html5Mode is enabled, re-encodes any forward slashes inside segments\n * as \"%2F\" to avoid confusion with path separators.\n *\n * @param {string} path - The URL path to decode.\n * @param {boolean} html5Mode - If true, encodes forward slashes in segments as \"%2F\".\n * @returns {string} The decoded path with segments optionally encoding slashes.\n */\nexport function decodePath(path, html5Mode) {\n const segments = path.split(\"/\");\n\n let i = segments.length;\n\n while (i--) {\n segments[i] = decodeURIComponent(segments[i]);\n\n if (html5Mode) {\n // encode forward slashes to prevent them from being mistaken for path separators\n segments[i] = segments[i].replace(/\\//g, \"%2F\");\n }\n }\n\n return segments.join(\"/\");\n}\n\n/**\n * @ignore\n * Normalizes a URL path by encoding the path segments, query parameters, and hash fragment.\n *\n * - Path segments are encoded using `encodePath`, which encodes each segment individually.\n * - Query parameters (`searchValue`) are converted to a query string using `toKeyValue`.\n * - Hash fragment (`hashValue`) is encoded using `encodeUriSegment` and prefixed with `#`.\n *\n * This function returns a fully constructed URL path with optional query and hash components.\n *\n * @param {string} pathValue - The base URL path (e.g., \"folder/item name\").\n * @param {Object.<string, any> | string | null} searchValue - An object or string representing query parameters.\n * - If an object, it can contain strings, numbers, booleans, or arrays of values.\n * - If a string, it is assumed to be a raw query string.\n * - If null or undefined, no query string is added.\n * @param {string | null} hashValue - The URL fragment (everything after `#`). If null or undefined, no hash is added.\n *\n * @returns {string} The normalized URL path including encoded path, optional query string, and optional hash.\n *\n * @example\n * normalizePath(\"products/list\", { category: \"books\", page: 2 }, \"section1\")\n * // returns \"products/list?category=books&page=2#section1\"\n *\n * @example\n * normalizePath(\"user profile/images\", null, null)\n * // returns \"user%20profile/images\"\n */\nexport function normalizePath(pathValue, searchValue, hashValue) {\n const search = toKeyValue(searchValue);\n\n const hash = hashValue ? `#${encodeUriSegment(hashValue)}` : \"\";\n\n const path = encodePath(pathValue);\n\n return path + (search ? `?${search}` : \"\") + hash;\n}\n\n/**\n * @ignore\n * Parses the application URL and updates the location object with path, search, and hash.\n *\n * @param {string} url - The URL string to parse.\n * @param {boolean} html5Mode - Whether HTML5 mode is enabled (affects decoding).\n * @throws Will throw an error if the URL starts with invalid slashes.\n */\nexport function parseAppUrl(url, html5Mode) {\n if (/^\\s*[\\\\/]{2,}/.test(url)) {\n throw $locationMinErr(\"badpath\", 'Invalid url \"{0}\".', url);\n }\n\n const prefixed = url.charAt(0) !== \"/\";\n\n if (prefixed) {\n url = `/${url}`;\n }\n const match = urlResolve(url);\n\n const path =\n prefixed && match.pathname.charAt(0) === \"/\"\n ? match.pathname.substring(1)\n : match.pathname;\n\n $$path = decodePath(path, html5Mode);\n $$search = parseKeyValue(match.search);\n $$hash = decodeURIComponent(match.hash);\n\n // make sure path starts with '/';\n if ($$path && $$path.charAt(0) !== \"/\") {\n $$path = `/${$$path}`;\n }\n}\n\n/**\n * @ignore\n * Returns the substring of `url` after the `base` string if `url` starts with `base`.\n * Returns `undefined` if `url` does not start with `base`.\n * @param {string} base\n * @param {string} url\n * @returns {string|undefined} returns text from `url` after `base` or `undefined` if it does not begin with\n * the expected string.\n */\nexport function stripBaseUrl(base, url) {\n if (startsWith(url, base)) {\n return url.substring(base.length);\n }\n\n return undefined;\n}\n\n/**\n * @ignore\n * Removes the hash fragment (including the '#') from the given URL string.\n *\n * @param {string} url - The URL string to process.\n * @returns {string} The URL without the hash fragment.\n */\nexport function stripHash(url) {\n const index = url.indexOf(\"#\");\n\n return index === -1 ? url : url.substring(0, index);\n}\n\n/**\n * @ignore\n * Removes the file name (and any hash) from a URL, returning the base directory path.\n *\n * For example:\n * - Input: \"https://example.com/path/to/file.js\"\n * Output: \"https://example.com/path/to/\"\n *\n * - Input: \"https://example.com/path/to/file.js#section\"\n * Output: \"https://example.com/path/to/\"\n *\n * @param {string} url - The URL from which to strip the file name and hash.\n * @returns {string} The base path of the URL, ending with a slash.\n */\nexport function stripFile(url) {\n return url.substring(0, stripHash(url).lastIndexOf(\"/\") + 1);\n}\n\n/**\n * @ignore\n * Extracts the base server URL (scheme, host, and optional port) from a full URL.\n *\n * If no path is present, returns the full URL.\n *\n * For example:\n * - Input: \"https://example.com/path/to/file\"\n * Output: \"https://example.com\"\n *\n * - Input: \"http://localhost:3000/api/data\"\n * Output: \"http://localhost:3000\"\n *\n * @param {string} url - The full URL to extract the server base from.\n * @returns {string} The server base, including scheme and host (and port if present).\n */\nexport function serverBase(url) {\n const start = url.indexOf(\"//\") + 2;\n\n const slashIndex = url.indexOf(\"/\", start);\n\n return slashIndex === -1 ? url : url.substring(0, slashIndex);\n}\n\n/**\n * @ignore\n * Determine if two URLs are equal despite potential differences in encoding,\n * trailing slashes, or empty hash fragments, such as between $location.absUrl() and $browser.url().\n *\n * @param {string} x - First URL to compare.\n * @param {string} y - Second URL to compare.\n * @returns {boolean} True if URLs are equivalent after normalization.\n */\nexport function urlsEqual(x, y) {\n return normalizeUrl(x) === normalizeUrl(y);\n}\n\n/**\n * @ignore\n * Normalize a URL by resolving it via a DOM anchor element,\n * removing trailing slashes (except root), and trimming empty hashes.\n *\n * @param {string} url - URL to normalize.\n * @returns {string} Normalized URL string.\n */\nfunction normalizeUrl(url) {\n const anchor = document.createElement(\"a\");\n\n anchor.href = url;\n\n let normalized = anchor.href;\n\n // Remove trailing slash unless it's root (e.g., https://example.com/)\n if (normalized.endsWith(\"/\") && !/^https?:\\/\\/[^/]+\\/$/.test(normalized)) {\n normalized = normalized.slice(0, -1);\n }\n\n // Remove empty hash (e.g., https://example.com/foo# -> https://example.com/foo)\n if (normalized.endsWith(\"#\")) {\n normalized = normalized.slice(0, -1);\n }\n\n return normalized;\n}\n","import { isError } from \"../../shared/utils.js\";\n\n/**\n * Configuration provider for `$log` service\n */\nexport class LogProvider {\n /** @private */\n constructor() {\n /** @type {boolean} */\n this.debug = false;\n /** @private @type {import(\"./interface.ts\").LogServiceFactory | null} */\n this._override = null;\n }\n\n /**\n * Override the default {@link LogService} implemenation\n * @param {import(\"./interface.ts\").LogServiceFactory} fn\n */\n setLogger(fn) {\n this._override = fn;\n }\n\n /** @private */\n formatError(arg) {\n if (isError(arg)) {\n if (arg.stack) {\n arg =\n arg.message && arg.stack.indexOf(arg.message) === -1\n ? `Error: ${arg.message}\\n${arg.stack}`\n : arg.stack;\n } else if (arg.sourceURL) {\n arg = `${arg.message}\\n${arg.sourceURL}:${arg.line}`;\n }\n }\n\n return arg;\n }\n\n /**\n * @private\n * @param {string} type\n */\n consoleLog(type) {\n const console = window.console || {};\n\n const logFn =\n console[type] ||\n console.log ||\n (() => {\n /* empty */\n });\n\n return (...args) => {\n const formattedArgs = args.map((arg) => this.formatError(arg));\n\n return logFn.apply(console, formattedArgs);\n };\n }\n\n /**\n * @returns {ng.LogService}\n */\n $get() {\n if (this._override) {\n return this._override();\n }\n\n return {\n log: this.consoleLog(\"log\"),\n info: this.consoleLog(\"info\"),\n warn: this.consoleLog(\"warn\"),\n error: this.consoleLog(\"error\"),\n debug: (() => {\n const fn = this.consoleLog(\"debug\");\n\n return (...args) => {\n if (this.debug) {\n fn.apply(this, args);\n }\n };\n })(),\n };\n }\n}\n","import {\n assert,\n concat,\n entries,\n hasOwn,\n isArray,\n isDefined,\n isFunction,\n isObject,\n isProxy,\n isProxySymbol,\n isString,\n isUndefined,\n keys,\n nextUid,\n} from \"../../shared/utils.js\";\nimport { ASTType } from \"../parse/ast-type.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\n\n/**\n * Decorator for excluding objects from scope observability\n */\nexport const NONSCOPE = \"$nonscope\";\n\n/**\n * @type {number}\n */\nlet uid = 0;\n\nexport function nextId() {\n uid += 1;\n\n return uid;\n}\n\n/**\n * @type {ng.ParseService}\n */\nlet $parse;\n\n/**@type {ng.ExceptionHandlerService} */\nlet $exceptionHandler;\n\nexport const $postUpdateQueue = [];\n\nexport let rootScope;\n\nexport class RootScopeProvider {\n constructor() {\n rootScope = this.rootScope = createScope();\n }\n\n $get = [\n $t.$exceptionHandler,\n $t.$parse,\n /**\n * @param {ng.ExceptionHandlerService} exceptionHandler\n * @param {ng.ParseService} parse\n */\n (exceptionHandler, parse) => {\n $exceptionHandler = exceptionHandler;\n $parse = parse;\n\n return this.rootScope;\n },\n ];\n}\n\n/**\n * Creates a deep proxy for the target object, intercepting property changes\n * and recursively applying proxies to nested objects.\n *\n * @param {Object} target - The object to be wrapped in a proxy.\n * @param {Scope} [context] - The context for the handler, used to track listeners.\n * @returns {Scope} - A proxy that intercepts operations on the target object,\n * or the original value if the target is not an object.\n */\nexport function createScope(target = {}, context) {\n if (!isObject(target) || isNonScope(target)) return target;\n\n const proxy = new Proxy(target, context || new Scope());\n\n const keyList = keys(target);\n\n const ctorNonScope = isArray(target.constructor?.$nonscope)\n ? target.constructor.$nonscope\n : null;\n\n const instNonScope = isArray(target.$nonscope) ? target.$nonscope : null;\n\n for (let i = 0, l = keyList.length; i < l; i++) {\n const key = keyList[i];\n\n if (ctorNonScope?.includes(key) || instNonScope?.includes(key)) continue;\n target[key] = createScope(target[key], proxy.$handler);\n }\n\n return proxy;\n}\n\nconst global = globalThis;\n\nconst proto = Object.prototype;\n\nconst { toString } = proto;\n\nconst wStr = \"[object Window]\";\n\n/**\n * @ignore\n * Checks if a target should be excluded from scope observability\n * @param {any} target\n * @returns {boolean}\n */\nexport function isNonScope(target) {\n if (\n target[NONSCOPE] === true ||\n (target.constructor && target.constructor[NONSCOPE]) === true ||\n target === global.window ||\n target === global.document ||\n target === global.self ||\n target === global.frames ||\n target instanceof Window ||\n target instanceof Document ||\n target instanceof Element ||\n target instanceof Node ||\n target instanceof EventTarget ||\n target instanceof Promise ||\n target instanceof HTMLCollection ||\n target instanceof NodeList ||\n target instanceof Event\n ) {\n return true;\n }\n\n try {\n return toString.call(target) === wStr;\n } catch {\n return false;\n }\n}\n\n/**\n * Scope class for the Proxy. It intercepts operations like property access (get)\n * and property setting (set), and adds support for deep change tracking and\n * observer-like behavior.\n * @extends {Record<string, any>}\n */\nexport class Scope {\n /**\n * Initializes the handler with the target object and a context.\n *\n * @param {Scope} [context] - The context containing listeners.\n * @param {Scope} [parent] - Custom parent.\n */\n constructor(context, parent) {\n this.context = context\n ? context.context\n ? context.context\n : context\n : undefined;\n\n /** @type {Map<string, Array<import('./interface.ts').Listener>>} Watch listeners */\n this.watchers = context ? context.watchers : new Map();\n\n /** @type {Map<String, Function[]>} Event listeners */\n this.$$listeners = new Map();\n\n /** @type {Map<string, Array<import('./interface.ts').Listener>>} Watch listeners from other proxies */\n this.foreignListeners = context ? context.foreignListeners : new Map();\n\n /** @type {Set<ProxyConstructor>} */\n this.foreignProxies = context ? context.foreignProxies : new Set();\n\n /** @type {WeakMap<Object, Array<string>>} */\n this.objectListeners = context ? context.objectListeners : new WeakMap();\n\n /** @type {Map<Function, {oldValue: any, fn: Function}>} */\n this.functionListeners = context ? context.functionListeners : new Map();\n\n /** Current proxy being operated on */\n this.$proxy = null;\n\n /** @type {Scope} The actual proxy */\n this.$handler = /** @type {Scope} */ (this);\n\n /** @type {*} Current target being called on */\n this.$target = null;\n\n /** @type {*} Value wrapped by the proxy */\n this.$value = null;\n\n /**\n * @type {Scope[]}\n */\n this.$children = [];\n\n /**\n * @type {number} Unique model ID (monotonically increasing) useful for debugging.\n */\n this.$id = nextId();\n\n /**\n * @type {Scope}\n */\n this.$root = context ? context.$root : /** @type {Scope} */ (this);\n\n this.$parent = parent\n ? parent\n : /** @type {Scope} */ (this).$root === /** @type {Scope} */ (this)\n ? null\n : context;\n\n this.filters = [];\n\n /** @type {boolean} */\n this.$$destroyed = false;\n\n this.scheduled = [];\n\n this.$scopename = undefined;\n\n /** @private */\n this.propertyMap = {\n $watch: this.$watch.bind(this),\n $new: this.$new.bind(this),\n $newIsolate: this.$newIsolate.bind(this),\n $destroy: this.$destroy.bind(this),\n $flushQueue: this.$flushQueue.bind(this),\n $eval: this.$eval.bind(this),\n $apply: this.$apply.bind(this),\n $postUpdate: this.$postUpdate.bind(this),\n $isRoot: this.#isRoot.bind(this),\n $on: this.$on.bind(this),\n $emit: this.$emit.bind(this),\n $broadcast: this.$broadcast.bind(this),\n $transcluded: this.$transcluded.bind(this),\n $handler: /** @type {Scope} */ (this),\n $merge: this.$merge.bind(this),\n $getById: this.$getById.bind(this),\n $searchByName: this.$searchByName.bind(this),\n $proxy: this.$proxy,\n $parent: this.$parent,\n $root: this.$root,\n $children: this.$children,\n $id: this.$id,\n $scopename: this.$scopename,\n };\n }\n\n /**\n * Intercepts and handles property assignments on the target object. If a new value is\n * an object, it will be recursively proxied.\n *\n * @param {Object} target - The target object.\n * @param {string} property - The name of the property being set.\n * @param {*} value - The new value being assigned to the property.\n * @param {Proxy} proxy - The proxy intercepting property access\n * @returns {boolean} - Returns true to indicate success of the operation.\n */\n set(target, property, value, proxy) {\n if (property === \"undefined\") {\n return false;\n }\n\n if (property === \"$scopename\") {\n this.$scopename = value;\n\n return true;\n }\n\n if (\n (target.constructor?.$nonscope &&\n isArray(target.constructor.$nonscope) &&\n target.constructor.$nonscope.includes(property)) ||\n (target.$nonscope &&\n isArray(target.$nonscope) &&\n target.$nonscope.includes(property))\n ) {\n target[property] = value;\n\n return true;\n }\n\n this.$proxy = proxy;\n this.$target = target;\n const oldValue = target[property];\n\n // Handle NaNs\n if (\n oldValue !== undefined &&\n Number.isNaN(oldValue) &&\n Number.isNaN(value)\n ) {\n return true;\n }\n\n if (oldValue && oldValue[isProxySymbol]) {\n if (isArray(value)) {\n if (oldValue !== value) {\n const listeners = this.watchers.get(property);\n\n if (listeners) {\n this.#scheduleListener(listeners);\n }\n\n const foreignListeners = this.foreignListeners.get(property);\n\n if (foreignListeners) {\n this.#scheduleListener(foreignListeners);\n }\n }\n\n if (this.objectListeners.get(target[property])) {\n this.objectListeners.delete(target[property]);\n }\n target[property] = createScope(value, this);\n this.objectListeners.set(target[property], [property]);\n\n return true;\n }\n\n if (isObject(value)) {\n if (hasOwn(target, property)) {\n const keyList = keys(oldValue);\n\n for (const k of keyList) {\n if (!value[k]) delete oldValue[k];\n }\n }\n\n if (oldValue !== value) {\n const listeners = this.watchers.get(property);\n\n if (listeners) {\n this.#scheduleListener(listeners);\n }\n\n const foreignListeners = this.foreignListeners.get(property);\n\n if (foreignListeners) {\n this.#scheduleListener(foreignListeners);\n }\n\n this.#checkeListenersForAllKeys(value);\n }\n target[property] = createScope(value, this);\n\n //setDeepValue(target[property], value);\n return true;\n }\n\n if (isUndefined(value)) {\n let called = false;\n\n const keyList = keys(oldValue.$target);\n\n const tgt = oldValue.$target;\n\n let i = 0;\n\n for (i; i < keyList.length; i++) {\n const k = keyList[i];\n\n const v = tgt[k];\n\n if (v && v[isProxySymbol]) {\n called = true;\n }\n delete oldValue[k];\n }\n\n target[property] = undefined;\n\n if (!called) {\n const listeners = this.watchers.get(property);\n\n if (listeners) {\n this.#scheduleListener(listeners);\n }\n }\n\n return true;\n }\n\n if (isDefined(value)) {\n target[property] = value;\n const listeners = this.watchers.get(property);\n\n if (listeners) {\n this.#scheduleListener(listeners);\n }\n\n if (isArray(target)) {\n if (this.objectListeners.has(proxy) && property !== \"length\") {\n const keyList = this.objectListeners.get(proxy);\n\n for (let i = 0, l = keyList.length; i < l; i++) {\n const currentListeners = this.watchers.get(keyList[i]);\n\n if (currentListeners) this.#scheduleListener(currentListeners);\n }\n decodeURI;\n }\n }\n\n return true;\n }\n\n return true;\n } else {\n if (isUndefined(target[property]) && isProxy(value)) {\n this.foreignProxies.add(value);\n target[property] = value;\n\n if (!this.watchers.has(property)) {\n return true;\n }\n }\n\n if (isUndefined(value)) {\n target[property] = value;\n } else {\n target[property] = createScope(value, this);\n }\n\n if (oldValue !== value) {\n let expectedTarget = this.$target;\n\n const listeners = [];\n\n // Handle the case where we need to start observing object after a watcher has been set\n if (isUndefined(oldValue) && isObject(target[property])) {\n if (!this.objectListeners.has(target[property])) {\n this.objectListeners.set(target[property], [property]);\n }\n const keyList = keys(value);\n\n for (let i = 0, l = keyList.length; i < l; i++) {\n const key = keyList[i];\n\n const keyListeners = this.watchers.get(key);\n\n if (keyListeners) {\n for (let j = 0, jl = keyListeners.length; j < jl; j++) {\n listeners.push(keyListeners[j]);\n }\n }\n }\n expectedTarget = value;\n }\n\n if (isArray(target)) {\n const lengthListeners = this.watchers.get(\"length\");\n\n if (lengthListeners) {\n for (let i = 0, l = lengthListeners.length; i < l; i++) {\n listeners.push(lengthListeners[i]);\n }\n }\n }\n\n const propListeners = this.watchers.get(property);\n\n if (propListeners) {\n for (let i = 0, l = propListeners.length; i < l; i++) {\n listeners.push(propListeners[i]);\n }\n }\n\n if (listeners.length > 0) {\n this.#scheduleListener(listeners, (list) => {\n const scheduled = [];\n\n for (let i = 0, l = list.length; i < l; i++) {\n const x = list[i];\n\n if (!x.watchProp) {\n scheduled.push(x);\n continue;\n }\n\n const wrapperExpr = x.watchProp.split(\".\").slice(0, -1).join(\".\");\n\n const expectedHandler = $parse(wrapperExpr)(\n x.originalTarget,\n )?.$handler;\n\n if (expectedTarget === expectedHandler?.$target) {\n scheduled.push(x);\n }\n }\n\n return scheduled;\n });\n }\n\n let foreignListeners = this.foreignListeners.get(property);\n\n if (!foreignListeners && this.$parent?.foreignListeners) {\n foreignListeners = this.$parent.foreignListeners.get(property);\n }\n\n if (foreignListeners) {\n let scheduled = foreignListeners;\n\n // filter for repeaters\n const hashKey = this.$target.$$hashKey;\n\n if (hashKey) {\n scheduled = [];\n\n for (let i = 0, l = foreignListeners.length; i < l; i++) {\n const listener = foreignListeners[i];\n\n if (listener.originalTarget.$$hashKey === hashKey) {\n scheduled.push(listener);\n }\n }\n }\n\n if (scheduled.length > 0) {\n this.#scheduleListener(scheduled);\n }\n }\n }\n\n if (this.objectListeners.has(proxy) && property !== \"length\") {\n const keyList = this.objectListeners.get(proxy);\n\n for (let i = 0, l = keyList.length; i < l; i++) {\n const key = keyList[i];\n\n const listeners = this.watchers.get(key);\n\n if (listeners && this.scheduled !== listeners) {\n this.#scheduleListener(listeners);\n }\n }\n }\n\n return true;\n }\n }\n\n /**\n * Intercepts property access on the target object. It checks for specific\n * properties (`watch` and `sync`) and binds their methods. For other properties,\n * it returns the value directly.\n *\n * @param {Object} target - The target object.\n * @param {string|number|symbol} property - The name of the property being accessed.\n * @param {Proxy} proxy - The proxy object being invoked\n * @returns {*} - The value of the property or a method if accessing `watch` or `sync`.\n */\n get(target, property, proxy) {\n if (property === \"$scopename\" && this.$scopename) return this.$scopename;\n\n if (property === \"$$watchersCount\") return calculateWatcherCount(this);\n\n if (property === isProxySymbol) return true;\n\n if (target[property] && isProxy(target[property])) {\n this.$proxy = target[property];\n } else {\n this.$proxy = proxy;\n }\n\n this.propertyMap.$target = target;\n this.propertyMap.$proxy = proxy;\n\n if (\n isArray(target) &&\n [\"pop\", \"shift\", \"unshift\"].includes(/** @type { string } */ (property))\n ) {\n if (this.objectListeners.has(proxy)) {\n const keyList = this.objectListeners.get(proxy);\n\n for (let i = 0, l = keyList.length; i < l; i++) {\n const key = keyList[i];\n\n const listeners = this.watchers.get(key);\n\n if (listeners) {\n this.scheduled = listeners;\n }\n }\n }\n\n if (property === \"unshift\") {\n this.#scheduleListener(this.scheduled);\n }\n }\n\n if (hasOwn(this.propertyMap, property)) {\n this.$target = target;\n\n return this.propertyMap[property];\n } else {\n // we are a simple getter\n return target[property];\n }\n }\n\n deleteProperty(target, property) {\n // Currently deletes $model\n if (target[property] && target[property][isProxySymbol]) {\n target[property] = undefined;\n\n const listeners = this.watchers.get(property);\n\n if (listeners) {\n this.#scheduleListener(listeners);\n }\n\n if (this.objectListeners.has(this.$proxy)) {\n const keyList = this.objectListeners.get(this.$proxy);\n\n for (let i = 0, l = keyList.length; i < l; i++) {\n const key = keyList[i];\n\n const currentListeners = this.watchers.get(key);\n\n if (currentListeners) this.#scheduleListener(currentListeners);\n }\n }\n\n if (this.scheduled) {\n this.#scheduleListener(this.scheduled);\n this.scheduled = [];\n }\n\n return true;\n }\n\n delete target[property];\n\n if (this.objectListeners.has(this.$proxy)) {\n const keyList = this.objectListeners.get(this.$proxy);\n\n for (let i = 0, l = keyList.length; i < l; i++) {\n const key = keyList[i];\n\n const listeners = this.watchers.get(key);\n\n if (listeners) this.#scheduleListener(listeners);\n }\n } else {\n const listeners = this.watchers.get(property);\n\n if (listeners) {\n this.#scheduleListener(listeners, target[property]);\n }\n }\n\n return true;\n }\n\n /** @internal **/\n #checkeListenersForAllKeys(value) {\n if (isUndefined(value)) {\n return;\n }\n keys(value).forEach((k) => {\n const listeners = this.watchers.get(k);\n\n if (listeners) {\n this.#scheduleListener(listeners);\n }\n\n if (isObject(value[k])) {\n this.#checkeListenersForAllKeys(value[k]);\n }\n });\n }\n\n /**\n * @param {import('./interface.ts').Listener[]} listeners\n * @param {Function} filter\n */\n #scheduleListener(listeners, filter = (val) => val) {\n queueMicrotask(() => {\n let index = 0;\n\n const filteredListeners = filter(listeners);\n\n while (index < filteredListeners.length) {\n const listener = filteredListeners[index];\n\n if (listener.foreignListener) {\n listener.foreignListener.#notifyListener(listener, this.$target);\n } else {\n this.#notifyListener(listener, this.$target);\n }\n index++;\n }\n });\n }\n\n /**\n * Registers a watcher for a property along with a listener function. The listener\n * function is invoked when changes to that property are detected.\n *\n * @param {string} watchProp - An expression to be watched in the context of this model.\n * @param {ng.ListenerFn} [listenerFn] - A function to execute when changes are detected on watched context.\n * @param {boolean} [lazy] - A flag to indicate if the listener should be invoked immediately. Defaults to false.\n */\n $watch(watchProp, listenerFn, lazy = false) {\n assert(isString(watchProp), \"Watched property required\");\n watchProp = watchProp.trim();\n const get = $parse(watchProp);\n\n // Constant are immediately passed to listener function\n if (get.constant) {\n if (listenerFn) {\n queueMicrotask(() => {\n let res = get();\n\n while (isFunction(res)) {\n res = res();\n }\n listenerFn(res, this.$target);\n });\n }\n\n return () => {\n /* empty */\n };\n }\n\n /** @type {ng.Listener} */\n const listener = {\n originalTarget: this.$target,\n listenerFn,\n watchFn: get,\n scopeId: this.$id,\n id: nextUid(),\n property: [],\n };\n\n // simplest case\n let key = get.decoratedNode.body[0].expression.name;\n\n const keySet = [];\n\n const { type } = get.decoratedNode.body[0].expression;\n\n switch (type) {\n // 3\n case ASTType._AssignmentExpression:\n // assignment calls without listener functions\n if (!listenerFn) {\n let res = get(this.$target);\n\n while (isFunction(res)) {\n res = res(this.$target);\n }\n\n return undefined;\n }\n key = get.decoratedNode.body[0].expression.left.name;\n break;\n // 4\n case ASTType._ConditionalExpression: {\n key = get.decoratedNode.body[0].expression.toWatch[0]?.test?.name;\n listener.property.push(key);\n break;\n }\n // 5\n case ASTType._LogicalExpression: {\n const keyList = [\n get.decoratedNode.body[0].expression.left.toWatch[0]?.name,\n get.decoratedNode.body[0].expression.right.toWatch[0]?.name,\n ];\n\n for (let i = 0, l = keyList.length; i < l; i++) {\n const registerKey = keyList[i];\n\n if (registerKey) this.#registerKey(registerKey, listener);\n }\n\n return () => {\n for (let i = 0, l = keyList.length; i < l; i++) {\n const deregisterKey = keyList[i];\n\n this.#deregisterKey(deregisterKey, listener.id);\n }\n };\n }\n // 6\n case ASTType._BinaryExpression: {\n if (get.decoratedNode.body[0].expression.isPure) {\n const expr = get.decoratedNode.body[0].expression.toWatch[0];\n\n key = expr.property ? expr.property.name : expr.name;\n\n if (!key) {\n throw new Error(\"Unable to determine key\");\n }\n listener.property.push(key);\n break;\n } else {\n const { toWatch } = get.decoratedNode.body[0].expression;\n\n for (let i = 0, l = toWatch.length; i < l; i++) {\n const x = toWatch[i];\n\n const registerKey = x.property ? x.property.name : x.name;\n\n if (!registerKey) throw new Error(\"Unable to determine key\");\n\n this.#registerKey(registerKey, listener);\n this.#scheduleListener([listener]);\n }\n\n // Return deregistration function\n return () => {\n for (let i = 0, l = toWatch.length; i < l; i++) {\n const x = toWatch[i];\n\n const deregisterKey = x.property ? x.property.name : x.name;\n\n this.#deregisterKey(deregisterKey, listener.id);\n }\n };\n }\n }\n // 7\n case ASTType._UnaryExpression: {\n const expr = get.decoratedNode.body[0].expression.toWatch[0];\n\n key = expr.property ? expr.property.name : expr.name;\n\n if (!key) {\n throw new Error(\"Unable to determine key\");\n }\n listener.property.push(key);\n break;\n }\n // 8 function\n case ASTType._CallExpression: {\n const { toWatch } = get.decoratedNode.body[0].expression;\n\n for (let i = 0, l = toWatch.length; i < l; i++) {\n const x = toWatch[i];\n\n if (!isDefined(x)) continue;\n this.#registerKey(x.name, listener);\n this.#scheduleListener([listener]);\n }\n\n return () => {\n for (let i = 0, l = toWatch.length; i < l; i++) {\n const x = toWatch[i];\n\n if (!isDefined(x)) continue;\n this.#deregisterKey(x.name, listener.id);\n }\n };\n }\n\n // 9\n case ASTType._MemberExpression: {\n key = get.decoratedNode.body[0].expression.property.name;\n\n // array watcher\n if (!key) {\n key = get.decoratedNode.body[0].expression.object.name;\n }\n\n listener.property.push(key);\n\n if (watchProp !== key) {\n // Handle nested expression call\n listener.watchProp = watchProp;\n\n const potentialProxy = $parse(\n watchProp.split(\".\").slice(0, -1).join(\".\"),\n )(/** @type {Scope} */ (listener.originalTarget));\n\n if (potentialProxy && this.foreignProxies.has(potentialProxy)) {\n potentialProxy.$handler.#registerForeignKey(key, listener);\n potentialProxy.$handler.#scheduleListener([listener]);\n\n return () => {\n return potentialProxy.$handler.#deregisterKey(key, listener.id);\n };\n }\n }\n break;\n }\n\n // 10\n case ASTType._Identifier: {\n listener.property.push(get.decoratedNode.body[0].expression.name);\n break;\n }\n\n // 12\n case ASTType._ArrayExpression: {\n const { elements } = get.decoratedNode.body[0].expression;\n\n for (let i = 0, l = elements.length; i < l; i++) {\n const x = elements[i];\n\n const registerKey =\n x.type === ASTType._Literal ? x.value : x.toWatch[0]?.name;\n\n if (!registerKey) continue;\n\n this.#registerKey(registerKey, listener);\n this.#scheduleListener([listener]);\n }\n\n return () => {\n for (let i = 0, l = elements.length; i < l; i++) {\n const x = elements[i];\n\n const deregisterKey =\n x.type === ASTType._Literal ? x.value : x.toWatch[0]?.name;\n\n if (!deregisterKey) continue;\n\n this.#deregisterKey(deregisterKey, listener.id);\n }\n };\n }\n\n // 14\n case ASTType._ObjectExpression: {\n const { properties } = get.decoratedNode.body[0].expression;\n\n for (let i = 0, l = properties.length; i < l; i++) {\n const prop = properties[i];\n\n let currentKey;\n\n if (prop.key.isPure === false) {\n currentKey = prop.key.name;\n } else if (prop.value?.name) {\n currentKey = prop.value.name;\n } else {\n const target = get.decoratedNode.body[0].expression.toWatch[0];\n\n currentKey = target.property ? target.property.name : target.name;\n }\n\n if (currentKey) {\n keySet.push(currentKey);\n listener.property.push(currentKey);\n }\n }\n break;\n }\n default: {\n throw new Error(`Unsupported type ${type}`);\n }\n }\n\n // if the target is an object, then start observing it\n const listenerObject = listener.watchFn(this.$target);\n\n if (isObject(listenerObject)) {\n this.objectListeners.set(listenerObject, [key]);\n }\n\n if (keySet.length > 0) {\n for (let i = 0, l = keySet.length; i < l; i++) {\n this.#registerKey(keySet[i], listener);\n }\n } else {\n this.#registerKey(key, listener);\n }\n\n if (!lazy) {\n this.#scheduleListener([listener]);\n }\n\n return () => {\n if (keySet.length > 0) {\n let res = true;\n\n for (let i = 0, l = keySet.length; i < l; i++) {\n const success = this.#deregisterKey(keySet[i], listener.id);\n\n if (!success) {\n res = false;\n }\n }\n\n return res;\n } else {\n return this.#deregisterKey(key, listener.id);\n }\n };\n }\n\n $new(childInstance) {\n let child;\n\n if (childInstance) {\n if (Object.getPrototypeOf(childInstance) === Object.prototype) {\n Object.setPrototypeOf(childInstance, this.$target);\n } else {\n if (Object.getPrototypeOf(childInstance) === this.$target) {\n Object.setPrototypeOf(childInstance, this.$target);\n } else {\n Object.setPrototypeOf(\n Object.getPrototypeOf(childInstance) || childInstance,\n this.$target,\n );\n }\n }\n\n child = childInstance;\n } else {\n child = Object.create(this.$target);\n }\n\n const proxy = new Proxy(child, new Scope(this));\n\n this.$children.push(proxy);\n\n return proxy;\n }\n\n $newIsolate(instance) {\n const child = instance ? Object.create(instance) : Object.create(null);\n\n const proxy = new Proxy(child, new Scope(this, this.$root));\n\n this.$children.push(proxy);\n\n return proxy;\n }\n\n $transcluded(parentInstance) {\n const child = Object.create(this.$target);\n\n const proxy = new Proxy(child, new Scope(this, parentInstance));\n\n this.$children.push(proxy);\n\n return proxy;\n }\n\n /** @internal **/\n #registerKey(key, listener) {\n if (this.watchers.has(key)) {\n this.watchers.get(key).push(listener);\n } else {\n this.watchers.set(key, [listener]);\n }\n }\n\n /** @internal **/\n #registerForeignKey(key, listener) {\n if (this.foreignListeners.has(key)) {\n this.foreignListeners.get(key).push(listener);\n } else {\n this.foreignListeners.set(key, [listener]);\n }\n }\n\n #deregisterKey(key, id) {\n const listenerList = this.watchers.get(key);\n\n if (!listenerList) return false;\n\n const index = listenerList.findIndex((x) => x.id === id);\n\n if (index === -1) return false;\n\n listenerList.splice(index, 1);\n\n if (listenerList.length) {\n this.watchers.set(key, listenerList);\n } else {\n this.watchers.delete(key);\n }\n\n return true;\n }\n\n // #deregisterForeignKey(key, id) {\n // const listenerList = this.foreignListeners.get(key);\n // if (!listenerList) return false;\n\n // const index = listenerList.findIndex((x) => x.id === id);\n // if (index === -1) return false;\n\n // listenerList.splice(index, 1);\n // if (listenerList.length) {\n // this.foreignListeners.set(key, listenerList);\n // } else {\n // this.foreignListeners.delete(key);\n // }\n // return true;\n // }\n\n $eval(expr, locals) {\n const fn = $parse(expr);\n\n const res = fn(this, locals);\n\n if (isUndefined(res) || res === null) {\n return res;\n }\n\n if (res.name === Object.hasOwnProperty.name) {\n return res;\n }\n\n if (isFunction(res)) {\n return res();\n }\n\n if (Number.isNaN(res)) {\n return 0;\n }\n\n return res;\n }\n\n /**\n * @param {Object} newTarget\n */\n $merge(newTarget) {\n const list = entries(newTarget);\n\n for (let i = 0, l = list.length; i < l; i++) {\n const [key, value] = list[i];\n\n this.set(this.$target, key, value, this.$proxy);\n }\n }\n\n /**\n * @param {ng.Expression} expr\n * @returns {any}\n */\n $apply(expr) {\n try {\n return $parse(expr)(this.$proxy);\n } catch (err) {\n return $exceptionHandler(err);\n }\n }\n\n /**\n * @param {string} name\n * @param {Function} listener\n * @returns {(function(): void)|*}\n */\n $on(name, listener) {\n let namedListeners = this.$$listeners.get(name);\n\n if (!namedListeners) {\n namedListeners = [];\n this.$$listeners.set(name, namedListeners);\n }\n namedListeners.push(listener);\n\n return () => {\n const indexOfListener = namedListeners.indexOf(listener);\n\n if (indexOfListener !== -1) {\n namedListeners.splice(indexOfListener, 1);\n\n if (namedListeners.length === 0) {\n this.$$listeners.delete(name);\n }\n }\n };\n }\n\n /**\n * @param {string} name\n * @param {...any} args\n * @returns {void}\n */\n $emit(name, ...args) {\n return this.#eventHelper(\n { name, event: undefined, broadcast: false },\n ...args,\n );\n }\n\n /**\n * @param {string} name\n * @param {...any} args\n * @returns {any}\n */\n $broadcast(name, ...args) {\n return this.#eventHelper(\n { name, event: undefined, broadcast: true },\n ...args,\n );\n }\n\n /**\n * @internal\n * @returns {any}\n */\n #eventHelper({ name, event, broadcast }, ...args) {\n if (!broadcast) {\n if (!this.$$listeners.has(name)) {\n if (this.$parent) {\n return this.$parent.$handler.#eventHelper(\n { name, event, broadcast },\n ...args,\n );\n }\n\n return undefined;\n }\n }\n\n if (event) {\n event.currentScope = this.$target;\n } else {\n event = event || {\n name,\n targetScope: this.$target,\n currentScope: this.$target,\n stopped: false,\n stopPropagation() {\n event.stopped = true;\n },\n preventDefault() {\n event.defaultPrevented = true;\n },\n defaultPrevented: false,\n };\n }\n\n const listenerArgs = concat([event], [event].concat(args), 1);\n\n const listeners = this.$$listeners.get(name);\n\n if (listeners) {\n let { length } = listeners;\n\n for (let i = 0; i < length; i++) {\n try {\n const cb = listeners[i];\n\n cb.apply(null, listenerArgs);\n\n const currentLength = listeners.length;\n\n if (currentLength !== length) {\n if (currentLength < length) {\n i--;\n }\n length = currentLength;\n }\n } catch (err) {\n $exceptionHandler(err);\n }\n }\n }\n\n event.currentScope = null;\n\n if (event.stopped) {\n return event;\n }\n\n if (broadcast) {\n if (this.$children.length > 0) {\n this.$children.forEach((child) => {\n event = child.$handler.#eventHelper(\n { name, event, broadcast },\n ...args,\n );\n });\n }\n\n return event;\n } else {\n if (this.$parent) {\n return this.$parent.#eventHelper({ name, event, broadcast }, ...args);\n } else {\n return event;\n }\n }\n }\n\n /**\n * @internal\n * @returns {boolean}\n */\n #isRoot() {\n return this.$root === /** @type {Scope} */ (this);\n }\n\n /**\n * @param {Function} fn\n */\n $postUpdate(fn) {\n $postUpdateQueue.push(fn);\n }\n\n $destroy() {\n if (this.$$destroyed) return;\n\n this.$broadcast(\"$destroy\");\n\n for (const [key, val] of this.watchers) {\n for (let i = val.length - 1; i >= 0; i--) {\n if (val[i].scopeId === this.$id) {\n val.splice(i, 1);\n }\n }\n\n if (val.length === 0) {\n this.watchers.delete(key);\n } else {\n this.watchers.set(key, val);\n }\n }\n\n if (this.#isRoot()) {\n this.watchers.clear();\n } else {\n const children = this.$parent.$children;\n\n for (let i = 0, l = children.length; i < l; i++) {\n if (children[i].$id === this.$id) {\n children.splice(i, 1);\n break;\n }\n }\n }\n\n this.$$listeners.clear();\n this.$$destroyed = true;\n }\n\n /**\n * @internal\n * @param {import('./interface.ts').Listener} listener - The property path that was changed.\n */\n #notifyListener(listener, target) {\n const { originalTarget, listenerFn, watchFn } = listener;\n\n try {\n let newVal = watchFn(originalTarget);\n\n if (isUndefined(newVal)) {\n newVal = watchFn(target);\n }\n\n if (isFunction(newVal)) {\n newVal = newVal(originalTarget);\n }\n\n if (isArray(newVal)) {\n for (let i = 0, l = newVal.length; i < l; i++) {\n if (isFunction(newVal[i])) {\n newVal[i] = newVal[i](originalTarget);\n }\n }\n }\n\n listenerFn(newVal, originalTarget);\n\n while ($postUpdateQueue.length) {\n const fn = $postUpdateQueue.shift();\n\n fn();\n }\n } catch (err) {\n $exceptionHandler(err);\n }\n }\n\n /* @ignore */\n $flushQueue() {\n while ($postUpdateQueue.length) {\n $postUpdateQueue.shift()();\n }\n }\n\n /**\n * Searches the scope instance\n *\n * @param {string|number}id\n * @returns {Scope|undefined}\n */\n $getById(id) {\n if (isString(id)) {\n id = parseInt(/** @type {string} */ (id), 10);\n }\n\n if (this.$id === id) {\n return this;\n } else {\n let res = undefined;\n\n for (const child of this.$children) {\n const found = child.$getById(id);\n\n if (found) {\n res = found;\n break;\n }\n }\n\n return res;\n }\n }\n\n $searchByName(name) {\n const getByName = (scope, nameParam) => {\n if (scope.$scopename === nameParam) {\n return scope;\n } else {\n let res = undefined;\n\n for (const child of scope.$children) {\n const found = getByName(child, nameParam);\n\n if (found) {\n res = found;\n break;\n }\n }\n\n return res;\n }\n };\n\n return getByName(this.$root, name);\n }\n}\n\n/*------------- Private helpers -------------*/\n\n/**\n * @param {Scope} model\n * @returns {number}\n */\nfunction calculateWatcherCount(model) {\n const childIds = collectChildIds(model);\n\n let count = 0;\n\n for (const watchers of model.watchers.values()) {\n for (let i = 0, l = watchers.length; i < l; i++) {\n if (childIds.has(watchers[i].scopeId)) {\n count++;\n }\n }\n }\n\n return count;\n}\n\n/**\n * @param {Scope} child\n * @returns {Set<number>}\n */\nfunction collectChildIds(child) {\n const ids = new Set();\n\n const stack = [child];\n\n while (stack.length) {\n const node = stack.pop();\n\n if (!ids.has(node.$id)) {\n ids.add(node.$id);\n\n if (node.$children) {\n for (let i = 0, l = node.$children.length; i < l; i++) {\n stack.push(node.$children[i]);\n }\n }\n }\n }\n\n return ids;\n}\n","import { defaultHttpResponseTransform } from \"../http/http.js\";\nimport { extend, isArray, isString, minErr } from \"../../shared/utils.js\";\n\nconst $templateRequestMinErr = minErr(\"$templateRequest\");\n\n/**\n * Used to configure the options passed to the {@link $http} service when making a template request.\n *\n * For example, it can be used for specifying the \"Accept\" header that is sent to the server, when\n * requesting a template.\n */\nexport function TemplateRequestProvider() {\n let httpOptions;\n\n /**\n * The options to be passed to the {@link $http} service when making the request.\n * You can use this to override options such as the \"Accept\" header for template requests.\n * The {@link $templateRequest} will set the `cache` and the `transformResponse` properties of the\n * options if not overridden here.\n *\n * @param {string=} val new value for the {@link $http} options.\n * @returns {string|TemplateRequestProvider} Returns the {@link $http} options when used as getter and self if used as setter.\n */\n this.httpOptions = function (val) {\n if (val) {\n httpOptions = val;\n\n return this;\n }\n\n return httpOptions;\n };\n\n /**\n * The `$templateRequest` service runs security checks then downloads the provided template using\n * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request\n * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the\n * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the\n * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted\n * when `tpl` is of type string and `$templateCache` has the matching entry.\n *\n * If you want to pass custom options to the `$http` service, such as setting the Accept header you\n * can configure this via {@link $templateRequestProvider#httpOptions}.\n *\n * `$templateRequest` is used internally by {@link $compile}, {@link ngRoute.$route}, and directives such\n * as {@link ngInclude} to download and cache templates.\n *\n * 3rd party modules should use `$templateRequest` if their services or directives are loading\n * templates.\n *\n * @param {string} tpl The HTTP request template URL\n * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty\n *\n * @return {Promise} a promise for the HTTP response data of the given URL.\n *\n * @property {number} totalPendingRequests total amount of pending template requests being downloaded.\n */\n this.$get = [\n \"$exceptionHandler\",\n \"$templateCache\",\n \"$http\",\n \"$sce\",\n /**\n *\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @param {ng.TemplateCacheService} $templateCache\n * @param {ng.HttpService} $http\n * @param {*} $sce\n * @returns {ng.TemplateRequestService}\n */\n function ($exceptionHandler, $templateCache, $http, $sce) {\n function handleRequestFn(tpl, ignoreRequestError) {\n handleRequestFn.totalPendingRequests++;\n\n // We consider the template cache holds only trusted templates, so\n // there's no need to go through adding the template again to the trusted\n // resources for keys that already are included in there. This also makes\n // AngularTS accept any script directive, no matter its name. However, we\n // still need to unwrap trusted types.\n\n if (!isString(tpl) || !$templateCache.has(tpl)) {\n try {\n tpl = $sce.getTrustedResourceUrl(tpl);\n\n if (!tpl) {\n return Promise.reject(\"Template not found\");\n }\n } catch (err) {\n return Promise.reject(err.message);\n }\n }\n\n let transformResponse =\n $http.defaults && $http.defaults.transformResponse;\n\n if (isArray(transformResponse)) {\n transformResponse = transformResponse.filter(function (transformer) {\n return transformer !== defaultHttpResponseTransform;\n });\n } else if (transformResponse === defaultHttpResponseTransform) {\n transformResponse = null;\n }\n\n return $http\n .get(\n tpl,\n extend(\n {\n cache: $templateCache,\n transformResponse,\n },\n httpOptions,\n ),\n )\n .finally(function () {\n handleRequestFn.totalPendingRequests--;\n })\n .then(function (response) {\n $templateCache.set(tpl, response.data);\n\n return response.data;\n }, handleError);\n\n function handleError(resp) {\n if (!ignoreRequestError) {\n resp = $templateRequestMinErr(\n \"tpload\",\n \"Failed to load template: {0} (HTTP status: {1} {2})\",\n tpl,\n resp.status,\n resp.statusText,\n );\n\n $exceptionHandler(resp);\n }\n\n return Promise.reject(resp);\n }\n }\n\n handleRequestFn.totalPendingRequests = 0;\n\n return handleRequestFn;\n },\n ];\n}\n","import { isDefined } from \"../../shared/utils.js\";\nimport { $injectTokens } from \"../../injection-tokens.js\";\n\n/** @typedef {import('../../interface.ts').ServiceProvider} ServiceProvider */\n\n/**\n * Private service to sanitize uris for links and images. Used by $compile.\n * @implements {ServiceProvider}\n */\nexport class SanitizeUriProvider {\n constructor() {\n /**\n * @private\n * @type {RegExp}\n */\n this._aHrefSanitizationTrustedUrlList =\n /^\\s*(https?|s?ftp|mailto|tel|file):/;\n\n /**\n * @private\n * @type {RegExp}\n */\n this._imgSrcSanitizationTrustedUrlList =\n /^\\s*((https?|ftp|file|blob):|data:image\\/)/;\n }\n\n /**\n * Retrieves or overrides the regexp used to trust URLs for a[href] sanitization.\n *\n * @param {RegExp=} regexp New regexp to trust URLs with.\n * @returns {RegExp|SanitizeUriProvider} Current regexp if no param, or self for chaining.\n */\n aHrefSanitizationTrustedUrlList(regexp) {\n if (isDefined(regexp)) {\n this._aHrefSanitizationTrustedUrlList = regexp;\n\n return this;\n }\n\n return this._aHrefSanitizationTrustedUrlList;\n }\n\n /**\n * Retrieves or overrides the regexp used to trust URLs for img[src] sanitization.\n *\n * @param {RegExp=} regexp New regexp to trust URLs with.\n * @returns {RegExp|SanitizeUriProvider} Current regexp if no param, or self for chaining.\n */\n imgSrcSanitizationTrustedUrlList(regexp) {\n if (isDefined(regexp)) {\n this._imgSrcSanitizationTrustedUrlList = regexp;\n\n return this;\n }\n\n return this._imgSrcSanitizationTrustedUrlList;\n }\n\n /**\n * @returns {import(\"./interface.ts\").SanitizerFn}\n */\n $get = [\n $injectTokens.$window,\n /** @param {ng.WindowService} $window */\n ($window) => {\n return /** @type {import(\"./interface.ts\").SanitizerFn} */ (\n (uri, isMediaUrl) => {\n if (!uri) return uri;\n\n /** @type {RegExp} */\n const regex = isMediaUrl\n ? this._imgSrcSanitizationTrustedUrlList\n : this._aHrefSanitizationTrustedUrlList;\n\n const normalizedVal = new URL(uri.trim(), $window.location.href).href;\n\n if (normalizedVal !== \"\" && !normalizedVal.match(regex)) {\n return `unsafe:${normalizedVal}`;\n }\n\n return uri;\n }\n );\n },\n ];\n}\n","import { entries, hasOwn, isArray, isString } from \"../../shared/utils.js\";\n\nconst ACTIVE_CLASS = \"ng-active\";\n\nconst INACTIVE_CLASS = \"ng-inactive\";\n\nclass NgMessageCtrl {\n /**\n * @param {Element} $element\n * @param {ng.Scope} $scope\n * @param {ng.Attributes} $attrs\n * @param {ng.AnimateService} $animate\n */\n constructor($element, $scope, $attrs, $animate) {\n this.$element = $element;\n this.$scope = $scope;\n this.$attrs = $attrs;\n this.$animate = $animate;\n\n this.latestKey = 0;\n this.nextAttachId = 0;\n this.messages = {};\n this.renderLater = false;\n this.cachedCollection = null;\n\n this.head = undefined;\n this.default = undefined;\n\n this.$scope.$watch(\n this.$attrs.ngMessages || this.$attrs.for,\n this.render.bind(this),\n );\n }\n\n getAttachId() {\n return this.nextAttachId++;\n }\n\n render(collection = {}) {\n this.renderLater = false;\n this.cachedCollection = collection;\n\n const multiple =\n isAttrTruthy(this.$scope, this.$attrs.ngMessagesMultiple) ||\n isAttrTruthy(this.$scope, this.$attrs.multiple);\n\n const unmatchedMessages = [];\n\n const matchedKeys = {};\n\n let truthyKeys = 0;\n\n let messageItem = this.head;\n\n let messageFound = false;\n\n let totalMessages = 0;\n\n while (messageItem) {\n totalMessages++;\n const messageCtrl = messageItem.message;\n\n let messageUsed = false;\n\n if (!messageFound) {\n entries(collection).forEach(([key, value]) => {\n if (truthy(value) && !messageUsed) {\n truthyKeys++;\n\n if (messageCtrl.test(key)) {\n if (matchedKeys[key]) return;\n matchedKeys[key] = true;\n\n messageUsed = true;\n messageCtrl.attach();\n }\n }\n });\n }\n\n if (messageUsed) {\n messageFound = !multiple;\n } else {\n unmatchedMessages.push(messageCtrl);\n }\n\n messageItem = messageItem.next;\n }\n\n unmatchedMessages.forEach((messageCtrl) => {\n messageCtrl.detach();\n });\n\n const messageMatched = unmatchedMessages.length !== totalMessages;\n\n const attachDefault = this.default && !messageMatched && truthyKeys > 0;\n\n if (attachDefault) {\n this.default.attach();\n } else if (this.default) {\n this.default.detach();\n }\n\n if (messageMatched || attachDefault) {\n this.$animate.setClass(this.$element, ACTIVE_CLASS, INACTIVE_CLASS);\n } else {\n this.$animate.setClass(this.$element, INACTIVE_CLASS, ACTIVE_CLASS);\n }\n }\n\n reRender() {\n if (!this.renderLater) {\n this.renderLater = true;\n Promise.resolve().then(() => {\n if (this.renderLater && this.cachedCollection) {\n this.render(this.cachedCollection);\n }\n });\n }\n }\n\n register(comment, messageCtrl, isDefault) {\n if (isDefault) {\n this.default = messageCtrl;\n } else {\n const nextKey = this.latestKey.toString();\n\n this.messages[nextKey] = {\n message: messageCtrl,\n };\n this.insertMessageNode(this.$element, comment, nextKey);\n comment.$$ngMessageNode = nextKey;\n this.latestKey++;\n }\n\n this.reRender();\n }\n\n deregister(comment, isDefault) {\n if (isDefault) {\n delete this.default;\n } else {\n const key = comment.$$ngMessageNode;\n\n delete comment.$$ngMessageNode;\n this.removeMessageNode(this.$element, comment, key);\n delete this.messages[key];\n }\n this.reRender();\n }\n\n findPreviousMessage(parent, comment) {\n let prevNode = comment;\n\n const parentLookup = [];\n\n while (prevNode && prevNode !== parent) {\n const prevKey = prevNode.$$ngMessageNode;\n\n if (prevKey && prevKey.length) {\n return this.messages[prevKey];\n }\n\n if (prevNode.childNodes.length && parentLookup.indexOf(prevNode) === -1) {\n parentLookup.push(prevNode);\n prevNode = prevNode.childNodes[prevNode.childNodes.length - 1];\n } else if (prevNode.previousSibling) {\n prevNode = prevNode.previousSibling;\n } else {\n prevNode = prevNode.parentNode;\n parentLookup.push(prevNode);\n }\n }\n\n return undefined;\n }\n\n insertMessageNode(parent, comment, key) {\n const messageNode = this.messages[key];\n\n if (!this.head) {\n this.head = messageNode;\n } else {\n const match = this.findPreviousMessage(parent, comment);\n\n if (match) {\n messageNode.next = match.next;\n match.next = messageNode;\n } else {\n messageNode.next = this.head;\n this.head = messageNode;\n }\n }\n }\n\n removeMessageNode(parent, comment, key) {\n const messageNode = this.messages[key];\n\n if (!messageNode) return;\n\n const match = this.findPreviousMessage(parent, comment);\n\n if (match) {\n match.next = messageNode.next;\n } else {\n this.head = messageNode.next;\n }\n }\n}\n\nngMessagesDirective.$inject = [\"$animate\"];\n/**\n * @param {ng.AnimateService} $animate\n * @returns {ng.Directive<NgMessageCtrl>}\n */\nexport function ngMessagesDirective($animate) {\n return {\n require: \"ngMessages\",\n restrict: \"AE\",\n controller: ($element, $scope, $attrs) =>\n new NgMessageCtrl($element, $scope, $attrs, $animate),\n };\n}\n\nfunction isAttrTruthy(scope, attr) {\n return (\n (isString(attr) && attr.length === 0) || // empty attribute\n truthy(scope.$eval(attr))\n );\n}\n\nfunction truthy(val) {\n return isString(val) ? val.length : !!val;\n}\n\nngMessagesIncludeDirective.$inject = [\"$templateRequest\", \"$compile\"];\nexport function ngMessagesIncludeDirective($templateRequest, $compile) {\n return {\n restrict: \"AE\",\n require: \"^^ngMessages\", // we only require this for validation sake\n link($scope, element, attrs) {\n const src = attrs.ngMessagesInclude || attrs.src;\n\n $templateRequest(src).then((html) => {\n if ($scope.$$destroyed) return;\n\n if (isString(html) && !html.trim()) {\n // Empty template - nothing to compile\n } else {\n // Non-empty template - compile and link\n $compile(html)($scope, (contents) => {\n element.after(contents);\n });\n }\n });\n },\n };\n}\n\nexport const ngMessageDirective = ngMessageDirectiveFactory(false);\nexport const ngMessageExpDirective = ngMessageDirectiveFactory(false);\nexport const ngMessageDefaultDirective = ngMessageDirectiveFactory(true);\n\n/**\n * @param {boolean} isDefault\n * @returns {(any) => ng.Directive}\n */\nfunction ngMessageDirectiveFactory(isDefault) {\n ngMessageDirectiveFn.$inject = [\"$animate\"];\n /**\n * @param {ng.AnimateService} $animate\n * @returns {ng.Directive}\n */\n function ngMessageDirectiveFn($animate) {\n return {\n restrict: \"AE\",\n transclude: \"element\",\n priority: 1, // must run before ngBind, otherwise the text is set on the comment\n terminal: true,\n require: \"^^ngMessages\",\n link(scope, element, attrs, ngMessagesCtrl, $transclude) {\n let commentNode;\n\n let records;\n\n let staticExp;\n\n let dynamicExp;\n\n if (!isDefault) {\n commentNode = element;\n staticExp = attrs.ngMessage || attrs.when;\n dynamicExp = attrs.ngMessageExp || attrs.whenExp;\n\n const assignRecords = function (items) {\n records = items\n ? isArray(items)\n ? items\n : items.split(/[\\s,]+/)\n : null;\n ngMessagesCtrl.reRender();\n };\n\n if (dynamicExp) {\n assignRecords(scope.$eval(dynamicExp));\n scope.$watch(dynamicExp, assignRecords);\n } else {\n assignRecords(staticExp);\n }\n }\n\n let currentElement;\n\n let messageCtrl;\n\n ngMessagesCtrl.register(\n commentNode,\n (messageCtrl = {\n test(name) {\n return contains(records, name);\n },\n attach() {\n if (!currentElement) {\n $transclude((elm, newScope) => {\n $animate.enter(elm, null, element);\n currentElement = elm;\n\n // Each time we attach this node to a message we get a new id that we can match\n // when we are destroying the node later.\n const $$attachId = (currentElement.$$attachId =\n ngMessagesCtrl.getAttachId());\n\n // in the event that the element or a parent element is destroyed\n // by another structural directive then it's time\n // to deregister the message from the controller\n currentElement.addEventListener(\"$destroy\", () => {\n // If the message element was removed via a call to `detach` then `currentElement` will be null\n // So this handler only handles cases where something else removed the message element.\n if (\n currentElement &&\n currentElement.$$attachId === $$attachId\n ) {\n ngMessagesCtrl.deregister(commentNode, isDefault);\n messageCtrl.detach();\n }\n newScope.$destroy();\n });\n });\n }\n },\n detach() {\n if (currentElement) {\n const elm = currentElement;\n\n currentElement = null;\n $animate.leave(elm);\n }\n },\n }),\n isDefault,\n );\n\n // We need to ensure that this directive deregisters itself when it no longer exists\n // Normally this is done when the attached element is destroyed; but if this directive\n // gets removed before we attach the message to the DOM there is nothing to watch\n // in which case we must deregister when the containing scope is destroyed.\n scope.$on(\"$destroy\", () => {\n ngMessagesCtrl.deregister(commentNode, isDefault);\n });\n },\n };\n }\n\n return ngMessageDirectiveFn;\n}\n\nfunction contains(collection, key) {\n if (collection) {\n return isArray(collection)\n ? collection.indexOf(key) >= 0\n : hasOwn(collection, key);\n }\n\n return undefined;\n}\n","import { extend, hasOwn } from \"../../shared/utils.js\";\nimport { $injectTokens } from \"../../injection-tokens.js\";\n\nconst ARIA_DISABLE_ATTR = \"ngAriaDisable\";\n\n/**\n * Internal Utilities\n */\nconst nativeAriaNodeNames = [\n \"BUTTON\",\n \"A\",\n \"INPUT\",\n \"TEXTAREA\",\n \"SELECT\",\n \"DETAILS\",\n \"SUMMARY\",\n];\n\nconst isNodeOneOf = function (elem, nodeTypeArray) {\n if (nodeTypeArray.indexOf(elem.nodeName) !== -1) {\n return true;\n }\n\n return false;\n};\n\n/**\n * Used for configuring the ARIA attributes injected and managed by ngAria.\n *\n * ```js\n * angular.module('myApp', ['ngAria'], function config($ariaProvider) {\n * $ariaProvider.config({\n * ariaValue: true,\n * tabindex: false\n * });\n * });\n *```\n *\n * ## Dependencies\n * Requires the {@link ngAria} module to be installed.\n *\n */\nexport function AriaProvider() {\n let config = {\n ariaHidden: true,\n ariaChecked: true,\n ariaReadonly: true,\n ariaDisabled: true,\n ariaRequired: true,\n ariaInvalid: true,\n ariaValue: true,\n tabindex: true,\n bindKeydown: true,\n bindRoleForClick: true,\n };\n\n this.config = function (newConfig) {\n config = extend(config, newConfig);\n };\n\n function watchExpr(attrName, ariaAttr, nativeAriaNodeNamesParam, negate) {\n return function (scope, elem, attr) {\n if (hasOwn(attr, ARIA_DISABLE_ATTR)) return;\n\n const ariaCamelName = attr.$normalize(ariaAttr);\n\n if (\n config[ariaCamelName] &&\n !isNodeOneOf(elem, nativeAriaNodeNamesParam) &&\n !attr[ariaCamelName]\n ) {\n scope.$watch(attr[attrName], (boolVal) => {\n // ensure boolean value\n boolVal = negate ? !boolVal : !!boolVal;\n elem.setAttribute(ariaAttr, boolVal);\n });\n }\n };\n }\n\n this.$get = function () {\n return {\n config(key) {\n return config[key];\n },\n $$watchExpr: watchExpr,\n };\n };\n}\n\nngDisabledAriaDirective.$inject = [$injectTokens.$aria];\nexport function ngDisabledAriaDirective($aria) {\n return $aria.$$watchExpr(\n \"ngDisabled\",\n \"aria-disabled\",\n nativeAriaNodeNames,\n false,\n );\n}\n\nngShowAriaDirective.$inject = [$injectTokens.$aria];\nexport function ngShowAriaDirective($aria) {\n return $aria.$$watchExpr(\"ngShow\", \"aria-hidden\", [], true);\n}\n\n/**\n * @return {ng.Directive}\n */\nexport function ngMessagesAriaDirective() {\n return {\n restrict: \"A\",\n require: \"?ngMessages\",\n link(_scope, elem, attr) {\n if (hasOwn(attr, ARIA_DISABLE_ATTR)) return;\n\n if (!elem.hasAttribute(\"aria-live\")) {\n elem.setAttribute(\"aria-live\", \"assertive\");\n }\n },\n };\n}\n\nngClickAriaDirective.$inject = [$injectTokens.$aria, $injectTokens.$parse];\n\n/**\n * @param $aria\n * @param {ng.ParseService} $parse\n * @return {ng.Directive}\n */\nexport function ngClickAriaDirective($aria, $parse) {\n return {\n restrict: \"A\",\n compile(_elem, attr) {\n if (hasOwn(attr, ARIA_DISABLE_ATTR)) return undefined;\n\n const fn = $parse(attr.ngClick);\n\n return (scope, elem, attrParam) => {\n if (!isNodeOneOf(elem, nativeAriaNodeNames)) {\n if ($aria.config(\"bindRoleForClick\") && !elem.hasAttribute(\"role\")) {\n elem.setAttribute(\"role\", \"button\");\n }\n\n if ($aria.config(\"tabindex\") && !elem.hasAttribute(\"tabindex\")) {\n elem.setAttribute(\"tabindex\", \"0\");\n }\n\n if (\n $aria.config(\"bindKeydown\") &&\n !attrParam.ngKeydown &&\n !attrParam.ngKeypress &&\n !attrParam.ngKeyup\n ) {\n elem.addEventListener(\n \"keydown\",\n /** @param {KeyboardEvent} event */\n (event) => {\n const keyCode = parseInt(event.key, 10);\n\n // eslint-disable-next-line no-magic-numbers\n if (keyCode === 13 || keyCode === 32) {\n // If the event is triggered on a non-interactive element ...\n if (\n nativeAriaNodeNames.indexOf(\n /** @type {Node} */ (event.target).nodeName,\n ) === -1 &&\n !(\n /** @type {HTMLElement} */ (event.target)\n .isContentEditable\n )\n ) {\n // ... prevent the default browser behavior (e.g. scrolling when pressing spacebar)\n // See https://github.com/angular/angular.js/issues/16664\n event.preventDefault();\n }\n fn(scope, { $event: event });\n }\n },\n );\n }\n }\n };\n },\n };\n}\n\nngRequiredAriaDirective.$inject = [$injectTokens.$aria];\nexport function ngRequiredAriaDirective($aria) {\n return $aria.$$watchExpr(\n \"ngRequired\",\n \"aria-required\",\n nativeAriaNodeNames,\n false,\n );\n}\n\nngCheckedAriaDirective.$inject = [\"$aria\"];\nexport function ngCheckedAriaDirective($aria) {\n return $aria.$$watchExpr(\n \"ngChecked\",\n \"aria-checked\",\n nativeAriaNodeNames,\n false,\n );\n}\n\nngValueAriaDirective.$inject = [$injectTokens.$aria];\nexport function ngValueAriaDirective($aria) {\n return $aria.$$watchExpr(\n \"ngValue\",\n \"aria-checked\",\n nativeAriaNodeNames,\n false,\n );\n}\n\nngHideAriaDirective.$inject = [$injectTokens.$aria];\nexport function ngHideAriaDirective($aria) {\n return $aria.$$watchExpr(\"ngHide\", \"aria-hidden\", [], false);\n}\n\nngReadonlyAriaDirective.$inject = [$injectTokens.$aria];\nexport function ngReadonlyAriaDirective($aria) {\n return $aria.$$watchExpr(\n \"ngReadonly\",\n \"aria-readonly\",\n nativeAriaNodeNames,\n false,\n );\n}\n\nngModelAriaDirective.$inject = [$injectTokens.$aria];\nexport function ngModelAriaDirective($aria) {\n function shouldAttachAttr(attr, normalizedAttr, elem, allowNonAriaNodes) {\n return (\n $aria.config(normalizedAttr) &&\n !elem.getAttribute(attr) &&\n (allowNonAriaNodes || !isNodeOneOf(elem, nativeAriaNodeNames)) &&\n (elem.getAttribute(\"type\") !== \"hidden\" || elem.nodeName !== \"INPUT\")\n );\n }\n\n function shouldAttachRole(role, elem) {\n // if element does not have role attribute\n // AND element type is equal to role (if custom element has a type equaling shape) <-- remove?\n // AND element is not in nativeAriaNodeNames\n return (\n !elem.getAttribute(\"role\") &&\n elem.getAttribute(\"type\") === role &&\n !isNodeOneOf(elem, nativeAriaNodeNames)\n );\n }\n\n function getShape(attr) {\n const { type } = attr;\n\n const { role } = attr;\n\n return (type || role) === \"checkbox\" || role === \"menuitemcheckbox\"\n ? \"checkbox\"\n : (type || role) === \"radio\" || role === \"menuitemradio\"\n ? \"radio\"\n : type === \"range\" || role === \"progressbar\" || role === \"slider\"\n ? \"range\"\n : \"\";\n }\n\n return {\n restrict: \"A\",\n require: \"ngModel\",\n priority: 200, // Make sure watches are fired after any other directives that affect the ngModel value\n compile(_, attr) {\n if (hasOwn(attr, ARIA_DISABLE_ATTR)) return undefined;\n\n const shape = getShape(attr);\n\n return {\n // eslint-disable-next-line no-shadow\n post(_, elem, attrPost, ngModel) {\n const needsTabIndex = shouldAttachAttr(\n \"tabindex\",\n \"tabindex\",\n elem,\n false,\n );\n\n function getRadioReaction() {\n // Strict comparison would cause a BC\n elem.setAttribute(\n \"aria-checked\",\n // eslint-disable-next-line eqeqeq\n (attrPost.value == ngModel.$viewValue).toString(),\n );\n }\n\n function getCheckboxReaction() {\n elem.setAttribute(\n \"aria-checked\",\n (!ngModel.$isEmpty(ngModel.$viewValue)).toString(),\n );\n }\n\n switch (shape) {\n case \"radio\":\n case \"checkbox\":\n if (shouldAttachRole(shape, elem)) {\n elem.setAttribute(\"role\", shape);\n }\n\n if (\n shouldAttachAttr(\"aria-checked\", \"ariaChecked\", elem, false)\n ) {\n ngModel.$watch(\n \"$modelValue\",\n shape === \"radio\" ? getRadioReaction : getCheckboxReaction,\n );\n }\n\n if (needsTabIndex) {\n elem.setAttribute(\"tabindex\", 0);\n }\n break;\n case \"range\":\n if (shouldAttachRole(shape, elem)) {\n elem.setAttribute(\"role\", \"slider\");\n }\n\n if ($aria.config(\"ariaValue\")) {\n const needsAriaValuemin =\n !elem.hasAttribute(\"aria-valuemin\") &&\n (hasOwn(attrPost, \"min\") || hasOwn(attrPost, \"ngMin\"));\n\n const needsAriaValuemax =\n !elem.hasAttribute(\"aria-valuemax\") &&\n (hasOwn(attrPost, \"max\") || hasOwn(attrPost, \"ngMax\"));\n\n const needsAriaValuenow = !elem.hasAttribute(\"aria-valuenow\");\n\n if (needsAriaValuemin) {\n attrPost.$observe(\"min\", (newVal) => {\n elem.setAttribute(\"aria-valuemin\", newVal);\n });\n }\n\n if (needsAriaValuemax) {\n attrPost.$observe(\"max\", (newVal) => {\n elem.setAttribute(\"aria-valuemax\", newVal);\n });\n }\n\n if (needsAriaValuenow) {\n ngModel.$watch(\"$modelValue\", (newVal) => {\n elem.setAttribute(\"aria-valuenow\", newVal);\n });\n }\n }\n\n if (needsTabIndex) {\n elem.setAttribute(\"tabindex\", 0);\n }\n break;\n }\n\n if (\n !hasOwn(attrPost, \"ngRequired\") &&\n ngModel.$validators.required &&\n shouldAttachAttr(\"aria-required\", \"ariaRequired\", elem, false)\n ) {\n // ngModel.$error.required is undefined on custom controls\n attrPost.$observe(\"required\", () => {\n elem.setAttribute(\n \"aria-required\",\n (!!attrPost.required).toString(),\n );\n });\n }\n\n if (shouldAttachAttr(\"aria-invalid\", \"ariaInvalid\", elem, true)) {\n ngModel.$watch(\"$invalid\", (newVal) => {\n elem.setAttribute(\"aria-invalid\", (!!newVal).toString());\n });\n }\n },\n };\n },\n };\n}\n\nngDblclickAriaDirective.$inject = [$injectTokens.$aria];\nexport function ngDblclickAriaDirective($aria) {\n return function (scope, elem, attr) {\n if (hasOwn(attr, ARIA_DISABLE_ATTR)) return;\n\n if (\n $aria.config(\"tabindex\") &&\n !elem.hasAttribute(\"tabindex\") &&\n !isNodeOneOf(elem, nativeAriaNodeNames)\n ) {\n elem.setAttribute(\"tabindex\", 0);\n }\n };\n}\n","/**\n * @fileoverview\n * Frame-synchronized animation runner and scheduler.\n * Provides async batching of animation callbacks using requestAnimationFrame.\n * In AngularJS, this used to be implemented as `$$AnimateRunner`\n */\n\n/**\n * Internal runner states.\n * @internal\n * @enum {number}\n */\nconst RunnerState = {\n _INITIAL: 0,\n _PENDING: 1,\n _DONE: 2,\n};\n\n/** @type {VoidFunction[]} */\nlet queue = [];\n\n/** @type {boolean} */\nlet scheduled = false;\n\n/**\n * Flush all queued callbacks.\n * @private\n */\nfunction flush() {\n const tasks = queue;\n\n queue = [];\n scheduled = false;\n\n for (let i = 0; i < tasks.length; i++) {\n tasks[i]();\n }\n}\n\n/**\n * Schedule a callback to run on the next animation frame.\n * Multiple calls within the same frame are batched together.\n *\n * @param {VoidFunction} fn - The callback to execute.\n */\nexport function schedule(fn) {\n queue.push(fn);\n\n if (!scheduled) {\n scheduled = true;\n (typeof requestAnimationFrame === \"function\"\n ? requestAnimationFrame\n : setTimeout)(flush, 0);\n }\n}\n\n/**\n * Represents an asynchronous animation operation.\n * Provides both callback-based and promise-based completion APIs.\n */\nexport class AnimateRunner {\n /**\n * Run an array of animation runners in sequence.\n * Each runner waits for the previous one to complete.\n *\n * @param {AnimateRunner[]} runners - Runners to execute in order.\n * @param {(ok: boolean) => void} callback - Invoked when all complete or one fails.\n */\n static _chain(runners, callback) {\n let i = 0;\n\n const next = (ok = true) => {\n if (!ok || i >= runners.length) {\n callback(ok);\n\n return;\n }\n runners[i++].done(next);\n };\n\n next();\n }\n\n /**\n * Waits for all animation runners to complete before invoking the callback.\n *\n * @param {AnimateRunner[]} runners - Active runners to wait for.\n * @param {(ok: boolean) => void} callback - Called when all runners complete.\n */\n static _all(runners, callback) {\n let remaining = runners.length;\n\n let status = true;\n\n for (const i of runners) {\n i.done((result) => {\n status = status && result !== false;\n\n if (--remaining === 0) callback(status);\n });\n }\n }\n\n /**\n * @param {import(\"../interface.ts\").AnimationHost} [host] - Optional animation host.\n */\n constructor(host) {\n /** @type {import(\"../interface.ts\").AnimationHost} */\n this._host = host || {};\n\n /** @type {Array<(ok: boolean) => void>} */\n this._doneCallbacks = [];\n\n /** @type {RunnerState} */\n this._state = RunnerState._INITIAL;\n\n /** @type {Promise<void>|null} */\n this._promise = null;\n\n /** @type {(fn: VoidFunction) => void} */\n this._schedule = schedule;\n }\n\n /**\n * Sets or updates the animation host.\n * @param {import(\"../interface.ts\").AnimationHost} host - The host object.\n */\n setHost(host) {\n this._host = host || {};\n }\n\n /**\n * Registers a callback to be called once the animation completes.\n * If the animation is already complete, it's called immediately.\n *\n * @param {(ok: boolean) => void} fn - Completion callback.\n */\n done(fn) {\n if (this._state === RunnerState._DONE) {\n fn(true);\n } else {\n this._doneCallbacks.push(fn);\n }\n }\n\n /**\n * Notifies the host of animation progress.\n * @param {...any} args - Progress arguments.\n */\n progress(...args) {\n this._host.progress?.(...args);\n }\n\n /** Pauses the animation, if supported by the host. */\n pause() {\n this._host.pause?.();\n }\n\n /** Resumes the animation, if supported by the host. */\n resume() {\n this._host.resume?.();\n }\n\n /** Ends the animation successfully. */\n end() {\n this._host.end?.();\n this._finish(true);\n }\n\n /** Cancels the animation. */\n cancel() {\n this._host.cancel?.();\n this._finish(false);\n }\n\n /**\n * Marks the animation as complete on the next animation frame.\n * @param {boolean} [status=true] - True if successful, false if canceled.\n */\n complete(status = true) {\n if (this._state === RunnerState._INITIAL) {\n this._state = RunnerState._PENDING;\n this._schedule(() => this._finish(status));\n }\n }\n\n /**\n * Returns a promise that resolves or rejects when the animation completes.\n * @returns {Promise<void>} Promise resolved on success or rejected on cancel.\n */\n getPromise() {\n if (!this._promise) {\n this._promise = new Promise((resolve, reject) => {\n this.done((success) => {\n if (success === false) reject();\n else resolve();\n });\n });\n }\n\n return this._promise;\n }\n\n /** @inheritdoc */\n then(onFulfilled, onRejected) {\n return this.getPromise().then(onFulfilled, onRejected);\n }\n\n /** @inheritdoc */\n catch(onRejected) {\n return this.getPromise().catch(onRejected);\n }\n\n /** @inheritdoc */\n finally(onFinally) {\n return this.getPromise().finally(onFinally);\n }\n\n /**\n * Completes the animation and invokes all done callbacks.\n * @private\n * @param {boolean} status - True if completed successfully, false if canceled.\n */\n _finish(status) {\n if (this._state === RunnerState._DONE) return;\n this._state = RunnerState._DONE;\n\n const callbacks = this._doneCallbacks;\n\n for (let i = 0; i < callbacks.length; i++) {\n callbacks[i](status);\n }\n callbacks.length = 0;\n }\n}\n","import {\n getCacheData,\n removeElementData,\n setCacheData,\n} from \"../shared/dom.js\";\nimport {\n entries,\n isArray,\n isDefined,\n isNullOrUndefined,\n keys,\n} from \"../shared/utils.js\";\nimport { AnimateRunner } from \"./runner/animate-runner.js\";\nimport {\n ACTIVE_CLASS_SUFFIX,\n ADD_CLASS_SUFFIX,\n ANIMATIONEND_EVENT,\n ANIMATION_DELAY_PROP,\n ANIMATION_DURATION_PROP,\n ANIMATION_ITERATION_COUNT_KEY,\n ANIMATION_PROP,\n DURATION_KEY,\n EVENT_CLASS_PREFIX,\n PROPERTY_KEY,\n REMOVE_CLASS_SUFFIX,\n SAFE_FAST_FORWARD_DURATION_VALUE,\n TIMING_KEY,\n TRANSITIONEND_EVENT,\n TRANSITION_DELAY_PROP,\n TRANSITION_DURATION_PROP,\n TRANSITION_PROP,\n applyAnimationClassesFactory,\n applyAnimationFromStyles,\n applyAnimationStyles,\n applyAnimationToStyles,\n applyInlineStyle,\n blockKeyframeAnimations,\n packageStyles,\n pendClasses,\n prepareAnimationOptions,\n removeFromArray,\n} from \"./shared.js\";\n\nconst ANIMATE_TIMER_KEY = \"$$animateCss\";\n\nconst ONE_SECOND = 1000;\n\nconst ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;\n\nconst CLOSING_TIME_BUFFER = 1.5;\n\nconst DETECT_CSS_PROPERTIES = {\n transitionDuration: TRANSITION_DURATION_PROP,\n transitionDelay: TRANSITION_DELAY_PROP,\n transitionProperty: TRANSITION_PROP + PROPERTY_KEY,\n animationDuration: ANIMATION_DURATION_PROP,\n animationDelay: ANIMATION_DELAY_PROP,\n animationIterationCount: ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY,\n};\n\nconst DETECT_STAGGER_CSS_PROPERTIES = {\n transitionDuration: TRANSITION_DURATION_PROP,\n transitionDelay: TRANSITION_DELAY_PROP,\n animationDuration: ANIMATION_DURATION_PROP,\n animationDelay: ANIMATION_DELAY_PROP,\n};\n\nfunction getCssKeyframeDurationStyle(duration) {\n return [ANIMATION_DURATION_PROP, `${duration}s`];\n}\n\nfunction getCssDelayStyle(delay, isKeyframeAnimation) {\n const prop = isKeyframeAnimation\n ? ANIMATION_DELAY_PROP\n : TRANSITION_DELAY_PROP;\n\n return [prop, `${delay}s`];\n}\n\nfunction computeCssStyles(element, properties) {\n const styles = Object.create(null);\n\n const detectedStyles = window.getComputedStyle(element) || {};\n\n entries(properties).forEach(([actualStyleName, formalStyleName]) => {\n let val = detectedStyles[formalStyleName];\n\n if (val) {\n const char = val.charAt(0);\n\n // only numerical-based values have a negative sign or digit as the first value\n if (char === \"-\" || char === \"+\" || char >= 0) {\n val = parseMaxTime(val);\n }\n\n // by setting this to null in the event that the delay is not set or is set directly as 0\n // then we can still allow for negative values to be used later on and not mistake this\n // value for being greater than any other negative value.\n if (val === 0) {\n val = null;\n }\n styles[actualStyleName] = val;\n }\n });\n\n return styles;\n}\n\nfunction parseMaxTime(str) {\n let maxValue = 0;\n\n str.split(/\\s*,\\s*/).forEach((value) => {\n // it's always safe to consider only second values and omit `ms` values since\n // getComputedStyle will always handle the conversion for us\n if (value.charAt(value.length - 1) === \"s\") {\n value = value.substring(0, value.length - 1);\n }\n value = parseFloat(value) || 0;\n maxValue = maxValue ? Math.max(value, maxValue) : value;\n });\n\n return maxValue;\n}\n\nfunction truthyTimingValue(val) {\n return val === 0 || !isNullOrUndefined(val);\n}\n\nfunction getCssTransitionDurationStyle(duration, applyOnlyDuration) {\n let style = TRANSITION_PROP;\n\n let value = `${duration}s`;\n\n if (applyOnlyDuration) {\n style += DURATION_KEY;\n } else {\n value += \" linear all\";\n }\n\n return [style, value];\n}\n\n// we do not reassign an already present style value since\n// if we detect the style property value again we may be\n// detecting styles that were added via the `from` styles.\n// We make use of `isDefined` here since an empty string\n// or null value (which is what getPropertyValue will return\n// for a non-existing style) will still be marked as a valid\n// value for the style (a falsy value implies that the style\n// is to be removed at the end of the animation). If we had a simple\n// \"OR\" statement then it would not be enough to catch that.\nfunction registerRestorableStyles(backup, node, properties) {\n properties.forEach((prop) => {\n backup[prop] = isDefined(backup[prop])\n ? backup[prop]\n : node.style.getPropertyValue(prop);\n });\n}\n\nexport function AnimateCssProvider() {\n let activeClasses;\n\n this.$get = [\n \"$$animateCache\",\n \"$$rAFScheduler\",\n\n /**\n *\n * @param {*} $$animateCache\n * @param {import(\"./raf-scheduler\").RafScheduler} $$rAFScheduler\n * @returns\n */\n function ($$animateCache, $$rAFScheduler) {\n const applyAnimationClasses = applyAnimationClassesFactory();\n\n // TODO add types\n function computeCachedCssStyles(\n node,\n cacheKey,\n allowNoDuration,\n properties,\n ) {\n let timings = $$animateCache.get(cacheKey);\n\n if (!timings) {\n timings = computeCssStyles(node, properties);\n\n if (timings.animationIterationCount === \"infinite\") {\n timings.animationIterationCount = 1;\n }\n }\n\n // if a css animation has no duration we\n // should mark that so that repeated addClass/removeClass calls are skipped\n const hasDuration =\n allowNoDuration ||\n timings.transitionDuration > 0 ||\n timings.animationDuration > 0;\n\n // we keep putting this in multiple times even though the value and the cacheKey are the same\n // because we're keeping an internal tally of how many duplicate animations are detected.\n $$animateCache.put(cacheKey, timings, hasDuration);\n\n return timings;\n }\n\n function computeCachedCssStaggerStyles(\n node,\n className,\n cacheKey,\n properties,\n ) {\n let stagger;\n\n const staggerCacheKey = `stagger-${cacheKey}`;\n\n // if we have one or more existing matches of matching elements\n // containing the same parent + CSS styles (which is how cacheKey works)\n // then staggering is possible\n if ($$animateCache.count(cacheKey) > 0) {\n stagger = $$animateCache.get(staggerCacheKey);\n\n if (!stagger) {\n const staggerClassName = pendClasses(className, \"-stagger\");\n\n node.className += ` ${staggerClassName}`;\n stagger = computeCssStyles(node, properties);\n\n // force the conversion of a null value to zero incase not set\n stagger.animationDuration = Math.max(stagger.animationDuration, 0);\n stagger.transitionDuration = Math.max(\n stagger.transitionDuration,\n 0,\n );\n\n node.classList.remove(staggerClassName);\n\n $$animateCache.put(staggerCacheKey, stagger, true);\n }\n }\n\n return stagger || {};\n }\n\n const rafWaitQueue = [];\n\n function waitUntilQuiet(callback) {\n rafWaitQueue.push(callback);\n $$rAFScheduler._waitUntilQuiet(() => {\n $$animateCache.flush();\n\n // DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable.\n // the line below will force the browser to perform a repaint so\n // that all the animated elements within the animation frame will\n // be properly updated and drawn on screen. This is required to\n // ensure that the preparation animation is properly flushed so that\n // the active state picks up from there. DO NOT REMOVE THIS LINE.\n // DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH\n // WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND\n // WILL TAKE YEARS AWAY FROM YOUR LIFE.\n\n const pageWidth = document.body.offsetWidth + 1;\n\n // we use a for loop to ensure that if the queue is changed\n // during this looping then it will consider new requests\n for (let i = 0; i < rafWaitQueue.length; i++) {\n rafWaitQueue[i](pageWidth);\n }\n rafWaitQueue.length = 0;\n });\n }\n\n function computeTimings(node, cacheKey, allowNoDuration) {\n const timings = computeCachedCssStyles(\n node,\n cacheKey,\n allowNoDuration,\n DETECT_CSS_PROPERTIES,\n );\n\n const aD = timings.animationDelay;\n\n const tD = timings.transitionDelay;\n\n timings.maxDelay = aD && tD ? Math.max(aD, tD) : aD || tD;\n timings.maxDuration = Math.max(\n timings.animationDuration * timings.animationIterationCount,\n timings.transitionDuration,\n );\n\n return timings;\n }\n\n return function init(element, initialOptions) {\n // all of the animation functions should create\n // a copy of the options data, however, if a\n // parent service has already created a copy then\n let delayStyle;\n\n // we should stick to using that\n let options = initialOptions || {\n $$skipPreparationClasses: false,\n };\n\n if (!options.$$prepared) {\n options = prepareAnimationOptions(structuredClone(options));\n }\n\n const restoreStyles = {};\n\n const node = /** @type {HTMLElement} */ (element);\n\n // Note: this had an additional !$$animateQueue.enabled() check\n if (!node || !node.parentNode) {\n return closeAndReturnNoopAnimator();\n }\n\n const temporaryStyles = [];\n\n const styles = packageStyles(options);\n\n let animationClosed;\n\n let animationPaused;\n\n let animationCompleted;\n\n let runner;\n\n let runnerHost;\n\n let maxDelay;\n\n let maxDelayTime;\n\n let maxDuration;\n\n let maxDurationTime;\n\n let startTime;\n\n const events = [];\n\n if (options.duration === 0) {\n return closeAndReturnNoopAnimator();\n }\n\n const method =\n options.event && isArray(options.event)\n ? options.event.join(\" \")\n : options.event;\n\n const isStructural = method && options.structural;\n\n let structuralClassName = \"\";\n\n let addRemoveClassName = \"\";\n\n if (isStructural) {\n structuralClassName = pendClasses(method, EVENT_CLASS_PREFIX, true);\n } else if (method) {\n structuralClassName = method;\n }\n\n if (options.addClass) {\n addRemoveClassName += pendClasses(options.addClass, ADD_CLASS_SUFFIX);\n }\n\n if (options.removeClass) {\n if (addRemoveClassName.length) {\n addRemoveClassName += \" \";\n }\n addRemoveClassName += pendClasses(\n options.removeClass,\n REMOVE_CLASS_SUFFIX,\n );\n }\n\n // there may be a situation where a structural animation is combined together\n // with CSS classes that need to resolve before the animation is computed.\n // However this means that there is no explicit CSS code to block the animation\n // from happening (by setting 0s none in the class name). If this is the case\n // we need to apply the classes before the first rAF so we know to continue if\n // there actually is a detected transition or keyframe animation\n if (options.applyClassesEarly && addRemoveClassName.length) {\n applyAnimationClasses(element, options);\n }\n\n let preparationClasses = [structuralClassName, addRemoveClassName]\n .join(\" \")\n .trim();\n\n const hasToStyles = styles.to && Object.keys(styles.to).length > 0;\n\n const containsKeyframeAnimation =\n (options.keyframeStyle || \"\").length > 0;\n\n // there is no way we can trigger an animation if no styles and\n // no classes are being applied which would then trigger a transition,\n // unless there a is raw keyframe value that is applied to the element.\n if (!containsKeyframeAnimation && !hasToStyles && !preparationClasses) {\n return closeAndReturnNoopAnimator();\n }\n\n let stagger;\n\n let cacheKey = $$animateCache.cacheKey(\n node,\n method,\n options.addClass,\n options.removeClass,\n );\n\n if ($$animateCache.containsCachedAnimationWithoutDuration(cacheKey)) {\n preparationClasses = null;\n\n return closeAndReturnNoopAnimator();\n }\n\n if (options.stagger > 0) {\n const staggerVal = parseFloat(options.stagger);\n\n stagger = {\n transitionDelay: staggerVal,\n animationDelay: staggerVal,\n transitionDuration: 0,\n animationDuration: 0,\n };\n } else {\n stagger = computeCachedCssStaggerStyles(\n node,\n preparationClasses,\n cacheKey,\n DETECT_STAGGER_CSS_PROPERTIES,\n );\n }\n\n if (!options.$$skipPreparationClasses) {\n element.classList.add(\n ...preparationClasses.split(\" \").filter((x) => x !== \"\"),\n );\n }\n\n let applyOnlyDuration;\n\n if (options.transitionStyle) {\n const transitionStyle = [TRANSITION_PROP, options.transitionStyle];\n\n applyInlineStyle(node, transitionStyle);\n temporaryStyles.push(transitionStyle);\n }\n\n if (options.duration >= 0) {\n applyOnlyDuration = node.style[TRANSITION_PROP].length > 0;\n const durationStyle = getCssTransitionDurationStyle(\n options.duration,\n applyOnlyDuration,\n );\n\n // we set the duration so that it will be picked up by getComputedStyle later\n applyInlineStyle(node, durationStyle);\n\n temporaryStyles.push(durationStyle);\n }\n\n if (options.keyframeStyle) {\n const keyframeStyle = [ANIMATION_PROP, options.keyframeStyle];\n\n applyInlineStyle(node, keyframeStyle);\n temporaryStyles.push(keyframeStyle);\n }\n\n const itemIndex = stagger\n ? options.staggerIndex >= 0\n ? options.staggerIndex\n : $$animateCache.count(cacheKey)\n : 0;\n\n const isFirst = itemIndex === 0;\n\n // this is a pre-emptive way of forcing the setup classes to be added and applied INSTANTLY\n // without causing any combination of transitions to kick in. By adding a negative delay value\n // it forces the setup class' transition to end immediately. We later then remove the negative\n // transition delay to allow for the transition to naturally do it's thing. The beauty here is\n // that if there is no transition defined then nothing will happen and this will also allow\n // other transitions to be stacked on top of each other without any chopping them out.\n if (isFirst && !options.skipBlocking) {\n blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE);\n }\n\n let timings = computeTimings(node, cacheKey, !isStructural);\n\n let relativeDelay = timings.maxDelay;\n\n maxDelay = Math.max(relativeDelay, 0);\n // eslint-disable-next-line prefer-destructuring\n maxDuration = timings.maxDuration;\n\n const flags = {};\n\n flags.hasTransitions = timings.transitionDuration > 0;\n flags.hasAnimations = timings.animationDuration > 0;\n flags.hasTransitionAll =\n flags.hasTransitions && timings.transitionProperty === \"all\";\n flags.applyTransitionDuration =\n hasToStyles &&\n ((flags.hasTransitions && !flags.hasTransitionAll) ||\n (flags.hasAnimations && !flags.hasTransitions));\n flags.applyAnimationDuration = options.duration && flags.hasAnimations;\n flags.applyTransitionDelay =\n truthyTimingValue(options.delay) &&\n (flags.applyTransitionDuration || flags.hasTransitions);\n flags.applyAnimationDelay =\n truthyTimingValue(options.delay) && flags.hasAnimations;\n flags.recalculateTimingStyles = addRemoveClassName.length > 0;\n\n if (flags.applyTransitionDuration || flags.applyAnimationDuration) {\n maxDuration = options.duration\n ? parseFloat(options.duration)\n : maxDuration;\n\n if (flags.applyTransitionDuration) {\n flags.hasTransitions = true;\n timings.transitionDuration = maxDuration;\n applyOnlyDuration =\n node.style[TRANSITION_PROP + PROPERTY_KEY].length > 0;\n temporaryStyles.push(\n getCssTransitionDurationStyle(maxDuration, applyOnlyDuration),\n );\n }\n\n if (flags.applyAnimationDuration) {\n flags.hasAnimations = true;\n timings.animationDuration = maxDuration;\n temporaryStyles.push(getCssKeyframeDurationStyle(maxDuration));\n }\n }\n\n if (maxDuration === 0 && !flags.recalculateTimingStyles) {\n return closeAndReturnNoopAnimator();\n }\n\n activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX);\n\n if (!isNullOrUndefined(options.delay)) {\n if (typeof options.delay !== \"boolean\") {\n delayStyle = parseFloat(options.delay);\n // number in options.delay means we have to recalculate the delay for the closing timeout\n maxDelay = Math.max(delayStyle, 0);\n }\n\n if (flags.applyTransitionDelay) {\n temporaryStyles.push(getCssDelayStyle(delayStyle));\n }\n\n if (flags.applyAnimationDelay) {\n temporaryStyles.push(getCssDelayStyle(delayStyle, true));\n }\n }\n\n // we need to recalculate the delay value since we used a pre-emptive negative\n // delay value and the delay value is required for the final event checking. This\n // property will ensure that this will happen after the RAF phase has passed.\n if (\n isNullOrUndefined(options.duration) &&\n timings.transitionDuration > 0\n ) {\n flags.recalculateTimingStyles =\n flags.recalculateTimingStyles || isFirst;\n }\n\n maxDelayTime = maxDelay * ONE_SECOND;\n maxDurationTime = maxDuration * ONE_SECOND;\n\n if (!options.skipBlocking) {\n flags.blockTransition = timings.transitionDuration > 0;\n flags.blockKeyframeAnimation =\n timings.animationDuration > 0 &&\n stagger.animationDelay > 0 &&\n stagger.animationDuration === 0;\n }\n\n if (options.from) {\n if (options.cleanupStyles) {\n registerRestorableStyles(\n restoreStyles,\n node,\n Object.keys(options.from),\n );\n }\n applyAnimationFromStyles(element, options);\n }\n\n if (flags.blockTransition || flags.blockKeyframeAnimation) {\n applyBlocking(maxDuration);\n } else if (!options.skipBlocking) {\n blockTransitions(node, false);\n }\n\n // TODO(matsko): for 1.5 change this code to have an animator object for better debugging\n return {\n $$willAnimate: true,\n end: endFn,\n start() {\n if (animationClosed) return undefined;\n\n runnerHost = {\n end: endFn,\n cancel: cancelFn,\n resume: null, // this will be set during the start() phase\n pause: null,\n };\n\n runner = new AnimateRunner(runnerHost);\n\n waitUntilQuiet(start);\n\n // we don't have access to pause/resume the animation\n // since it hasn't run yet. AnimateRunner will therefore\n // set noop functions for resume and pause and they will\n // later be overridden once the animation is triggered\n return runner;\n },\n };\n\n function endFn() {\n close();\n }\n\n function cancelFn() {\n close(true);\n }\n\n function close(rejected) {\n // if the promise has been called already then we shouldn't close\n // the animation again\n if (animationClosed || (animationCompleted && animationPaused))\n return;\n animationClosed = true;\n animationPaused = false;\n\n if (preparationClasses && !options.$$skipPreparationClasses) {\n element.classList.remove(...preparationClasses.split(\" \"));\n }\n activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX);\n\n if (activeClasses) {\n element.classList.remove(...activeClasses.split(\" \"));\n }\n\n blockKeyframeAnimations(node, false);\n blockTransitions(node, false);\n\n temporaryStyles.forEach((entry) => {\n // There is only one way to remove inline style properties entirely from elements.\n // By using `removeProperty` this works, but we need to convert camel-cased CSS\n // styles down to hyphenated values.\n node.style[entry[0]] = \"\";\n });\n\n applyAnimationClasses(element, options);\n applyAnimationStyles(element, options);\n\n if (keys(restoreStyles).length) {\n entries(restoreStyles).forEach(([prop, value]) => {\n if (value) {\n node.style.setProperty(prop, value);\n } else {\n node.style.removeProperty(prop);\n }\n });\n }\n\n // the reason why we have this option is to allow a synchronous closing callback\n // that is fired as SOON as the animation ends (when the CSS is removed) or if\n // the animation never takes off at all. A good example is a leave animation since\n // the element must be removed just after the animation is over or else the element\n // will appear on screen for one animation frame causing an overbearing flicker.\n if (options.onDone) {\n options.onDone();\n }\n\n if (events && events.length) {\n // Remove the transitionend / animationend listener(s)\n events.forEach((i) =>\n element.removeEventListener(i, onAnimationProgress),\n );\n }\n\n // Cancel the fallback closing timeout and remove the timer data\n const animationTimerData = getCacheData(element, ANIMATE_TIMER_KEY);\n\n if (animationTimerData) {\n clearTimeout(animationTimerData[0].timer);\n removeElementData(element, ANIMATE_TIMER_KEY);\n }\n\n // if the preparation function fails then the promise is not setup\n if (runner) {\n runner.complete(!rejected);\n }\n }\n\n function applyBlocking(duration) {\n if (flags.blockTransition) {\n blockTransitions(node, duration);\n }\n\n if (flags.blockKeyframeAnimation) {\n blockKeyframeAnimations(node, !!duration);\n }\n }\n\n function closeAndReturnNoopAnimator() {\n runner = new AnimateRunner({\n end: endFn,\n cancel: cancelFn,\n });\n\n // should flush the cache animation\n waitUntilQuiet(() => {\n /* empty */\n });\n close();\n\n return {\n $$willAnimate: false,\n start() {\n return runner;\n },\n end: endFn,\n };\n }\n\n function onAnimationProgress(event) {\n event.stopPropagation();\n const ev = event.originalEvent || event;\n\n if (ev.target !== node) {\n // Since TransitionEvent / AnimationEvent bubble up,\n // we have to ignore events by finished child animations\n return;\n }\n\n // we now always use `Date.now()` due to the recent changes with\n // event.timeStamp in Firefox, Webkit and Chrome (see #13494 for more info)\n const timeStamp = ev.$manualTimeStamp || Date.now();\n\n /* Firefox (or possibly just Gecko) likes to not round values up\n * when a ms measurement is used for the animation */\n const elapsedTime = parseFloat(\n ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES),\n );\n\n /* $manualTimeStamp is a mocked timeStamp value which is set\n * within browserTrigger(). This is only here so that tests can\n * mock animations properly. Real events fallback to event.timeStamp,\n * or, if they don't, then a timeStamp is automatically created for them.\n * We're checking to see if the timeStamp surpasses the expected delay,\n * but we're using elapsedTime instead of the timeStamp on the 2nd\n * pre-condition since animationPauseds sometimes close off early */\n if (\n Math.max(timeStamp - startTime, 0) >= maxDelayTime &&\n elapsedTime >= maxDuration\n ) {\n // we set this flag to ensure that if the transition is paused then, when resumed,\n // the animation will automatically close itself since transitions cannot be paused.\n animationCompleted = true;\n close();\n }\n }\n\n function start() {\n if (animationClosed) return;\n\n if (!node.parentNode) {\n close();\n\n return;\n }\n\n // even though we only pause keyframe animations here the pause flag\n // will still happen when transitions are used. Only the transition will\n // not be paused since that is not possible. If the animation ends when\n // paused then it will not complete until unpaused or cancelled.\n const playPause = function (playAnimation) {\n if (!animationCompleted) {\n animationPaused = !playAnimation;\n\n if (timings.animationDuration) {\n const value = blockKeyframeAnimations(node, animationPaused);\n\n if (animationPaused) {\n temporaryStyles.push(value);\n } else {\n removeFromArray(temporaryStyles, value);\n }\n }\n } else if (animationPaused && playAnimation) {\n animationPaused = false;\n close();\n }\n };\n\n // checking the stagger duration prevents an accidentally cascade of the CSS delay style\n // being inherited from the parent. If the transition duration is zero then we can safely\n // rely that the delay value is an intentional stagger delay style.\n const maxStagger =\n itemIndex > 0 &&\n ((timings.transitionDuration && stagger.transitionDuration === 0) ||\n (timings.animationDuration && stagger.animationDuration === 0)) &&\n Math.max(stagger.animationDelay, stagger.transitionDelay);\n\n if (maxStagger) {\n setTimeout(\n triggerAnimationStart,\n Math.floor(maxStagger * itemIndex * ONE_SECOND),\n false,\n );\n } else {\n triggerAnimationStart();\n }\n\n // this will decorate the existing promise runner with pause/resume methods\n runnerHost.resume = function () {\n playPause(true);\n };\n\n runnerHost.pause = function () {\n playPause(false);\n };\n\n function triggerAnimationStart() {\n // just incase a stagger animation kicks in when the animation\n // itself was cancelled entirely\n if (animationClosed) return;\n\n applyBlocking(false);\n\n temporaryStyles.forEach((entry) => {\n const key = entry[0];\n\n node.style[key] = entry[1];\n });\n\n applyAnimationClasses(element, options);\n element.classList.add(\n ...activeClasses.split(\" \").filter((x) => x !== \"\"),\n );\n\n if (flags.recalculateTimingStyles) {\n cacheKey = $$animateCache.cacheKey(\n node,\n method,\n options.addClass,\n options.removeClass,\n );\n\n timings = computeTimings(node, cacheKey, false);\n relativeDelay = timings.maxDelay;\n maxDelay = Math.max(relativeDelay, 0);\n // eslint-disable-next-line prefer-destructuring\n maxDuration = timings.maxDuration;\n\n if (maxDuration === 0) {\n close();\n\n return;\n }\n\n flags.hasTransitions = timings.transitionDuration > 0;\n flags.hasAnimations = timings.animationDuration > 0;\n }\n\n if (flags.applyAnimationDelay) {\n relativeDelay =\n typeof options.delay !== \"boolean\" &&\n truthyTimingValue(options.delay)\n ? parseFloat(options.delay)\n : relativeDelay;\n\n maxDelay = Math.max(relativeDelay, 0);\n timings.animationDelay = relativeDelay;\n delayStyle = getCssDelayStyle(relativeDelay, true);\n temporaryStyles.push(delayStyle);\n node.style[delayStyle[0]] = delayStyle[1];\n }\n\n maxDelayTime = maxDelay * ONE_SECOND;\n maxDurationTime = maxDuration * ONE_SECOND;\n\n if (options.easing) {\n let easeProp;\n\n const easeVal = options.easing;\n\n if (flags.hasTransitions) {\n easeProp = TRANSITION_PROP + TIMING_KEY;\n temporaryStyles.push([easeProp, easeVal]);\n node.style[easeProp] = easeVal;\n }\n\n if (flags.hasAnimations) {\n easeProp = ANIMATION_PROP + TIMING_KEY;\n temporaryStyles.push([easeProp, easeVal]);\n node.style[easeProp] = easeVal;\n }\n }\n\n if (timings.transitionDuration) {\n events.push(TRANSITIONEND_EVENT);\n }\n\n if (timings.animationDuration) {\n events.push(ANIMATIONEND_EVENT);\n }\n\n startTime = Date.now();\n const timerTime =\n maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime;\n\n const endTime = startTime + timerTime;\n\n const animationsData =\n getCacheData(element, ANIMATE_TIMER_KEY) || [];\n\n let setupFallbackTimer = true;\n\n if (animationsData.length) {\n const currentTimerData = animationsData[0];\n\n setupFallbackTimer = endTime > currentTimerData.expectedEndTime;\n\n if (setupFallbackTimer) {\n clearTimeout(currentTimerData.timer);\n } else {\n animationsData.push(close);\n }\n }\n\n if (setupFallbackTimer) {\n const timer = setTimeout(onAnimationExpired, timerTime, false);\n\n animationsData[0] = {\n timer,\n expectedEndTime: endTime,\n };\n animationsData.push(close);\n setCacheData(element, ANIMATE_TIMER_KEY, animationsData);\n }\n\n if (events.length) {\n events.forEach((x) => {\n element.addEventListener(x, onAnimationProgress);\n });\n }\n\n if (options.to) {\n if (options.cleanupStyles) {\n registerRestorableStyles(\n restoreStyles,\n node,\n Object.keys(options.to),\n );\n }\n applyAnimationToStyles(element, options);\n }\n }\n\n function onAnimationExpired() {\n const animationsData = getCacheData(element, ANIMATE_TIMER_KEY);\n\n // this will be false in the event that the element was\n // removed from the DOM (via a leave animation or something\n // similar)\n if (animationsData) {\n for (let i = 1; i < animationsData.length; i++) {\n animationsData[i]();\n }\n removeElementData(element, ANIMATE_TIMER_KEY);\n }\n }\n }\n };\n },\n ];\n}\n\nfunction blockTransitions(node, duration) {\n // we use a negative delay value since it performs blocking\n // yet it doesn't kill any existing transitions running on the\n // same element which makes this safe for class-based animations\n const value = duration ? `-${duration}s` : \"\";\n\n applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]);\n\n return [TRANSITION_DELAY_PROP, value];\n}\n","import { getOrSetCacheData, setCacheData } from \"../../shared/dom.js\";\nimport {\n extend,\n isArray,\n isDefined,\n isObject,\n isString,\n isUndefined,\n} from \"../../shared/utils.js\";\nimport {\n NG_ANIMATE_CHILDREN_DATA,\n applyAnimationClassesFactory,\n applyAnimationStyles,\n applyGeneratedPreparationClasses,\n clearGeneratedClasses,\n extractElementNode,\n mergeAnimationDetails,\n prepareAnimationOptions,\n stripCommentsFromElement,\n} from \"../shared.js\";\nimport { $injectTokens as $t } from \"../../injection-tokens.js\";\nimport { AnimateRunner } from \"../runner/animate-runner.js\";\nimport { NodeType } from \"../../shared/node.js\";\n\nconst NG_ANIMATE_ATTR_NAME = \"data-ng-animate\";\n\nconst NG_ANIMATE_PIN_DATA = \"$ngAnimatePin\";\n\nAnimateQueueProvider.$inject = [\"$animateProvider\"];\nexport function AnimateQueueProvider($animateProvider) {\n const PRE_DIGEST_STATE = 1;\n\n const RUNNING_STATE = 2;\n\n const ONE_SPACE = \" \";\n\n const rules = (this.rules = {\n skip: [],\n cancel: [],\n join: [],\n });\n\n function getEventData(options) {\n return {\n addClass: options.addClass,\n removeClass: options.removeClass,\n from: options.from,\n to: options.to,\n };\n }\n\n function makeTruthyCssClassMap(classString) {\n if (!classString) {\n return null;\n }\n\n const keys = classString.split(ONE_SPACE);\n\n const map = Object.create(null);\n\n keys.forEach((key) => {\n map[key] = true;\n });\n\n return map;\n }\n\n function hasMatchingClasses(newClassString, currentClassString) {\n if (newClassString && currentClassString) {\n const currentClassMap = makeTruthyCssClassMap(currentClassString);\n\n return newClassString\n .split(ONE_SPACE)\n .some((className) => currentClassMap[className]);\n }\n\n return undefined;\n }\n\n function isAllowed(ruleType, currentAnimation, previousAnimation) {\n return rules[ruleType].some((fn) =>\n fn(currentAnimation, previousAnimation),\n );\n }\n\n function hasAnimationClasses(animation, and) {\n const a = (animation.addClass || \"\").length > 0;\n\n const b = (animation.removeClass || \"\").length > 0;\n\n return and ? a && b : a || b;\n }\n\n rules.join.push(\n (newAnimation) =>\n // if the new animation is class-based then we can just tack that on\n !newAnimation.structural && hasAnimationClasses(newAnimation),\n );\n\n rules.skip.push(\n (newAnimation) =>\n // there is no need to animate anything if no classes are being added and\n // there is no structural animation that will be triggered\n !newAnimation.structural && !hasAnimationClasses(newAnimation),\n );\n\n rules.skip.push(\n (newAnimation, currentAnimation) =>\n // why should we trigger a new structural animation if the element will\n // be removed from the DOM anyway?\n currentAnimation.event === \"leave\" && newAnimation.structural,\n );\n\n rules.skip.push(\n (newAnimation, currentAnimation) =>\n // if there is an ongoing current animation then don't even bother running the class-based animation\n currentAnimation.structural &&\n currentAnimation.state === RUNNING_STATE &&\n !newAnimation.structural,\n );\n\n rules.cancel.push(\n (newAnimation, currentAnimation) =>\n // there can never be two structural animations running at the same time\n currentAnimation.structural && newAnimation.structural,\n );\n\n rules.cancel.push(\n (newAnimation, currentAnimation) =>\n // if the previous animation is already running, but the new animation will\n // be triggered, but the new animation is structural\n currentAnimation.state === RUNNING_STATE && newAnimation.structural,\n );\n\n rules.cancel.push((newAnimation, currentAnimation) => {\n // cancel the animation if classes added / removed in both animation cancel each other out,\n // but only if the current animation isn't structural\n\n if (currentAnimation.structural) return false;\n\n const nA = newAnimation.addClass;\n\n const nR = newAnimation.removeClass;\n\n const cA = currentAnimation.addClass;\n\n const cR = currentAnimation.removeClass;\n\n // early detection to save the global CPU shortage :)\n if (\n (isUndefined(nA) && isUndefined(nR)) ||\n (isUndefined(cA) && isUndefined(cR))\n ) {\n return false;\n }\n\n return hasMatchingClasses(nA, cR) || hasMatchingClasses(nR, cA);\n });\n\n this.$get = [\n $t.$rootScope,\n $t.$injector,\n $t.$$animation,\n /**\n *\n * @param {ng.RootScopeService} $rootScope\n * @param {ng.InjectorService} $injector\n * @param {*} $$animation\n * @returns {import(\"../queue/interface.ts\").AnimateQueueService}\n */\n function ($rootScope, $injector, $$animation) {\n const activeAnimationsLookup = new Map();\n\n const disabledElementsLookup = new Map();\n\n function postDigestTaskFactory() {\n let postDigestCalled = false;\n\n return function (fn) {\n // we only issue a call to postDigest before\n // it has first passed. This prevents any callbacks\n // from not firing once the animation has completed\n // since it will be out of the digest cycle.\n if (postDigestCalled) {\n fn();\n } else {\n $rootScope.$postUpdate(() => {\n postDigestCalled = true;\n fn();\n });\n }\n };\n }\n\n const callbackRegistry = Object.create(null);\n\n // remember that the `customFilter`/`classNameFilter` are set during the\n // provider/config stage therefore we can optimize here and setup helper functions\n const customFilter = $animateProvider.customFilter();\n\n const classNameFilter = $animateProvider.classNameFilter();\n\n const returnTrue = function () {\n return true;\n };\n\n const isAnimatableByFilter = customFilter || returnTrue;\n\n const isAnimatableClassName = !classNameFilter\n ? returnTrue\n : function (node, options) {\n const className = [\n node.getAttribute(\"class\"),\n options.addClass,\n options.removeClass,\n ].join(\" \");\n\n return classNameFilter.test(className);\n };\n\n const applyAnimationClasses = applyAnimationClassesFactory();\n\n function normalizeAnimationDetails(element, animation) {\n return mergeAnimationDetails(element, animation, {});\n }\n\n function findCallbacks(targetParentNode, targetNode, event) {\n const matches = [];\n\n const entries = callbackRegistry[event];\n\n if (entries) {\n entries.forEach((entry) => {\n if (entry.node.contains(targetNode)) {\n matches.push(entry.callback);\n } else if (\n event === \"leave\" &&\n entry.node.contains(targetParentNode)\n ) {\n matches.push(entry.callback);\n }\n });\n }\n\n return matches;\n }\n\n function filterFromRegistry(list, matchContainer, matchCallback) {\n const containerNode = extractElementNode(matchContainer);\n\n return list.filter((entry) => {\n const isMatch =\n entry.node === containerNode &&\n (!matchCallback || entry.callback === matchCallback);\n\n return !isMatch;\n });\n }\n\n function cleanupEventListeners(phase, node) {\n if (phase === \"close\" && !node.parentNode) {\n // If the element is not attached to a parentNode, it has been removed by\n // the domOperation, and we can safely remove the event callbacks\n $animate.off(node);\n }\n }\n\n const $animate = {\n on(event, container, callback) {\n const node = extractElementNode(container);\n\n callbackRegistry[event] = callbackRegistry[event] || [];\n callbackRegistry[event].push({\n node,\n callback,\n });\n\n // Remove the callback when the element is removed from the DOM\n container.addEventListener(\"$destroy\", () => {\n const animationDetails = activeAnimationsLookup.get(node);\n\n if (!animationDetails) {\n // If there's an animation ongoing, the callback calling code will remove\n // the event listeners. If we'd remove here, the callbacks would be removed\n // before the animation ends\n $animate.off(event, container, callback);\n }\n });\n },\n\n off(event, container, callback) {\n if (arguments.length === 1 && !isString(arguments[0])) {\n container = arguments[0];\n\n for (const eventType in callbackRegistry) {\n callbackRegistry[eventType] = filterFromRegistry(\n callbackRegistry[eventType],\n container,\n );\n }\n\n return;\n }\n\n const entries = callbackRegistry[event];\n\n if (!entries) return;\n\n callbackRegistry[event] =\n arguments.length === 1\n ? null\n : filterFromRegistry(entries, container, callback);\n },\n\n pin(element, parentElement) {\n setCacheData(element, NG_ANIMATE_PIN_DATA, parentElement);\n },\n\n push(element, event, options, domOperation) {\n options = options || {};\n options.domOperation = domOperation;\n\n return queueAnimation(element, event, options);\n },\n };\n\n return $animate;\n\n /**\n * @param {Element} originalElement\n * @param {string} event\n * @param {*} initialOptions\n * @returns void\n */\n function queueAnimation(originalElement, event, initialOptions) {\n // we always make a copy of the options since\n // there should never be any side effects on\n // the input data when running `$animateCss`.\n let options = initialOptions;\n\n // strip comments\n\n let element = isArray(originalElement)\n ? // @ts-ignore\n originalElement.filter((x) => x.nodeName !== \"#comment\")[0]\n : originalElement;\n\n const node = element;\n\n const parentNode = node && node.parentNode;\n\n options = prepareAnimationOptions(options);\n\n // we create a fake runner with a working promise.\n // These methods will become available after the digest has passed\n const runner = new AnimateRunner();\n\n // this is used to trigger callbacks in postDigest mode\n const runInNextPostDigestOrNow = postDigestTaskFactory();\n\n if (isArray(options.addClass)) {\n options.addClass = options.addClass.join(\" \");\n }\n\n if (options.addClass && !isString(options.addClass)) {\n options.addClass = null;\n }\n\n if (isArray(options.removeClass)) {\n options.removeClass = options.removeClass.join(\" \");\n }\n\n if (options.removeClass && !isString(options.removeClass)) {\n options.removeClass = null;\n }\n\n if (options.from && !isObject(options.from)) {\n options.from = null;\n }\n\n if (options.to && !isObject(options.to)) {\n options.to = null;\n }\n\n // If animations are hard-disabled for the whole application there is no need to continue.\n // There are also situations where a directive issues an animation for a JQLite wrapper that\n // contains only comment nodes. In this case, there is no way we can perform an animation.\n if (\n // !animationsEnabled ||\n !node ||\n !isAnimatableByFilter(node, event, initialOptions) ||\n !isAnimatableClassName(node, options)\n ) {\n close();\n\n return runner;\n }\n const isStructural = [\"enter\", \"move\", \"leave\"].indexOf(event) >= 0;\n\n // This is a hard disable of all animations the element itself, therefore there is no need to\n // continue further past this point if not enabled\n // Animations are also disabled if the document is currently hidden (page is not visible\n // to the user), because browsers slow down or do not flush calls to requestAnimationFrame\n let skipAnimations =\n document.hidden || disabledElementsLookup.get(node);\n\n const existingAnimation =\n (!skipAnimations && activeAnimationsLookup.get(node)) || {};\n\n const hasExistingAnimation = !!existingAnimation.state;\n\n // there is no point in traversing the same collection of parent ancestors if a followup\n // animation will be run on the same element that already did all that checking work\n if (\n !skipAnimations &&\n (!hasExistingAnimation ||\n existingAnimation.state !== PRE_DIGEST_STATE)\n ) {\n skipAnimations = !areAnimationsAllowed(node, parentNode);\n }\n\n if (skipAnimations) {\n // Callbacks should fire even if the document is hidden (regression fix for issue #14120)\n if (document.hidden)\n notifyProgress(runner, event, \"start\", getEventData(options));\n close();\n\n if (document.hidden)\n notifyProgress(runner, event, \"close\", getEventData(options));\n\n return runner;\n }\n\n if (isStructural) {\n closeChildAnimations(node);\n }\n\n const newAnimation = {\n structural: isStructural,\n element,\n event,\n addClass: options.addClass,\n removeClass: options.removeClass,\n close,\n options,\n runner,\n };\n\n if (hasExistingAnimation) {\n const skipAnimationFlag = isAllowed(\n \"skip\",\n newAnimation,\n existingAnimation,\n );\n\n if (skipAnimationFlag) {\n if (existingAnimation.state === RUNNING_STATE) {\n close();\n\n return runner;\n }\n mergeAnimationDetails(element, existingAnimation, newAnimation);\n\n return existingAnimation.runner;\n }\n const cancelAnimationFlag = isAllowed(\n \"cancel\",\n newAnimation,\n existingAnimation,\n );\n\n if (cancelAnimationFlag) {\n if (existingAnimation.state === RUNNING_STATE) {\n // this will end the animation right away and it is safe\n // to do so since the animation is already running and the\n // runner callback code will run in async\n existingAnimation.runner.end();\n } else if (existingAnimation.structural) {\n // this means that the animation is queued into a digest, but\n // hasn't started yet. Therefore it is safe to run the close\n // method which will call the runner methods in async.\n existingAnimation.close();\n } else {\n // this will merge the new animation options into existing animation options\n mergeAnimationDetails(element, existingAnimation, newAnimation);\n\n return existingAnimation.runner;\n }\n } else {\n // a joined animation means that this animation will take over the existing one\n // so an example would involve a leave animation taking over an enter. Then when\n // the postDigest kicks in the enter will be ignored.\n const joinAnimationFlag = isAllowed(\n \"join\",\n newAnimation,\n existingAnimation,\n );\n\n if (joinAnimationFlag) {\n if (existingAnimation.state === RUNNING_STATE) {\n normalizeAnimationDetails(element, newAnimation);\n } else {\n applyGeneratedPreparationClasses(\n element,\n isStructural ? event : null,\n options,\n );\n\n event = newAnimation.event = existingAnimation.event;\n options = mergeAnimationDetails(\n element,\n existingAnimation,\n newAnimation,\n );\n\n // we return the same runner since only the option values of this animation will\n // be fed into the `existingAnimation`.\n return existingAnimation.runner;\n }\n }\n }\n } else {\n // normalization in this case means that it removes redundant CSS classes that\n // already exist (addClass) or do not exist (removeClass) on the element\n normalizeAnimationDetails(element, newAnimation);\n }\n\n // when the options are merged and cleaned up we may end up not having to do\n // an animation at all, therefore we should check this before issuing a post\n // digest callback. Structural animations will always run no matter what.\n let isValidAnimation = newAnimation.structural;\n\n if (!isValidAnimation) {\n // animate (from/to) can be quickly checked first, otherwise we check if any classes are present\n isValidAnimation =\n (newAnimation.event === \"animate\" &&\n Object.keys(newAnimation.options.to || {}).length > 0) ||\n hasAnimationClasses(newAnimation);\n }\n\n if (!isValidAnimation) {\n close();\n clearElementAnimationState(node);\n\n return runner;\n }\n\n // the counter keeps track of cancelled animations\n const counter = (existingAnimation.counter || 0) + 1;\n\n newAnimation.counter = counter;\n\n markElementAnimationState(node, PRE_DIGEST_STATE, newAnimation);\n $rootScope.$postUpdate(() => {\n // It is possible that the DOM nodes inside `originalElement` have been replaced. This can\n // happen if the animated element is a transcluded clone and also has a `templateUrl`\n // directive on it. Therefore, we must recreate `element` in order to interact with the\n // actual DOM nodes.\n // Note: We still need to use the old `node` for certain things, such as looking up in\n // HashMaps where it was used as the key.\n\n element = stripCommentsFromElement(originalElement);\n\n let animationDetails = activeAnimationsLookup.get(node);\n\n const animationCancelled = !animationDetails;\n\n animationDetails = animationDetails || {};\n\n // if addClass/removeClass is called before something like enter then the\n // registered parent element may not be present. The code below will ensure\n // that a final value for parent element is obtained\n const parentElement = element.parentElement || [];\n\n // animate/structural/class-based animations all have requirements. Otherwise there\n // is no point in performing an animation. The parent node must also be set.\n const isCurrentAnimationValid =\n parentElement &&\n (animationDetails.event === \"animate\" ||\n animationDetails.structural ||\n hasAnimationClasses(animationDetails));\n\n // this means that the previous animation was cancelled\n // even if the follow-up animation is the same event\n if (\n animationCancelled ||\n animationDetails.counter !== counter ||\n !isCurrentAnimationValid\n ) {\n // if another animation did not take over then we need\n // to make sure that the domOperation and options are\n // handled accordingly\n if (animationCancelled) {\n applyAnimationClasses(element, options);\n applyAnimationStyles(element, options);\n }\n\n // if the event changed from something like enter to leave then we do\n // it, otherwise if it's the same then the end result will be the same too\n if (\n animationCancelled ||\n (isStructural && animationDetails.event !== event)\n ) {\n options.domOperation();\n runner.end();\n }\n\n // in the event that the element animation was not cancelled or a follow-up animation\n // isn't allowed to animate from here then we need to clear the state of the element\n // so that any future animations won't read the expired animation data.\n if (!isCurrentAnimationValid) {\n clearElementAnimationState(node);\n }\n\n return;\n }\n\n // this combined multiple class to addClass / removeClass into a setClass event\n // so long as a structural event did not take over the animation\n event =\n !animationDetails.structural &&\n hasAnimationClasses(animationDetails, true)\n ? \"setClass\"\n : animationDetails.event;\n\n markElementAnimationState(node, RUNNING_STATE);\n const realRunner = $$animation(\n element,\n event,\n animationDetails.options,\n );\n\n // this will update the runner's flow-control events based on\n // the `realRunner` object.\n runner.setHost(realRunner);\n notifyProgress(runner, event, \"start\", getEventData(options));\n\n realRunner.done((status) => {\n close(!status);\n\n if (activeAnimationsLookup.get(node)?.counter === counter) {\n clearElementAnimationState(node);\n }\n notifyProgress(runner, event, \"close\", getEventData(options));\n });\n });\n\n // Since we don't have digest any more - trigger queue here\n setTimeout($rootScope.$flushQueue, 0);\n\n return runner;\n\n function notifyProgress(runnerParam, eventParam, phase, data) {\n runInNextPostDigestOrNow(() => {\n const callbacks = findCallbacks(parentNode, node, eventParam);\n\n if (callbacks.length) {\n callbacks.forEach((callback) => {\n callback(element, phase, data);\n });\n cleanupEventListeners(phase, node);\n } else {\n cleanupEventListeners(phase, node);\n }\n });\n runnerParam.progress(eventParam, phase, data);\n }\n\n function close(reject) {\n clearGeneratedClasses(element, options);\n applyAnimationClasses(element, options);\n applyAnimationStyles(element, options);\n options.domOperation();\n runner.complete(!reject);\n }\n }\n\n /**\n * Closes and cleans up any child animations found under the given node.\n *\n * Looks for elements that have the NG_ANIMATE_ATTR_NAME attribute, checks their\n * animation state, ends running animations, and removes them from the\n * activeAnimationsLookup if appropriate.\n *\n * @param {Element | ParentNode} node\n * The DOM node whose descendant animations should be closed.\n *\n * @returns {void}\n */\n function closeChildAnimations(node) {\n const children = node.querySelectorAll(`[${NG_ANIMATE_ATTR_NAME}]`);\n\n children.forEach((child) => {\n const state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME), 10);\n\n const animationDetails = activeAnimationsLookup.get(child);\n\n if (animationDetails) {\n switch (state) {\n case RUNNING_STATE:\n animationDetails.runner.end();\n /* falls through */\n case PRE_DIGEST_STATE:\n activeAnimationsLookup.delete(child);\n break;\n }\n }\n });\n }\n\n function clearElementAnimationState(node) {\n node.removeAttribute(NG_ANIMATE_ATTR_NAME);\n activeAnimationsLookup.delete(node);\n }\n\n /**\n * This fn returns false if any of the following is true:\n * a) animations on any parent element are disabled, and animations on the element aren't explicitly allowed\n * b) a parent element has an ongoing structural animation, and animateChildren is false\n * c) the element is not a child of the body\n * d) the element is not a child of the $rootElement\n */\n function areAnimationsAllowed(node, parentNode) {\n const bodyNode = document.body;\n\n const rootNode = $injector.get(\"$rootElement\");\n\n let bodyNodeDetected = node === bodyNode || node.nodeName === \"HTML\";\n\n let rootNodeDetected = node === rootNode;\n\n let parentAnimationDetected = false;\n\n let elementDisabled = disabledElementsLookup.get(node);\n\n let animateChildren;\n\n let parentHost = getOrSetCacheData(node, NG_ANIMATE_PIN_DATA);\n\n if (parentHost) {\n parentNode = parentHost;\n }\n\n while (parentNode) {\n if (!rootNodeDetected) {\n // AngularTS doesn't want to attempt to animate elements outside of the application\n // therefore we need to ensure that the rootElement is an ancestor of the current element\n rootNodeDetected = parentNode === rootNode;\n }\n\n if (parentNode.nodeType !== NodeType._ELEMENT_NODE) {\n // no point in inspecting the #document element\n break;\n }\n\n const details = activeAnimationsLookup.get(parentNode) || {};\n\n // either an enter, leave or move animation will commence\n // therefore we can't allow any animations to take place\n // but if a parent animation is class-based then that's ok\n if (!parentAnimationDetected) {\n const parentNodeDisabled = disabledElementsLookup.get(parentNode);\n\n if (parentNodeDisabled === true && elementDisabled !== false) {\n // disable animations if the user hasn't explicitly enabled animations on the\n // current element\n elementDisabled = true;\n // element is disabled via parent element, no need to check anything else\n break;\n } else if (parentNodeDisabled === false) {\n elementDisabled = false;\n }\n parentAnimationDetected = details.structural;\n }\n\n if (isUndefined(animateChildren) || animateChildren === true) {\n const value = getOrSetCacheData(\n parentNode,\n NG_ANIMATE_CHILDREN_DATA,\n );\n\n if (isDefined(value)) {\n animateChildren = value;\n }\n }\n\n // there is no need to continue traversing at this point\n if (parentAnimationDetected && animateChildren === false) break;\n\n if (!bodyNodeDetected) {\n // we also need to ensure that the element is or will be a part of the body element\n // otherwise it is pointless to even issue an animation to be rendered\n bodyNodeDetected = parentNode === bodyNode;\n }\n\n if (bodyNodeDetected && rootNodeDetected) {\n // If both body and root have been found, any other checks are pointless,\n // as no animation data should live outside the application\n break;\n }\n\n if (!rootNodeDetected) {\n // If `rootNode` is not detected, check if `parentNode` is pinned to another element\n parentHost = getOrSetCacheData(parentNode, NG_ANIMATE_PIN_DATA);\n\n if (parentHost) {\n // The pin target element becomes the next parent element\n parentNode = parentHost;\n continue;\n }\n }\n\n // eslint-disable-next-line prefer-destructuring\n parentNode = parentNode.parentNode;\n }\n\n const allowAnimation =\n (!parentAnimationDetected || animateChildren) &&\n elementDisabled !== true;\n\n return allowAnimation && rootNodeDetected && bodyNodeDetected;\n }\n\n function markElementAnimationState(node, state, details) {\n details = details || {};\n details.state = state;\n\n node.setAttribute(NG_ANIMATE_ATTR_NAME, state);\n\n const oldValue = activeAnimationsLookup.get(node);\n\n const newValue = oldValue ? extend(oldValue, details) : details;\n\n activeAnimationsLookup.set(node, newValue);\n }\n },\n ];\n}\n","import { isArray, isFunction, isObject } from \"../shared/utils.js\";\nimport {\n applyAnimationClassesFactory,\n applyAnimationStyles,\n prepareAnimationOptions,\n} from \"./shared.js\";\nimport { $injectTokens as $t } from \"../injection-tokens.js\";\nimport { AnimateRunner } from \"./runner/animate-runner.js\";\n\n// TODO: use caching here to speed things up for detection\n// TODO: add documentation\n\nAnimateJsProvider.$inject = [`${$t.$animate}Provider`];\nexport function AnimateJsProvider($animateProvider) {\n this.$get = [\n $t.$injector,\n /**\n *\n * @param {ng.InjectorService} $injector\n * @returns\n */\n function ($injector) {\n const applyAnimationClasses = applyAnimationClassesFactory();\n\n // $animateJs(element, 'enter');\n return function (element, event, classes, options) {\n let animationClosed = false;\n\n // the `classes` argument is optional and if it is not used\n // then the classes will be resolved from the element's className\n // property as well as options.addClass/options.removeClass.\n if (arguments.length === 3 && isObject(classes)) {\n options = classes;\n classes = null;\n }\n\n options = prepareAnimationOptions(options);\n\n if (!classes) {\n classes = element.getAttribute(\"class\") || \"\";\n\n if (options.addClass) {\n classes += ` ${options.addClass}`;\n }\n\n if (options.removeClass) {\n classes += ` ${options.removeClass}`;\n }\n }\n\n const classesToAdd = options.addClass;\n\n const classesToRemove = options.removeClass;\n\n // the lookupAnimations function returns a series of animation objects that are\n // matched up with one or more of the CSS classes. These animation objects are\n // defined via the module.animation factory function. If nothing is detected then\n // we don't return anything which then makes $animation query the next driver.\n const animations = lookupAnimations(classes);\n\n let before;\n\n let after;\n\n if (animations.length) {\n let afterFn;\n\n let beforeFn;\n\n if (event === \"leave\") {\n beforeFn = \"leave\";\n afterFn = \"afterLeave\"; // TODO(matsko): get rid of this\n } else {\n beforeFn = `before${event.charAt(0).toUpperCase()}${event.substring(1)}`;\n afterFn = event;\n }\n\n if (event !== \"enter\" && event !== \"move\") {\n before = packageAnimations(\n element,\n event,\n options,\n animations,\n beforeFn,\n );\n }\n after = packageAnimations(\n element,\n event,\n options,\n animations,\n afterFn,\n );\n }\n\n // no matching animations\n if (!before && !after) return undefined;\n\n function applyOptions() {\n options.domOperation();\n applyAnimationClasses(element, options);\n }\n\n function close() {\n animationClosed = true;\n applyOptions();\n applyAnimationStyles(element, options);\n }\n\n let runner;\n\n return {\n $$willAnimate: true,\n end() {\n if (runner) {\n runner.end();\n } else {\n close();\n runner = new AnimateRunner();\n runner.complete(true);\n }\n\n return runner;\n },\n start() {\n if (runner) {\n return runner;\n }\n\n runner = new AnimateRunner();\n /** @type {(cancelled?: boolean) => void} */\n let closeActiveAnimations;\n\n const chain = [];\n\n if (before) {\n const runnerBefore = new AnimateRunner({\n end(fn) {\n // call the before animation function, then mark runner done\n const endFn =\n before(fn) ||\n (() => {\n /* empty */\n });\n\n endFn();\n },\n cancel() {\n (\n before(true) ||\n (() => {\n /* empty */\n })\n )();\n },\n });\n\n chain.push(runnerBefore);\n }\n\n if (chain.length) {\n const runnerApplyOptions = new AnimateRunner({\n end(fn) {\n applyOptions();\n fn(true);\n },\n cancel() {\n applyOptions();\n },\n });\n\n chain.push(runnerApplyOptions);\n } else {\n applyOptions();\n }\n\n if (after) {\n const runnerAfter = new AnimateRunner({\n end(fn) {\n const endFn =\n after(fn) ||\n (() => {\n /* empty */\n });\n\n endFn();\n },\n cancel() {\n (\n after(true) ||\n (() => {\n /* empty */\n })\n )();\n },\n });\n\n chain.push(runnerAfter);\n }\n\n // finally, set host for overall runner\n runner.setHost({\n end() {\n endAnimations();\n },\n cancel() {\n endAnimations(true);\n },\n });\n\n AnimateRunner._chain(chain, onComplete);\n\n return runner;\n\n function onComplete(success) {\n close();\n runner.complete(success);\n }\n\n function endAnimations(cancelled) {\n if (!animationClosed) {\n (\n closeActiveAnimations ||\n (() => {\n /* empty */\n })\n )(cancelled);\n onComplete(cancelled);\n }\n }\n },\n };\n\n function executeAnimationFn(\n fn,\n elemParam,\n eventParam,\n optionsParam,\n onDone,\n ) {\n let args;\n\n switch (eventParam) {\n case \"animate\":\n args = [elemParam, optionsParam.from, optionsParam.to, onDone];\n break;\n\n case \"setClass\":\n args = [elemParam, classesToAdd, classesToRemove, onDone];\n break;\n\n case \"addClass\":\n args = [elemParam, classesToAdd, onDone];\n break;\n\n case \"removeClass\":\n args = [elemParam, classesToRemove, onDone];\n break;\n\n default:\n args = [elemParam, onDone];\n break;\n }\n\n args.push(optionsParam);\n\n let value = fn.apply(fn, args);\n\n if (value) {\n if (isFunction(value.start)) {\n value = value.start();\n }\n\n if (value instanceof AnimateRunner) {\n value.done(onDone);\n } else if (isFunction(value)) {\n // optional onEnd / onCancel callback\n return value;\n }\n }\n\n return () => {\n /* empty */\n };\n }\n\n function groupEventedAnimations(\n elemParam,\n eventParam,\n optionsParam,\n animationsParam,\n fnName,\n ) {\n const operations = [];\n\n animationsParam.forEach((ani) => {\n const animation = ani[fnName];\n\n if (!animation) return;\n\n // note that all of these animations will run in parallel\n operations.push(() => {\n const newRunner = new AnimateRunner({\n end() {\n onAnimationComplete();\n },\n cancel() {\n onAnimationComplete(true);\n },\n });\n\n const endProgressCb = executeAnimationFn(\n animation,\n elemParam,\n eventParam,\n optionsParam,\n (result) => {\n const cancelled = result === false;\n\n onAnimationComplete(cancelled);\n },\n );\n\n let resolved = false;\n\n const onAnimationComplete = function (rejected) {\n if (!resolved) {\n resolved = true;\n (\n endProgressCb ||\n (() => {\n /* empty */\n })\n )(rejected);\n newRunner.complete(!rejected);\n }\n };\n\n return newRunner;\n });\n });\n\n return operations;\n }\n\n function packageAnimations(\n elementParam,\n eventParam,\n optionsParam,\n animationsParam,\n fnName,\n ) {\n let operations = groupEventedAnimations(\n elementParam,\n eventParam,\n optionsParam,\n animationsParam,\n fnName,\n );\n\n if (operations.length === 0) {\n let a;\n\n let b;\n\n if (fnName === \"beforeSetClass\") {\n a = groupEventedAnimations(\n elementParam,\n \"removeClass\",\n optionsParam,\n animationsParam,\n \"beforeRemoveClass\",\n );\n b = groupEventedAnimations(\n elementParam,\n \"addClass\",\n optionsParam,\n animationsParam,\n \"beforeAddClass\",\n );\n } else if (fnName === \"setClass\") {\n a = groupEventedAnimations(\n elementParam,\n \"removeClass\",\n optionsParam,\n animationsParam,\n \"removeClass\",\n );\n b = groupEventedAnimations(\n elementParam,\n \"addClass\",\n optionsParam,\n animationsParam,\n \"addClass\",\n );\n }\n\n if (a) {\n operations = operations.concat(a);\n }\n\n if (b) {\n operations = operations.concat(b);\n }\n }\n\n if (operations.length === 0) return undefined;\n\n // TODO(matsko): add documentation\n return function startAnimation(callback) {\n const runners = [];\n\n if (operations.length) {\n operations.forEach((animateFn) => {\n runners.push(animateFn());\n });\n }\n\n if (runners.length) {\n AnimateRunner._all(runners, callback);\n } else {\n callback();\n }\n\n return function endFn(reject) {\n runners.forEach((i) => {\n if (reject) {\n i.cancel();\n } else {\n i.end();\n }\n });\n };\n };\n }\n };\n\n function lookupAnimations(classes) {\n classes = isArray(classes) ? classes : classes.split(\" \");\n const matches = [];\n\n const flagMap = {};\n\n for (let i = 0; i < classes.length; i++) {\n const klass = classes[i];\n\n const animationFactory =\n $animateProvider.$$registeredAnimations[klass];\n\n if (animationFactory && !flagMap[klass]) {\n matches.push($injector.get(animationFactory));\n flagMap[klass] = true;\n }\n }\n\n return matches;\n }\n },\n ];\n}\n","import {\n deleteCacheData,\n getCacheData,\n removeElementData,\n setCacheData,\n} from \"../shared/dom.js\";\nimport { mergeClasses } from \"../shared/utils.js\";\nimport {\n NG_ANIMATE_CLASSNAME,\n PREPARE_CLASS_SUFFIX,\n applyAnimationClassesFactory,\n applyAnimationStyles,\n prepareAnimationOptions,\n} from \"./shared.js\";\nimport { $injectTokens as $t } from \"../injection-tokens.js\";\nimport { AnimateRunner } from \"./runner/animate-runner.js\";\n\nconst RUNNER_STORAGE_KEY = \"$$animationRunner\";\n\nconst PREPARE_CLASSES_KEY = \"$$animatePrepareClasses\";\n\nexport function AnimationProvider() {\n const NG_ANIMATE_REF_ATTR = \"ng-animate-ref\";\n\n const drivers = (this.drivers = []);\n\n function setRunner(element, runner) {\n setCacheData(element, RUNNER_STORAGE_KEY, runner);\n }\n\n function removeRunner(element) {\n deleteCacheData(element, RUNNER_STORAGE_KEY);\n }\n\n function getRunner(element) {\n return getCacheData(element, RUNNER_STORAGE_KEY);\n }\n\n this.$get = [\n $t.$rootScope,\n $t.$injector,\n $t.$$rAFScheduler,\n $t.$$animateCache,\n /**\n *\n * @param {ng.RootScopeService} $rootScope\n * @param {ng.InjectorService} $injector\n * @param {import(\"./raf-scheduler.js\").RafScheduler} $$rAFScheduler\n * @param {*} $$animateCache\n * @returns\n */\n function ($rootScope, $injector, $$rAFScheduler, $$animateCache) {\n const animationQueue = [];\n\n const applyAnimationClasses = applyAnimationClassesFactory();\n\n function sortAnimations(animations) {\n const tree = { children: [] };\n\n let i;\n\n const lookup = new Map();\n\n // this is done first beforehand so that the map\n // is filled with a list of the elements that will be animated\n\n for (i = 0; i < animations.length; i++) {\n const animation = animations[i];\n\n lookup.set(\n animation.domNode,\n (animations[i] = {\n domNode: animation.domNode,\n element: animation.element,\n fn: animation.fn,\n children: [],\n }),\n );\n }\n\n for (i = 0; i < animations.length; i++) {\n processNode(animations[i]);\n }\n\n return flatten(tree);\n\n function processNode(entry) {\n if (entry.processed) return entry;\n entry.processed = true;\n\n const elementNode = entry.domNode;\n\n let { parentNode } = elementNode;\n\n lookup.set(elementNode, entry);\n\n let parentEntry;\n\n while (parentNode) {\n parentEntry = lookup.get(parentNode);\n\n if (parentEntry) {\n if (!parentEntry.processed) {\n parentEntry = processNode(parentEntry);\n }\n break;\n }\n // eslint-disable-next-line prefer-destructuring\n parentNode = parentNode.parentNode;\n }\n\n (parentEntry || tree).children.push(entry);\n\n return entry;\n }\n\n function flatten(theeParam) {\n const result = [];\n\n const queue = [];\n\n for (i = 0; i < theeParam.children.length; i++) {\n queue.push(theeParam.children[i]);\n }\n\n let remainingLevelEntries = queue.length;\n\n let nextLevelEntries = 0;\n\n let row = [];\n\n for (let j = 0; j < queue.length; j++) {\n const entry = queue[j];\n\n if (remainingLevelEntries <= 0) {\n remainingLevelEntries = nextLevelEntries;\n nextLevelEntries = 0;\n result.push(row);\n row = [];\n }\n row.push(entry);\n entry.children.forEach((childEntry) => {\n nextLevelEntries++;\n queue.push(childEntry);\n });\n remainingLevelEntries--;\n }\n\n if (row.length) {\n result.push(row);\n }\n\n return result;\n }\n }\n\n // TODO(matsko): document the signature in a better way\n return function (elementParam, event, options) {\n options = prepareAnimationOptions(options);\n const isStructural = [\"enter\", \"move\", \"leave\"].indexOf(event) >= 0;\n\n // there is no animation at the current moment, however\n // these runner methods will get later updated with the\n // methods leading into the driver's end/cancel methods\n // for now they just stop the animation from starting\n const runner = new AnimateRunner({\n end() {\n close();\n },\n cancel() {\n close(true);\n },\n });\n\n if (!drivers.length) {\n close();\n\n return runner;\n }\n\n let classes = mergeClasses(\n elementParam.getAttribute(\"class\"),\n mergeClasses(options.addClass, options.removeClass),\n );\n\n let { tempClasses } = options;\n\n if (tempClasses) {\n classes += ` ${tempClasses}`;\n options.tempClasses = null;\n }\n\n if (isStructural) {\n setCacheData(\n elementParam,\n PREPARE_CLASSES_KEY,\n `ng-${event}${PREPARE_CLASS_SUFFIX}`,\n );\n }\n\n setRunner(elementParam, runner);\n\n animationQueue.push({\n // this data is used by the postDigest code and passed into\n // the driver step function\n element: elementParam,\n classes,\n event,\n structural: isStructural,\n options,\n beforeStart,\n close,\n });\n\n elementParam.addEventListener(\"$destroy\", handleDestroyedElement);\n\n // we only want there to be one function called within the post digest\n // block. This way we can group animations for all the animations that\n // were apart of the same postDigest flush call.\n if (animationQueue.length > 1) return runner;\n $rootScope.$postUpdate(() => {\n const animations = [];\n\n animationQueue.forEach((entry) => {\n // the element was destroyed early on which removed the runner\n // form its storage. This means we can't animate this element\n // at all and it already has been closed due to destruction.\n if (getRunner(entry.element)) {\n animations.push(entry);\n } else {\n entry.close();\n }\n });\n\n // now any future animations will be in another postDigest\n animationQueue.length = 0;\n\n const groupedAnimations = groupAnimations(animations);\n\n const toBeSortedAnimations = [];\n\n groupedAnimations.forEach((animationEntry) => {\n const fromElement = animationEntry.from\n ? animationEntry.from.element\n : animationEntry.element;\n\n let extraClasses = options.addClass;\n\n extraClasses =\n (extraClasses ? `${extraClasses} ` : \"\") + NG_ANIMATE_CLASSNAME;\n const cacheKey = $$animateCache.cacheKey(\n fromElement,\n animationEntry.event,\n extraClasses,\n options.removeClass,\n );\n\n toBeSortedAnimations.push({\n element: fromElement,\n domNode: fromElement,\n fn: function triggerAnimationStart() {\n let startAnimationFn;\n\n const closeFn = animationEntry.close;\n\n // in the event that we've cached the animation status for this element\n // and it's in fact an invalid animation (something that has duration = 0)\n // then we should skip all the heavy work from here on\n if (\n $$animateCache.containsCachedAnimationWithoutDuration(\n cacheKey,\n )\n ) {\n closeFn();\n\n return;\n }\n\n // it's important that we apply the `ng-animate` CSS class and the\n // temporary classes before we do any driver invoking since these\n // CSS classes may be required for proper CSS detection.\n animationEntry.beforeStart();\n\n // in the event that the element was removed before the digest runs or\n // during the RAF sequencing then we should not trigger the animation.\n const targetElement = animationEntry.anchors\n ? animationEntry.from.element || animationEntry.to.element\n : animationEntry.element;\n\n if (getRunner(targetElement)) {\n const operation = invokeFirstDriver(animationEntry);\n\n if (operation) {\n startAnimationFn = operation.start;\n }\n }\n\n if (!startAnimationFn) {\n closeFn();\n } else {\n const animationRunner = startAnimationFn();\n\n animationRunner.done((status) => {\n closeFn(!status);\n });\n updateAnimationRunners(animationEntry, animationRunner);\n }\n },\n });\n });\n\n // we need to sort each of the animations in order of parent to child\n // relationships. This ensures that the child classes are applied at the\n // right time.\n const finalAnimations = sortAnimations(toBeSortedAnimations);\n\n for (let i = 0; i < finalAnimations.length; i++) {\n const innerArray = finalAnimations[i];\n\n for (let j = 0; j < innerArray.length; j++) {\n const entry = innerArray[j];\n\n const { element } = entry;\n\n // the RAFScheduler code only uses functions\n finalAnimations[i][j] = entry.fn;\n\n // the first row of elements shouldn't have a prepare-class added to them\n // since the elements are at the top of the animation hierarchy and they\n // will be applied without a RAF having to pass...\n if (i === 0) {\n removeElementData(element, PREPARE_CLASSES_KEY);\n continue;\n }\n\n const prepareClassName = getCacheData(\n element,\n PREPARE_CLASSES_KEY,\n );\n\n if (prepareClassName) {\n element.classList.add(prepareClassName);\n }\n }\n }\n // @ts-ignore\n $$rAFScheduler(finalAnimations);\n });\n\n return runner;\n\n // TODO(matsko): change to reference nodes\n function getAnchorNodes(node) {\n const SELECTOR = `[${NG_ANIMATE_REF_ATTR}]`;\n\n const items = node.hasAttribute(NG_ANIMATE_REF_ATTR)\n ? [node]\n : node.querySelectorAll(SELECTOR);\n\n const anchors = [];\n\n items.forEach((nodeItem) => {\n const attr = nodeItem.getAttribute(NG_ANIMATE_REF_ATTR);\n\n if (attr && attr.length) {\n anchors.push(nodeItem);\n }\n });\n\n return anchors;\n }\n\n function groupAnimations(animations) {\n const preparedAnimations = [];\n\n const refLookup = {};\n\n animations.forEach((animation, index) => {\n // eslint-disable-next-line no-shadow\n const { element, event } = animation;\n\n const node = element;\n\n const enterOrMove = [\"enter\", \"move\"].indexOf(event) >= 0;\n\n const anchorNodes = animation.structural\n ? getAnchorNodes(node)\n : [];\n\n if (anchorNodes.length) {\n const direction = enterOrMove ? \"to\" : \"from\";\n\n anchorNodes.forEach((anchor) => {\n const key = anchor.getAttribute(NG_ANIMATE_REF_ATTR);\n\n refLookup[key] = refLookup[key] || {};\n refLookup[key][direction] = {\n animationID: index,\n element: anchor,\n };\n });\n } else {\n preparedAnimations.push(animation);\n }\n });\n\n const usedIndicesLookup = {};\n\n const anchorGroups = {};\n\n Object.values(refLookup).forEach((operations) => {\n const { from } = operations;\n\n const { to } = operations;\n\n if (!from || !to) {\n // only one of these is set therefore we can't have an\n // anchor animation since all three pieces are required\n const index = from ? from.animationID : to.animationID;\n\n const indexKey = index.toString();\n\n if (!usedIndicesLookup[indexKey]) {\n usedIndicesLookup[indexKey] = true;\n preparedAnimations.push(animations[index]);\n }\n\n return;\n }\n\n const fromAnimation = animations[from.animationID];\n\n const toAnimation = animations[to.animationID];\n\n const lookupKey = from.animationID.toString();\n\n if (!anchorGroups[lookupKey]) {\n const group = (anchorGroups[lookupKey] = {\n structural: true,\n beforeStart() {\n fromAnimation.beforeStart();\n toAnimation.beforeStart();\n },\n close() {\n fromAnimation.close();\n toAnimation.close();\n },\n classes: cssClassesIntersection(\n fromAnimation.classes,\n toAnimation.classes,\n ),\n from: fromAnimation,\n to: toAnimation,\n anchors: [], // TODO(matsko): change to reference nodes\n });\n\n // the anchor animations require that the from and to elements both have at least\n // one shared CSS class which effectively marries the two elements together to use\n // the same animation driver and to properly sequence the anchor animation.\n if (group.classes.length) {\n preparedAnimations.push(group);\n } else {\n preparedAnimations.push(fromAnimation);\n preparedAnimations.push(toAnimation);\n }\n }\n\n anchorGroups[lookupKey].anchors.push({\n out: from.element,\n in: to.element,\n });\n });\n\n return preparedAnimations;\n }\n\n function cssClassesIntersection(a, b) {\n a = a.split(\" \");\n b = b.split(\" \");\n const matches = [];\n\n for (let i = 0; i < a.length; i++) {\n const aa = a[i];\n\n if (aa.substring(0, 3) === \"ng-\") continue;\n\n for (let j = 0; j < b.length; j++) {\n if (aa === b[j]) {\n matches.push(aa);\n break;\n }\n }\n }\n\n return matches.join(\" \");\n }\n\n function invokeFirstDriver(animationDetails) {\n // we loop in reverse order since the more general drivers (like CSS and JS)\n // may attempt more elements, but custom drivers are more particular\n for (let i = drivers.length - 1; i >= 0; i--) {\n const driverName = drivers[i];\n\n const factory = $injector.get(driverName);\n\n const driver = factory(animationDetails);\n\n if (driver) {\n return driver;\n }\n }\n\n return undefined;\n }\n\n function beforeStart() {\n tempClasses =\n (tempClasses ? `${tempClasses} ` : \"\") + NG_ANIMATE_CLASSNAME;\n elementParam.className += ` ${tempClasses}`;\n let prepareClassName = getCacheData(\n elementParam,\n PREPARE_CLASSES_KEY,\n );\n\n if (prepareClassName) {\n elementParam.classList.remove(prepareClassName);\n prepareClassName = null;\n }\n }\n\n function updateAnimationRunners(animation, newRunner) {\n if (animation.from && animation.to) {\n update(animation.from.element);\n update(animation.to.element);\n } else {\n update(animation.element);\n }\n\n function update(el) {\n getRunner(el).setHost(newRunner);\n }\n }\n\n function handleDestroyedElement() {\n (event !== \"leave\" || !options.$$domOperationFired) &&\n getRunner(elementParam)?.end();\n }\n\n function close(rejected) {\n removeRunner(elementParam);\n\n applyAnimationClasses(elementParam, options);\n applyAnimationStyles(elementParam, options);\n options.domOperation();\n\n if (tempClasses) {\n tempClasses\n .split(\" \")\n .forEach((cls) => elementParam.classList.remove(cls));\n }\n\n runner.complete(!rejected);\n }\n };\n },\n ];\n}\n","/**\n * @typedef {import('./interface.ts').RafScheduler} RafScheduler\n */\n\n/**\n * Service provider that creates a requestAnimationFrame-based scheduler.\n * @type {ng.ServiceProvider}\n */\nexport class RafSchedulerProvider {\n constructor() {\n /**\n * Internal task queue, where each item is an array of functions to run.\n * @type {Array<Array<() => void>>}\n */\n this._queue = [];\n\n /**\n * ID of the currently scheduled animation frame (if any).\n * Used for cancellation and tracking.\n * @type {number|null}\n */\n this._cancelFn = null;\n }\n\n /**\n * Processes the next batch of tasks in the animation frame.\n * Executes the first group of functions in the queue, then\n * schedules the next frame if needed.\n */\n _nextTick() {\n if (!this._queue.length) return;\n\n const items = this._queue.shift();\n\n items.forEach((fn) => fn());\n\n if (!this._cancelFn) {\n this._cancelFn = window.requestAnimationFrame(() => {\n this._cancelFn = null;\n this._nextTick();\n });\n }\n }\n\n /**\n * Returns the scheduler function.\n * This function allows tasks to be queued for execution on future animation frames.\n * It also has helper methods and state attached.\n *\n * @returns {RafScheduler} The scheduler function with `queue` and `waitUntilQuiet`.\n */\n $get() {\n /**\n * The main scheduler function.\n * Accepts an array of functions and schedules them to run in the next available frame(s).\n *\n * @type {RafScheduler}\n */\n const scheduler = (tasks) => {\n // Clone the input array to avoid mutating the original.\n this._queue = this._queue.concat(tasks);\n this._nextTick();\n };\n\n /**\n * Exposes the internal queue to consumers (read-only use preferred).\n * This matches the type signature for RafScheduler.\n */\n scheduler._queue = this._queue;\n\n /**\n * Cancels any pending frame and runs the given function once the frame is idle.\n * Useful for debounced updates.\n *\n * @param {Function} fn - Function to run when the animation frame is quiet.\n */\n scheduler._waitUntilQuiet = (fn) => {\n if (this._cancelFn !== null) {\n window.cancelAnimationFrame(this._cancelFn);\n this._cancelFn = null;\n }\n\n this._cancelFn = window.requestAnimationFrame(() => {\n this._cancelFn = null;\n fn();\n this._nextTick();\n });\n };\n\n return scheduler;\n }\n}\n","const KEY = \"$animId\";\n\nlet parentCounter = 0;\n\nconst cache = new Map();\n\nexport function animateCache() {\n return {\n /**\n * Generates a unique cache key based on the node's parent and other parameters.\n * @param {HTMLElement} node - The DOM node to generate the cache key for.\n * @param {string} method - The animation method being applied.\n * @param {string} [addClass] - Class to add during the animation.\n * @param {string} [removeClass] - Class to remove during the animation.\n * @returns {string} - The generated cache key.\n */\n cacheKey(node, method, addClass, removeClass) {\n const { parentNode } = node;\n\n const parentID = parentNode[KEY] ?? (parentNode[KEY] = ++parentCounter);\n\n const parts = [parentID, method, node.getAttribute(\"class\")];\n\n if (addClass) parts.push(addClass);\n\n if (removeClass) parts.push(removeClass);\n\n return parts.join(\" \");\n },\n\n /**\n * Checks if a cached animation without a duration exists.\n * @param {string} key - The cache key to check.\n * @returns {boolean} - True if an invalid animation is cached, false otherwise.\n */\n containsCachedAnimationWithoutDuration(key) {\n const entry = cache.get(key);\n\n return entry ? !entry.isValid : false;\n },\n\n /**\n * Clears the cache.\n * @returns {void}\n */\n flush() {\n cache.clear();\n },\n\n /**\n * Gets the count of a specific cache entry.\n * @param {string} key - The cache key to count.\n * @returns {number} - The count of the cache entry.\n */\n count(key) {\n return cache.get(key)?.total ?? 0;\n },\n\n /**\n * Retrieves a value associated with a specific cache key.\n * @param {string} key - The cache key to retrieve.\n * @returns {any} - The value associated with the cache key.\n */\n get(key) {\n return cache.get(key)?.value;\n },\n\n /**\n * Adds or updates a cache entry.\n * @param {string} key - The cache key to add or update.\n * @param {any} value - The value to store.\n * @param {boolean} isValid - Whether the cache entry is valid.\n */\n put(key, value, isValid) {\n const entry = cache.get(key);\n\n if (entry) {\n entry.total++;\n entry.value = value;\n } else {\n cache.set(key, { total: 1, value, isValid });\n }\n },\n };\n}\n\nexport function AnimateCacheProvider() {\n this.$get = [animateCache];\n}\n","import { isString } from \"../shared/utils.js\";\nimport { AnimateRunner } from \"./runner/animate-runner.js\";\nimport { concatWithSpace } from \"./shared.js\";\n\nconst NG_ANIMATE_SHIM_CLASS_NAME = \"ng-animate-shim\";\n\nconst NG_ANIMATE_ANCHOR_CLASS_NAME = \"ng-anchor\";\n\nconst NG_OUT_ANCHOR_CLASS_NAME = \"ng-anchor-out\";\n\nconst NG_IN_ANCHOR_CLASS_NAME = \"ng-anchor-in\";\n\nAnimateCssDriverProvider.$inject = [\"$$animationProvider\"];\nexport function AnimateCssDriverProvider($$animationProvider) {\n $$animationProvider.drivers.push(\"$$animateCssDriver\");\n\n function isDocumentFragment(node) {\n // eslint-disable-next-line no-magic-numbers\n return node.parentNode && node.parentNode.nodeType === 11;\n }\n\n /**\n * @returns {Function}\n */\n this.$get = [\n \"$animateCss\",\n \"$rootElement\",\n /**\n *\n * @param {*} $animateCss\n * @param {Element} $rootElement\n * @returns\n */\n function ($animateCss, $rootElement) {\n const bodyNode = document.body;\n\n const rootNode = $rootElement;\n\n const rootBodyElement =\n // this is to avoid using something that exists outside of the body\n // we also special case the doc fragment case because our unit test code\n // appends the $rootElement to the body after the app has been bootstrapped\n isDocumentFragment(rootNode) || bodyNode.contains(rootNode)\n ? rootNode\n : bodyNode;\n\n return function initDriverFn(animationDetails) {\n return animationDetails.from && animationDetails.to\n ? prepareFromToAnchorAnimation(\n animationDetails.from,\n animationDetails.to,\n animationDetails.anchors,\n )\n : prepareRegularAnimation(animationDetails);\n };\n\n function prepareAnchoredAnimation(outAnchor, inAnchor) {\n const clone = outAnchor.cloneNode(true);\n\n const startingClasses = filterCssClasses(getClassVal(clone));\n\n outAnchor[0].classList.add(NG_ANIMATE_SHIM_CLASS_NAME);\n inAnchor[0].classList.add(NG_ANIMATE_SHIM_CLASS_NAME);\n\n clone.classList.add(NG_ANIMATE_ANCHOR_CLASS_NAME);\n\n rootBodyElement.append(clone);\n\n let animatorIn;\n\n const animatorOut = prepareOutAnimation();\n\n // the user may not end up using the `out` animation and\n // only making use of the `in` animation or vice-versa.\n // In either case we should allow this and not assume the\n // animation is over unless both animations are not used.\n if (!animatorOut) {\n animatorIn = prepareInAnimation();\n\n if (!animatorIn) {\n return end();\n }\n }\n\n const startingAnimator = animatorOut || animatorIn;\n\n return {\n start() {\n const runner = new AnimateRunner({\n end: endFn,\n cancel: endFn,\n });\n\n let currentAnimation = startingAnimator.start();\n\n currentAnimation.done(() => {\n currentAnimation = null;\n\n if (!animatorIn) {\n animatorIn = prepareInAnimation();\n\n if (animatorIn) {\n currentAnimation = animatorIn.start();\n currentAnimation.done(() => {\n currentAnimation = null;\n end();\n runner.complete();\n });\n\n return currentAnimation;\n }\n }\n // in the event that there is no `in` animation\n end();\n runner.complete();\n\n return undefined;\n });\n\n return runner;\n\n function endFn() {\n if (currentAnimation) {\n currentAnimation.end();\n }\n }\n },\n };\n\n function calculateAnchorStyles(anchor) {\n const styles = {};\n\n const coords = anchor.getBoundingClientRect();\n\n // we iterate directly since safari messes up and doesn't return\n // all the keys for the coords object when iterated\n [\"width\", \"height\", \"top\", \"left\"].forEach((key) => {\n let value = coords[key];\n\n switch (key) {\n case \"top\":\n value += bodyNode.scrollTop;\n break;\n case \"left\":\n value += bodyNode.scrollLeft;\n break;\n }\n styles[key] = `${Math.floor(value)}px`;\n });\n\n return styles;\n }\n\n function prepareOutAnimation() {\n const animator = $animateCss(clone, {\n addClass: NG_OUT_ANCHOR_CLASS_NAME,\n delay: true,\n from: calculateAnchorStyles(outAnchor),\n });\n\n // read the comment within `prepareRegularAnimation` to understand\n // why this check is necessary\n return animator.$$willAnimate ? animator : null;\n }\n\n function getClassVal(element) {\n return element.getAttribute(\"class\") || \"\";\n }\n\n function prepareInAnimation() {\n const endingClasses = filterCssClasses(getClassVal(inAnchor));\n\n const toAdd = getUniqueValues(endingClasses, startingClasses);\n\n const toRemove = getUniqueValues(startingClasses, endingClasses);\n\n const animator = $animateCss(clone, {\n to: calculateAnchorStyles(inAnchor),\n addClass: `${NG_IN_ANCHOR_CLASS_NAME} ${toAdd}`,\n removeClass: `${NG_OUT_ANCHOR_CLASS_NAME} ${toRemove}`,\n delay: true,\n });\n\n // read the comment within `prepareRegularAnimation` to understand\n // why this check is necessary\n return animator.$$willAnimate ? animator : null;\n }\n\n function end() {\n clone.remove();\n outAnchor[0].classList.remove(NG_ANIMATE_SHIM_CLASS_NAME);\n inAnchor[0].classList.remove(NG_ANIMATE_SHIM_CLASS_NAME);\n }\n }\n\n function prepareFromToAnchorAnimation(from, to, anchors) {\n const fromAnimation = prepareRegularAnimation(from);\n\n const toAnimation = prepareRegularAnimation(to);\n\n const anchorAnimations = [];\n\n anchors.forEach((anchor) => {\n const outElement = anchor.out;\n\n const inElement = anchor.in;\n\n const animator = prepareAnchoredAnimation(outElement, inElement);\n\n if (animator) {\n anchorAnimations.push(animator);\n }\n });\n\n // no point in doing anything when there are no elements to animate\n if (!fromAnimation && !toAnimation && anchorAnimations.length === 0)\n return undefined;\n\n return {\n start() {\n const animationRunners = [];\n\n if (fromAnimation) {\n animationRunners.push(fromAnimation.start());\n }\n\n if (toAnimation) {\n animationRunners.push(toAnimation.start());\n }\n\n anchorAnimations.forEach((animation) => {\n animationRunners.push(animation.start());\n });\n\n const runner = new AnimateRunner({\n end: endFn,\n cancel: endFn, // CSS-driven animations cannot be cancelled, only ended\n });\n\n AnimateRunner._all(animationRunners, (status) => {\n runner.complete(status);\n });\n\n return runner;\n\n function endFn() {\n animationRunners.forEach((runnerItem) => {\n runnerItem.end();\n });\n }\n },\n };\n }\n\n function prepareRegularAnimation(animationDetails) {\n const options = animationDetails.options || {};\n\n if (animationDetails.structural) {\n options.event = animationDetails.event;\n options.structural = true;\n options.applyClassesEarly = true;\n\n // we special case the leave animation since we want to ensure that\n // the element is removed as soon as the animation is over. Otherwise\n // a flicker might appear or the element may not be removed at all\n if (animationDetails.event === \"leave\") {\n options.onDone = options.domOperation;\n }\n }\n\n // We assign the preparationClasses as the actual animation event since\n // the internals of $animateCss will just suffix the event token values\n // with `-active` to trigger the animation.\n if (options.preparationClasses) {\n options.event = concatWithSpace(\n options.event,\n options.preparationClasses,\n );\n }\n\n const animator = $animateCss(animationDetails.element, options);\n\n // the driver lookup code inside of $$animation attempts to spawn a\n // driver one by one until a driver returns a.$$willAnimate animator object.\n // $animateCss will always return an object, however, it will pass in\n // a flag as a hint as to whether an animation was detected or not\n\n return animator.$$willAnimate ? animator : null;\n }\n },\n ];\n}\n\nfunction filterCssClasses(classes) {\n // remove all the `ng-` stuff\n return classes.replace(/\\bng-\\S+\\b/g, \"\");\n}\n\nfunction getUniqueValues(a, b) {\n if (isString(a)) a = a.split(\" \");\n\n if (isString(b)) b = b.split(\" \");\n\n return a.filter((val) => b.indexOf(val) === -1).join(\" \");\n}\n","import { AnimateRunner } from \"./runner/animate-runner.js\";\n\nAnimateJsDriverProvider.$inject = [\"$$animationProvider\"];\nexport function AnimateJsDriverProvider($$animationProvider) {\n $$animationProvider.drivers.push(\"$$animateJsDriver\");\n this.$get = [\n \"$$animateJs\",\n /**\n *\n * @param {*} $$animateJs\n */\n function ($$animateJs) {\n return function initDriverFn(animationDetails) {\n if (animationDetails.from && animationDetails.to) {\n const fromAnimation = prepareAnimation(animationDetails.from);\n\n const toAnimation = prepareAnimation(animationDetails.to);\n\n if (!fromAnimation && !toAnimation) return undefined;\n\n return {\n start() {\n const animationRunners = [];\n\n if (fromAnimation) {\n animationRunners.push(fromAnimation.start());\n }\n\n if (toAnimation) {\n animationRunners.push(toAnimation.start());\n }\n\n AnimateRunner._all(animationRunners, done);\n\n const runner = new AnimateRunner({\n end: endFnFactory(),\n cancel: endFnFactory(),\n });\n\n return runner;\n\n function endFnFactory() {\n return function () {\n animationRunners.forEach((x) => {\n // at this point we cannot cancel animations for groups just yet. 1.5+\n x.end();\n });\n };\n }\n\n function done(status) {\n runner.complete(status);\n }\n },\n };\n }\n\n return prepareAnimation(animationDetails);\n };\n\n function prepareAnimation(animationDetails) {\n // TODO(matsko): make sure to check for grouped animations and delegate down to normal animations\n const { element, event, options, classes } = animationDetails;\n\n return $$animateJs(element, event, classes, options);\n }\n },\n ];\n}\n","import { $injectTokens } from \"../injection-tokens.js\";\nngAnimateSwapDirective.$inject = [$injectTokens.$animate];\n/**\n * @returns {ng.Directive}\n */\nexport function ngAnimateSwapDirective($animate) {\n return {\n restrict: \"A\",\n transclude: \"element\",\n terminal: true,\n priority: 550, // We use 550 here to ensure that the directive is caught before others,\n // but after `ngIf` (at priority 600).\n link(scope, $element, attrs, _ctrl, $transclude) {\n let previousElement;\n\n let previousScope;\n\n scope.$watch(attrs.ngAnimateSwap || attrs.for, (value) => {\n if (previousElement) {\n $animate.leave(previousElement);\n }\n\n if (previousScope) {\n previousScope.$destroy();\n previousScope = null;\n }\n\n if (value) {\n $transclude((clone, childScope) => {\n previousElement = clone;\n previousScope = childScope;\n $animate.enter(clone, null, $element);\n });\n }\n });\n },\n };\n}\n","import { isString } from \"../shared/utils.js\";\nimport { NG_ANIMATE_CHILDREN_DATA } from \"./shared.js\";\nimport { setCacheData } from \"../shared/dom.js\";\nimport { $injectTokens as $t } from \"../injection-tokens.js\";\n\n$$AnimateChildrenDirective.$inject = [$t.$interpolate];\n\n/**\n * @param {*} $interpolate\n * @returns {import(\"../interface.ts\").Directive}\n */\nexport function $$AnimateChildrenDirective($interpolate) {\n return {\n link(scope, element, attrs) {\n const val = attrs.ngAnimateChildren;\n\n if (isString(val) && val.length === 0) {\n // empty attribute\n setCacheData(element, NG_ANIMATE_CHILDREN_DATA, true);\n } else {\n // Interpolate and set the value, so that it is available to\n // animations that run right after compilation\n setData($interpolate(val)(scope));\n attrs.$observe(\"ngAnimateChildren\", setData);\n }\n\n function setData(value) {\n value = value === \"on\" || value === \"true\";\n setCacheData(element, NG_ANIMATE_CHILDREN_DATA, value);\n }\n },\n };\n}\n","import {\n entries,\n isArray,\n isDate,\n isFunction,\n isRegExp,\n isString,\n} from \"./utils.js\";\n\nexport function equals(o1, o2) {\n if (o1 === o2) return true;\n\n if (o1 === null || o2 === null) return false;\n\n if (Number.isNaN(o1) && Number.isNaN(o2)) return true; // NaN === NaN\n const t1 = typeof o1,\n t2 = typeof o2;\n\n if (t1 !== t2 || t1 !== \"object\") return false;\n const tup = [o1, o2];\n\n if (tup.every(isArray)) return _arraysEq(o1, o2);\n\n if (tup.every(isDate)) return o1.getTime() === o2.getTime();\n\n if (tup.every(isRegExp)) return o1.toString() === o2.toString();\n\n if (tup.every(isFunction)) return true; // meh\n\n if ([isFunction, isArray, isDate, isRegExp].some((fn) => !!fn(tup))) {\n return false;\n }\n const keys = {};\n\n for (const key in o1) {\n if (!equals(o1[key], o2[key])) return false;\n keys[key] = true;\n }\n\n for (const key in o2) {\n if (!keys[key]) return false;\n }\n\n return true;\n}\n\n/**\n * prototypal inheritance helper.\n * Creates a new object which has `parent` object as its prototype, and then copies the properties from `extra` onto it\n */\n\n/**\n * prototypal inheritance helper.\n * Creates a new object which has `parent` object as its prototype, and then copies the properties from `extra` onto it.\n *\n * @param {Object} parent - The object to be used as the prototype.\n * @param {Object} [extra] - The object containing additional properties to be copied.\n * @returns {Object} - A new object with `parent` as its prototype and properties from `extra`.\n */\nexport function inherit(parent, extra) {\n const newObj = Object.create(parent);\n\n if (extra) {\n Object.assign(newObj, extra);\n }\n\n return newObj;\n}\n\n/**\n * Given an array, and an item, if the item is found in the array, it removes it (in-place).\n * The same array is returned\n * @param {Array} array\n * @param {any} obj\n * @returns {Array}\n */\nexport function removeFrom(array, obj) {\n const i = array.indexOf(obj);\n\n if (i !== -1) array.splice(i, 1);\n\n return array;\n}\n\n/**\n * Applies a set of defaults to an options object. The options object is filtered\n * to only those properties of the objects in the defaultsList.\n * Earlier objects in the defaultsList take precedence when applying defaults.\n */\nexport function defaults(opts, ...defaultsList) {\n const defaultVals = Object.assign({}, ...defaultsList.reverse());\n\n return Object.assign(defaultVals, pick(opts || {}, Object.keys(defaultVals)));\n}\n\n/**\n * Finds the common ancestor path between two states.\n *\n * @param {Object} first The first state.\n * @param {Object} second The second state.\n * @return {Array} Returns an array of state names in descending order, not including the root.\n */\nexport function ancestors(first, second) {\n const path = [];\n\n for (const i in first.path) {\n if (first.path[i] !== second.path[i]) break;\n path.push(first.path[i]);\n }\n\n return path;\n}\n/**\n * Return a copy of the object only containing the whitelisted properties.\n *\n * #### Example:\n * ```\n * var foo = { a: 1, b: 2, c: 3 };\n * var ab = pick(foo, ['a', 'b']); // { a: 1, b: 2 }\n * ```\n * @param obj the source object\n * @param propNames an Array of strings, which are the whitelisted property names\n */\nexport function pick(obj, propNames) {\n const objCopy = {};\n\n for (const _prop in obj) {\n if (propNames.indexOf(_prop) !== -1) {\n objCopy[_prop] = obj[_prop];\n }\n }\n\n return objCopy;\n}\n/**\n * Return a copy of the object omitting the blacklisted properties.\n *\n * @example\n * ```\n *\n * var foo = { a: 1, b: 2, c: 3 };\n * var ab = omit(foo, ['a', 'b']); // { c: 3 }\n * ```\n * @param obj the source object\n * @param propNames an Array of strings, which are the blacklisted property names\n */\nexport function omit(obj, propNames) {\n return Object.keys(obj)\n .filter((x) => !propNames.includes(x))\n .reduce((acc, key) => ((acc[key] = obj[key]), acc), {});\n}\n\n/** Filters an Array or an Object's properties based on a predicate */\nexport function filter(collection, callback) {\n const arr = isArray(collection),\n result = arr ? [] : {};\n\n const accept = arr ? (x) => result.push(x) : (x, key) => (result[key] = x);\n\n entries(collection).forEach(([i, item]) => {\n if (callback(item, i)) accept(item, i);\n });\n\n return result;\n}\n\n/** Finds an object from an array, or a property of an object, that matches a predicate */\nexport function find(collection, callback) {\n let result;\n\n entries(collection).forEach(([i, item]) => {\n if (result) return;\n\n if (callback(item, i)) result = item;\n });\n\n return result;\n}\n\n/** Maps an array or object properties using a callback function */\nexport function map(collection, callback, target) {\n target = target || (isArray(collection) ? [] : {});\n entries(collection).forEach(([i, item]) => (target[i] = callback(item, i)));\n\n return target;\n}\n\n/**\n * Reduce function that returns true if all of the values are truthy.\n *\n * @example\n * ```\n *\n * let vals = [ 1, true, {}, \"hello world\"];\n * vals.reduce(allTrueR, true); // true\n *\n * vals.push(0);\n * vals.reduce(allTrueR, true); // false\n * ```\n */\nexport const allTrueR = (memo, elem) => memo && elem;\n/**\n * Reduce function that returns true if any of the values are truthy.\n *\n * * @example\n * ```\n *\n * let vals = [ 0, null, undefined ];\n * vals.reduce(anyTrueR, true); // false\n *\n * vals.push(\"hello world\");\n * vals.reduce(anyTrueR, true); // true\n * ```\n */\nexport const anyTrueR = (memo, elem) => memo || elem;\n/**\n * Reduce function which un-nests a single level of arrays\n * @example\n * ```\n *\n * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n * input.reduce(unnestR, []) // [ \"a\", \"b\", \"c\", \"d\", [ \"double, \"nested\" ] ]\n * ```\n */\nexport const unnestR = (memo, elem) => memo.concat(elem);\n/**\n * Reduce function which recursively un-nests all arrays\n *\n * @example\n * ```\n *\n * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n * input.reduce(unnestR, []) // [ \"a\", \"b\", \"c\", \"d\", \"double, \"nested\" ]\n * ```\n */\nexport const flattenR = (memo, elem) =>\n isArray(elem) ? memo.concat(elem.reduce(flattenR, [])) : pushR(memo, elem);\n/**\n * Reduce function that pushes an object to an array, then returns the array.\n * Mostly just for [[flattenR]] and [[uniqR]]\n */\nexport function pushR(arr, obj) {\n arr.push(obj);\n\n return arr;\n}\n/** Reduce function that filters out duplicates */\nexport const uniqR = (acc, token) =>\n acc.includes(token) ? acc : pushR(acc, token);\n/**\n * Return a new array with a single level of arrays unnested.\n *\n * @example\n * ```\n *\n * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n * unnest(input) // [ \"a\", \"b\", \"c\", \"d\", [ \"double, \"nested\" ] ]\n * ```\n */\nexport const unnest = (arr) => arr.reduce(unnestR, []);\n\n/**\n * Given a .filter Predicate, builds a .filter Predicate which throws an error if any elements do not pass.\n * @example\n * ```\n *\n * let isNumber = (obj) => typeof(obj) === 'number';\n * let allNumbers = [ 1, 2, 3, 4, 5 ];\n * allNumbers.filter(assertPredicate(isNumber)); //OK\n *\n * let oneString = [ 1, 2, 3, 4, \"5\" ];\n * oneString.filter(assertPredicate(isNumber, \"Not all numbers\")); // throws Error(\"\"Not all numbers\"\");\n * ```\n */\nexport const assertPredicate = assertFn;\n\nexport function assertFn(predicateOrMap, errMsg = \"assert failure\") {\n return (obj) => {\n const result = predicateOrMap(obj);\n\n if (!result) {\n throw new Error(errMsg);\n }\n\n return result;\n };\n}\n/**\n * Like _.pairs: Given an object, returns an array of key/value pairs\n *\n * @example\n * ```\n *\n * pairs({ foo: \"FOO\", bar: \"BAR }) // [ [ \"foo\", \"FOO\" ], [ \"bar\": \"BAR\" ] ]\n * ```\n */\nexport const pairs = (obj) => Object.keys(obj).map((key) => [key, obj[key]]);\n/**\n * Given two or more parallel arrays, returns an array of tuples where\n * each tuple is composed of [ a[i], b[i], ... z[i] ]\n *\n * @example\n * ```\n *\n * let foo = [ 0, 2, 4, 6 ];\n * let bar = [ 1, 3, 5, 7 ];\n * let baz = [ 10, 30, 50, 70 ];\n * arrayTuples(foo, bar); // [ [0, 1], [2, 3], [4, 5], [6, 7] ]\n * arrayTuples(foo, bar, baz); // [ [0, 1, 10], [2, 3, 30], [4, 5, 50], [6, 7, 70] ]\n * ```\n */\nexport function arrayTuples(...args) {\n if (args.length === 0) return [];\n const maxArrayLen = args.reduce(\n (min, arr) => Math.min(arr.length, min),\n Number.MAX_SAFE_INTEGER,\n );\n\n const result = [];\n\n for (let i = 0; i < maxArrayLen; i++) {\n // This is a hot function\n // Unroll when there are 1-4 arguments\n switch (args.length) {\n case 1:\n result.push([args[0][i]]);\n break;\n case 2:\n result.push([args[0][i], args[1][i]]);\n break;\n case 3:\n result.push([args[0][i], args[1][i], args[2][i]]);\n break;\n case 4:\n result.push([args[0][i], args[1][i], args[2][i], args[3][i]]);\n break;\n default:\n result.push(args.map((array) => array[i]));\n break;\n }\n }\n\n return result;\n}\n/**\n * Reduce function which builds an object from an array of [key, value] pairs.\n *\n * Each iteration sets the key/val pair on the memo object, then returns the memo for the next iteration.\n *\n * Each keyValueTuple should be an array with values [ key: string, value: any ]\n *\n * @example\n * ```\n *\n * var pairs = [ [\"fookey\", \"fooval\"], [\"barkey\", \"barval\"] ]\n *\n * var pairsToObj = pairs.reduce((memo, pair) => applyPairs(memo, pair), {})\n * // pairsToObj == { fookey: \"fooval\", barkey: \"barval\" }\n *\n * // Or, more simply:\n * var pairsToObj = pairs.reduce(applyPairs, {})\n * // pairsToObj == { fookey: \"fooval\", barkey: \"barval\" }\n * ```\n */\nexport function applyPairs(memo, keyValTuple) {\n let key, value;\n\n if (isArray(keyValTuple)) [key, value] = keyValTuple;\n\n if (!isString(key)) throw new Error(\"invalid parameters to applyPairs\");\n memo[key] = value;\n\n return memo;\n}\n\n/**\n * Returns the last element of an array, or undefined if the array is empty.\n * @template T\n * @param {T[]} arr - The input array.\n * @returns {T | undefined} The last element or undefined.\n */\nexport function tail(arr) {\n return arr.length > 0 ? arr[arr.length - 1] : undefined;\n}\n\n/**\n * shallow copy from src to dest\n */\nexport function copy(src, dest) {\n if (dest) Object.keys(dest).forEach((key) => delete dest[key]);\n\n if (!dest) dest = {};\n\n return Object.assign(dest, src);\n}\n\nfunction _arraysEq(a1, a2) {\n if (a1.length !== a2.length) return false;\n\n for (let i = 0; i < a1.length; i++) {\n if (!equals(a1[i], a2[i])) return false;\n }\n\n return true;\n}\n// issue #2676\nexport const silenceUncaughtInPromise = (promise) =>\n promise.catch(() => 0) && promise;\nexport const silentRejection = (error) =>\n silenceUncaughtInPromise(Promise.reject(error));\n","/**\n * Returns a new function for [Partial Application](https://en.wikipedia.org/wiki/Partial_application) of the original function.\n *\n * Given a function with N parameters, returns a new function that supports partial application.\n * The new function accepts anywhere from 1 to N parameters. When that function is called with M parameters,\n * where M is less than N, it returns a new function that accepts the remaining parameters. It continues to\n * accept more parameters until all N parameters have been supplied.\n *\n *\n * This contrived example uses a partially applied function as an predicate, which returns true\n * if an object is found in both arrays.\n * @example\n * ```\n * // returns true if an object is in both of the two arrays\n * function inBoth(array1, array2, object) {\n * return array1.indexOf(object) !== -1 &&\n * array2.indexOf(object) !== 1;\n * }\n * let obj1, obj2, obj3, obj4, obj5, obj6, obj7\n * let foos = [obj1, obj3]\n * let bars = [obj3, obj4, obj5]\n *\n * // A curried \"copy\" of inBoth\n * let curriedInBoth = curry(inBoth);\n * // Partially apply both the array1 and array2\n * let inFoosAndBars = curriedInBoth(foos, bars);\n *\n * // Supply the final argument; since all arguments are\n * // supplied, the original inBoth function is then called.\n * let obj1InBoth = inFoosAndBars(obj1); // false\n *\n * // Use the inFoosAndBars as a predicate.\n * // Filter, on each iteration, supplies the final argument\n * let allObjs = [ obj1, obj2, obj3, obj4, obj5, obj6, obj7 ];\n * let foundInBoth = allObjs.filter(inFoosAndBars); // [ obj3 ]\n *\n * ```\n *\n * @param fn\n * @returns {*|function(): (*|any)}\n */\nexport function curry(fn) {\n const curried = (...args) => {\n if (args.length >= fn.length) {\n return fn(...args);\n }\n\n return (...nextArgs) => curried(...args, ...nextArgs);\n };\n\n return curried;\n}\n\n/**\n * Given a varargs list of functions, returns a function that composes the argument functions, right-to-left\n * given: f(x), g(x), h(x)\n * let composed = compose(f,g,h)\n * then, composed is: f(g(h(x)))\n */\nexport function compose(...fns) {\n const start = fns.length - 1;\n\n return (...args) => {\n let i = start;\n\n let result = fns[start](...args);\n\n while (i--) {\n result = fns[i](result);\n }\n\n return result;\n };\n}\n\n/**\n * Given a property name and a value, returns a function that returns a boolean based on whether\n * the passed object has a property that matches the value\n * let obj = { foo: 1, name: \"blarg\" };\n * let getName = propEq(\"name\", \"blarg\");\n * getName(obj) === true\n */\nexport const propEq = curry((name, _val, obj) => obj && obj[name] === _val);\n/**\n * Given a dotted property name, returns a function that returns a nested property from an object, or undefined\n * let obj = { id: 1, nestedObj: { foo: 1, name: \"blarg\" }, };\n * let getName = prop(\"nestedObj.name\");\n * getName(obj) === \"blarg\"\n * let propNotFound = prop(\"this.property.doesnt.exist\");\n * propNotFound(obj) === undefined\n */\nexport const parse = (path) => {\n const parts = path.split(\".\");\n\n return (obj) => parts.reduce((acc, key) => acc && acc[key], obj);\n};\n\n/**\n * Given a class constructor, returns a predicate function that checks\n * whether a given object is an instance of that class.\n *\n * @param {new (...args: any[]) => any} ctor - The class constructor to check against.\n * @returns {(obj: any) => boolean} A predicate function that returns true if the object is of the given class.\n */\nexport function is(ctor) {\n /**\n * Checks if the provided object is an instance of the given constructor.\n *\n * @param {any} obj - The object to test.\n * @returns {boolean} True if the object is an instance of the given class.\n */\n return function (obj) {\n return (\n (obj !== null && obj !== undefined && obj.constructor === ctor) ||\n obj instanceof ctor\n );\n };\n}\n\n/** Given a value, returns a function which returns the value */\nexport const val = (value) => () => value;\n\n/**\n * Sorta like Pattern Matching (a functional programming conditional construct)\n *\n * See http://c2.com/cgi/wiki?PatternMatching\n *\n * This is a conditional construct which allows a series of predicates and output functions\n * to be checked and then applied. Each predicate receives the input. If the predicate\n * returns truthy, then its matching output function (mapping function) is provided with\n * the input and, then the result is returned.\n *\n * Each combination (2-tuple) of predicate + output function should be placed in an array\n * of size 2: [ predicate, mapFn ]\n *\n * These 2-tuples should be put in an outer array.\n *\n * @example\n * ```\n *\n * // Here's a 2-tuple where the first element is the isString predicate\n * // and the second element is a function that returns a description of the input\n * let firstTuple = [ angular.isString, (input) => `Heres your string ${input}` ];\n *\n * // Second tuple: predicate \"isNumber\", mapfn returns a description\n * let secondTuple = [ angular.isNumber, (input) => `(${input}) That's a number!` ];\n *\n * let third = [ (input) => input === null, (input) => `Oh, null...` ];\n *\n * let fourth = [ (input) => input === undefined, (input) => `notdefined` ];\n *\n * let descriptionOf = pattern([ firstTuple, secondTuple, third, fourth ]);\n *\n * console.log(descriptionOf(undefined)); // 'notdefined'\n * console.log(descriptionOf(55)); // '(55) That's a number!'\n * console.log(descriptionOf(\"foo\")); // 'Here's your string foo'\n * ```\n *\n * @param struct A 2D array. Each element of the array should be an array, a 2-tuple,\n * with a Predicate and a mapping/output function\n * @returns {function(any): *}\n */\nexport function pattern(struct) {\n return function (item) {\n for (let i = 0; i < struct.length; i++) {\n if (struct[i][0](item)) return struct[i][1](item);\n }\n\n return undefined;\n };\n}\n","import { filter, map } from \"../../shared/common.js\";\nimport { isArray, isDefined } from \"../../shared/utils.js\";\n/**\n * An internal class which implements [[ParamTypeDefinition]].\n *\n * A [[ParamTypeDefinition]] is a plain javascript object used to register custom parameter types.\n * When a param type definition is registered, an instance of this class is created internally.\n *\n * This class has naive implementations for all the [[ParamTypeDefinition]] methods.\n *\n * Used by [[UrlMatcher]] when matching or formatting URLs, or comparing and validating parameter values.\n *\n * #### Example:\n * ```js\n * var paramTypeDef = {\n * decode: function(val) { return parseInt(val, 10); },\n * encode: function(val) { return val && val.toString(); },\n * equals: function(a, b) { return this.is(a) && a === b; },\n * is: function(val) { return angular.isNumber(val) && isFinite(val) && val % 1 === 0; },\n * pattern: /\\d+/\n * }\n *\n * var paramType = new ParamType(paramTypeDef);\n * ```\n */\nexport class ParamType {\n /**\n * @param def A configuration object which contains the custom type definition. The object's\n * properties will override the default methods and/or pattern in `ParamType`'s public interface.\n */\n constructor(def) {\n this.pattern = /.*/;\n this.inherit = true;\n Object.assign(this, def);\n this.name = undefined;\n }\n // consider these four methods to be \"abstract methods\" that should be overridden\n\n is(val) {\n return !!val;\n }\n\n encode(val) {\n return val;\n }\n\n decode(val) {\n return val;\n }\n\n equals(a, b) {\n return a === b;\n }\n\n $subPattern() {\n const sub = this.pattern.toString();\n\n return sub.substring(1, sub.length - 2);\n }\n\n toString() {\n return `{ParamType:${this.name}}`;\n }\n\n /** Given an encoded string, or a decoded object, returns a decoded object */\n $normalize(val) {\n return this.is(val) ? val : this.decode(val);\n }\n\n /**\n * Wraps an existing custom ParamType as an array of ParamType, depending on 'mode'.\n * e.g.:\n * - urlmatcher pattern \"/path?{queryParam[]:int}\"\n * - url: \"/path?queryParam=1&queryParam=2\n * - $stateParams.queryParam will be [1, 2]\n * if `mode` is \"auto\", then\n * - url: \"/path?queryParam=1 will create $stateParams.queryParam: 1\n * - url: \"/path?queryParam=1&queryParam=2 will create $stateParams.queryParam: [1, 2]\n */\n $asArray(mode, isSearch) {\n if (!mode) return this;\n\n if (mode === \"auto\" && !isSearch)\n throw new Error(\"'auto' array mode is for query parameters only\");\n\n return new ArrayType(this, mode);\n }\n}\n/** Wraps up a `ParamType` object to handle array values. */\nfunction ArrayType(type, mode) {\n // Wrap non-array value as array\n function arrayWrap(val) {\n return isArray(val) ? val : isDefined(val) ? [val] : [];\n }\n // Unwrap array value for \"auto\" mode. Return undefined for empty array.\n function arrayUnwrap(val) {\n switch (val.length) {\n case 0:\n return undefined;\n case 1:\n return mode === \"auto\" ? val[0] : val;\n default:\n return val;\n }\n }\n // Wraps type (.is/.encode/.decode) functions to operate on each value of an array\n function arrayHandler(callback, allTruthyMode) {\n return function handleArray(val) {\n if (isArray(val) && val.length === 0) return val;\n const arr = arrayWrap(val);\n\n const result = map(arr, callback);\n\n return allTruthyMode === true\n ? filter(result, (x) => !x).length === 0\n : arrayUnwrap(result);\n };\n }\n // Wraps type (.equals) functions to operate on each value of an array\n function arrayEqualsHandler(callback) {\n return function handleArray(val1, val2) {\n const left = arrayWrap(val1),\n right = arrayWrap(val2);\n\n if (left.length !== right.length) return false;\n\n for (let i = 0; i < left.length; i++) {\n if (!callback(left[i], right[i])) return false;\n }\n\n return true;\n };\n }\n [\"encode\", \"decode\", \"equals\", \"$normalize\"].forEach((name) => {\n const paramTypeFn = type[name].bind(type);\n\n const wrapperFn = name === \"equals\" ? arrayEqualsHandler : arrayHandler;\n\n this[name] = wrapperFn(paramTypeFn);\n });\n Object.assign(this, {\n dynamic: type.dynamic,\n name: type.name,\n pattern: type.pattern,\n inherit: type.inherit,\n raw: type.raw,\n is: arrayHandler(type.is.bind(type), true),\n $arrayMode: mode,\n });\n}\n","import { equals, inherit, map, pick } from \"../../shared/common.js\";\nimport { hasOwn, isDefined, isNullOrUndefined } from \"../../shared/utils.js\";\nimport { is } from \"../../shared/hof.js\";\nimport { ParamType } from \"./param-type.js\";\n/**\n * A registry for parameter types.\n *\n * This registry manages the built-in (and custom) parameter types.\n *\n * The built-in parameter types are:\n *\n * - [[string]]\n * - [[path]]\n * - [[query]]\n * - [[hash]]\n * - [[int]]\n * - [[bool]]\n * - [[date]]\n * - [[json]]\n * - [[any]]\n *\n * To register custom parameter types, use [[UrlConfig.type]], i.e.,\n *\n * ```js\n * router.urlService.config.type(customType)\n * ```\n */\nexport class ParamTypes {\n constructor() {\n this.enqueue = true;\n this.typeQueue = [];\n this.defaultTypes = pick(ParamTypes.prototype, [\n \"hash\",\n \"string\",\n \"query\",\n \"path\",\n \"int\",\n \"bool\",\n \"date\",\n \"json\",\n \"any\",\n ]);\n // Register default types. Store them in the prototype of this.types.\n const makeType = (definition, name) =>\n new ParamType(Object.assign({ name }, definition));\n\n this.types = inherit(map(this.defaultTypes, makeType), {});\n }\n\n /**\n * Registers a parameter type\n *\n * End users should call [[UrlMatcherFactory.type]], which delegates to this method.\n */\n type(name, definition, definitionFn) {\n if (!isDefined(definition)) return this.types[name];\n\n if (hasOwn(this.types, name))\n throw new Error(`A type named '${name}' has already been defined.`);\n this.types[name] = new ParamType(Object.assign({ name }, definition));\n\n if (definitionFn) {\n this.typeQueue.push({ name, def: definitionFn });\n\n if (!this.enqueue) this._flushTypeQueue();\n }\n\n return this;\n }\n\n _flushTypeQueue() {\n while (this.typeQueue.length) {\n const type = this.typeQueue.shift();\n\n if (type.pattern)\n throw new Error(\"You cannot override a type's .pattern at runtime.\");\n Object.assign(\n this.types[type.name],\n window.angular.$injector.invoke(type.def),\n );\n }\n }\n}\nfunction initDefaultTypes() {\n const makeDefaultType = (def) => {\n const valToString = (val) =>\n !isNullOrUndefined(val) ? val.toString() : val;\n\n const defaultTypeBase = {\n encode: valToString,\n decode: valToString,\n is: is(String),\n pattern: /.*/,\n\n equals: (a, b) => a === b, // allow coersion for null/undefined/\"\"\n };\n\n return Object.assign({}, defaultTypeBase, def);\n };\n\n // Default Parameter Type Definitions\n Object.assign(ParamTypes.prototype, {\n string: makeDefaultType({}),\n path: makeDefaultType({\n pattern: /[^/]*/,\n }),\n query: makeDefaultType({}),\n hash: makeDefaultType({\n inherit: false,\n }),\n int: makeDefaultType({\n decode: (val) => parseInt(val, 10),\n is(val) {\n return !isNullOrUndefined(val) && this.decode(val.toString()) === val;\n },\n pattern: /-?\\d+/,\n }),\n bool: makeDefaultType({\n encode: (val) => (val && 1) || 0,\n decode: (val) => parseInt(val, 10) !== 0,\n is: is(Boolean),\n pattern: /[01]/,\n }),\n date: makeDefaultType({\n encode(val) {\n return !this.is(val)\n ? undefined\n : [\n val.getFullYear(),\n `0${val.getMonth() + 1}`.slice(-2),\n `0${val.getDate()}`.slice(-2),\n ].join(\"-\");\n },\n decode(val) {\n if (this.is(val)) return val;\n const match = this.capture.exec(val);\n\n return match ? new Date(match[1], match[2] - 1, match[3]) : undefined;\n },\n is: (val) => val instanceof Date && !isNaN(val.valueOf()),\n equals(left, right) {\n return [\"getFullYear\", \"getMonth\", \"getDate\"].reduce(\n (acc, fn) => acc && left[fn]() === right[fn](),\n true,\n );\n },\n pattern: /[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,\n capture: /([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/,\n }),\n json: makeDefaultType({\n encode: JSON.stringify,\n decode: JSON.parse,\n is: is(Object),\n equals,\n pattern: /[^/]*/,\n }),\n // does not encode/decode\n any: makeDefaultType({\n encode: (x) => x,\n decode: (x) => x,\n is: () => true,\n equals,\n }),\n });\n}\ninitDefaultTypes();\n","import { ParamTypes } from \"../params/param-types\";\nimport { isDefined, isNullOrUndefined, isString } from \"../../shared/utils.js\";\n/**\n * An API to customize the URL behavior and retrieve URL configuration\n *\n * This API is used to customize the behavior of the URL.\n * This includes optional trailing slashes ([[strictMode]]), case sensitivity ([[caseInsensitive]]),\n * and custom parameter encoding (custom [[type]]).\n *\n * It also has information about the location (url) configuration such as [[port]] and [[baseHref]].\n * This information can be used to build absolute URLs, such as\n * `https://example.com:443/basepath/state/substate?param1=a#hashvalue`;\n *\n * This API is found at `router.urlService.config` (see: [[UIRouter.urlService]], [[URLService.config]])\n */\nexport class UrlConfigProvider {\n constructor() {\n /** @type {ParamTypes} */\n this.paramTypes = new ParamTypes();\n /** @type {boolean} */\n this._isCaseInsensitive = false;\n /** @type {boolean} */\n this._isStrictMode = true;\n /** @type {boolean} */\n this._defaultSquashPolicy = false;\n /**\n * Applys ng1-specific path parameter encoding\n *\n * The Angular 1 `$location` service is a bit weird.\n * It doesn't allow slashes to be encoded/decoded bi-directionally.\n *\n * See the writeup at https://github.com/angular-ui/ui-router/issues/2598\n *\n * This code patches the `path` parameter type so it encoded/decodes slashes as ~2F\n *\n */\n const pathType = this.type(\"path\");\n\n pathType.encode = (x) =>\n !isNullOrUndefined(x)\n ? x\n .toString()\n .replace(/([~/])/g, (match) => ({ \"~\": \"~~\", \"/\": \"~2F\" })[match])\n : x;\n pathType.decode = (x) =>\n !isNullOrUndefined(x)\n ? x\n .toString()\n .replace(/(~~|~2F)/g, (match) => ({ \"~~\": \"~\", \"~2F\": \"/\" })[match])\n : x;\n this.paramTypes.enqueue = false;\n this.paramTypes._flushTypeQueue();\n }\n\n $get = () => this;\n\n /**\n * Defines whether URL matching should be case sensitive (the default behavior), or not.\n *\n * #### Example:\n * ```js\n * // Allow case insensitive url matches\n * urlService.config.caseInsensitive(true);\n * ```\n *\n * @param value `false` to match URL in a case sensitive manner; otherwise `true`;\n * @returns the current value of caseInsensitive\n */\n caseInsensitive(value) {\n return (this._isCaseInsensitive = isDefined(value)\n ? value\n : this._isCaseInsensitive);\n }\n\n /**\n * Sets the default behavior when generating or matching URLs with default parameter values.\n *\n * #### Example:\n * ```js\n * // Remove default parameter values from the url\n * urlService.config.defaultSquashPolicy(true);\n * ```\n *\n * @param value A string that defines the default parameter URL squashing behavior.\n * - `nosquash`: When generating an href with a default parameter value, do not squash the parameter value from the URL\n * - `slash`: When generating an href with a default parameter value, squash (remove) the parameter value, and, if the\n * parameter is surrounded by slashes, squash (remove) one slash from the URL\n * - any other string, e.g. \"~\": When generating an href with a default parameter value, squash (remove)\n * the parameter value from the URL and replace it with this string.\n * @returns the current value of defaultSquashPolicy\n */\n defaultSquashPolicy(value) {\n if (\n isDefined(value) &&\n value !== true &&\n value !== false &&\n !isString(value)\n )\n throw new Error(\n `Invalid squash policy: ${value}. Valid policies: false, true, arbitrary-string`,\n );\n\n return (this._defaultSquashPolicy = isDefined(value)\n ? value\n : this._defaultSquashPolicy);\n }\n\n /**\n * Defines whether URLs should match trailing slashes, or not (the default behavior).\n *\n * #### Example:\n * ```js\n * // Allow optional trailing slashes\n * urlService.config.strictMode(false);\n * ```\n *\n * @param value `false` to match trailing slashes in URLs, otherwise `true`.\n * @returns the current value of strictMode\n */\n strictMode(value) {\n return (this._isStrictMode = isDefined(value) ? value : this._isStrictMode);\n }\n\n /**\n * Creates and registers a custom [[ParamType]] object\n *\n * A custom parameter type can be used to generate URLs with typed parameters or custom encoding/decoding.\n *\n * #### Note: Register custom types *before using them* in a state definition.\n *\n * #### Example:\n * ```js\n * // Encode object parameter as JSON string\n * urlService.config.type('myjson', {\n * encode: (obj) => JSON.stringify(obj),\n * decode: (str) => JSON.parse(str),\n * is: (val) => typeof(val) === 'object',\n * pattern: /[^/]+/,\n * equals: (a, b) => _.isEqual(a, b),\n * });\n * ```\n *\n * See [[ParamTypeDefinition]] for more examples\n *\n * @param name The type name.\n * @param definition The type definition. See [[ParamTypeDefinition]] for information on the values accepted.\n * @param definitionFn A function that is injected before the app runtime starts.\n * The result of this function should be a [[ParamTypeDefinition]].\n * The result is merged into the existing `definition`.\n * See [[ParamType]] for information on the values accepted.\n *\n * @returns if only the `name` parameter was specified: the currently registered [[ParamType]] object, or undefined\n */\n type(name, definition, definitionFn) {\n const type = this.paramTypes.type(name, definition, definitionFn);\n\n return !isDefined(definition) ? type : this;\n }\n}\n","import { ancestors } from \"../../shared/common.js\";\nimport { keys } from \"../../shared/utils.js\";\n\nexport class StateParams {\n constructor(params = {}) {\n Object.assign(this, params);\n }\n\n /**\n * Merges a set of parameters with all parameters inherited between the common parents of the\n * current state and a given destination state.\n *\n * @param {Object} newParams The set of parameters which will be composited with inherited params.\n * @param {Object} $current Internal definition of object representing the current state.\n * @param {Object} $to Internal definition of object representing state to transition to.\n */\n $inherit(newParams, $current, $to) {\n const parents = ancestors($current, $to),\n inherited = {},\n inheritList = [];\n\n for (const i in parents) {\n if (!parents[i] || !parents[i].params) continue;\n const parentParams = parents[i].params;\n\n const parentParamsKeys = keys(parentParams);\n\n if (!parentParamsKeys.length) continue;\n\n for (const j in parentParamsKeys) {\n if (\n parentParams[parentParamsKeys[j]].inherit === false ||\n inheritList.indexOf(parentParamsKeys[j]) >= 0\n )\n continue;\n inheritList.push(parentParamsKeys[j]);\n inherited[parentParamsKeys[j]] = this[parentParamsKeys[j]];\n }\n }\n\n return Object.assign({}, inherited, newParams);\n }\n}\n","import { isArray } from \"./utils.js\";\n\n/**\n * A simple bounded FIFO queue with optional eviction notifications.\n * @template T\n */\nexport class Queue {\n /**\n * @param {T[]} [items=[]] - Initial queue items.\n * @param {number|null} [limit=null] - Maximum allowed items before eviction (null = unlimited).\n */\n constructor(items = [], limit = null) {\n /** @type {T[]} */\n this._items = isArray(items) ? [...items] : [];\n\n /** @type {number|null} */\n this._limit = Number.isInteger(limit) && limit > 0 ? limit : null;\n\n /** @type {Array<(item: T) => void>} */\n this._evictListeners = [];\n }\n\n /**\n * Register a listener that will be called with the evicted item.\n * @param {(item: T) => void} listener\n */\n onEvict(listener) {\n this._evictListeners.push(listener);\n }\n\n /**\n * Adds an item to the end of the queue, evicting the head if over limit.\n * @param {T} item\n * @returns {T}\n */\n enqueue(item) {\n this._items.push(item);\n\n if (this._limit !== null && this._items.length > this._limit) {\n this.evict();\n }\n\n return item;\n }\n\n /**\n * Removes the head item and notifies eviction listeners.\n * @returns {T|undefined}\n */\n evict() {\n const item = this._items.shift();\n\n if (item !== undefined) {\n this._evictListeners.forEach((fn) => fn(item));\n }\n\n return item;\n }\n\n /**\n * Removes and returns the first item in the queue.\n * @returns {T|undefined}\n */\n dequeue() {\n return this._items.length > 0 ? this._items.shift() : undefined;\n }\n\n /**\n * Clears all items from the queue.\n * @returns {T[]} The previously stored items.\n */\n clear() {\n const cleared = [...this._items];\n\n this._items.length = 0;\n\n return cleared;\n }\n\n /**\n * Returns the current number of items.\n * @returns {number}\n */\n size() {\n return this._items.length;\n }\n\n /**\n * Removes a specific item from the queue.\n * @param {T} item\n * @returns {T|false} The removed item, or false if not found.\n */\n remove(item) {\n const index = this._items.indexOf(item);\n\n return index !== -1 ? this._items.splice(index, 1)[0] : false;\n }\n\n /**\n * Returns the item at the tail (last).\n * @returns {T|undefined}\n */\n peekTail() {\n return this._items[this._items.length - 1];\n }\n\n /**\n * Returns the item at the head (first).\n * @returns {T|undefined}\n */\n peekHead() {\n return this._items[0];\n }\n}\n","import { StateParams } from \"./params/state-params.js\";\nimport { Queue } from \"../shared/queue.js\";\n\n/** @typedef {import('../interface.ts').ServiceProvider} ServiceProvider } */\n\n/**\n * Global router state\n *\n * This is where we hold the global mutable state such as current state, current\n * params, current transition, etc.\n */\nexport class Router {\n constructor() {\n /**\n * Current parameter values\n *\n * The parameter values from the latest successful transition\n * @type {StateParams}\n */\n this.params = new StateParams();\n\n /**\n * @type {number}\n */\n this.lastStartedTransitionId = -1;\n\n /**\n * @type {Queue<import(\"./transition/transition.js\").Transition>}\n */\n this.transitionHistory = new Queue([], 1);\n\n /**\n * @type {Queue<import(\"./transition/transition.js\").Transition>}\n */\n this.successfulTransitions = new Queue([], 1);\n\n /**\n * @type {import(\"./state/interface.ts\").StateDeclaration|undefined}\n */\n this.current = undefined;\n\n /**\n * @type {import(\"./state/state-object.js\").StateObject|undefined}\n */\n this.$current = undefined;\n\n /**\n * @type {import(\"./transition/transition.js\").Transition|undefined}\n */\n this.transition = undefined;\n }\n\n $get = () => this;\n}\n","import { pushR, tail } from \"./common.js\";\nimport { pattern, val } from \"./hof.js\";\nimport { isInjectable, isPromise } from \"./predicates.js\";\nimport {\n isArray,\n isFunction,\n isNull,\n isObject,\n isString,\n isUndefined,\n} from \"./utils.js\";\n\n/**\n * Functions that manipulate strings\n */\n\nconst DOTS = \"...\";\n\n/**\n * Returns a string shortened to a maximum length\n *\n * If the string is already less than the `max` length, return the string.\n * Else return the string, shortened to `max - 3` and append three dots (\"...\").\n *\n * @param {number} max the maximum length of the string to return\n * @param {string} str the input string\n * @returns {string}\n */\nexport function maxLength(max, str) {\n if (str.length <= max) return str;\n\n return `${str.substring(0, max - DOTS.length)}${DOTS}`;\n}\n/**\n * Returns a string, with spaces added to the end, up to a desired str length\n *\n * If the string is already longer than the desired length, return the string.\n * Else returns the string, with extra spaces on the end, such that it reaches `length` characters.\n *\n * @param length the desired length of the string to return\n * @param str the input string\n */\nexport function padString(length, str) {\n while (str.length < length) str += \" \";\n\n return str;\n}\nexport function kebobString(camelCase) {\n return camelCase\n .replace(/^([A-Z])/, ($1) => $1.toLowerCase()) // replace first char\n .replace(/([A-Z])/g, ($1) => `-${$1.toLowerCase()}`); // replace rest\n}\n\nconst FN_LENGTH = 9;\n\nexport function functionToString(fn) {\n const fnStr = fnToString(fn);\n\n const namedFunctionMatch = fnStr.match(/^(function [^ ]+\\([^)]*\\))/);\n\n const toStr = namedFunctionMatch ? namedFunctionMatch[1] : fnStr;\n\n const fnName = fn.name || \"\";\n\n if (fnName && toStr.match(/function \\(/)) {\n return `function ${fnName}${toStr.substring(FN_LENGTH)}`;\n }\n\n return toStr;\n}\nexport function fnToString(fn) {\n const _fn = isArray(fn) ? fn.slice(-1)[0] : fn;\n\n return (_fn && _fn.toString()) || \"undefined\";\n}\n\nexport function stringify(value) {\n const seen = [];\n\n const isRejection = (obj) => {\n return (\n obj &&\n typeof obj.then === \"function\" &&\n obj.constructor.name === \"Rejection\"\n );\n };\n\n const hasToString = (obj) =>\n isObject(obj) &&\n !isArray(obj) &&\n obj.constructor !== Object &&\n isFunction(obj.toString);\n\n const stringifyPattern = pattern([\n [isUndefined, val(\"undefined\")],\n [isNull, val(\"null\")],\n [isPromise, val(\"[Promise]\")],\n [isRejection, (reg) => reg._transitionRejection.toString()],\n [hasToString, (str) => str.toString()],\n [isInjectable, functionToString],\n [val(true), (bool) => bool],\n ]);\n\n function format(item) {\n if (isObject(item)) {\n if (seen.indexOf(item) !== -1) return \"[circular ref]\";\n seen.push(item);\n }\n\n return stringifyPattern(item);\n }\n\n if (isUndefined(value)) {\n // Workaround for IE & Edge Spec incompatibility where replacer function would not be called when JSON.stringify\n // is given `undefined` as value. To work around that, we simply detect `undefined` and bail out early by\n // manually stringifying it.\n return format(value);\n }\n\n return JSON.stringify(value, (_key, item) => format(item)).replace(\n /\\\\\"/g,\n '\"',\n );\n}\n\nexport const stripLastPathElement = (str) => str.replace(/\\/[^/]*$/, \"\");\n/**\n * Splits on a delimiter, but returns the delimiters in the array\n *\n * #### Example:\n * ```js\n * var splitOnSlashes = splitOnDelim('/');\n * splitOnSlashes(\"/foo\"); // [\"/\", \"foo\"]\n * splitOnSlashes(\"/foo/\"); // [\"/\", \"foo\", \"/\"]\n * ```\n */\nexport function splitOnDelim(delim) {\n const re = new RegExp(`(${delim})`, \"g\");\n\n return (str) => str.split(re).filter(Boolean);\n}\n/**\n * Reduce fn that joins neighboring strings\n *\n * Given an array of strings, returns a new array\n * where all neighboring strings have been joined.\n *\n * #### Example:\n * ```js\n * let arr = [\"foo\", \"bar\", 1, \"baz\", \"\", \"qux\" ];\n * arr.reduce(joinNeighborsR, []) // [\"foobar\", 1, \"bazqux\" ]\n * ```\n */\nexport function joinNeighborsR(acc, str) {\n if (isString(tail(acc)) && isString(str))\n return acc.slice(0, -1).concat(tail(acc) + str);\n\n return pushR(acc, str);\n}\n","/**\n * # Transition tracing (debug)\n *\n * Enable transition tracing to print transition information to the console,\n * in order to help debug your application.\n * Tracing logs detailed information about each Transition to your console.\n *\n * To enable tracing, import the [[Trace]] singleton and enable one or more categories.\n *\n * ### ES6\n * ```js\n * import {trace} from \"@uirouter/core/index\";\n * trace.enable(1, 5); // TRANSITION and VIEWCONFIG\n * ```\n *\n * ### CJS\n * ```js\n * let trace = require(\"@uirouter/core\").trace;\n * trace.enable(\"TRANSITION\", \"VIEWCONFIG\");\n * ```\n *\n * ### Globals\n * ```js\n * let trace = window[\"@uirouter/core\"].trace;\n * trace.enable(); // Trace everything (very verbose)\n * ```\n *\n * ### Angular 1:\n * ```js\n * app.run($trace => $trace.enable());\n * ```\n *\n * @packageDocumentation\n */\nimport { parse } from \"../../shared/hof.js\";\nimport { isNumber, keys } from \"../../shared/utils.js\";\nimport {\n functionToString,\n maxLength,\n padString,\n stringify,\n} from \"../../shared/strings.js\";\nimport { $injectTokens } from \"../../injection-tokens.js\";\n\nconst MAX_PAD_LENGTH = 30;\n\nfunction ngViewString(ngView) {\n if (!ngView) return \"ng-view (defunct)\";\n const state = ngView.creationContext\n ? ngView.creationContext.name || \"(root)\"\n : \"(none)\";\n\n return `[ng-view#${ngView.id}:${ngView.fqn} (${ngView.name}@${state})]`;\n}\n\nconst viewConfigString = (viewConfig) => {\n const view = viewConfig.viewDecl;\n\n const state = view.$context.name || \"(root)\";\n\n return `[View#${viewConfig.$id} from '${state}' state]: target ng-view: '${view.$ngViewName}@${view.$ngViewContextAnchor}'`;\n};\n\nfunction normalizedCat(input) {\n return isNumber(input) ? Category[input] : Category[Category[input]];\n}\n/**\n * Trace categories Enum\n *\n * Enable or disable a category using [[Trace.enable]] or [[Trace.disable]]\n *\n * `trace.enable(Category.TRANSITION)`\n *\n * These can also be provided using a matching string, or position ordinal\n *\n * `trace.enable(\"TRANSITION\")`\n *\n * `trace.enable(1)`\n */\n\n/**\n * @enum {number}\n */\nexport const Category = {\n _RESOLVE: 0,\n _TRANSITION: 1,\n _HOOK: 2,\n _UIVIEW: 3,\n _VIEWCONFIG: 4,\n};\n\nconst _tid = parse(\"$id\");\n\nconst _rid = parse(\"router.$id\");\n\nconst transLbl = (trans) => `Transition #${_tid(trans)}-${_rid(trans)}`;\n\n/**\n * Prints ng-router Transition trace information to the console.\n */\nexport class Trace {\n constructor() {\n this._enabled = {};\n this.approximateDigests = 0;\n this.$logger = window.angular?.$injector?.get($injectTokens.$log);\n }\n\n _set(enabled, categories) {\n if (!categories.length) {\n categories = keys(Category)\n .map((k) => parseInt(k, 10))\n .filter((k) => !isNaN(k))\n .map((key) => Category[key]);\n }\n categories\n .map(normalizedCat)\n .forEach((category) => (this._enabled[category] = enabled));\n }\n\n enable(...categories) {\n this._set(true, categories);\n }\n\n disable(...categories) {\n this._set(false, categories);\n }\n\n /**\n * Retrieves the enabled stateus of a [[Category]]\n *\n * ```js\n * trace.enabled(\"VIEWCONFIG\"); // true or false\n * ```\n *\n * @returns boolean true if the category is enabled\n */\n enabled(category) {\n return !!this._enabled[normalizedCat(category)];\n }\n\n /** @internal called by ng-router code */\n traceTransitionStart(trans) {\n if (!this.enabled(Category._TRANSITION)) return;\n this.$logger.log(`${transLbl(trans)}: Started -> ${stringify(trans)}`);\n }\n\n /** @internal called by ng-router code */\n traceTransitionIgnored(trans) {\n if (!this.enabled(Category._TRANSITION)) return;\n this.$logger.log(`${transLbl(trans)}: Ignored <> ${stringify(trans)}`);\n }\n\n /** @internal called by ng-router code */\n traceHookInvocation(step, trans, options) {\n if (!this.enabled(Category._HOOK)) return;\n const event = parse(\"traceData.hookType\")(options) || \"internal\",\n context =\n parse(\"traceData.context.state.name\")(options) ||\n parse(\"traceData.context\")(options) ||\n \"unknown\",\n name = functionToString(step.registeredHook.callback);\n\n this.$logger.log(\n `${transLbl(trans)}: Hook -> ${event} context: ${context}, ${maxLength(200, name)}`,\n );\n }\n\n /** @internal called by ng-router code */\n traceHookResult(hookResult, trans) {\n if (!this.enabled(Category._HOOK)) return;\n this.$logger.log(\n `${transLbl(trans)}: <- Hook returned: ${maxLength(200, stringify(hookResult))}`,\n );\n }\n\n /** @internal called by ng-router code */\n traceResolvePath(path, when, trans) {\n if (!this.enabled(Category._RESOLVE)) return;\n this.$logger.log(`${transLbl(trans)}: Resolving ${path} (${when})`);\n }\n\n /** @internal called by ng-router code */\n traceResolvableResolved(resolvable, trans) {\n if (!this.enabled(Category._RESOLVE)) return;\n this.$logger.log(\n `${transLbl(trans)}: <- Resolved ${resolvable} to: ${maxLength(200, stringify(resolvable.data))}`,\n );\n }\n\n /** @internal called by ng-router code */\n traceError(reason, trans) {\n if (!this.enabled(Category._TRANSITION)) return;\n this.$logger.log(\n `${transLbl(trans)}: <- Rejected ${stringify(trans)}, reason: ${reason}`,\n );\n }\n\n /** @internal called by ng-router code */\n traceSuccess(finalState, trans) {\n if (!this.enabled(Category._TRANSITION)) return;\n this.$logger.log(\n `${transLbl(trans)}: <- Success ${stringify(trans)}, final state: ${finalState.name}`,\n );\n }\n\n /** @internal called by ng-router code */\n traceUIViewEvent(event, viewData, extra = \"\") {\n if (!this.enabled(Category._UIVIEW)) return;\n this.$logger.log(\n `ng-view: ${padString(MAX_PAD_LENGTH, event)} ${ngViewString(viewData)}${extra}`,\n );\n }\n\n /** @internal called by ng-router code */\n traceUIViewConfigUpdated(viewData, context) {\n if (!this.enabled(Category._UIVIEW)) return;\n this.traceUIViewEvent(\n \"Updating\",\n viewData,\n ` with ViewConfig from context='${context}'`,\n );\n }\n\n /** @internal called by ng-router code */\n traceUIViewFill(viewData, html) {\n if (!this.enabled(Category._UIVIEW)) return;\n this.traceUIViewEvent(\"Fill\", viewData, ` with: ${maxLength(200, html)}`);\n }\n\n /** @internal called by ng-router code */\n traceViewSync(pairs) {\n if (!this.enabled(Category._VIEWCONFIG)) return;\n const uivheader = \"uiview component fqn\";\n\n const cfgheader = \"view config state (view name)\";\n\n const mapping = pairs\n .map(({ ngView, viewConfig }) => {\n const uiv = ngView && ngView.fqn;\n\n const cfg =\n viewConfig &&\n `${viewConfig.viewDecl.$context.name}: (${viewConfig.viewDecl.$name})`;\n\n return { [uivheader]: uiv, [cfgheader]: cfg };\n })\n .sort((a, b) => (a[uivheader] || \"\").localeCompare(b[uivheader] || \"\"));\n\n this.$logger.table(mapping);\n }\n\n /** @internal called by ng-router code */\n traceViewServiceEvent(event, viewConfig) {\n if (!this.enabled(Category._VIEWCONFIG)) return;\n this.$logger.log(`VIEWCONFIG: ${event} ${viewConfigString(viewConfig)}`);\n }\n\n /** @internal called by ng-router code */\n traceViewServiceUIViewEvent(event, viewData) {\n if (!this.enabled(Category._VIEWCONFIG)) return;\n this.$logger.log(`VIEWCONFIG: ${event} ${ngViewString(viewData)}`);\n }\n}\n/**\n * The [[Trace]] singleton\n *\n * #### Example:\n * ```js\n * import {trace} from \"@uirouter/core/index\";\n * trace.enable(1, 5);\n * ```\n */\nexport const trace = new Trace();\n","import {\n assert,\n hasOwn,\n isFunction,\n isNullOrUndefined,\n isObject,\n} from \"../../shared/utils.js\";\nimport { trace } from \"../common/trace.js\";\nimport { stringify } from \"../../shared/strings.js\";\n\n// TODO: explicitly make this user configurable\nexport const defaultResolvePolicy = {\n when: \"LAZY\",\n async: \"WAIT\",\n};\n/**\n * The basic building block for the resolve system.\n *\n * Resolvables encapsulate a state's resolve's resolveFn, the resolveFn's declared dependencies, the wrapped (.promise),\n * and the unwrapped-when-complete (.data) result of the resolveFn.\n *\n * Resolvable.get() either retrieves the Resolvable's existing promise, or else invokes resolve() (which invokes the\n * resolveFn) and returns the resulting promise.\n *\n * Resolvable.get() and Resolvable.resolve() both execute within a context path, which is passed as the first\n * parameter to those fns.\n */\nexport class Resolvable {\n constructor(arg1, resolveFn, deps, policy, data) {\n this.resolved = false;\n this.promise = undefined;\n\n if (arg1 instanceof Resolvable) {\n Object.assign(this, arg1);\n } else if (isFunction(resolveFn)) {\n assert(!isNullOrUndefined(arg1), \"token argument is required\");\n this.token = arg1;\n this.policy = policy;\n this.resolveFn = resolveFn;\n this.deps = deps || [];\n this.data = data;\n this.resolved = data !== undefined;\n this.promise = this.resolved ? Promise.resolve(this.data) : undefined;\n } else if (\n isObject(arg1) &&\n arg1.token &&\n (hasOwn(arg1, \"resolveFn\") || hasOwn(arg1, \"data\"))\n ) {\n this.token = arg1.token;\n this.resolveFn = arg1.resolveFn;\n this.deps = arg1.deps;\n this.policy = arg1.policy;\n this.data = arg1.data;\n }\n }\n\n getPolicy(state) {\n const thisPolicy = this.policy || {};\n\n const statePolicy = (state && state.resolvePolicy) || {};\n\n return {\n when: thisPolicy.when || statePolicy.when || defaultResolvePolicy.when,\n async:\n thisPolicy.async || statePolicy.async || defaultResolvePolicy.async,\n };\n }\n\n /**\n * Asynchronously resolve this Resolvable's data\n *\n * Given a ResolveContext that this Resolvable is found in:\n * Wait for this Resolvable's dependencies, then invoke this Resolvable's function\n * and update the Resolvable's state\n */\n resolve(resolveContext, trans) {\n // Gets all dependencies from ResolveContext and wait for them to be resolved\n const getResolvableDependencies = () =>\n Promise.all(\n resolveContext\n .getDependencies(this)\n .map((resolvable) => resolvable.get(resolveContext, trans)),\n );\n\n // Invokes the resolve function passing the resolved dependencies as arguments\n const invokeResolveFn = (resolvedDeps) =>\n this.resolveFn.apply(null, resolvedDeps);\n\n const node = resolveContext.findNode(this);\n\n const state = node && node.state;\n\n const asyncPolicy = this.getPolicy(state).async;\n\n const customAsyncPolicy = isFunction(asyncPolicy) ? asyncPolicy : (x) => x;\n\n // After the final value has been resolved, update the state of the Resolvable\n const applyResolvedValue = (resolvedValue) => {\n this.data = resolvedValue;\n this.resolved = true;\n this.resolveFn = null;\n trace.traceResolvableResolved(this, trans);\n\n return this.data;\n };\n\n // Sets the promise property first, then getsResolvableDependencies in the context of the promise chain. Always waits one tick.\n this.promise = Promise.resolve()\n .then(getResolvableDependencies)\n .then(invokeResolveFn)\n .then(customAsyncPolicy)\n .then(applyResolvedValue);\n\n return this.promise;\n }\n\n /**\n * Gets a promise for this Resolvable's data.\n *\n * Fetches the data and returns a promise.\n * Returns the existing promise if it has already been fetched once.\n */\n get(resolveContext, trans) {\n return this.promise || this.resolve(resolveContext, trans);\n }\n\n toString() {\n return `Resolvable(token: ${stringify(this.token)}, requires: [${this.deps.map(stringify)}])`;\n }\n\n clone() {\n return new Resolvable(this);\n }\n}\nResolvable.fromData = (token, data) =>\n new Resolvable(token, () => data, null, null, data);\n","import { isObject, isString } from \"../../shared/utils.js\";\nimport { stringify } from \"../../shared/strings\";\n/**\n * Encapsulate the target (destination) state/params/options of a [[Transition]].\n *\n * This class is frequently used to redirect a transition to a new destination.\n *\n * See:\n *\n * - [[HookResult]]\n * - [[TransitionHookFn]]\n * - [[TransitionService.onStart]]\n *\n * To create a `TargetState`, use [[StateService.target]].\n *\n * ---\n *\n * This class wraps:\n *\n * 1) an identifier for a state\n * 2) a set of parameters\n * 3) and transition options\n * 4) the registered state object (the [[StateDeclaration]])\n *\n * Many ng-router APIs such as [[StateService.go]] take a [[StateOrName]] argument which can\n * either be a *state object* (a [[StateDeclaration]] or [[StateObject]]) or a *state name* (a string).\n * The `TargetState` class normalizes those options.\n *\n * A `TargetState` may be valid (the state being targeted exists in the registry)\n * or invalid (the state being targeted is not registered).\n */\nexport class TargetState {\n /**\n * The TargetState constructor\n *\n * Note: Do not construct a `TargetState` manually.\n * To create a `TargetState`, use the [[StateService.target]] factory method.\n *\n * @param _stateRegistry The StateRegistry to use to look up the _definition\n * @param _identifier An identifier for a state.\n * Either a fully-qualified state name, or the object used to define the state.\n * @param _params Parameters for the target state\n * @param _options Transition options.\n *\n * @internal\n */\n constructor(_stateRegistry, _identifier, _params, _options) {\n this._stateRegistry = _stateRegistry;\n this._identifier = _identifier;\n this._identifier = _identifier;\n this._params = Object.assign({}, _params || {});\n this._options = Object.assign({}, _options || {});\n this._definition = _stateRegistry.matcher.find(\n _identifier,\n this._options.relative,\n );\n }\n\n /** The name of the state this object targets */\n name() {\n return (this._definition && this._definition.name) || this._identifier;\n }\n\n /** The identifier used when creating this TargetState */\n identifier() {\n return this._identifier;\n }\n\n /** The target parameter values */\n params() {\n return this._params;\n }\n\n /** The internal state object (if it was found) */\n $state() {\n return this._definition;\n }\n\n /** The internal state declaration (if it was found) */\n state() {\n return this._definition && this._definition.self;\n }\n\n /** The target options */\n options() {\n return this._options;\n }\n\n /** True if the target state was found */\n exists() {\n return !!(this._definition && this._definition.self);\n }\n\n /** True if the object is valid */\n valid() {\n return !this.error();\n }\n\n /** If the object is invalid, returns the reason why */\n error() {\n const base = this.options().relative;\n\n if (!this._definition && !!base) {\n const stateName = base.name ? base.name : base;\n\n return `Could not resolve '${this.name()}' from state '${stateName}'`;\n }\n\n if (!this._definition) return `No such state '${this.name()}'`;\n\n if (!this._definition.self)\n return `State '${this.name()}' has an invalid definition`;\n\n return undefined;\n }\n\n toString() {\n return `'${this.name()}'${stringify(this.params())}`;\n }\n\n /**\n * Returns a copy of this TargetState which targets a different state.\n * The new TargetState has the same parameter values and transition options.\n *\n * @param state The new state that should be targeted\n */\n withState(state) {\n return new TargetState(\n this._stateRegistry,\n state,\n this._params,\n this._options,\n );\n }\n\n /**\n * Returns a copy of this TargetState, using the specified parameter values.\n *\n * @param params the new parameter values to use\n * @param replace When false (default) the new parameter values will be merged with the current values.\n * When true the parameter values will be used instead of the current values.\n */\n withParams(params, replace = false) {\n const newParams = replace\n ? params\n : Object.assign({}, this._params, params);\n\n return new TargetState(\n this._stateRegistry,\n this._identifier,\n newParams,\n this._options,\n );\n }\n\n /**\n * Returns a copy of this TargetState, using the specified Transition Options.\n *\n * @param options the new options to use\n * @param replace When false (default) the new options will be merged with the current options.\n * When true the options will be used instead of the current options.\n */\n withOptions(options, replace = false) {\n const newOpts = replace\n ? options\n : Object.assign({}, this._options, options);\n\n return new TargetState(\n this._stateRegistry,\n this._identifier,\n this._params,\n newOpts,\n );\n }\n}\n/** Returns true if the object has a state property that might be a state or state name */\nTargetState.isDef = (obj) => {\n return (\n obj &&\n obj.state &&\n (isString(obj.state) || (isObject(obj.state) && isString(obj.state.name)))\n );\n};\n","import { allTrueR, filter, find, map } from \"../../shared/common.js\";\nimport { isInjectable } from \"../../shared/predicates.js\";\nimport {\n isArray,\n isDefined,\n isNullOrUndefined,\n isString,\n isUndefined,\n} from \"../../shared/utils.js\";\nimport { ParamType } from \"./param-type.js\";\n\nconst isShorthand = (cfg) =>\n [\"value\", \"type\", \"squash\", \"array\", \"dynamic\"].filter(\n Object.prototype.hasOwnProperty.bind(cfg || {}),\n ).length === 0;\n\n/**\n * @internal\n * @enum {number}\n */\nexport const DefType = {\n _PATH: 0,\n _SEARCH: 1,\n _CONFIG: 2,\n};\n\nfunction getParamDeclaration(paramName, location, state) {\n const noReloadOnSearch =\n (state.reloadOnSearch === false && location === DefType._SEARCH) ||\n undefined;\n\n const dynamic = find([state.dynamic, noReloadOnSearch], isDefined);\n\n const defaultConfig = isDefined(dynamic) ? { dynamic } : {};\n\n const paramConfig = unwrapShorthand(\n state && state.params && state.params[paramName],\n );\n\n return Object.assign(defaultConfig, paramConfig);\n}\n\nfunction unwrapShorthand(cfg) {\n cfg = isShorthand(cfg) ? { value: cfg } : cfg;\n getStaticDefaultValue.__cacheable = true;\n function getStaticDefaultValue() {\n return cfg.value;\n }\n const $$fn = isInjectable(cfg.value) ? cfg.value : getStaticDefaultValue;\n\n return Object.assign(cfg, { $$fn });\n}\n\nfunction getType(cfg, urlType, location, id, paramTypes) {\n if (cfg.type && urlType && urlType.name !== \"string\")\n throw new Error(`Param '${id}' has two type configurations.`);\n\n if (\n cfg.type &&\n urlType &&\n urlType.name === \"string\" &&\n paramTypes.type(cfg.type)\n )\n return paramTypes.type(cfg.type);\n\n if (urlType) return urlType;\n\n if (!cfg.type) {\n const type =\n location === DefType._CONFIG\n ? \"any\"\n : location === DefType._PATH\n ? \"path\"\n : location === DefType._SEARCH\n ? \"query\"\n : \"string\";\n\n return paramTypes.type(type);\n }\n\n return cfg.type instanceof ParamType ? cfg.type : paramTypes.type(cfg.type);\n}\n\n/** returns false, true, or the squash value to indicate the \"default parameter url squash policy\". */\nfunction getSquashPolicy(config, isOptional, defaultPolicy) {\n const { squash } = config;\n\n if (!isOptional || squash === false) return false;\n\n if (!isDefined(squash) || isNullOrUndefined(squash)) return defaultPolicy;\n\n if (squash === true || isString(squash)) return squash;\n throw new Error(\n `Invalid squash policy: '${squash}'. Valid policies: false, true, or arbitrary string`,\n );\n}\n\nfunction getReplace(config, arrayMode, isOptional, squash) {\n const defaultPolicy = [\n { from: \"\", to: isOptional || arrayMode ? undefined : \"\" },\n { from: null, to: isOptional || arrayMode ? undefined : \"\" },\n ];\n\n const replace = isArray(config.replace) ? config.replace : [];\n\n if (isString(squash)) replace.push({ from: squash, to: undefined });\n const configuredKeys = map(replace, (x) => x.from);\n\n return filter(\n defaultPolicy,\n (item) => configuredKeys.indexOf(item.from) === -1,\n ).concat(replace);\n}\n\nexport class Param {\n /**\n *\n * @param {*} id\n * @param {*} type\n * @param {DefType} location\n * @param {import(\"../url/url-config.js\").UrlConfigProvider} urlConfig\n * @param {*} state\n */\n constructor(id, type, location, urlConfig, state) {\n const config = getParamDeclaration(id, location, state);\n\n type = getType(config, type, location, id, urlConfig.paramTypes);\n const arrayMode = getArrayMode();\n\n type = arrayMode\n ? type.$asArray(arrayMode, location === DefType._SEARCH)\n : type;\n const isOptional =\n config.value !== undefined || location === DefType._SEARCH;\n\n const dynamic = isDefined(config.dynamic)\n ? !!config.dynamic\n : !!type.dynamic;\n\n const raw = isDefined(config.raw) ? !!config.raw : !!type.raw;\n\n const squash = getSquashPolicy(\n config,\n isOptional,\n urlConfig.defaultSquashPolicy(),\n );\n\n const replace = getReplace(config, arrayMode, isOptional, squash);\n\n const inherit = isDefined(config.inherit)\n ? !!config.inherit\n : !!type.inherit;\n\n // array config: param name (param[]) overrides default settings. explicit config overrides param name.\n function getArrayMode() {\n const arrayDefaults = {\n array: location === DefType._SEARCH ? \"auto\" : false,\n };\n\n const arrayParamNomenclature = id.match(/\\[\\]$/) ? { array: true } : {};\n\n return Object.assign(arrayDefaults, arrayParamNomenclature, config).array;\n }\n this.isOptional = isOptional;\n this.type = type;\n this.location = location;\n this.id = id;\n this.dynamic = dynamic;\n this.raw = raw;\n this.squash = squash;\n this.replace = replace;\n this.inherit = inherit;\n this.array = arrayMode;\n this.config = config;\n }\n\n isDefaultValue(value) {\n return this.isOptional && this.type.equals(this.value(), value);\n }\n\n /**\n * [Internal] Gets the decoded representation of a value if the value is defined, otherwise, returns the\n * default value, which may be the result of an injectable function.\n */\n value(value) {\n /**\n * [Internal] Get the default value of a parameter, which may be an injectable function.\n */\n const getDefaultValue = () => {\n if (this._defaultValueCache) return this._defaultValueCache.defaultValue;\n\n if (!window.angular.$injector)\n throw new Error(\n \"Injectable functions cannot be called at configuration time\",\n );\n const defaultValue = window.angular.$injector.invoke(this.config.$$fn);\n\n if (\n defaultValue !== null &&\n defaultValue !== undefined &&\n !this.type.is(defaultValue)\n )\n throw new Error(\n `Default value (${defaultValue}) for parameter '${this.id}' is not an instance of ParamType (${this.type.name})`,\n );\n\n if (this.config.$$fn.__cacheable) {\n this._defaultValueCache = { defaultValue };\n }\n\n return defaultValue;\n };\n\n const replaceSpecialValues = (val) => {\n for (const tuple of this.replace) {\n if (tuple.from === val) return tuple.to;\n }\n\n return val;\n };\n\n value = replaceSpecialValues(value);\n\n return isUndefined(value) ? getDefaultValue() : this.type.$normalize(value);\n }\n\n isSearch() {\n return this.location === DefType._SEARCH;\n }\n\n validates(value) {\n // There was no parameter value, but the param is optional\n if ((isUndefined(value) || value === null) && this.isOptional) return true;\n // The value was not of the correct ParamType, and could not be decoded to the correct ParamType\n const normalized = this.type.$normalize(value);\n\n if (!this.type.is(normalized)) return false;\n // The value was of the correct type, but when encoded, did not match the ParamType's regexp\n const encoded = normalized; // this.type.encode(normalized);\n\n return !(isString(encoded) && !this.type.pattern.exec(encoded));\n }\n\n toString() {\n return `{Param:${this.id} ${this.type} squash: '${this.squash}' optional: ${this.isOptional}}`;\n }\n\n static values(params, values = {}) {\n const paramValues = {};\n\n for (const param of params) {\n paramValues[param.id] = param.value(values[param.id]);\n }\n\n return paramValues;\n }\n\n /**\n * Finds [[Param]] objects which have different param values\n *\n * Filters a list of [[Param]] objects to only those whose parameter values differ in two param value objects\n *\n * @param params: The list of Param objects to filter\n * @param values1: The first set of parameter values\n * @param values2: the second set of parameter values\n *\n * @returns any Param objects whose values were different between values1 and values2\n */\n static changed(params, values1 = {}, values2 = {}) {\n return params.filter(\n (param) => !param.type.equals(values1[param.id], values2[param.id]),\n );\n }\n\n /**\n * Checks if two param value objects are equal (for a set of [[Param]] objects)\n *\n * @param params The list of [[Param]] objects to check\n * @param values1 The first set of param values\n * @param values2 The second set of param values\n *\n * @returns true if the param values in values1 and values2 are equal\n */\n static equals(params, values1 = {}, values2 = {}) {\n return Param.changed(params, values1, values2).length === 0;\n }\n\n /** Returns true if a the parameter values are valid, according to the Param definitions */\n static validates(params, values = {}) {\n return params\n .map((param) => param.validates(values[param.id]))\n .reduce(allTrueR, true);\n }\n}\n","import { applyPairs, find } from \"../../shared/common.js\";\nimport { propEq } from \"../../shared/hof.js\";\nimport { Param } from \"../params/param.js\";\n\n/**\n * A node in a [[TreeChanges]] path\n *\n * For a [[TreeChanges]] path, this class holds the stateful information for a single node in the path.\n * Each PathNode corresponds to a state being entered, exited, or retained.\n * The stateful information includes parameter values and resolve data.\n */\nexport class PathNode {\n constructor(stateOrNode) {\n if (stateOrNode instanceof PathNode) {\n const node = stateOrNode;\n\n this.state = node.state;\n this.paramSchema = node.paramSchema.slice();\n this.paramValues = Object.assign({}, node.paramValues);\n this.resolvables = node.resolvables.slice();\n this.views = node.views && node.views.slice();\n } else {\n const state = stateOrNode;\n\n this.state = state;\n this.paramSchema = state.parameters({ inherit: false });\n this.paramValues = {};\n this.resolvables = state.resolvables.map((res) => res.clone());\n }\n }\n\n clone() {\n return new PathNode(this);\n }\n\n /** Sets [[paramValues]] for the node, from the values of an object hash */\n applyRawParams(params) {\n const getParamVal = (paramDef) => [\n paramDef.id,\n paramDef.value(params[paramDef.id]),\n ];\n\n this.paramValues = this.paramSchema.reduce(\n (memo, pDef) => applyPairs(memo, getParamVal(pDef)),\n {},\n );\n\n return this;\n }\n\n /** Gets a specific [[Param]] metadata that belongs to the node */\n parameter(name) {\n return find(this.paramSchema, propEq(\"id\", name));\n }\n\n /**\n * @returns true if the state and parameter values for another PathNode are\n * equal to the state and param values for this PathNode\n */\n equals(node, paramsFn) {\n const diff = this.diff(node, paramsFn);\n\n return diff && diff.length === 0;\n }\n\n /**\n * Finds Params with different parameter values on another PathNode.\n *\n * Given another node (of the same state), finds the parameter values which differ.\n * Returns the [[Param]] (schema objects) whose parameter values differ.\n *\n * Given another node for a different state, returns `false`\n *\n * @param node The node to compare to\n * @param paramsFn A function that returns which parameters should be compared.\n * @returns The [[Param]]s which differ, or null if the two nodes are for different states\n */\n diff(node, paramsFn) {\n if (this.state !== node.state) return false;\n const params = paramsFn ? paramsFn(this) : this.paramSchema;\n\n return Param.changed(params, this.paramValues, node.paramValues);\n }\n}\n","import { arrayTuples, find, omit, pick, unnestR } from \"../../shared/common.js\";\nimport { propEq } from \"../../shared/hof.js\";\nimport { TargetState } from \"../state/target-state.js\";\nimport { PathNode } from \"./path-node.js\";\n/**\n * This class contains functions which convert TargetStates, Nodes and paths from one type to another.\n */\nexport class PathUtils {\n static buildPath(targetState) {\n const toParams = targetState.params();\n\n return targetState\n .$state()\n .path.map((state) => new PathNode(state).applyRawParams(toParams));\n }\n\n /** Given a fromPath: PathNode[] and a TargetState, builds a toPath: PathNode[] */\n static buildToPath(fromPath, targetState) {\n const toPath = PathUtils.buildPath(targetState);\n\n if (targetState.options().inherit) {\n return PathUtils.inheritParams(\n fromPath,\n toPath,\n Object.keys(targetState.params()),\n );\n }\n\n return toPath;\n }\n\n /**\n * Creates ViewConfig objects and adds to nodes.\n *\n * On each [[PathNode]], creates ViewConfig objects from the views: property of the node's state\n */\n static applyViewConfigs($view, path, states) {\n // Only apply the viewConfigs to the nodes for the given states\n path\n .filter((node) => states.includes(node.state))\n .forEach((node) => {\n const viewDecls = Object.values(node.state.views || {});\n\n const subPath = PathUtils.subPath(path, (x) => x === node);\n\n const viewConfigs = viewDecls.map((view) => {\n return $view.createViewConfig(subPath, view);\n });\n\n node.views = viewConfigs.reduce(unnestR, []);\n });\n }\n\n /**\n * Given a fromPath and a toPath, returns a new to path which inherits parameters from the fromPath\n *\n * For a parameter in a node to be inherited from the from path:\n * - The toPath's node must have a matching node in the fromPath (by state).\n * - The parameter name must not be found in the toKeys parameter array.\n *\n * Note: the keys provided in toKeys are intended to be those param keys explicitly specified by some\n * caller, for instance, $state.transitionTo(..., toParams). If a key was found in toParams,\n * it is not inherited from the fromPath.\n */\n static inheritParams(fromPath, toPath, toKeys = []) {\n function nodeParamVals(path, state) {\n /** @type {PathNode} */\n const node = find(path, propEq(\"state\", state));\n\n return Object.assign({}, node && node.paramValues);\n }\n const noInherit = fromPath\n .map((node) => node.paramSchema)\n .reduce(unnestR, [])\n .filter((param) => !param.inherit)\n .map((x) => x.id);\n\n /**\n * Given an [[PathNode]] \"toNode\", return a new [[PathNode]] with param values inherited from the\n * matching node in fromPath. Only inherit keys that aren't found in \"toKeys\" from the node in \"fromPath\"\"\n */\n function makeInheritedParamsNode(toNode) {\n // All param values for the node (may include default key/vals, when key was not found in toParams)\n let toParamVals = Object.assign({}, toNode && toNode.paramValues);\n\n // limited to only those keys found in toParams\n const incomingParamVals = pick(toParamVals, toKeys);\n\n toParamVals = omit(toParamVals, toKeys);\n const fromParamVals = omit(\n nodeParamVals(fromPath, toNode.state) || {},\n noInherit,\n );\n\n // extend toParamVals with any fromParamVals, then override any of those those with incomingParamVals\n const ownParamVals = Object.assign(\n toParamVals,\n fromParamVals,\n incomingParamVals,\n );\n\n return new PathNode(toNode.state).applyRawParams(ownParamVals);\n }\n\n // The param keys specified by the incoming toParams\n return toPath.map(makeInheritedParamsNode);\n }\n\n /**\n * Computes the tree changes (entering, exiting) between a fromPath and toPath.\n * @param {PathNode[]} fromPath\n * @param {PathNode[]} toPath\n * @param {boolean} [reloadState]\n * @returns {import(\"../transition/interface.ts\").TreeChanges}\n */\n static treeChanges(fromPath, toPath, reloadState) {\n const max = Math.min(fromPath.length, toPath.length);\n\n let keep = 0;\n\n const nodesMatch = (node1, node2) =>\n node1.equals(node2, PathUtils.nonDynamicParams);\n\n while (\n keep < max &&\n fromPath[keep].state !== reloadState &&\n nodesMatch(fromPath[keep], toPath[keep])\n ) {\n keep++;\n }\n /** Given a retained node, return a new node which uses the to node's param values */\n function applyToParams(retainedNode, idx) {\n const cloned = retainedNode.clone();\n\n cloned.paramValues = toPath[idx].paramValues;\n\n return cloned;\n }\n\n const from = fromPath;\n\n const retained = from.slice(0, keep);\n\n const exiting = from.slice(keep);\n\n // Create a new retained path (with shallow copies of nodes) which have the params of the toPath mapped\n const retainedWithToParams = retained.map(applyToParams);\n\n const entering = toPath.slice(keep);\n\n const to = retainedWithToParams.concat(entering);\n\n return { from, to, retained, retainedWithToParams, exiting, entering };\n }\n\n /**\n * Returns a new path which is: the subpath of the first path which matches the second path.\n *\n * The new path starts from root and contains any nodes that match the nodes in the second path.\n * It stops before the first non-matching node.\n *\n * Nodes are compared using their state property and their parameter values.\n * If a `paramsFn` is provided, only the [[Param]] returned by the function will be considered when comparing nodes.\n *\n * @param pathA the first path\n * @param pathB the second path\n * @param paramsFn a function which returns the parameters to consider when comparing\n *\n * @returns an array of PathNodes from the first path which match the nodes in the second path\n */\n static matching(pathA, pathB, paramsFn) {\n let done = false;\n\n const tuples = arrayTuples(pathA, pathB);\n\n return tuples.reduce((matching, [nodeA, nodeB]) => {\n done = done || !nodeA.equals(nodeB, paramsFn);\n\n return done ? matching : matching.concat(nodeA);\n }, []);\n }\n\n /**\n * Returns true if two paths are identical.\n *\n * @param pathA\n * @param pathB\n * @param paramsFn a function which returns the parameters to consider when comparing\n * @returns true if the the states and parameter values for both paths are identical\n */\n static equals(pathA, pathB, paramsFn) {\n return (\n pathA.length === pathB.length &&\n PathUtils.matching(pathA, pathB, paramsFn).length === pathA.length\n );\n }\n\n /**\n * Return a subpath of a path, which stops at the first matching node\n *\n * Given an array of nodes, returns a subset of the array starting from the first node,\n * stopping when the first node matches the predicate.\n *\n * @param path a path of [[PathNode]]s\n * @param predicate a [[Predicate]] fn that matches [[PathNode]]s\n * @returns a subpath up to the matching node, or undefined if no match is found\n */\n static subPath(path, predicate) {\n const node = find(path, predicate);\n\n const elementIdx = path.indexOf(node);\n\n return elementIdx === -1 ? undefined : path.slice(0, elementIdx + 1);\n }\n\n static nonDynamicParams(node) {\n return node.state\n .parameters({ inherit: false })\n .filter((param) => !param.dynamic);\n }\n\n /** Gets the raw parameter values from a path */\n static paramValues(path) {\n return path.reduce((acc, node) => Object.assign(acc, node.paramValues), {});\n }\n}\n\n/** Given a PathNode[], create an TargetState\n * @param {import(\"../state/state-registry.js\").StateRegistryProvider} registry\n * @param {Array<PathNode>} path\n * @returns\n */\nexport function makeTargetState(registry, path) {\n return new TargetState(\n registry,\n path.at(-1).state,\n path\n .map((x) => x.paramValues)\n .reduce((acc, obj) => ({ ...acc, ...obj }), {}),\n {},\n );\n}\n","import { find, tail, uniqR, unnestR } from \"../../shared/common.js\";\nimport { propEq } from \"../../shared/hof.js\";\nimport { trace } from \"../common/trace.js\";\nimport { Resolvable } from \"./resolvable.js\";\nimport { PathUtils } from \"../path/path-utils.js\";\nimport { stringify } from \"../../shared/strings.js\";\nimport { isUndefined } from \"../../shared/utils.js\";\n\nexport const resolvePolicies = {\n when: {\n LAZY: \"LAZY\",\n EAGER: \"EAGER\",\n },\n async: {\n WAIT: \"WAIT\",\n NOWAIT: \"NOWAIT\",\n },\n};\n\nconst ALL_WHENS = [resolvePolicies.when.EAGER, resolvePolicies.when.LAZY];\n\nconst EAGER_WHENS = [resolvePolicies.when.EAGER];\n\n/**\n * Encapsulates Dependency Injection for a path of nodes\n *\n * ng-router states are organized as a tree.\n * A nested state has a path of ancestors to the root of the tree.\n * When a state is being activated, each element in the path is wrapped as a [[PathNode]].\n * A `PathNode` is a stateful object that holds things like parameters and resolvables for the state being activated.\n *\n * The ResolveContext closes over the [[PathNode]]s, and provides DI for the last node in the path.\n */\nexport class ResolveContext {\n constructor(_path) {\n this._path = _path;\n }\n\n /** Gets all the tokens found in the resolve context, de-duplicated */\n getTokens() {\n return this._path\n .reduce(\n (acc, node) =>\n acc.concat(node.resolvables.map((resolve) => resolve.token)),\n [],\n )\n .reduce(uniqR, []);\n }\n\n /**\n * Gets the Resolvable that matches the token\n *\n * Gets the last Resolvable that matches the token in this context, or undefined.\n * Throws an error if it doesn't exist in the ResolveContext\n */\n getResolvable(token) {\n const matching = this._path\n .map((node) => node.resolvables)\n .reduce(unnestR, [])\n .filter((resolve) => resolve.token === token);\n\n return tail(matching);\n }\n\n /** Returns the [[ResolvePolicy]] for the given [[Resolvable]] */\n getPolicy(resolvable) {\n const node = this.findNode(resolvable);\n\n return resolvable.getPolicy(node);\n }\n\n /**\n * Returns a ResolveContext that includes a portion of this one\n *\n * Given a state, this method creates a new ResolveContext from this one.\n * The new context starts at the first node (root) and stops at the node for the `state` parameter.\n *\n * #### Why\n *\n * When a transition is created, the nodes in the \"To Path\" are injected from a ResolveContext.\n * A ResolveContext closes over a path of [[PathNode]]s and processes the resolvables.\n * The \"To State\" can inject values from its own resolvables, as well as those from all its ancestor state's (node's).\n * This method is used to create a narrower context when injecting ancestor nodes.\n *\n * @example\n * `let ABCD = new ResolveContext([A, B, C, D]);`\n *\n * Given a path `[A, B, C, D]`, where `A`, `B`, `C` and `D` are nodes for states `a`, `b`, `c`, `d`:\n * When injecting `D`, `D` should have access to all resolvables from `A`, `B`, `C`, `D`.\n * However, `B` should only be able to access resolvables from `A`, `B`.\n *\n * When resolving for the `B` node, first take the full \"To Path\" Context `[A,B,C,D]` and limit to the subpath `[A,B]`.\n * `let AB = ABCD.subcontext(a)`\n */\n subContext(state) {\n return new ResolveContext(\n PathUtils.subPath(this._path, (node) => node.state === state),\n );\n }\n\n /**\n * Adds Resolvables to the node that matches the state\n *\n * This adds a [[Resolvable]] (generally one created on the fly; not declared on a [[StateDeclaration.resolve]] block).\n * The resolvable is added to the node matching the `state` parameter.\n *\n * These new resolvables are not automatically fetched.\n * The calling code should either fetch them, fetch something that depends on them,\n * or rely on [[resolvePath]] being called when some state is being entered.\n *\n * Note: each resolvable's [[ResolvePolicy]] is merged with the state's policy, and the global default.\n *\n * @param {Resolvable[]} newResolvables the new Resolvables\n * @param state Used to find the node to put the resolvable on\n */\n addResolvables(newResolvables, state) {\n /** @type {import('../path/path-node').PathNode} */\n const node = find(this._path, propEq(\"state\", state));\n\n const keys = newResolvables.map((resolve) => resolve.token);\n\n node.resolvables = node.resolvables\n .filter((resolve) => keys.indexOf(resolve.token) === -1)\n .concat(newResolvables);\n }\n\n /**\n * Returns a promise for an array of resolved path Element promises\n *\n * @param {string} when\n * @param trans\n * @returns {Promise<any>|any}\n */\n resolvePath(when = \"LAZY\", trans) {\n // This option determines which 'when' policy Resolvables we are about to fetch.\n const whenOption = ALL_WHENS.includes(when) ? when : \"LAZY\";\n\n // If the caller specified EAGER, only the EAGER Resolvables are fetched.\n // if the caller specified LAZY, both EAGER and LAZY Resolvables are fetched.`\n const matchedWhens =\n whenOption === resolvePolicies.when.EAGER ? EAGER_WHENS : ALL_WHENS;\n\n // get the subpath to the state argument, if provided\n trace.traceResolvePath(this._path, when, trans);\n const matchesPolicy = (acceptedVals, whenOrAsync) => (resolvable) =>\n acceptedVals.includes(this.getPolicy(resolvable)[whenOrAsync]);\n\n // Trigger all the (matching) Resolvables in the path\n // Reduce all the \"WAIT\" Resolvables into an array\n const promises = this._path.reduce((acc, node) => {\n const nodeResolvables = node.resolvables.filter(\n matchesPolicy(matchedWhens, \"when\"),\n );\n\n const nowait = nodeResolvables.filter(matchesPolicy([\"NOWAIT\"], \"async\"));\n\n const wait = nodeResolvables.filter(\n (x) => !matchesPolicy([\"NOWAIT\"], \"async\")(x),\n );\n\n // For the matching Resolvables, start their async fetch process.\n const subContext = this.subContext(node.state);\n\n const getResult = (resolve) =>\n resolve\n .get(subContext, trans)\n // Return a tuple that includes the Resolvable's token\n .then((value) => ({ token: resolve.token, value }));\n\n nowait.forEach(getResult);\n\n return acc.concat(wait.map(getResult));\n }, []);\n\n // Wait for all the \"WAIT\" resolvables\n return Promise.all(promises);\n }\n\n findNode(resolvable) {\n return find(this._path, (node) => node.resolvables.includes(resolvable));\n }\n\n /**\n * Gets the async dependencies of a Resolvable\n *\n * Given a Resolvable, returns its dependencies as a Resolvable[]\n * @param {Resolvable} resolvable\n * @returns {Resolvable[]}\n */\n getDependencies(resolvable) {\n const node = this.findNode(resolvable);\n\n // Find which other resolvables are \"visible\" to the `resolvable` argument\n // subpath stopping at resolvable's node, or the whole path (if the resolvable isn't in the path)\n const subPath =\n PathUtils.subPath(this._path, (x) => x === node) || this._path;\n\n const availableResolvables = subPath\n .reduce((acc, _node) => acc.concat(_node.resolvables), []) // all of subpath's resolvables\n .filter((res) => res !== resolvable); // filter out the `resolvable` argument\n\n return resolvable.deps.map((token) => {\n const matching = availableResolvables.filter(\n (resolve) => resolve.token === token,\n );\n\n if (matching.length) return tail(matching);\n const fromInjector = window.angular.$injector.get(token);\n\n if (isUndefined(fromInjector)) {\n throw new Error(\n `Could not find Dependency Injection token: ${stringify(token)}`,\n );\n }\n\n return new Resolvable(token, () => fromInjector, [], fromInjector);\n });\n }\n}\n","import { pick, tail } from \"../../shared/common.js\";\nimport { entries, isArray, isDefined, isString } from \"../../shared/utils.js\";\nimport { isInjectable } from \"../../shared/predicates.js\";\nimport { trace } from \"../common/trace.js\";\nimport { ResolveContext } from \"../resolve/resolve-context.js\";\nimport { Resolvable } from \"../resolve/resolvable.js\";\nimport { annotate } from \"../../core/di/di.js\";\n\nexport function getViewConfigFactory() {\n let templateFactory = null;\n\n return (path, view) => {\n templateFactory =\n templateFactory || window.angular.$injector.get(\"$templateFactory\"); // TODO: remove static injector\n\n return new ViewConfig(path, view, templateFactory);\n };\n}\n\nconst hasAnyKey = (keys, obj) =>\n keys.reduce((acc, key) => acc || isDefined(obj[key]), false);\n\n/**\n * This is a [[StateBuilder.builder]] function for angular1 `views`.\n *\n * When the [[StateBuilder]] builds a [[StateObject]] object from a raw [[StateDeclaration]], this builder\n * handles the `views` property with logic specific to @uirouter/angularjs (ng1).\n *\n * If no `views: {}` property exists on the [[StateDeclaration]], then it creates the `views` object\n * and applies the state-level configuration to a view named `$default`.\n *\n */\nexport function ng1ViewsBuilder(state) {\n // Do not process root state\n if (!state.parent) return {};\n const tplKeys = [\n \"templateProvider\",\n \"templateUrl\",\n \"template\",\n \"notify\",\n \"async\",\n ],\n ctrlKeys = [\n \"controller\",\n \"controllerProvider\",\n \"controllerAs\",\n \"resolveAs\",\n ],\n compKeys = [\"component\", \"bindings\", \"componentProvider\"],\n nonCompKeys = tplKeys.concat(ctrlKeys),\n allViewKeys = compKeys.concat(nonCompKeys);\n\n // Do not allow a state to have both state-level props and also a `views: {}` property.\n // A state without a `views: {}` property can declare properties for the `$default` view as properties of the state.\n // However, the `$default` approach should not be mixed with a separate `views: ` block.\n if (isDefined(state.views) && hasAnyKey(allViewKeys, state)) {\n throw new Error(\n `State '${state.name}' has a 'views' object. ` +\n `It cannot also have \"view properties\" at the state level. ` +\n `Move the following properties into a view (in the 'views' object): ` +\n ` ${allViewKeys.filter((key) => isDefined(state[key])).join(\", \")}`,\n );\n }\n const views = {},\n viewsObject = state.views || { $default: pick(state, allViewKeys) };\n\n entries(viewsObject).forEach(([name, config]) => {\n // Account for views: { \"\": { template... } }\n name = name || \"$default\";\n\n // Account for views: { header: \"headerComponent\" }\n if (isString(config)) config = { component: config };\n // Make a shallow copy of the urlConfig object\n config = Object.assign({}, config);\n\n // Do not allow a view to mix props for component-style view with props for template/controller-style view\n if (hasAnyKey(compKeys, config) && hasAnyKey(nonCompKeys, config)) {\n throw new Error(\n `Cannot combine: ${compKeys.join(\"|\")} with: ${nonCompKeys.join(\"|\")} in stateview: '${name}@${state.name}'`,\n );\n }\n config.resolveAs = config.resolveAs || \"$resolve\";\n config.$context = state;\n config.$name = name;\n const normalized = ViewConfig.normalizeUIViewTarget(\n config.$context,\n config.$name,\n );\n\n config.$ngViewName = normalized.ngViewName;\n config.$ngViewContextAnchor = normalized.ngViewContextAnchor;\n views[name] = config;\n });\n\n return views;\n}\n\n/**\n * @type {Number}\n */\nlet id = 0;\n\nexport class ViewConfig {\n /**\n * @param {Array<import('../path/path-node.js').PathNode>} path\n * @param viewDecl\n * @param {import('../template-factory.js').TemplateFactoryProvider} factory\n */\n constructor(path, viewDecl, factory) {\n this.path = path;\n this.viewDecl = viewDecl;\n this.factory = factory;\n this.component = undefined;\n this.template = undefined;\n\n /** @type {Number} */ this.$id = id++;\n this.loaded = false;\n this.getTemplate = (ngView, context) =>\n this.component\n ? this.factory.makeComponentTemplate(\n ngView,\n context,\n this.component,\n this.viewDecl.bindings,\n )\n : this.template;\n }\n\n load() {\n const context = new ResolveContext(this.path);\n\n const params = this.path.reduce(\n (acc, node) => Object.assign(acc, node.paramValues),\n {},\n );\n\n const promises = [\n Promise.resolve(this.factory.fromConfig(this.viewDecl, params, context)),\n Promise.resolve(this.getController(context)),\n ];\n\n return Promise.all(promises).then((results) => {\n trace.traceViewServiceEvent(\"Loaded\", this);\n this.controller = results[1];\n Object.assign(this, results[0]); // Either { template: \"tpl\" } or { component: \"cmpName\" }\n\n return this;\n });\n }\n\n /**\n * Gets the controller for a view configuration.\n *\n * @returns {Function|Promise.<Function>} Returns a controller, or a promise that resolves to a controller.\n */\n getController(context) {\n const provider = this.viewDecl.controllerProvider;\n\n if (!isInjectable(provider)) return this.viewDecl.controller;\n const deps = annotate(provider);\n\n const providerFn = isArray(provider) ? tail(provider) : provider;\n\n const resolvable = new Resolvable(\"\", providerFn, deps);\n\n return resolvable.get(context);\n }\n\n /**\n * Normalizes a view's name from a state.views configuration block.\n *\n * This should be used by a framework implementation to calculate the values for\n * [[_ViewDeclaration.$ngViewName]] and [[_ViewDeclaration.$ngViewContextAnchor]].\n *\n * @param context the context object (state declaration) that the view belongs to\n * @param rawViewName the name of the view, as declared in the [[StateDeclaration.views]]\n *\n * @returns the normalized ngViewName and ngViewContextAnchor that the view targets\n */\n static normalizeUIViewTarget(context, rawViewName = \"\") {\n // TODO: Validate incoming view name with a regexp to allow:\n // ex: \"view.name@foo.bar\" , \"^.^.view.name\" , \"view.name@^.^\" , \"\" ,\n // \"@\" , \"$default@^\" , \"!$default.$default\" , \"!foo.bar\"\n const viewAtContext = rawViewName.split(\"@\");\n\n let ngViewName = viewAtContext[0] || \"$default\"; // default to unnamed view\n\n let ngViewContextAnchor = isString(viewAtContext[1])\n ? viewAtContext[1]\n : \"^\"; // default to parent context\n\n // Handle relative view-name sugar syntax.\n // Matches rawViewName \"^.^.^.foo.bar\" into array: [\"^.^.^.foo.bar\", \"^.^.^\", \"foo.bar\"],\n const relativeViewNameSugar = /^(\\^(?:\\.\\^)*)\\.(.*$)/.exec(ngViewName);\n\n if (relativeViewNameSugar) {\n // Clobbers existing contextAnchor (rawViewName validation will fix this)\n ngViewContextAnchor = relativeViewNameSugar[1]; // set anchor to \"^.^.^\"\n ngViewName = relativeViewNameSugar[2]; // set view-name to \"foo.bar\"\n }\n\n if (ngViewName.charAt(0) === \"!\") {\n ngViewName = ngViewName.substring(1);\n ngViewContextAnchor = \"\"; // target absolutely from root\n }\n // handle parent relative targeting \"^.^.^\"\n const relativeMatch = /^(\\^(?:\\.\\^)*)$/;\n\n if (relativeMatch.exec(ngViewContextAnchor)) {\n const anchorState = ngViewContextAnchor\n .split(\".\")\n .reduce((anchor) => anchor.parent, context);\n\n ngViewContextAnchor = anchorState.name;\n } else if (ngViewContextAnchor === \".\") {\n ngViewContextAnchor = context.name;\n }\n\n return { ngViewName, ngViewContextAnchor };\n }\n}\n","import { applyPairs, equals, removeFrom } from \"../../shared/common.js\";\nimport { curry } from \"../../shared/hof.js\";\nimport { trace } from \"../common/trace.js\";\nimport { getViewConfigFactory } from \"../state/views.js\";\n\n/**\n * The View service\n *\n * This service pairs existing `ng-view` components (which live in the DOM)\n * with view configs (from the state declaration objects: [[StateDeclaration.views]]).\n *\n * - After a successful Transition, the views from the newly entered states are activated via [[activateViewConfig]].\n * The views from exited states are deactivated via [[deactivateViewConfig]].\n * (See: the [[registerActivateViews]] Transition Hook)\n *\n * - As `ng-view` components pop in and out of existence, they register themselves using [[registerUIView]].\n *\n * - When the [[sync]] function is called, the registered `ng-view`(s) ([[ActiveUIView]])\n * are configured with the matching [[ViewConfig]](s)\n *\n */\n\nconst FQN_MULTIPLIER = 10_000;\n\nexport class ViewService {\n constructor() {\n this._ngViews = [];\n this._viewConfigs = [];\n this._listeners = [];\n this.viewConfigFactory(getViewConfigFactory());\n }\n\n $get = () => this;\n\n /**\n * @param {?import('../state/state-object.js').StateObject} context\n * @return {?import('../state/state-object.js').StateObject}\n */\n rootViewContext(context) {\n return (this._rootContext = context || this._rootContext);\n }\n\n viewConfigFactory(factory) {\n this.viewConfigFactory = factory;\n }\n\n /**\n * @param path\n * @param decl\n * @return {import(\"../state/views.js\").ViewConfig}\n */\n createViewConfig(path, decl) {\n /** @type {function(any, any): any} */\n const cfgFactory = this.viewConfigFactory;\n\n if (!cfgFactory)\n throw new Error(\n `ViewService: No view config factory registered for type ${decl.$type}`,\n );\n\n return cfgFactory(path, decl);\n }\n\n /**\n * Deactivates a ViewConfig.\n *\n * This function deactivates a `ViewConfig`.\n * After calling [[sync]], it will un-pair from any `ng-view` with which it is currently paired.\n *\n * @param viewConfig The ViewConfig view to deregister.\n */\n deactivateViewConfig(viewConfig) {\n trace.traceViewServiceEvent(\"<- Removing\", viewConfig);\n removeFrom(this._viewConfigs, viewConfig);\n }\n\n activateViewConfig(viewConfig) {\n trace.traceViewServiceEvent(\"-> Registering\", viewConfig);\n this._viewConfigs.push(viewConfig);\n }\n\n sync() {\n const ngViewsByFqn = this._ngViews\n .map((uiv) => [uiv.fqn, uiv])\n .reduce(applyPairs, {});\n\n // Return a weighted depth value for a ngView.\n // The depth is the nesting depth of ng-views (based on FQN; times 10,000)\n // plus the depth of the state that is populating the ngView\n function ngViewDepth(ngView) {\n const stateDepth = (context) =>\n context && context.parent ? stateDepth(context.parent) + 1 : 1;\n\n return (\n ngView.fqn.split(\".\").length * FQN_MULTIPLIER +\n stateDepth(ngView.creationContext)\n );\n }\n // Return the ViewConfig's context's depth in the context tree.\n function viewConfigDepth(config) {\n let context = config.viewDecl.$context,\n count = 0;\n\n while (++count && context.parent) context = context.parent;\n\n return count;\n }\n // Given a depth function, returns a compare function which can return either ascending or descending order\n const depthCompare = curry(\n (depthFn, posNeg, left, right) =>\n posNeg * (depthFn(left) - depthFn(right)),\n );\n\n const matchingConfigPair = (ngView) => {\n const matchingConfigs = this._viewConfigs.filter(\n ViewService.matches(ngViewsByFqn, ngView),\n );\n\n if (matchingConfigs.length > 1) {\n // This is OK. Child states can target a ng-view that the parent state also targets (the child wins)\n // Sort by depth and return the match from the deepest child\n // console.log(`Multiple matching view configs for ${ngView.fqn}`, matchingConfigs);\n matchingConfigs.sort(depthCompare(viewConfigDepth, -1)); // descending\n }\n\n return { ngView, viewConfig: matchingConfigs[0] };\n };\n\n const configureUIView = (tuple) => {\n // If a parent ng-view is reconfigured, it could destroy child ng-views.\n // Before configuring a child ng-view, make sure it's still in the active ngViews array.\n if (this._ngViews.indexOf(tuple.ngView) !== -1) {\n tuple.ngView.configUpdated(tuple.viewConfig);\n }\n };\n\n // Sort views by FQN and state depth. Process uiviews nearest the root first.\n const ngViewTuples = this._ngViews\n .sort(depthCompare(ngViewDepth, 1))\n .map(matchingConfigPair);\n\n const matchedViewConfigs = ngViewTuples.map((tuple) => tuple.viewConfig);\n\n const unmatchedConfigTuples = this._viewConfigs\n .filter((config) => !matchedViewConfigs.includes(config))\n .map((viewConfig) => ({ ngView: undefined, viewConfig }));\n\n ngViewTuples.forEach((tuple) => {\n configureUIView(tuple);\n });\n const allTuples = ngViewTuples.concat(unmatchedConfigTuples);\n\n this._listeners.forEach((cb) => cb(allTuples));\n trace.traceViewSync(allTuples);\n }\n\n /**\n * Registers a `ng-view` component\n *\n * When a `ng-view` component is created, it uses this method to register itself.\n * After registration the [[sync]] method is used to ensure all `ng-view` are configured with the proper [[ViewConfig]].\n *\n * Note: the `ng-view` component uses the `ViewConfig` to determine what view should be loaded inside the `ng-view`,\n * and what the view's state context is.\n *\n * Note: There is no corresponding `deregisterUIView`.\n * A `ng-view` should hang on to the return value of `registerUIView` and invoke it to deregister itself.\n *\n * @param ngView The metadata for a UIView\n * @return a de-registration function used when the view is destroyed.\n */\n registerUIView(ngView) {\n trace.traceViewServiceUIViewEvent(\"-> Registering\", ngView);\n const ngViews = this._ngViews;\n\n const fqnAndTypeMatches = (uiv) => uiv.fqn === ngView.fqn;\n\n if (ngViews.filter(fqnAndTypeMatches).length)\n trace.traceViewServiceUIViewEvent(\"!!!! duplicate ngView named:\", ngView);\n ngViews.push(ngView);\n this.sync();\n\n return () => {\n const idx = ngViews.indexOf(ngView);\n\n if (idx === -1) {\n trace.traceViewServiceUIViewEvent(\n \"Tried removing non-registered ngView\",\n ngView,\n );\n\n return;\n }\n trace.traceViewServiceUIViewEvent(\"<- Deregistering\", ngView);\n removeFrom(ngViews, ngView);\n };\n }\n\n /**\n * Returns the list of views currently available on the page, by fully-qualified name.\n *\n * @return {Array} Returns an array of fully-qualified view names.\n */\n available() {\n return this._ngViews.map((view) => view.fqn);\n }\n\n /**\n * Returns the list of views on the page containing loaded content.\n *\n * @return {Array} Returns an array of fully-qualified view names.\n */\n active() {\n return this._ngViews\n .filter((view) => view.$config)\n .map((view) => view.name);\n }\n}\n/**\n * Given a ng-view and a ViewConfig, determines if they \"match\".\n *\n * A ng-view has a fully qualified name (fqn) and a context object. The fqn is built from its overall location in\n * the DOM, describing its nesting relationship to any parent ng-view tags it is nested inside of.\n *\n * A ViewConfig has a target ng-view name and a context anchor. The ng-view name can be a simple name, or\n * can be a segmented ng-view path, describing a portion of a ng-view fqn.\n *\n * In order for a ng-view to match ViewConfig, ng-view's $type must match the ViewConfig's $type\n *\n * If the ViewConfig's target ng-view name is a simple name (no dots), then a ng-view matches if:\n * - the ng-view's name matches the ViewConfig's target name\n * - the ng-view's context matches the ViewConfig's anchor\n *\n * If the ViewConfig's target ng-view name is a segmented name (with dots), then a ng-view matches if:\n * - There exists a parent ng-view where:\n * - the parent ng-view's name matches the first segment (index 0) of the ViewConfig's target name\n * - the parent ng-view's context matches the ViewConfig's anchor\n * - And the remaining segments (index 1..n) of the ViewConfig's target name match the tail of the ng-view's fqn\n *\n * Example:\n *\n * DOM:\n * <ng-view> <!-- created in the root context (name: \"\") -->\n * <ng-view name=\"foo\"> <!-- created in the context named: \"A\" -->\n * <ng-view> <!-- created in the context named: \"A.B\" -->\n * <ng-view name=\"bar\"> <!-- created in the context named: \"A.B.C\" -->\n * </ng-view>\n * </ng-view>\n * </ng-view>\n * </ng-view>\n *\n * ngViews: [\n * { fqn: \"$default\", creationContext: { name: \"\" } },\n * { fqn: \"$default.foo\", creationContext: { name: \"A\" } },\n * { fqn: \"$default.foo.$default\", creationContext: { name: \"A.B\" } }\n * { fqn: \"$default.foo.$default.bar\", creationContext: { name: \"A.B.C\" } }\n * ]\n *\n * These four view configs all match the ng-view with the fqn: \"$default.foo.$default.bar\":\n *\n * - ViewConfig1: { ngViewName: \"bar\", ngViewContextAnchor: \"A.B.C\" }\n * - ViewConfig2: { ngViewName: \"$default.bar\", ngViewContextAnchor: \"A.B\" }\n * - ViewConfig3: { ngViewName: \"foo.$default.bar\", ngViewContextAnchor: \"A\" }\n * - ViewConfig4: { ngViewName: \"$default.foo.$default.bar\", ngViewContextAnchor: \"\" }\n *\n * Using ViewConfig3 as an example, it matches the ng-view with fqn \"$default.foo.$default.bar\" because:\n * - The ViewConfig's segmented target name is: [ \"foo\", \"$default\", \"bar\" ]\n * - There exists a parent ng-view (which has fqn: \"$default.foo\") where:\n * - the parent ng-view's name \"foo\" matches the first segment \"foo\" of the ViewConfig's target name\n * - the parent ng-view's context \"A\" matches the ViewConfig's anchor context \"A\"\n * - And the remaining segments [ \"$default\", \"bar\" ].join(\".\"_ of the ViewConfig's target name match\n * the tail of the ng-view's fqn \"default.bar\"\n *\n * @internal\n */\nViewService.matches = (ngViewsByFqn, ngView) => (viewConfig) => {\n // Don't supply an ng1 ng-view with an ng2 ViewConfig, etc\n if (ngView.$type !== viewConfig.viewDecl.$type) return false;\n // Split names apart from both viewConfig and ngView into segments\n const vc = viewConfig.viewDecl;\n\n const vcSegments = vc.$ngViewName.split(\".\");\n\n const uivSegments = ngView.fqn.split(\".\");\n\n // Check if the tails of the segment arrays match. ex, these arrays' tails match:\n // vc: [\"foo\", \"bar\"], uiv fqn: [\"$default\", \"foo\", \"bar\"]\n if (!equals(vcSegments, uivSegments.slice(0 - vcSegments.length)))\n return false;\n // Now check if the fqn ending at the first segment of the viewConfig matches the context:\n // [\"$default\", \"foo\"].join(\".\") == \"$default.foo\", does the ng-view $default.foo context match?\n const negOffset = 1 - vcSegments.length || undefined;\n\n const fqnToFirstSegment = uivSegments.slice(0, negOffset).join(\".\");\n\n const ngViewContext = ngViewsByFqn[fqnToFirstSegment].creationContext;\n\n return vc.$ngViewContextAnchor === (ngViewContext && ngViewContext.name);\n};\n","import { silentRejection } from \"../../shared/common.js\";\nimport { stringify } from \"../../shared/strings.js\";\nimport { is } from \"../../shared/hof.js\";\n\n/**\n * An object for Transition Rejection reasons.\n * @internal\n * @enum {number}\n */\nexport const RejectType = {\n /**\n * A new transition superseded this one.\n *\n * While this transition was running, a new transition started.\n * This transition is cancelled because it was superseded by a new transition.\n * @type {number}\n */\n _SUPERSEDED: 2,\n\n /**\n * The transition was aborted.\n *\n * The transition was aborted by a hook which returned `false`.\n * @type {number}\n */\n _ABORTED: 3,\n\n /**\n * The transition was invalid.\n *\n * The transition was never started because it was invalid.\n * @type {number}\n */\n _INVALID: 4,\n\n /**\n * The transition was ignored.\n *\n * The transition was ignored because it would have no effect.\n * Either:\n * - The transition is targeting the current state and parameter values.\n * - The transition is targeting the same state and parameter values as the currently running transition.\n * @type {number}\n */\n _IGNORED: 5,\n\n /**\n * The transition errored.\n *\n * This generally means a hook threw an error or returned a rejected promise.\n * @type {number}\n */\n _ERROR: 6,\n};\n\nlet id = 0;\n\nexport class Rejection {\n /** Returns a Rejection due to transition superseded */\n static superseded(detail, options) {\n const message =\n \"The transition has been superseded by a different transition\";\n\n const rejection = new Rejection(RejectType._SUPERSEDED, message, detail);\n\n if (options && options.redirected) {\n rejection.redirected = true;\n }\n\n return rejection;\n }\n\n /** Returns a Rejection due to redirected transition */\n static redirected(detail) {\n return Rejection.superseded(detail, { redirected: true });\n }\n\n /** Returns a Rejection due to invalid transition */\n static invalid(detail) {\n const message = \"This transition is invalid\";\n\n return new Rejection(RejectType._INVALID, message, detail);\n }\n\n /** Returns a Rejection due to ignored transition */\n static ignored(detail) {\n const message = \"The transition was ignored\";\n\n return new Rejection(RejectType._IGNORED, message, detail);\n }\n\n /** Returns a Rejection due to aborted transition */\n static aborted(detail) {\n const message = \"The transition has been aborted\";\n\n return new Rejection(RejectType._ABORTED, message, detail);\n }\n\n /** Returns a Rejection due to aborted transition */\n static errored(detail) {\n const message = \"The transition errored\";\n\n return new Rejection(RejectType._ERROR, message, detail);\n }\n\n /**\n * Returns a Rejection\n *\n * Normalizes a value as a Rejection.\n * If the value is already a Rejection, returns it.\n * Otherwise, wraps and returns the value as a Rejection (Rejection type: ERROR).\n *\n * @returns `detail` if it is already a `Rejection`, else returns an ERROR Rejection.\n */\n static normalize(detail) {\n return is(Rejection)(detail) ? detail : Rejection.errored(detail);\n }\n\n constructor(type, message, detail) {\n this.$id = id++;\n this.type = type;\n this.message = message;\n this.detail = detail;\n this.redirected = false;\n }\n\n toString() {\n const detailString = (data) =>\n data && data.toString !== Object.prototype.toString\n ? data.toString()\n : stringify(data);\n\n const detail = detailString(this.detail);\n\n const { $id, type, message } = this;\n\n return `Transition Rejection($id: ${$id} type: ${type}, message: ${message}, detail: ${detail})`;\n }\n\n toPromise() {\n return Object.assign(silentRejection(this), { _transitionRejection: this });\n }\n}\n","import { $injectTokens } from \"../../injection-tokens\";\n\n/** @typedef {import('../../interface.ts').ServiceProvider} ServiceProvider\n\n/**\n * Configurable provider for an injectable event bus\n * @extends {ServiceProvider}\n */\nexport class PubSubProvider {\n constructor() {\n /**\n * @type {PubSub}\n */\n this.eventBus = EventBus;\n }\n\n $get = [\n $injectTokens.$exceptionHandler,\n /**\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n * @returns {PubSub}\n */\n ($exceptionHandler) => {\n this.eventBus._$exceptionHandler = $exceptionHandler;\n\n return this.eventBus;\n },\n ];\n}\n\nexport class PubSub {\n constructor() {\n /** @private {Object<string, Array<{fn: Function, context: any}>>} */\n this._topics = Object.create(null);\n\n /** @private */\n this._disposed = false;\n\n /** @type {ng.ExceptionHandlerService} */\n this._$exceptionHandler = undefined;\n }\n\n /**\n * Set instance to initial state\n */\n reset() {\n /** @private {Object<string, Array<{fn: Function, context: any}>>} */\n this._topics = Object.create(null);\n\n /** @private */\n this._disposed = false;\n }\n\n /**\n * Checks if instance has been disposed.\n * @returns {boolean} True if disposed.\n */\n isDisposed() {\n return this._disposed;\n }\n\n /**\n * Dispose the instance, removing all topics and listeners.\n */\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n this._topics = Object.create(null);\n }\n\n /**\n * Subscribe a function to a topic.\n * @param {string} topic - The topic to subscribe to.\n * @param {Function} fn - The callback function to invoke when published.\n * @param {*} [context] - Optional `this` context for the callback.\n * @returns {() => boolean} A function that unsubscribes this listener.\n */\n subscribe(topic, fn, context = undefined) {\n if (this._disposed) return () => false;\n\n /** @type {Array<{fn: Function, context: any}>} */\n let listeners = this._topics[topic];\n\n if (!listeners) this._topics[topic] = listeners = [];\n\n const entry = { fn, context };\n\n listeners.push(entry);\n\n return () => this.unsubscribe(topic, fn, context);\n }\n\n /**\n * Subscribe a function to a topic only once.\n * Listener is removed before the first invocation.\n * @param {string} topic - The topic to subscribe to.\n * @param {Function} fn - The callback function.\n * @param {*} [context] - Optional `this` context for the callback.\n * @returns {() => boolean} A function that unsubscribes this listener.\n */\n subscribeOnce(topic, fn, context = undefined) {\n if (this._disposed) return () => false;\n\n let called = false;\n\n const wrapper = (...args) => {\n if (called) return;\n called = true;\n\n unsub(); // unsubscribe before running\n fn.apply(context, args);\n };\n\n const unsub = this.subscribe(topic, wrapper);\n\n return unsub;\n }\n\n /**\n * Unsubscribe a specific function from a topic.\n * Matches by function reference and optional context.\n * @param {string} topic - The topic to unsubscribe from.\n * @param {Function} fn - The listener function.\n * @param {*} [context] - Optional `this` context.\n * @returns {boolean} True if the listener was found and removed.\n */\n unsubscribe(topic, fn, context = undefined) {\n if (this._disposed) return false;\n\n const listeners = this._topics[topic];\n\n if (!listeners || listeners.length === 0) return false;\n\n for (let i = 0; i < listeners.length; i++) {\n const l = listeners[i];\n\n if (l.fn === fn && l.context === context) {\n listeners.splice(i, 1);\n\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Get the number of subscribers for a topic.\n * @param {string} topic\n * @returns {number}\n */\n getCount(topic) {\n const listeners = this._topics[topic];\n\n return listeners ? listeners.length : 0;\n }\n\n /**\n * Publish a value to a topic asynchronously.\n * All listeners are invoked in the order they were added.\n * @param {string} topic - The topic to publish.\n * @param {...*} args - Arguments to pass to listeners.\n * @returns {boolean} True if any listeners exist for this topic.\n */\n publish(topic, ...args) {\n if (this._disposed) return false;\n\n const listeners = this._topics[topic];\n\n if (!listeners || listeners.length === 0) return false;\n\n // snapshot to prevent modifications during publish from affecting this call\n const snapshot = listeners.slice();\n\n queueMicrotask(() => {\n for (const { fn, context } of snapshot) {\n try {\n fn.apply(context, args);\n } catch (err) {\n this._$exceptionHandler(err);\n }\n }\n });\n\n return true;\n }\n}\n\nexport const EventBus = new PubSub();\n","import { defaults, silentRejection } from \"../../shared/common.js\";\nimport { fnToString, maxLength } from \"../../shared/strings.js\";\nimport { isPromise } from \"../../shared/predicates.js\";\nimport { parse } from \"../../shared/hof.js\";\nimport { trace } from \"../common/trace.js\";\nimport { Rejection } from \"./reject-factory.js\";\nimport { TargetState } from \"../state/target-state.js\";\nimport { EventBus } from \"../../services/pubsub/pubsub.js\";\n\nconst defaultOptions = {\n current: () => {\n /* empty */\n },\n transition: null,\n traceData: {},\n bind: null,\n};\n\n/**\n * Enum representing the different phases of a transition hook.\n * @internal\n * @enum {number}\n */\nexport const TransitionHookPhase = {\n _CREATE: 0,\n _BEFORE: 1,\n _RUN: 2,\n _SUCCESS: 3,\n _ERROR: 4,\n};\n\n/**\n * Enum representing the scope in which a transition hook operates.\n * @enum {number}\n */\nexport const TransitionHookScope = {\n _TRANSITION: 0,\n _STATE: 1,\n};\n\nexport class TransitionHook {\n /**\n * Chains together an array of TransitionHooks.\n *\n * Given a list of [[TransitionHook]] objects, chains them together.\n * Each hook is invoked after the previous one completes.\n *\n * #### Example:\n * ```js\n * var hooks: TransitionHook[] = getHooks();\n * let promise: Promise<any> = TransitionHook.chain(hooks);\n *\n * promise.then(handleSuccess, handleError);\n * ```\n *\n * @param hooks the list of hooks to chain together\n * @param waitFor if provided, the chain is `.then()`'ed off this promise\n * @returns a `Promise` for sequentially invoking the hooks (in order)\n */\n static chain(hooks, waitFor) {\n // Chain the next hook off the previous\n const createHookChainR = (prev, nextHook) =>\n prev.then(() => nextHook.invokeHook());\n\n return hooks.reduce(createHookChainR, waitFor || Promise.resolve());\n }\n\n /**\n * Invokes all the provided TransitionHooks, in order.\n * Each hook's return value is checked.\n * If any hook returns a promise, then the rest of the hooks are chained off that promise, and the promise is returned.\n * If no hook returns a promise, then all hooks are processed synchronously.\n *\n * @param hooks the list of TransitionHooks to invoke\n * @param doneCallback a callback that is invoked after all the hooks have successfully completed\n *\n * @returns a promise for the async result, or the result of the callback\n */\n static invokeHooks(hooks, doneCallback) {\n for (let idx = 0; idx < hooks.length; idx++) {\n const hookResult = hooks[idx].invokeHook();\n\n if (isPromise(hookResult)) {\n const remainingHooks = hooks.slice(idx + 1);\n\n return TransitionHook.chain(remainingHooks, hookResult).then(() => {\n doneCallback();\n });\n }\n }\n\n return doneCallback();\n }\n\n /**\n * Run all TransitionHooks, ignoring their return value.\n */\n static runAllHooks(hooks) {\n hooks.forEach((hook) => hook.invokeHook());\n }\n\n constructor(transition, stateContext, registeredHook, options) {\n this.transition = transition;\n this.stateContext = stateContext;\n this.registeredHook = registeredHook;\n this.options = options;\n this.isSuperseded = () =>\n this.type.hookPhase === TransitionHookPhase._RUN &&\n !this.options.transition.isActive();\n this.options = defaults(options, defaultOptions);\n this.type = registeredHook.eventType;\n }\n\n logError(err) {\n EventBus.publish(\"$stateService:defaultErrorHandler\", err);\n }\n\n invokeHook() {\n const hook = this.registeredHook;\n\n if (hook._deregistered) return undefined;\n const notCurrent = this.getNotCurrentRejection();\n\n if (notCurrent) return notCurrent;\n const { options } = this;\n\n trace.traceHookInvocation(this, this.transition, options);\n const invokeCallback = () =>\n hook.callback.call(options.bind, this.transition, this.stateContext);\n\n const normalizeErr = (err) => Rejection.normalize(err).toPromise();\n\n const handleError = (err) => hook.eventType.getErrorHandler(this)(err);\n\n const handleResult = (result) =>\n hook.eventType.getResultHandler(this)(result);\n\n try {\n const result = invokeCallback();\n\n if (!this.type.synchronous && isPromise(result)) {\n return result.catch(normalizeErr).then(handleResult, handleError);\n } else {\n return handleResult(result);\n }\n } catch (err) {\n // If callback throws (synchronously)\n return handleError(Rejection.normalize(err));\n } finally {\n if (hook.invokeLimit && ++hook.invokeCount >= hook.invokeLimit) {\n hook.deregister();\n }\n }\n }\n\n /**\n * This method handles the return value of a Transition Hook.\n *\n * A hook can return false (cancel), a TargetState (redirect),\n * or a promise (which may later resolve to false or a redirect)\n *\n * This also handles \"transition superseded\" -- when a new transition\n * was started while the hook was still running\n */\n handleHookResult(result) {\n const notCurrent = this.getNotCurrentRejection();\n\n if (notCurrent) return notCurrent;\n\n // Hook returned a promise\n if (isPromise(result)) {\n // Wait for the promise, then reprocess with the resulting value\n return result.then((val) => this.handleHookResult(val));\n }\n trace.traceHookResult(result, this.transition);\n\n // Hook returned false\n if (result === false) {\n // Abort this Transition\n return Rejection.aborted(\"Hook aborted transition\").toPromise();\n }\n\n // hook returned a TargetState\n if (result instanceof TargetState) {\n // Halt the current Transition and redirect (a new Transition) to the TargetState.\n return Rejection.redirected(result).toPromise();\n }\n\n return undefined;\n }\n\n /**\n * Return a Rejection promise if the transition is no longer current due\n * a new transition has started and superseded this one.\n */\n getNotCurrentRejection() {\n if (this.transition._aborted) {\n return Rejection.aborted().toPromise();\n }\n\n // This transition is no longer current.\n // Another transition started while this hook was still running.\n if (this.isSuperseded()) {\n // Abort this transition\n return Rejection.superseded(this.options.current()).toPromise();\n }\n\n return undefined;\n }\n\n toString() {\n const { options, registeredHook } = this;\n\n const event = parse(\"traceData.hookType\")(options) || \"internal\",\n context =\n parse(\"traceData.context.state.name\")(options) ||\n parse(\"traceData.context\")(options) ||\n \"unknown\",\n name = fnToString(registeredHook.callback);\n\n return `${event} context: ${context}, ${maxLength(200, name)}`;\n }\n}\n/**\n * These GetResultHandler(s) are used by [[invokeHook]] below\n * Each HookType chooses a GetResultHandler (See: [[TransitionService._defineCoreEvents]])\n */\nTransitionHook.HANDLE_RESULT = (hook) => (result) =>\n hook.handleHookResult(result);\n/**\n * If the result is a promise rejection, log it.\n * Otherwise, ignore the result.\n */\nTransitionHook.LOG_REJECTED_RESULT = (hook) => (result) => {\n isPromise(result) &&\n result.catch((err) => hook.logError(Rejection.normalize(err)));\n\n return undefined;\n};\n/**\n * These GetErrorHandler(s) are used by [[invokeHook]] below\n * Each HookType chooses a GetErrorHandler (See: [[TransitionService._defineCoreEvents]])\n */\nTransitionHook.LOG_ERROR = (hook) => (error) => hook.logError(error);\nTransitionHook.REJECT_ERROR = () => (error) => silentRejection(error);\nTransitionHook.THROW_ERROR = () => (error) => {\n throw error;\n};\n","/**\n * Matches state names using glob-like pattern strings.\n *\n * Globs can be used in specific APIs including:\n *\n * - [[StateService.is]]\n * - [[StateService.includes]]\n * - The first argument to Hook Registration functions like [[TransitionService.onStart]]\n * - [[HookMatchCriteria]] and [[HookMatchCriterion]]\n *\n * A `Glob` string is a pattern which matches state names.\n * Nested state names are split into segments (separated by a dot) when processing.\n * The state named `foo.bar.baz` is split into three segments ['foo', 'bar', 'baz']\n *\n * Globs work according to the following rules:\n *\n * ### Exact match:\n *\n * The glob `'A.B'` matches the state named exactly `'A.B'`.\n *\n * | Glob |Matches states named|Does not match state named|\n * |:------------|:--------------------|:---------------------|\n * | `'A'` | `'A'` | `'B'` , `'A.C'` |\n * | `'A.B'` | `'A.B'` | `'A'` , `'A.B.C'` |\n * | `'foo'` | `'foo'` | `'FOO'` , `'foo.bar'`|\n *\n * ### Single star (`*`)\n *\n * A single star (`*`) is a wildcard that matches exactly one segment.\n *\n * | Glob |Matches states named |Does not match state named |\n * |:------------|:---------------------|:--------------------------|\n * | `'*'` | `'A'` , `'Z'` | `'A.B'` , `'Z.Y.X'` |\n * | `'A.*'` | `'A.B'` , `'A.C'` | `'A'` , `'A.B.C'` |\n * | `'A.*.*'` | `'A.B.C'` , `'A.X.Y'`| `'A'`, `'A.B'` , `'Z.Y.X'`|\n *\n * ### Double star (`**`)\n *\n * A double star (`'**'`) is a wildcard that matches *zero or more segments*\n *\n * | Glob |Matches states named |Does not match state named |\n * |:------------|:----------------------------------------------|:----------------------------------|\n * | `'**'` | `'A'` , `'A.B'`, `'Z.Y.X'` | (matches all states) |\n * | `'A.**'` | `'A'` , `'A.B'` , `'A.C.X'` | `'Z.Y.X'` |\n * | `'**.X'` | `'X'` , `'A.X'` , `'Z.Y.X'` | `'A'` , `'A.login.Z'` |\n * | `'A.**.X'` | `'A.X'` , `'A.B.X'` , `'A.B.C.X'` | `'A'` , `'A.B.C'` |\n *\n */\nexport class Glob {\n /** Returns a glob from the string, or null if the string isn't Glob-like\n * @param {string} text\n * @returns {?Glob}\n */\n static fromString(text) {\n return hasGlobs(text) ? new Glob(text) : null;\n }\n\n /**\n * @param {string} text\n */\n constructor(text) {\n /**\n * @type {string}\n */\n this.text = text;\n\n /**\n * @type {string[]}\n */\n this.glob = text.split(\".\");\n\n const regexpString = this.text\n .split(\".\")\n .map((seg) => {\n if (seg === \"**\") return \"(?:|(?:\\\\.[^.]*)*)\";\n\n if (seg === \"*\") return \"\\\\.[^.]*\";\n\n return `\\\\.${seg}`;\n })\n .join(\"\");\n\n /**\n * @type {RegExp}\n */\n this.regexp = new RegExp(`^${regexpString}$`);\n }\n\n /**\n * @param {string} name\n * @return {boolean}\n */\n matches(name) {\n return this.regexp.test(`.${name}`);\n }\n}\n\n/** Returns true if the string has glob-like characters in it\n * @param {string} text\n * @returns {boolean}\n */\nexport function hasGlobs(text) {\n return !!/[!,*]+/.exec(text);\n}\n","import { map, removeFrom, tail } from \"../../shared/common.js\";\nimport { isFunction, isString } from \"../../shared/utils.js\";\nimport { Glob } from \"../glob/glob.js\";\nimport { TransitionHookScope } from \"./transition-hook.js\";\n/**\n * Determines if the given state matches the matchCriteria\n *\n * @internal\n *\n * @param state a State Object to test against\n * @param criterion\n * - If a string, matchState uses the string as a glob-matcher against the state name\n * - If an array (of strings), matchState uses each string in the array as a glob-matchers against the state name\n * and returns a positive match if any of the globs match.\n * - If a function, matchState calls the function with the state and returns true if the function's result is truthy.\n * @returns {boolean}\n */\nexport function matchState(state, criterion, transition) {\n const toMatch = isString(criterion) ? [criterion] : criterion;\n\n function matchGlobs(_state) {\n const globStrings = toMatch;\n\n for (let i = 0; i < globStrings.length; i++) {\n const glob = new Glob(globStrings[i]);\n\n if (\n (glob && glob.matches(_state.name)) ||\n (!glob && globStrings[i] === _state.name)\n ) {\n return true;\n }\n }\n\n return false;\n }\n const matchFn = isFunction(toMatch) ? toMatch : matchGlobs;\n\n return !!matchFn(state, transition);\n}\n/**\n * The registration data for a registered transition hook\n */\nexport class RegisteredHook {\n /**\n * @param {import(\"./transition-service.js\").TransitionProvider} tranSvc\n * @param eventType\n * @param callback\n * @param matchCriteria\n * @param removeHookFromRegistry\n * @param options\n */\n constructor(\n tranSvc,\n eventType,\n callback,\n matchCriteria,\n removeHookFromRegistry,\n options = {},\n ) {\n /** @type {import(\"./transition-service.js\").TransitionProvider} */\n this.tranSvc = tranSvc;\n this.eventType = eventType;\n this.callback = callback;\n this.matchCriteria = matchCriteria;\n this.removeHookFromRegistry = removeHookFromRegistry;\n this.invokeCount = 0;\n this._deregistered = false;\n this.priority = options.priority || 0;\n this.bind = options.bind || null;\n this.invokeLimit = options.invokeLimit;\n }\n\n /**\n * Gets the matching [[PathNode]]s\n *\n * Given an array of [[PathNode]]s, and a [[HookMatchCriterion]], returns an array containing\n * the [[PathNode]]s that the criteria matches, or `null` if there were no matching nodes.\n *\n * Returning `null` is significant to distinguish between the default\n * \"match-all criterion value\" of `true` compared to a `() => true` function,\n * when the nodes is an empty array.\n *\n * This is useful to allow a transition match criteria of `entering: true`\n * to still match a transition, even when `entering === []`. Contrast that\n * with `entering: (state) => true` which only matches when a state is actually\n * being entered.\n */\n _matchingNodes(nodes, criterion, transition) {\n if (criterion === true) return nodes;\n const matching = nodes.filter((node) =>\n matchState(node.state, criterion, transition),\n );\n\n return matching.length ? matching : null;\n }\n\n /**\n * Gets the default match criteria (all `true`)\n *\n * Returns an object which has all the criteria match paths as keys and `true` as values, i.e.:\n *\n * ```js\n * {\n * to: true,\n * from: true,\n * entering: true,\n * exiting: true,\n * retained: true,\n * }\n */\n _getDefaultMatchCriteria() {\n return map(this.tranSvc._getPathTypes(), () => true);\n }\n\n /**\n * Gets matching nodes as [[IMatchingNodes]]\n *\n * Create a IMatchingNodes object from the TransitionHookTypes that is roughly equivalent to:\n *\n * ```js\n * let matches: IMatchingNodes = {\n * to: _matchingNodes([tail(treeChanges.to)], mc.to),\n * from: _matchingNodes([tail(treeChanges.from)], mc.from),\n * exiting: _matchingNodes(treeChanges.exiting, mc.exiting),\n * retained: _matchingNodes(treeChanges.retained, mc.retained),\n * entering: _matchingNodes(treeChanges.entering, mc.entering),\n * };\n * ```\n */\n _getMatchingNodes(treeChanges, transition) {\n const criteria = Object.assign(\n this._getDefaultMatchCriteria(),\n this.matchCriteria,\n );\n\n const paths = Object.values(this.tranSvc._getPathTypes());\n\n return paths.reduce((mn, pathtype) => {\n // STATE scope criteria matches against every node in the path.\n // TRANSITION scope criteria matches against only the last node in the path\n const isStateHook = pathtype.scope === TransitionHookScope._STATE;\n\n const path = treeChanges[pathtype.name] || [];\n\n const nodes = isStateHook ? path : [tail(path)];\n\n mn[pathtype.name] = this._matchingNodes(\n nodes,\n criteria[pathtype.name],\n transition,\n );\n\n return mn;\n }, {});\n }\n\n /**\n * Determines if this hook's [[matchCriteria]] match the given [[TreeChanges]]\n *\n * @returns an IMatchingNodes object, or null. If an IMatchingNodes object is returned, its values\n * are the matching [[PathNode]]s for each [[HookMatchCriterion]] (to, from, exiting, retained, entering)\n */\n matches(treeChanges, transition) {\n const matches = this._getMatchingNodes(treeChanges, transition);\n\n // Check if all the criteria matched the TreeChanges object\n const allMatched = Object.values(matches).every((x) => x);\n\n return allMatched ? matches : null;\n }\n\n deregister() {\n this.removeHookFromRegistry(this);\n this._deregistered = true;\n }\n}\n/** Return a registration function of the requested type. */\nexport function makeEvent(registry, transitionService, eventType) {\n // Create the object which holds the registered transition hooks.\n const _registeredHooks = (registry._registeredHooks =\n registry._registeredHooks || {});\n\n const hooks = (_registeredHooks[eventType.name] = []);\n\n const removeHookFn = (x) => removeFrom(hooks, x);\n\n // Create hook registration function on the IHookRegistry for the event\n registry[eventType.name] = hookRegistrationFn;\n function hookRegistrationFn(matchObject, callback, options = {}) {\n const registeredHook = new RegisteredHook(\n transitionService,\n eventType,\n callback,\n matchObject,\n removeHookFn,\n options,\n );\n\n hooks.push(registeredHook);\n\n return registeredHook.deregister.bind(registeredHook);\n }\n\n return hookRegistrationFn;\n}\n","import { assertPredicate, unnestR } from \"../../shared/common.js\";\nimport { isArray } from \"../../shared/utils.js\";\nimport {\n TransitionHook,\n TransitionHookPhase,\n TransitionHookScope,\n} from \"./transition-hook.js\";\n\n/**\n * This class returns applicable TransitionHooks for a specific Transition instance.\n *\n * Hooks ([[RegisteredHook]]) may be registered globally, e.g., $transitions.onEnter(...), or locally, e.g.\n * myTransition.onEnter(...). The HookBuilder finds matching RegisteredHooks (where the match criteria is\n * determined by the type of hook)\n *\n * The HookBuilder also converts RegisteredHooks objects to TransitionHook objects, which are used to run a Transition.\n *\n * The HookBuilder constructor is given the $transitions service and a Transition instance. Thus, a HookBuilder\n * instance may only be used for one specific Transition object. (side note: the _treeChanges accessor is private\n * in the Transition class, so we must also provide the Transition's _treeChanges)\n */\nexport class HookBuilder {\n /**\n * @param {import(\"./transition.js\").Transition} transition\n */\n constructor(transition) {\n this.transition = transition;\n }\n\n /**\n * @param {TransitionHookPhase} phase\n * @returns\n */\n buildHooksForPhase(phase) {\n return this.transition.transitionService\n ._getEvents(phase)\n .map((type) => this.buildHooks(type))\n .reduce(unnestR, [])\n .filter(Boolean);\n }\n\n /**\n * Returns an array of newly built TransitionHook objects.\n *\n * - Finds all RegisteredHooks registered for the given `hookType` which matched the transition's [[TreeChanges]].\n * - Finds [[PathNode]] (or `PathNode[]`) to use as the TransitionHook context(s)\n * - For each of the [[PathNode]]s, creates a TransitionHook\n *\n * @param hookType the type of the hook registration function, e.g., 'onEnter', 'onFinish'.\n */\n buildHooks(hookType) {\n const { transition } = this;\n\n const treeChanges = transition.treeChanges();\n\n // Find all the matching registered hooks for a given hook type\n const matchingHooks = this.getMatchingHooks(\n hookType,\n treeChanges,\n transition,\n );\n\n if (!matchingHooks) return [];\n const baseHookOptions = {\n transition,\n current: transition.options().current,\n };\n\n const makeTransitionHooks = (hook) => {\n // Fetch the Nodes that caused this hook to match.\n const matches = hook.matches(treeChanges, transition);\n\n // Select the PathNode[] that will be used as TransitionHook context objects\n const matchingNodes = matches[hookType.criteriaMatchPath.name];\n\n // Return an array of HookTuples\n return matchingNodes.map((node) => {\n const _options = Object.assign(\n {\n bind: hook.bind,\n traceData: { hookType: hookType.name, context: node },\n },\n baseHookOptions,\n );\n\n const state =\n hookType.criteriaMatchPath.scope === TransitionHookScope._STATE\n ? node.state.self\n : null;\n\n const transitionHook = new TransitionHook(\n transition,\n state,\n hook,\n _options,\n );\n\n return { hook, node, transitionHook };\n });\n };\n\n return matchingHooks\n .map(makeTransitionHooks)\n .reduce(unnestR, [])\n .sort(tupleSort(hookType.reverseSort))\n .map((tuple) => tuple.transitionHook);\n }\n\n /**\n * Finds all RegisteredHooks from:\n * - The Transition object instance hook registry\n * - The TransitionService ($transitions) global hook registry\n *\n * which matched:\n * - the eventType\n * - the matchCriteria (to, from, exiting, retained, entering)\n *\n * @returns an array of matched [[RegisteredHook]]s\n */\n getMatchingHooks(hookType, treeChanges, transition) {\n const isCreate = hookType.hookPhase === TransitionHookPhase._CREATE;\n\n // Instance and Global hook registries\n const $transitions = this.transition.transitionService;\n\n const registries = isCreate\n ? [$transitions]\n : [this.transition, $transitions];\n\n return registries\n .map((reg) => reg.getHooks(hookType.name)) // Get named hooks from registries\n .filter(assertPredicate(isArray, `broken event named: ${hookType.name}`)) // Sanity check\n .reduce(unnestR, []) // Un-nest RegisteredHook[][] to RegisteredHook[] array\n .filter((hook) => hook.matches(treeChanges, transition)); // Only those satisfying matchCriteria\n }\n}\n/**\n * A factory for a sort function for HookTuples.\n *\n * The sort function first compares the PathNode depth (how deep in the state tree a node is), then compares\n * the EventHook priority.\n *\n * @param reverseDepthSort a boolean, when true, reverses the sort order for the node depth\n * @returns a tuple sort function\n */\nfunction tupleSort(reverseDepthSort = false) {\n return function nodeDepthThenPriority(left, right) {\n const factor = reverseDepthSort ? -1 : 1;\n\n const depthDelta =\n (left.node.state.path.length - right.node.state.path.length) * factor;\n\n return depthDelta !== 0\n ? depthDelta\n : right.hook.priority - left.hook.priority;\n };\n}\n","import { trace } from \"../common/trace.js\";\nimport { stringify } from \"../../shared/strings.js\";\nimport {\n anyTrueR,\n arrayTuples,\n find,\n map,\n omit,\n tail,\n unnestR,\n} from \"../../shared/common.js\";\nimport {\n assert,\n isNullOrUndefined,\n isObject,\n isUndefined,\n} from \"../../shared/utils.js\";\nimport { is, propEq, val } from \"../../shared/hof.js\";\nimport { TransitionHook, TransitionHookPhase } from \"./transition-hook.js\";\nimport { makeEvent, matchState } from \"./hook-registry.js\";\nimport { HookBuilder } from \"./hook-builder.js\";\nimport { PathUtils } from \"../path/path-utils.js\";\nimport { Param } from \"../params/param.js\";\nimport { Resolvable } from \"../resolve/resolvable.js\";\nimport { ResolveContext } from \"../resolve/resolve-context.js\";\nimport { Rejection } from \"./reject-factory.js\";\n\n/** @typedef {import('./interface.ts').IHookRegistry} IHookRegistry */\n\nconst REDIRECT_MAX = 20;\n\n/**\n * Represents a transition between two states.\n *\n * When navigating to a state, we are transitioning **from** the current state **to** the new state.\n *\n * This object contains all contextual information about the to/from states, parameters, resolves.\n * It has information about all states being entered and exited as a result of the transition.\n * @implements {IHookRegistry}\n */\nexport class Transition {\n /**\n * Creates a new Transition object.\n *\n * If the target state is not valid, an error is thrown.\n *\n * @param {Array<import('../path/path-node.js').PathNode>} fromPath The path of [[PathNode]]s from which the transition is leaving. The last node in the `fromPath`\n * encapsulates the \"from state\".\n * @param {import('../state/target-state.js').TargetState} targetState The target state and parameters being transitioned to (also, the transition options)\n * @param {import('../transition/transition-service.js').TransitionProvider} transitionService The [[TransitionService]] instance\n * @param {import('../router.js').Router} globals\n */\n constructor(fromPath, targetState, transitionService, globals) {\n /**\n * @type {import('../router.js').Router}\n */\n this.globals = globals;\n this.transitionService = transitionService;\n this._deferred = Promise.withResolvers();\n /**\n * This promise is resolved or rejected based on the outcome of the Transition.\n *\n * When the transition is successful, the promise is resolved\n * When the transition is unsuccessful, the promise is rejected with the [[Rejection]] or javascript error\n */\n this.promise = this._deferred.promise;\n /** @internal Holds the hook registration functions such as those passed to Transition.onStart() */\n this._registeredHooks = {};\n\n this._hookBuilder = new HookBuilder(this);\n /** Checks if this transition is currently active/running. */\n this.isActive = () => this.globals.transition === this;\n this._targetState = targetState;\n\n if (!targetState.valid()) {\n throw new Error(targetState.error());\n }\n // current() is assumed to come from targetState.options, but provide a naive implementation otherwise.\n this._options = Object.assign(\n { current: val(this) },\n targetState.options(),\n );\n this.$id = transitionService._transitionCount++;\n const toPath = PathUtils.buildToPath(fromPath, targetState);\n\n this._treeChanges = PathUtils.treeChanges(\n fromPath,\n toPath,\n this._options.reloadState,\n );\n this.createTransitionHookRegFns();\n const onCreateHooks = this._hookBuilder.buildHooksForPhase(\n TransitionHookPhase._CREATE,\n );\n\n TransitionHook.invokeHooks(onCreateHooks, () => null);\n this.applyViewConfigs();\n this.onStart = undefined;\n this.onBefore = undefined;\n this.onSuccess = undefined;\n this.onEnter = undefined;\n this.onRetain = undefined;\n this.onExit = undefined;\n this.onFinish = undefined;\n this.onError = undefined;\n }\n\n /**\n * Creates the transition-level hook registration functions\n * (which can then be used to register hooks)\n */\n createTransitionHookRegFns() {\n this.transitionService\n ._getEvents()\n .filter((type) => type.hookPhase !== TransitionHookPhase._CREATE)\n .forEach((type) => makeEvent(this, this.transitionService, type));\n }\n\n getHooks(hookName) {\n return this._registeredHooks[hookName];\n }\n\n applyViewConfigs() {\n const enteringStates = this._treeChanges.entering.map((node) => node.state);\n\n PathUtils.applyViewConfigs(\n this.transitionService.$view,\n this._treeChanges.to,\n enteringStates,\n );\n }\n\n /**\n * @returns {import('../state/state-object.js').StateObject} the internal from [State] object\n */\n $from() {\n return tail(this._treeChanges.from).state;\n }\n\n /**\n * @returns {import('../state/state-object.js').StateObject} the internal to [State] object\n */\n $to() {\n return tail(this._treeChanges.to).state;\n }\n\n /**\n * Returns the \"from state\"\n *\n * Returns the state that the transition is coming *from*.\n *\n * @returns The state declaration object for the Transition's (\"from state\").\n */\n from() {\n return this.$from().self;\n }\n\n /**\n * Returns the \"to state\"\n *\n * Returns the state that the transition is going *to*.\n *\n * @returns The state declaration object for the Transition's target state (\"to state\").\n */\n to() {\n return this.$to().self;\n }\n\n /**\n * Gets the Target State\n *\n * A transition's [[TargetState]] encapsulates the [[to]] state, the [[params]], and the [[options]] as a single object.\n *\n * @returns the [[TargetState]] of this Transition\n */\n targetState() {\n return this._targetState;\n }\n\n /**\n * Determines whether two transitions are equivalent.\n * @deprecated\n */\n is(compare) {\n if (compare instanceof Transition) {\n // TODO: Also compare parameters\n return this.is({ to: compare.$to().name, from: compare.$from().name });\n }\n\n return !(\n (compare.to && !matchState(this.$to(), compare.to, this)) ||\n (compare.from && !matchState(this.$from(), compare.from, this))\n );\n }\n\n params(pathname = \"to\") {\n return Object.freeze(\n this._treeChanges[pathname]\n .map((x) => x.paramValues)\n .reduce((acc, obj) => ({ ...acc, ...obj }), {}),\n );\n }\n\n /**\n * Gets all available resolve tokens (keys)\n *\n * This method can be used in conjunction with [[injector]] to inspect the resolve values\n * available to the Transition.\n *\n * This returns all the tokens defined on [[StateDeclaration.resolve]] blocks, for the states\n * in the Transition's [[TreeChanges.to]] path.\n *\n * #### Example:\n * This example logs all resolve values\n * ```js\n * let tokens = trans.getResolveTokens();\n * tokens.forEach(token => console.log(token + \" = \" + trans.injector().get(token)));\n * ```\n *\n * #### Example:\n * This example creates promises for each resolve value.\n * This triggers fetches of resolves (if any have not yet been fetched).\n * When all promises have all settled, it logs the resolve values.\n * ```js\n * let tokens = trans.getResolveTokens();\n * let promise = tokens.map(token => trans.injector().getAsync(token));\n * Promise.all(promises).then(values => console.log(\"Resolved values: \" + values));\n * ```\n *\n * Note: Angular 1 users whould use `$q.all()`\n *\n * @param pathname resolve context's path name (e.g., `to` or `from`)\n *\n * @returns an array of resolve tokens (keys)\n */\n getResolveTokens(pathname = \"to\") {\n return new ResolveContext(this._treeChanges[pathname]).getTokens();\n }\n\n /**\n * Dynamically adds a new [[Resolvable]] (i.e., [[StateDeclaration.resolve]]) to this transition.\n *\n * Allows a transition hook to dynamically add a Resolvable to this Transition.\n *\n * Use the [[Transition.injector]] to retrieve the resolved data in subsequent hooks ([[UIInjector.get]]).\n *\n * If a `state` argument is provided, the Resolvable is processed when that state is being entered.\n * If no `state` is provided then the root state is used.\n * If the given `state` has already been entered, the Resolvable is processed when any child state is entered.\n * If no child states will be entered, the Resolvable is processed during the `onFinish` phase of the Transition.\n *\n * The `state` argument also scopes the resolved data.\n * The resolved data is available from the injector for that `state` and any children states.\n *\n * #### Example:\n * ```js\n * transitionService.onBefore({}, transition => {\n * transition.addResolvable({\n * token: 'myResolve',\n * deps: ['MyService'],\n * resolveFn: myService => myService.getData()\n * });\n * });\n * ```\n *\n * @param resolvable a [[ResolvableLiteral]] object (or a [[Resolvable]])\n * @param state the state in the \"to path\" which should receive the new resolve (otherwise, the root state)\n */\n addResolvable(resolvable, state) {\n if (state === void 0) {\n state = \"\";\n }\n resolvable = is(Resolvable)(resolvable)\n ? resolvable\n : new Resolvable(resolvable);\n const stateName = typeof state === \"string\" ? state : state.name;\n\n const topath = this._treeChanges.to;\n\n const targetNode = find(topath, (node) => {\n return node.state.name === stateName;\n });\n\n assert(!!targetNode, `targetNode not found ${stateName}`);\n const resolveContext = new ResolveContext(topath);\n\n resolveContext.addResolvables(\n [resolvable],\n /** @type {import(\"../path/path-node.js\").PathNode} */ (targetNode).state,\n );\n }\n\n /**\n * Gets the transition from which this transition was redirected.\n *\n * If the current transition is a redirect, this method returns the transition that was redirected.\n *\n * #### Example:\n * ```js\n * let transitionA = $state.go('A').transition\n * transitionA.onStart({}, () => $state.target('B'));\n * $transitions.onSuccess({ to: 'B' }, (trans) => {\n * trans.to().name === 'B'; // true\n * trans.redirectedFrom() === transitionA; // true\n * });\n * ```\n *\n * @returns The previous Transition, or null if this Transition is not the result of a redirection\n */\n redirectedFrom() {\n return this._options.redirectedFrom || null;\n }\n\n /**\n * Gets the original transition in a redirect chain\n *\n * A transition might belong to a long chain of multiple redirects.\n * This method walks the [[redirectedFrom]] chain back to the original (first) transition in the chain.\n *\n * #### Example:\n * ```js\n * // states\n * registry.register({ name: 'A', redirectTo: 'B' });\n * registry.register({ name: 'B', redirectTo: 'C' });\n * registry.register({ name: 'C', redirectTo: 'D' });\n * registry.register({ name: 'D' });\n *\n * let transitionA = $state.go('A').transition\n *\n * $transitions.onSuccess({ to: 'D' }, (trans) => {\n * trans.to().name === 'D'; // true\n * trans.redirectedFrom().to().name === 'C'; // true\n * trans.originalTransition() === transitionA; // true\n * trans.originalTransition().to().name === 'A'; // true\n * });\n * ```\n *\n * @returns The original Transition that started a redirect chain\n */\n originalTransition() {\n const rf = this.redirectedFrom();\n\n return (rf && rf.originalTransition()) || this;\n }\n\n /**\n * Get the transition options\n *\n * @returns the options for this Transition.\n */\n options() {\n return this._options;\n }\n\n /**\n * Gets the states being entered.\n *\n * @returns an array of states that will be entered during this transition.\n */\n entering() {\n return map(this._treeChanges.entering, (x) => x.state).map((x) => x.self);\n }\n\n /**\n * Gets the states being exited.\n *\n * @returns an array of states that will be exited during this transition.\n */\n exiting() {\n return map(this._treeChanges.exiting, (x) => x.state)\n .map((x) => x.self)\n .reverse();\n }\n\n /**\n * Gets the states being retained.\n *\n * @returns an array of states that are already entered from a previous Transition, that will not be\n * exited during this Transition\n */\n retained() {\n return map(this._treeChanges.retained, (x) => x.state).map((x) => x.self);\n }\n\n /**\n * Get the [[ViewConfig]]s associated with this Transition\n *\n * Each state can define one or more views (template/controller), which are encapsulated as `ViewConfig` objects.\n * This method fetches the `ViewConfigs` for a given path in the Transition (e.g., \"to\" or \"entering\").\n *\n * @param pathname the name of the path to fetch views for:\n * (`'to'`, `'from'`, `'entering'`, `'exiting'`, `'retained'`)\n * @param state If provided, only returns the `ViewConfig`s for a single state in the path\n *\n * @returns a list of ViewConfig objects for the given path.\n */\n views(pathname = \"entering\", state) {\n let path = this._treeChanges[pathname];\n\n path = !state ? path : path.filter(propEq(\"state\", state));\n\n return path.map((x) => x.views).reduce(unnestR, []);\n }\n\n treeChanges(pathname) {\n return pathname ? this._treeChanges[pathname] : this._treeChanges;\n }\n\n /**\n * Creates a new transition that is a redirection of the current one.\n *\n * This transition can be returned from a [[TransitionService]] hook to\n * redirect a transition to a new state and/or set of parameters.\n *\n * @internal\n *\n * @returns Returns a new [[Transition]] instance.\n */\n redirect(targetState) {\n let redirects = 1,\n trans = this;\n\n while (!isNullOrUndefined((trans = trans.redirectedFrom()))) {\n if (++redirects > REDIRECT_MAX)\n throw new Error(`Too many consecutive Transition redirects (20+)`);\n }\n const redirectOpts = { redirectedFrom: this, source: \"redirect\" };\n\n // If the original transition was caused by URL sync, then use { location: 'replace' }\n // on the new transition (unless the target state explicitly specifies location: false).\n // This causes the original url to be replaced with the url for the redirect target\n // so the original url disappears from the browser history.\n if (\n this.options().source === \"url\" &&\n targetState.options().location !== false\n ) {\n redirectOpts.location = \"replace\";\n }\n const newOptions = Object.assign(\n {},\n this.options(),\n targetState.options(),\n redirectOpts,\n );\n\n targetState = targetState.withOptions(newOptions, true);\n const newTransition = this.transitionService.create(\n this._treeChanges.from,\n targetState,\n );\n\n const originalEnteringNodes = this._treeChanges.entering;\n\n const redirectEnteringNodes = newTransition._treeChanges.entering;\n\n // --- Re-use resolve data from original transition ---\n // When redirecting from a parent state to a child state where the parent parameter values haven't changed\n // (because of the redirect), the resolves fetched by the original transition are still valid in the\n // redirected transition.\n //\n // This allows you to define a redirect on a parent state which depends on an async resolve value.\n // You can wait for the resolve, then redirect to a child state based on the result.\n // The redirected transition does not have to re-fetch the resolve.\n // ---------------------------------------------------------\n const nodeIsReloading = (reloadState) => (node) => {\n return reloadState && node.state.includes[reloadState.name];\n };\n\n // Find any \"entering\" nodes in the redirect path that match the original path and aren't being reloaded\n const matchingEnteringNodes = PathUtils.matching(\n redirectEnteringNodes,\n originalEnteringNodes,\n PathUtils.nonDynamicParams,\n ).filter((x) => !nodeIsReloading(targetState.options().reloadState)(x));\n\n // Use the existing (possibly pre-resolved) resolvables for the matching entering nodes.\n matchingEnteringNodes.forEach((node, idx) => {\n node.resolvables = originalEnteringNodes[idx].resolvables;\n });\n\n return newTransition;\n }\n\n /** @internal If a transition doesn't exit/enter any states, returns any [[Param]] whose value changed */\n _changedParams() {\n const tc = this._treeChanges;\n\n /** Return undefined if it's not a \"dynamic\" transition, for the following reasons */\n // If user explicitly wants a reload\n if (this._options.reload) return undefined;\n\n // If any states are exiting or entering\n if (tc.exiting.length || tc.entering.length) return undefined;\n\n // If to/from path lengths differ\n if (tc.to.length !== tc.from.length) return undefined;\n // If the to/from paths are different\n const pathsDiffer = arrayTuples(tc.to, tc.from)\n .map((tuple) => tuple[0].state !== tuple[1].state)\n .reduce(anyTrueR, false);\n\n if (pathsDiffer) return undefined;\n // Find any parameter values that differ\n const nodeSchemas = tc.to.map((node) => node.paramSchema);\n\n const [toValues, fromValues] = [tc.to, tc.from].map((path) =>\n path.map((x) => x.paramValues),\n );\n\n const tuples = arrayTuples(nodeSchemas, toValues, fromValues);\n\n return tuples\n .map(([schema, toVals, fromVals]) =>\n Param.changed(schema, toVals, fromVals),\n )\n .reduce(unnestR, []);\n }\n\n /**\n * Returns true if the transition is dynamic.\n *\n * A transition is dynamic if no states are entered nor exited, but at least one dynamic parameter has changed.\n *\n * @returns true if the Transition is dynamic\n */\n dynamic() {\n const changes = this._changedParams();\n\n return !changes\n ? false\n : changes.map((x) => x.dynamic).reduce(anyTrueR, false);\n }\n\n /**\n * Returns true if the transition is ignored.\n *\n * A transition is ignored if no states are entered nor exited, and no parameter values have changed.\n *\n * @returns true if the Transition is ignored.\n */\n ignored() {\n return !!this._ignoredReason();\n }\n\n _ignoredReason() {\n const pending = this.globals.transition;\n\n const { reloadState } = this._options;\n\n const same = (pathA, pathB) => {\n if (pathA.length !== pathB.length) return false;\n const matching = PathUtils.matching(pathA, pathB);\n\n return (\n pathA.length ===\n matching.filter(\n (node) => !reloadState || !node.state.includes[reloadState.name],\n ).length\n );\n };\n\n const newTC = this._treeChanges;\n\n const pendTC = pending && pending._treeChanges;\n\n if (\n pendTC &&\n same(pendTC.to, newTC.to) &&\n same(pendTC.exiting, newTC.exiting)\n )\n return \"SameAsPending\";\n\n if (\n newTC.exiting.length === 0 &&\n newTC.entering.length === 0 &&\n same(newTC.from, newTC.to)\n )\n return \"SameAsCurrent\";\n\n return undefined;\n }\n\n /**\n * Runs the transition\n *\n * This method is generally called from the [[StateService.transitionTo]]\n *\n * @internal\n *\n * @returns {Promise} a promise for a successful transition.\n */\n run() {\n // Gets transition hooks array for the given phase\n const getHooksFor = (phase) => this._hookBuilder.buildHooksForPhase(phase);\n\n // When the chain is complete, then resolve or reject the deferred\n const transitionSuccess = () => {\n trace.traceSuccess(this.$to(), this);\n this.success = true;\n this._deferred.resolve(this.to());\n const hooks = this._hookBuilder.buildHooksForPhase(\n TransitionHookPhase._SUCCESS,\n );\n\n hooks.forEach((hook) => {\n hook.invokeHook();\n });\n };\n\n const transitionError = (reason) => {\n trace.traceError(reason, this);\n this.success = false;\n this._deferred.reject(reason);\n this._error = reason;\n const hooks = getHooksFor(TransitionHookPhase._ERROR);\n\n hooks.forEach((hook) => hook.invokeHook());\n };\n\n const runTransition = () => {\n // Wait to build the RUN hook chain until the BEFORE hooks are done\n // This allows a BEFORE hook to dynamically add additional RUN hooks via the Transition object.\n const allRunHooks = getHooksFor(TransitionHookPhase._RUN);\n\n const resolved = Promise.resolve();\n\n return TransitionHook.invokeHooks(allRunHooks, () => resolved);\n };\n\n const startTransition = () => {\n const { globals } = this;\n\n globals.lastStartedTransitionId = this.$id;\n globals.transition = this;\n globals.transitionHistory.enqueue(this);\n trace.traceTransitionStart(this);\n\n return Promise.resolve();\n };\n\n const allBeforeHooks = getHooksFor(TransitionHookPhase._BEFORE);\n\n TransitionHook.invokeHooks(allBeforeHooks, startTransition)\n .then(runTransition)\n .then(transitionSuccess, transitionError);\n\n return this.promise;\n }\n\n /**\n * Checks if the Transition is valid\n *\n * @returns true if the Transition is valid\n */\n valid() {\n return !this.error() || this.success !== undefined;\n }\n\n /**\n * Aborts this transition\n *\n * Imperative API to abort a Transition.\n * This only applies to Transitions that are not yet complete.\n */\n abort() {\n // Do not set flag if the transition is already complete\n if (isUndefined(this.success)) {\n this._aborted = true;\n }\n }\n\n /**\n * The Transition error reason.\n *\n * If the transition is invalid (and could not be run), returns the reason the transition is invalid.\n * If the transition was valid and ran, but was not successful, returns the reason the transition failed.\n *\n * @returns a transition rejection explaining why the transition is invalid, or the reason the transition failed.\n */\n error() {\n const state = this.$to();\n\n if (state.self.abstract) {\n return Rejection.invalid(\n `Cannot transition to abstract state '${state.name}'`,\n );\n }\n const paramDefs = state.parameters();\n\n const values = this.params();\n\n const invalidParams = paramDefs.filter(\n (param) => !param.validates(values[param.id]),\n );\n\n if (invalidParams.length) {\n const invalidValues = invalidParams\n .map((param) => `[${param.id}:${stringify(values[param.id])}]`)\n .join(\", \");\n\n const detail = `The following parameter values are not valid for state '${state.name}': ${invalidValues}`;\n\n return Rejection.invalid(detail);\n }\n\n if (this.success === false) return this._error;\n\n return undefined;\n }\n\n /**\n * A string representation of the Transition\n *\n * @returns A string representation of the Transition\n */\n toString() {\n const fromStateOrName = this.from();\n\n const toStateOrName = this.to();\n\n const avoidEmptyHash = (params) =>\n params[\"#\"] !== null && params[\"#\"] !== undefined\n ? params\n : omit(params, [\"#\"]);\n\n // (X) means the to state is invalid.\n const id = this.$id,\n from = isObject(fromStateOrName) ? fromStateOrName.name : fromStateOrName,\n fromParams = stringify(\n avoidEmptyHash(\n this._treeChanges.from\n .map((x) => x.paramValues)\n .reduce((acc, obj) => ({ ...acc, ...obj }), {}),\n ),\n ),\n toValid = this.valid() ? \"\" : \"(X) \",\n to = isObject(toStateOrName) ? toStateOrName.name : toStateOrName,\n toParams = stringify(avoidEmptyHash(this.params()));\n\n return `Transition#${id}( '${from}'${fromParams} -> ${toValid}'${to}'${toParams} )`;\n }\n}\n\nTransition.diToken = Transition;\n","import { Transition } from \"../transition/transition.js\";\nimport { Resolvable } from \"../resolve/resolvable.js\";\nimport { uniqR, unnestR } from \"../../shared/common.js\";\n\nexport function registerAddCoreResolvables(transitionService) {\n transitionService.onCreate({}, function addCoreResolvables(trans) {\n trans.addResolvable(Resolvable.fromData(Transition, trans), \"\");\n trans.addResolvable(Resolvable.fromData(\"$transition$\", trans), \"\");\n trans.addResolvable(\n Resolvable.fromData(\"$stateParams\", trans.params()),\n \"\",\n );\n trans.entering().forEach((state) => {\n trans.addResolvable(Resolvable.fromData(\"$state$\", state), state);\n });\n });\n}\n\nconst TRANSITION_TOKENS = [\"$transition$\", Transition];\n\n// References to Transition in the treeChanges pathnodes makes all\n// previous Transitions reachable in memory, causing a memory leak\n// This function removes resolves for '$transition$' and `Transition` from the treeChanges.\n// Do not use this on current transitions, only on old ones.\nexport function treeChangesCleanup(trans) {\n const nodes = Object.values(trans.treeChanges())\n .reduce(unnestR, [])\n .reduce(uniqR, []);\n\n // If the resolvable is a Transition, return a new resolvable with null data\n const replaceTransitionWithNull = (resolve) => {\n return TRANSITION_TOKENS.includes(resolve.token)\n ? Resolvable.fromData(resolve.token, null)\n : resolve;\n };\n\n nodes.forEach((node) => {\n node.resolvables = node.resolvables.map(replaceTransitionWithNull);\n });\n}\n","/**\n * A factory which creates an onEnter, onExit or onRetain transition hook function\n *\n * The returned function invokes the (for instance) state.onEnter hook when the\n * state is being entered.\n */\nfunction makeEnterExitRetainHook(hookName) {\n return (transition, state) => {\n const _state = state.$$state();\n\n const hookFn = _state[hookName];\n\n return hookFn(transition, state);\n };\n}\n/**\n * The [[TransitionStateHookFn]] for onExit\n *\n * When the state is being exited, the state's .onExit function is invoked.\n *\n * Registered using `transitionService.onExit({ exiting: (state) => !!state.onExit }, onExitHook);`\n *\n * See: [[IHookRegistry.onExit]]\n */\nconst onExitHook = makeEnterExitRetainHook(\"onExit\");\n\nexport const registerOnExitHook = (transitionService) =>\n transitionService.onExit({ exiting: (state) => !!state.onExit }, onExitHook);\n/**\n * The [[TransitionStateHookFn]] for onRetain\n *\n * When the state was already entered, and is not being exited or re-entered, the state's .onRetain function is invoked.\n *\n * Registered using `transitionService.onRetain({ retained: (state) => !!state.onRetain }, onRetainHook);`\n *\n * See: [[IHookRegistry.onRetain]]\n */\nconst onRetainHook = makeEnterExitRetainHook(\"onRetain\");\n\nexport const registerOnRetainHook = (transitionService) =>\n transitionService.onRetain(\n { retained: (state) => !!state.onRetain },\n onRetainHook,\n );\n/**\n * The [[TransitionStateHookFn]] for onEnter\n *\n * When the state is being entered, the state's .onEnter function is invoked.\n *\n * Registered using `transitionService.onEnter({ entering: (state) => !!state.onEnter }, onEnterHook);`\n *\n * See: [[IHookRegistry.onEnter]]\n */\nconst onEnterHook = makeEnterExitRetainHook(\"onEnter\");\n\nexport const registerOnEnterHook = (transitionService) =>\n transitionService.onEnter(\n { entering: (state) => !!state.onEnter },\n onEnterHook,\n );\n","import { ResolveContext } from \"../resolve/resolve-context.js\";\nimport { val } from \"../../shared/hof.js\";\n\nexport const RESOLVE_HOOK_PRIORITY = 1000;\n/**\n * A [[TransitionHookFn]] which resolves all EAGER Resolvables in the To Path\n *\n * Registered using `transitionService.onStart({}, eagerResolvePath, { priority: 1000 });`\n *\n * When a Transition starts, this hook resolves all the EAGER Resolvables, which the transition then waits for.\n *\n * See [[StateDeclaration.resolve]]\n */\nconst eagerResolvePath = (trans) =>\n new ResolveContext(trans.treeChanges().to)\n .resolvePath(\"EAGER\", trans)\n .then(() => {\n /* empty */\n });\n\nexport const registerEagerResolvePath = (transitionService) =>\n transitionService.onStart({}, eagerResolvePath, {\n priority: RESOLVE_HOOK_PRIORITY,\n });\n/**\n * A [[TransitionHookFn]] which resolves all LAZY Resolvables for the state (and all its ancestors) in the To Path\n *\n * Registered using `transitionService.onEnter({ entering: () => true }, lazyResolveState, { priority: 1000 });`\n *\n * When a State is being entered, this hook resolves all the Resolvables for this state, which the transition then waits for.\n *\n * See [[StateDeclaration.resolve]]\n */\nconst lazyResolveState = (trans, state) =>\n new ResolveContext(trans.treeChanges().to)\n .subContext(state.$$state())\n .resolvePath(\"LAZY\", trans)\n .then(() => {\n /* empty */\n });\n\nexport const registerLazyResolveState = (transitionService) =>\n transitionService.onEnter({ entering: val(true) }, lazyResolveState, {\n priority: RESOLVE_HOOK_PRIORITY,\n });\n/**\n * A [[TransitionHookFn]] which resolves any dynamically added (LAZY or EAGER) Resolvables.\n *\n * Registered using `transitionService.onFinish({}, eagerResolvePath, { priority: 1000 });`\n *\n * After all entering states have been entered, this hook resolves any remaining Resolvables.\n * These are typically dynamic resolves which were added by some Transition Hook using [[Transition.addResolvable]].\n *\n * See [[StateDeclaration.resolve]]\n */\nconst resolveRemaining = (trans) =>\n new ResolveContext(trans.treeChanges().to)\n .resolvePath(\"LAZY\", trans)\n .then(() => {\n /* empty */\n });\n\nexport const registerResolveRemaining = (transitionService) =>\n transitionService.onFinish({}, resolveRemaining, {\n priority: RESOLVE_HOOK_PRIORITY,\n });\n","/**\n * A [[TransitionHookFn]] which waits for the views to load\n *\n * Registered using `transitionService.onStart({}, loadEnteringViews);`\n *\n * Allows the views to do async work in [[ViewConfig.load]] before the transition continues.\n * In angular 1, this includes loading the templates.\n */\nconst loadEnteringViews = (transition) => {\n const enteringViews = transition.views(\"entering\");\n\n if (!enteringViews.length) return undefined;\n\n return Promise.all(\n enteringViews.map((view) => Promise.resolve(view.load())),\n ).then(() => {\n /* empty */\n });\n};\n\nexport const registerLoadEnteringViews = (transitionService) =>\n transitionService.onFinish({}, loadEnteringViews);\n\nexport const registerActivateViews = (transitionService, viewService) => {\n /**\n * A [[TransitionHookFn]] which activates the new views when a transition is successful.\n *\n * Registered using `transitionService.onSuccess({}, activateViews);`\n *\n * After a transition is complete, this hook deactivates the old views from the previous state,\n * and activates the new views from the destination state.\n *\n * See [[ViewService]]\n */\n const activateViews = (transition) => {\n const enteringViews = transition.views(\"entering\");\n\n const exitingViews = transition.views(\"exiting\");\n\n if (!enteringViews.length && !exitingViews.length) return;\n exitingViews.forEach((vc) => viewService.deactivateViewConfig(vc));\n enteringViews.forEach((vc) => {\n viewService.activateViewConfig(vc);\n });\n viewService.sync();\n };\n\n transitionService.onSuccess({}, activateViews);\n};\n","import { copy } from \"../../shared/common.js\";\n\n/**\n * A [[TransitionHookFn]] which updates global ng-router state\n *\n * Registered using `transitionService.onBefore({}, updateGlobalState);`\n *\n * Before a [[Transition]] starts, updates the global value of \"the current transition\" ([[Globals.transition]]).\n * After a successful [[Transition]], updates the global values of \"the current state\"\n * ([[Globals.current]] and [[Globals.$current]]) and \"the current param values\" ([[Globals.params]]).\n *\n * See also the deprecated properties:\n * [[StateService.transition]], [[StateService.current]], [[StateService.params]]\n *\n * @param {import('../transition/transition.js').Transition} trans\n */\nconst updateGlobalState = (trans) => {\n const { globals } = trans;\n\n const transitionSuccessful = () => {\n globals.successfulTransitions.enqueue(trans);\n globals.$current = trans.$to();\n globals.current = globals.$current.self;\n copy(trans.params(), globals.params);\n };\n\n const clearCurrentTransition = () => {\n // Do not clear globals.transition if a different transition has started in the meantime\n if (globals.transition === trans) globals.transition = null;\n };\n\n trans.onSuccess({}, transitionSuccessful, { priority: 10000 });\n trans.promise.then(clearCurrentTransition, clearCurrentTransition);\n};\n\nexport const registerUpdateGlobalState = (transitionService) =>\n transitionService.onCreate({}, updateGlobalState);\n","import { isArray } from \"../../shared/utils\";\n\n/**\n * A [[TransitionHookFn]] that performs lazy loading\n *\n * When entering a state \"abc\" which has a `lazyLoad` function defined:\n * - Invoke the `lazyLoad` function (unless it is already in process)\n * - Flag the hook function as \"in process\"\n * - The function should return a promise (that resolves when lazy loading is complete)\n * - Wait for the promise to settle\n * - If the promise resolves to a [[LazyLoadResult]], then register those states\n * - Flag the hook function as \"not in process\"\n * - If the hook was successful\n * - Remove the `lazyLoad` function from the state declaration\n * - If all the hooks were successful\n * - Retry the transition (by returning a TargetState)\n *\n * ```\n * .state('abc', {\n * component: 'fooComponent',\n * lazyLoad: () => import('./fooComponent')\n * });\n * ```\n *\n * See [[StateDeclaration.lazyLoad]]\n */\nexport function registerLazyLoadHook(\n transitionService,\n stateService,\n urlService,\n stateRegistry,\n) {\n return transitionService.onBefore(\n { entering: (state) => !!state.lazyLoad },\n (transition) => {\n function retryTransition() {\n if (transition.originalTransition().options().source !== \"url\") {\n // The original transition was not triggered via url sync\n // The lazy state should be loaded now, so re-try the original transition\n const orig = transition.targetState();\n\n return stateService.target(\n orig.identifier(),\n orig.params(),\n orig.options(),\n );\n }\n // The original transition was triggered via url sync\n // Run the URL rules and find the best match\n const result = urlService.match(urlService.parts());\n\n const rule = result && result.rule;\n\n // If the best match is a state, redirect the transition (instead\n // of calling sync() which supersedes the current transition)\n if (rule && rule.type === \"STATE\") {\n const { state } = rule;\n\n const params = result.match;\n\n return stateService.target(state, params, transition.options());\n }\n // No matching state found, so let .sync() choose the best non-state match/otherwise\n urlService.sync();\n\n return undefined;\n }\n const promises = transition\n .entering()\n .filter((state) => !!state.$$state().lazyLoad)\n .map((state) => lazyLoadState(transition, state, stateRegistry));\n\n return Promise.all(promises).then(retryTransition);\n },\n );\n}\n\n/**\n * Invokes a state's lazy load function\n *\n * @param transition a Transition context\n * @param state the state to lazy load\n * @returns A promise for the lazy load result\n */\nexport function lazyLoadState(transition, state, stateRegistry) {\n const lazyLoadFn = state.$$state().lazyLoad;\n\n // Store/get the lazy load promise on/from the hookfn so it doesn't get re-invoked\n let promise = lazyLoadFn._promise;\n\n if (!promise) {\n const success = (result) => {\n delete state.lazyLoad;\n delete state.$$state().lazyLoad;\n delete lazyLoadFn._promise;\n\n return result;\n };\n\n const error = (err) => {\n delete lazyLoadFn._promise;\n\n return Promise.reject(err);\n };\n\n promise = lazyLoadFn._promise = Promise.resolve(\n lazyLoadFn(transition, state),\n )\n .then(updateStateRegistry)\n .then(success, error);\n }\n /** Register any lazy loaded state definitions */\n function updateStateRegistry(result) {\n if (result && isArray(result.states)) {\n result.states.forEach((_state) => stateRegistry.register(_state));\n }\n\n return result;\n }\n\n return promise;\n}\n","import { TransitionHook } from \"./transition-hook.js\";\n/**\n * This class defines a type of hook, such as `onBefore` or `onEnter`.\n * Plugins can define custom hook types, such as sticky states does for `onInactive`.\n */\nexport class TransitionEventType {\n constructor(\n name,\n hookPhase,\n hookOrder,\n criteriaMatchPath,\n reverseSort = false,\n getResultHandler = TransitionHook.HANDLE_RESULT,\n getErrorHandler = TransitionHook.REJECT_ERROR,\n synchronous = false,\n ) {\n this.name = name;\n this.hookPhase = hookPhase;\n this.hookOrder = hookOrder;\n this.criteriaMatchPath = criteriaMatchPath;\n this.reverseSort = reverseSort;\n this.getResultHandler = getResultHandler;\n this.getErrorHandler = getErrorHandler;\n this.synchronous = synchronous;\n }\n}\n","import { trace } from \"../common/trace.js\";\nimport { Rejection } from \"../transition/reject-factory.js\";\n/**\n * A [[TransitionHookFn]] that skips a transition if it should be ignored\n *\n * This hook is invoked at the end of the onBefore phase.\n *\n * If the transition should be ignored (because no parameter or states changed)\n * then the transition is ignored and not processed.\n */\nfunction ignoredHook(trans) {\n const ignoredReason = trans._ignoredReason();\n\n if (!ignoredReason) return undefined;\n trace.traceTransitionIgnored(trans);\n const pending = trans.globals.transition;\n\n // The user clicked a link going back to the *current state* ('A')\n // However, there is also a pending transition in flight (to 'B')\n // Abort the transition to 'B' because the user now wants to be back at 'A'.\n if (ignoredReason === \"SameAsCurrent\" && pending) {\n pending.abort();\n }\n\n return Rejection.ignored().toPromise();\n}\nexport const registerIgnoredTransitionHook = (transitionService) =>\n transitionService.onBefore({}, ignoredHook, { priority: -9999 });\n","/**\n * A [[TransitionHookFn]] that rejects the Transition if it is invalid\n *\n * This hook is invoked at the end of the onBefore phase.\n * If the transition is invalid (for example, param values do not validate)\n * then the transition is rejected.\n */\nfunction invalidTransitionHook(trans) {\n if (!trans.valid()) {\n throw new Error(trans.error().toString());\n }\n}\nexport const registerInvalidTransitionHook = (transitionService) =>\n transitionService.onBefore({}, invalidTransitionHook, { priority: -10000 });\n","import { Transition } from \"./transition.js\";\nimport { makeEvent } from \"./hook-registry.js\";\nimport {\n registerAddCoreResolvables,\n treeChangesCleanup,\n} from \"../hooks/core-resolvables.js\";\nimport {\n registerOnEnterHook,\n registerOnExitHook,\n registerOnRetainHook,\n} from \"../hooks/on-enter-exit-retain.js\";\nimport {\n registerEagerResolvePath,\n registerLazyResolveState,\n registerResolveRemaining,\n} from \"../hooks/resolve.js\";\nimport {\n registerActivateViews,\n registerLoadEnteringViews,\n} from \"../hooks/views.js\";\nimport { registerUpdateGlobalState } from \"../hooks/update-globals.js\";\n\nimport { registerLazyLoadHook } from \"../hooks/lazy-load.js\";\nimport { TransitionEventType } from \"./transition-event-type.js\";\nimport {\n TransitionHook,\n TransitionHookPhase,\n TransitionHookScope,\n} from \"./transition-hook.js\";\nimport { isDefined } from \"../../shared/utils.js\";\nimport { registerIgnoredTransitionHook } from \"../hooks/ignored-transition.js\";\nimport { registerInvalidTransitionHook } from \"../hooks/invalid-transition.js\";\nimport { registerRedirectToHook } from \"../hooks/redirect-to.js\";\nimport { registerUpdateUrl } from \"../hooks/url.js\";\nimport { $injectTokens as $t, provider } from \"../../injection-tokens.js\";\n/**\n * The default [[Transition]] options.\n *\n * Include this object when applying custom defaults:\n * let reloadOpts = { reload: true, notify: true }\n * let options = defaults(theirOpts, customDefaults, defaultOptions);\n */\nexport const defaultTransOpts = {\n location: true,\n relative: null,\n inherit: false,\n notify: true,\n reload: false,\n supercede: true,\n custom: {},\n current: () => null,\n source: \"unknown\",\n};\n/**\n * This class provides services related to Transitions.\n *\n * - Most importantly, it allows global Transition Hooks to be registered.\n * - It allows the default transition error handler to be set.\n * - It also has a factory function for creating new [[Transition]] objects, (used internally by the [[StateService]]).\n *\n * At bootstrap, [[UIRouter]] creates a single instance (singleton) of this class.\n *\n * This API is located at `router.transitionService` ([[UIRouter.transitionService]])\n */\nexport class TransitionProvider {\n /* @ignore */ static $inject = provider([$t.$router, $t.$view]);\n\n /**\n * @param {import('../router.js').Router} globals\n * @param viewService\n */\n constructor(globals, viewService) {\n this._transitionCount = 0;\n /** The transition hook types, such as `onEnter`, `onStart`, etc */\n this._eventTypes = [];\n /** @internal The registered transition hooks */\n this._registeredHooks = {};\n /** The paths on a criteria object */\n this._criteriaPaths = {};\n this.globals = globals;\n this.$view = viewService;\n this._deregisterHookFns = {};\n this._defineCorePaths();\n this._defineCoreEvents();\n this._registerCoreTransitionHooks();\n globals.successfulTransitions.onEvict(treeChangesCleanup);\n }\n\n $get = [\n $t.$state,\n $t.$url,\n $t.$stateRegistry,\n $t.$view,\n (stateService, urlService, stateRegistry, viewService) => {\n // Lazy load state trees\n this._deregisterHookFns.lazyLoad = registerLazyLoadHook(\n this,\n stateService,\n urlService,\n stateRegistry,\n );\n\n // After globals.current is updated at priority: 10000\n this._deregisterHookFns.updateUrl = registerUpdateUrl(\n this,\n stateService,\n urlService,\n );\n\n // Wire up redirectTo hook\n this._deregisterHookFns.redirectTo = registerRedirectToHook(\n this,\n stateService,\n );\n\n this._deregisterHookFns.activateViews = registerActivateViews(\n this,\n viewService,\n );\n\n return this;\n },\n ];\n /**\n * Registers a [[TransitionHookFn]], called *while a transition is being constructed*.\n *\n * Registers a transition lifecycle hook, which is invoked during transition construction.\n *\n * This low level hook should only be used by plugins.\n * This can be a useful time for plugins to add resolves or mutate the transition as needed.\n * The Sticky States plugin uses this hook to modify the treechanges.\n *\n * ### Lifecycle\n *\n * `onCreate` hooks are invoked *while a transition is being constructed*.\n *\n * ### Return value\n *\n * The hook's return value is ignored\n *\n * @internal\n * @param criteria defines which Transitions the Hook should be invoked for.\n * @param callback the hook function which will be invoked.\n * @param options the registration options\n * @returns a function which deregisters the hook.\n */\n\n /**\n * Creates a new [[Transition]] object\n *\n * This is a factory function for creating new Transition objects.\n * It is used internally by the [[StateService]] and should generally not be called by application code.\n *\n * @internal\n * @param fromPath the path to the current state (the from state)\n * @param targetState the target state (destination)\n * @returns a Transition\n */\n create(fromPath, targetState) {\n return new Transition(fromPath, targetState, this, this.globals);\n }\n\n _defineCoreEvents() {\n const TH = TransitionHook;\n\n const paths = this._criteriaPaths;\n\n const NORMAL_SORT = false,\n REVERSE_SORT = true;\n\n const SYNCHRONOUS = true;\n\n this._defineEvent(\n \"onCreate\",\n TransitionHookPhase._CREATE,\n 0,\n paths.to,\n NORMAL_SORT,\n TH.LOG_REJECTED_RESULT,\n TH.THROW_ERROR,\n SYNCHRONOUS,\n );\n this._defineEvent(\"onBefore\", TransitionHookPhase._BEFORE, 0, paths.to);\n this._defineEvent(\"onStart\", TransitionHookPhase._RUN, 0, paths.to);\n this._defineEvent(\n \"onExit\",\n TransitionHookPhase._RUN,\n 100,\n paths.exiting,\n REVERSE_SORT,\n );\n this._defineEvent(\n \"onRetain\",\n TransitionHookPhase._RUN,\n 200,\n paths.retained,\n );\n this._defineEvent(\"onEnter\", TransitionHookPhase._RUN, 300, paths.entering);\n this._defineEvent(\"onFinish\", TransitionHookPhase._RUN, 400, paths.to);\n this._defineEvent(\n \"onSuccess\",\n TransitionHookPhase._SUCCESS,\n 0,\n paths.to,\n NORMAL_SORT,\n TH.LOG_REJECTED_RESULT,\n TH.LOG_ERROR,\n SYNCHRONOUS,\n );\n this._defineEvent(\n \"onError\",\n TransitionHookPhase._ERROR,\n 0,\n paths.to,\n NORMAL_SORT,\n TH.LOG_REJECTED_RESULT,\n TH.LOG_ERROR,\n SYNCHRONOUS,\n );\n }\n\n _defineCorePaths() {\n const { _STATE: STATE, _TRANSITION: TRANSITION } = TransitionHookScope;\n\n this._definePathType(\"to\", TRANSITION);\n this._definePathType(\"from\", TRANSITION);\n this._definePathType(\"exiting\", STATE);\n this._definePathType(\"retained\", STATE);\n this._definePathType(\"entering\", STATE);\n }\n\n _defineEvent(\n name,\n hookPhase,\n hookOrder,\n criteriaMatchPath,\n reverseSort = false,\n getResultHandler = TransitionHook.HANDLE_RESULT,\n getErrorHandler = TransitionHook.REJECT_ERROR,\n synchronous = false,\n ) {\n const eventType = new TransitionEventType(\n name,\n hookPhase,\n hookOrder,\n criteriaMatchPath,\n reverseSort,\n getResultHandler,\n getErrorHandler,\n synchronous,\n );\n\n this._eventTypes.push(eventType);\n makeEvent(this, this, eventType);\n }\n\n /**\n * @param {TransitionHookPhase} [phase]\n * @return {any[]}\n */\n _getEvents(phase) {\n const transitionHookTypes = isDefined(phase)\n ? this._eventTypes.filter((type) => type.hookPhase === phase)\n : this._eventTypes.slice();\n\n return transitionHookTypes.sort((left, right) => {\n const cmpByPhase = left.hookPhase - right.hookPhase;\n\n return cmpByPhase === 0 ? left.hookOrder - right.hookOrder : cmpByPhase;\n });\n }\n\n /**\n * Adds a Path to be used as a criterion against a TreeChanges path\n *\n * For example: the `exiting` path in [[HookMatchCriteria]] is a STATE scoped path.\n * It was defined by calling `defineTreeChangesCriterion('exiting', TransitionHookScope.STATE)`\n * Each state in the exiting path is checked against the criteria and returned as part of the match.\n *\n * Another example: the `to` path in [[HookMatchCriteria]] is a TRANSITION scoped path.\n * It was defined by calling `defineTreeChangesCriterion('to', TransitionHookScope.TRANSITION)`\n * Only the tail of the `to` path is checked against the criteria and returned as part of the match.\n *\n * @internal\n */\n _definePathType(name, hookScope) {\n this._criteriaPaths[name] = { name, scope: hookScope };\n }\n\n _getPathTypes() {\n return this._criteriaPaths;\n }\n\n getHooks(hookName) {\n return this._registeredHooks[hookName];\n }\n\n _registerCoreTransitionHooks() {\n const fns = this._deregisterHookFns;\n\n fns.addCoreResolves = registerAddCoreResolvables(this);\n fns.ignored = registerIgnoredTransitionHook(this);\n fns.invalid = registerInvalidTransitionHook(this);\n\n // Wire up onExit/Retain/Enter state hooks\n fns.onExit = registerOnExitHook(this);\n fns.onRetain = registerOnRetainHook(this);\n fns.onEnter = registerOnEnterHook(this);\n // Wire up Resolve hooks\n fns.eagerResolve = registerEagerResolvePath(this);\n fns.lazyResolve = registerLazyResolveState(this);\n fns.resolveAll = registerResolveRemaining(this);\n // Wire up the View management hooks\n fns.loadViews = registerLoadEnteringViews(this);\n\n // Updates global state after a transition\n fns.updateGlobals = registerUpdateGlobalState(this);\n // Lazy load state trees\n fns.lazyLoad = registerLazyLoadHook(this);\n }\n}\n","export const registerUpdateUrl = (\n transitionService,\n stateService,\n urlService,\n) => {\n /**\n * A [[TransitionHookFn]] which updates the URL after a successful transition\n *\n * Registered using `transitionService.onSuccess({}, updateUrl);`\n */\n const updateUrl = (transition) => {\n const options = transition.options();\n\n const $state = stateService;\n\n // Dont update the url in these situations:\n // The transition was triggered by a URL sync (options.source === 'url')\n // The user doesn't want the url to update (options.location === false)\n // The destination state, and all parents have no navigable url\n if (\n options.source !== \"url\" &&\n options.location &&\n $state.$current.navigable\n ) {\n const urlOptions = { replace: options.location === \"replace\" };\n\n urlService.push(\n $state.$current.navigable.url,\n $state.globals.params,\n urlOptions,\n );\n }\n urlService.update(true);\n };\n\n transitionService.onSuccess({}, updateUrl, { priority: 9999 });\n};\n","import { isFunction, isString } from \"../../shared/utils.js\";\nimport { TargetState } from \"../state/target-state\";\n\nexport const registerRedirectToHook = (transitionService, stateService) => {\n /**\n * A [[TransitionHookFn]] that redirects to a different state or params\n *\n * Registered using `transitionService.onStart({ to: (state) => !!state.redirectTo }, redirectHook);`\n *\n * See [[StateDeclaration.redirectTo]]\n */\n const redirectToHook = (trans) => {\n const redirect = trans.to().redirectTo;\n\n if (!redirect) return undefined;\n const $state = stateService;\n\n function handleResult(result) {\n if (!result) return undefined;\n\n if (result instanceof TargetState) {\n return result;\n }\n\n if (isString(result)) {\n return $state.target(result, trans.params(), trans.options());\n }\n\n if (result.state || result.params) {\n return $state.target(\n result.state || trans.to(),\n result.params || trans.params(),\n trans.options(),\n );\n }\n\n return undefined;\n }\n\n if (isFunction(redirect)) {\n return Promise.resolve(redirect(trans)).then(handleResult);\n }\n\n return handleResult(redirect);\n };\n\n transitionService.onStart(\n { to: (state) => !!state.redirectTo },\n redirectToHook,\n );\n};\n","import {\n defaults,\n removeFrom,\n silenceUncaughtInPromise,\n silentRejection,\n} from \"../../shared/common.js\";\nimport { isDefined, isObject, isString, minErr } from \"../../shared/utils.js\";\nimport { Queue } from \"../../shared/queue.js\";\nimport { makeTargetState } from \"../path/path-utils.js\";\nimport { PathNode } from \"../path/path-node.js\";\nimport { defaultTransOpts } from \"../transition/transition-service.js\";\nimport { RejectType, Rejection } from \"../transition/reject-factory.js\";\nimport { TargetState } from \"./target-state.js\";\nimport { Param } from \"../params/param.js\";\nimport { Glob } from \"../glob/glob.js\";\nimport { lazyLoadState } from \"../hooks/lazy-load.js\";\nimport { EventBus } from \"../../services/pubsub/pubsub.js\";\n\nconst stdErr = minErr(\"$stateProvider\");\n\n/**\n * Provides services related to ng-router states.\n *\n * This API is located at `router.stateService` ([[UIRouter.stateService]])\n */\nexport class StateProvider {\n /**\n * The latest successful state parameters\n *\n * @deprecated This is a passthrough through to [[Router.params]]\n */\n get params() {\n return this.globals.params;\n }\n\n /**\n * The current [[StateDeclaration]]\n *\n * @deprecated This is a passthrough through to [[Router.current]]\n */\n get current() {\n return this.globals.current;\n }\n\n /**\n * The current [[StateObject]] (an internal API)\n *\n * @deprecated This is a passthrough through to [[Router.$current]]\n */\n get $current() {\n return this.globals.$current;\n }\n\n /* @ignore */ static $inject = [\"$routerProvider\", \"$transitionsProvider\"];\n\n /**\n *\n * @param {import('../router.js').Router} globals\n * @param {*} transitionService\n * @param {import('../../core/di/internal-injector.js').InjectorService} $injector\n */\n constructor(globals, transitionService, $injector) {\n this.stateRegistry = undefined;\n this.urlService = undefined;\n this.globals = globals;\n this.transitionService = transitionService;\n this.$injector = $injector;\n this.invalidCallbacks = [];\n\n this._defaultErrorHandler = function $defaultErrorHandler($error$) {\n if ($error$ instanceof Error && $error$.stack) {\n throw $error$;\n } else if ($error$ instanceof Rejection) {\n throw new Error($error$.toString());\n } else {\n throw new Error($error$);\n }\n };\n\n EventBus.subscribe(\"$stateService:defaultErrorHandler\", (error) =>\n this.defaultErrorHandler()(error),\n );\n }\n\n $get = () => this;\n\n /**\n * Decorates states when they are registered\n *\n * Allows you to extend (carefully) or override (at your own peril) the\n * `stateBuilder` object used internally by [[StateRegistry]].\n * This can be used to add custom functionality to ng-router,\n * for example inferring templateUrl based on the state name.\n *\n * When passing only a name, it returns the current (original or decorated) builder\n * function that matches `name`.\n *\n * The builder functions that can be decorated are listed below. Though not all\n * necessarily have a good use case for decoration, that is up to you to decide.\n *\n * In addition, users can attach custom decorators, which will generate new\n * properties within the state's internal definition. There is currently no clear\n * use-case for this beyond accessing internal states (i.e. $state.$current),\n * however, expect this to become increasingly relevant as we introduce additional\n * meta-programming features.\n *\n * **Warning**: Decorators should not be interdependent because the order of\n * execution of the builder functions in non-deterministic. Builder functions\n * should only be dependent on the state definition object and super function.\n *\n *\n * Existing builder functions and current return values:\n *\n * - **parent** `{object}` - returns the parent state object.\n * - **data** `{object}` - returns state data, including any inherited data that is not\n * overridden by own values (if any).\n * - **url** `{object}` - returns a {@link ui.router.util.type:UrlMatcher UrlMatcher}\n * or `null`.\n * - **navigable** `{object}` - returns closest ancestor state that has a URL (aka is\n * navigable).\n * - **params** `{object}` - returns an array of state params that are ensured to\n * be a super-set of parent's params.\n * - **views** `{object}` - returns a views object where each key is an absolute view\n * name (i.e. \"viewName@stateName\") and each value is the urlConfig object\n * (template, controller) for the view. Even when you don't use the views object\n * explicitly on a state urlConfig, one is still created for you internally.\n * So by decorating this builder function you have access to decorating template\n * and controller properties.\n * - **ownParams** `{object}` - returns an array of params that belong to the state,\n * not including any params defined by ancestor states.\n * - **path** `{string}` - returns the full path from the root down to this state.\n * Needed for state activation.\n * - **includes** `{object}` - returns an object that includes every state that\n * would pass a `$state.includes()` test.\n *\n * #### Example:\n * Override the internal 'views' builder with a function that takes the state\n * definition, and a reference to the internal function being overridden:\n * ```js\n * $stateProvider.decorator('views', function (state, parent) {\n * let result = {},\n * views = parent(state);\n *\n * angular.forEach(views, function (urlConfig, name) {\n * let autoName = (state.name + '.' + name).replace('.', '/');\n * urlConfig.templateUrl = urlConfig.templateUrl || '/partials/' + autoName + '.html';\n * result[name] = urlConfig;\n * });\n * return result;\n * });\n *\n * $stateProvider.state('home', {\n * views: {\n * 'contact.list': { controller: 'ListController' },\n * 'contact.item': { controller: 'ItemController' }\n * }\n * });\n * ```\n *\n *\n * ```js\n * // Auto-populates list and item views with /partials/home/contact/list.html,\n * // and /partials/home/contact/item.html, respectively.\n * $state.go('home');\n * ```\n *\n * @param {string} name The name of the builder function to decorate.\n * @param {object} func A function that is responsible for decorating the original\n * builder function. The function receives two parameters:\n *\n * - `{object}` - state - The state urlConfig object.\n * - `{object}` - super - The original builder function.\n *\n * @return {object} $stateProvider - $stateProvider instance\n */\n decorator(name, func) {\n return this.stateRegistry.decorator(name, func) || this;\n }\n\n /**\n *\n * @param {import(\"./interface.ts\").StateDeclaration} definition\n */\n state(definition) {\n if (!definition.name) {\n throw stdErr(\"stateinvalid\", `'name' required`);\n }\n\n try {\n this.stateRegistry.register(definition);\n } catch (err) {\n throw stdErr(\"stateinvalid\", err.message);\n }\n\n return this;\n }\n\n /**\n * Handler for when [[transitionTo]] is called with an invalid state.\n *\n * Invokes the [[onInvalid]] callbacks, in natural order.\n * Each callback's return value is checked in sequence until one of them returns an instance of TargetState.\n * The results of the callbacks are wrapped in Promise.resolve(), so the callbacks may return promises.\n *\n * If a callback returns an TargetState, then it is used as arguments to $state.transitionTo() and the result returned.\n *\n * @internal\n */\n _handleInvalidTargetState(fromPath, toState) {\n const fromState = makeTargetState(this.stateRegistry, fromPath);\n\n const { globals } = this;\n\n const latestThing = () => globals.transitionHistory.peekTail();\n\n const latest = latestThing();\n\n /** @type {Queue<Function>} */\n const callbackQueue = new Queue(this.invalidCallbacks.slice());\n\n const injector = this.$injector;\n\n const checkForRedirect = (result) => {\n if (!(result instanceof TargetState)) {\n return undefined;\n }\n let target = result;\n\n // Recreate the TargetState, in case the state is now defined.\n target = this.target(\n target.identifier(),\n target.params(),\n target.options(),\n );\n\n if (!target.valid()) {\n return Rejection.invalid(target.error()).toPromise();\n }\n\n if (latestThing() !== latest) {\n return Rejection.superseded().toPromise();\n }\n\n return this.transitionTo(\n target.identifier(),\n target.params(),\n target.options(),\n );\n };\n\n function invokeNextCallback() {\n const nextCallback = callbackQueue.dequeue();\n\n if (nextCallback === undefined)\n return Rejection.invalid(toState.error()).toPromise();\n const callbackResult = Promise.resolve(\n nextCallback(toState, fromState, injector),\n );\n\n return callbackResult\n .then(checkForRedirect)\n .then((result) => result || invokeNextCallback());\n }\n\n return invokeNextCallback();\n }\n\n /**\n * Registers an Invalid State handler\n *\n * Registers a [[OnInvalidCallback]] function to be invoked when [[StateService.transitionTo]]\n * has been called with an invalid state reference parameter\n *\n * Example:\n * ```js\n * stateService.onInvalid(function(to, from, injector) {\n * if (to.name() === 'foo') {\n * let lazyLoader = injector.get('LazyLoadService');\n * return lazyLoader.load('foo')\n * .then(() => stateService.target('foo'));\n * }\n * });\n * ```\n *\n * @param {function} callback invoked when the toState is invalid\n * This function receives the (invalid) toState, the fromState, and an injector.\n * The function may optionally return a [[TargetState]] or a Promise for a TargetState.\n * If one is returned, it is treated as a redirect.\n *\n * @returns a function which deregisters the callback\n */\n onInvalid(callback) {\n this.invalidCallbacks.push(callback);\n\n return function deregisterListener() {\n removeFrom(this.invalidCallbacks, callback);\n }.bind(this);\n }\n\n /**\n * Reloads the current state\n *\n * A method that force reloads the current state, or a partial state hierarchy.\n * All resolves are re-resolved, and components reinstantiated.\n *\n * #### Example:\n * ```js\n * let app angular.module('app', ['ui.router']);\n *\n * app.controller('ctrl', function ($scope, $state) {\n * $scope.reload = function(){\n * $state.reload();\n * }\n * });\n * ```\n *\n * Note: `reload()` is just an alias for:\n *\n * ```js\n * $state.transitionTo($state.current, $state.params, {\n * reload: true, inherit: false\n * });\n * ```\n *\n * @param reloadState A state name or a state object.\n * If present, this state and all its children will be reloaded, but ancestors will not reload.\n *\n * #### Example:\n * ```js\n * //assuming app application consists of 3 states: 'contacts', 'contacts.detail', 'contacts.detail.item'\n * //and current state is 'contacts.detail.item'\n * let app angular.module('app', ['ui.router']);\n *\n * app.controller('ctrl', function ($scope, $state) {\n * $scope.reload = function(){\n * //will reload 'contact.detail' and nested 'contact.detail.item' states\n * $state.reload('contact.detail');\n * }\n * });\n * ```\n *\n * @returns A promise representing the state of the new transition. See [[StateService.go]]\n */\n reload(reloadState) {\n return this.transitionTo(this.globals.current, this.globals.params, {\n reload: isDefined(reloadState) ? reloadState : true,\n inherit: false,\n notify: false,\n });\n }\n\n /**\n * Transition to a different state and/or parameters\n *\n * Convenience method for transitioning to a new state.\n *\n * `$state.go` calls `$state.transitionTo` internally but automatically sets options to\n * `{ location: true, inherit: true, relative: router.globals.$current, notify: true }`.\n * This allows you to use either an absolute or relative `to` argument (because of `relative: router.globals.$current`).\n * It also allows you to specify * only the parameters you'd like to update, while letting unspecified parameters\n * inherit from the current parameter values (because of `inherit: true`).\n *\n * #### Example:\n * ```js\n * let app = angular.module('app', ['ui.router']);\n *\n * app.controller('ctrl', function ($scope, $state) {\n * $scope.changeState = function () {\n * $state.go('contact.detail');\n * };\n * });\n * ```\n *\n * @param to Absolute state name, state object, or relative state path (relative to current state).\n *\n * Some examples:\n *\n * - `$state.go('contact.detail')` - will go to the `contact.detail` state\n * - `$state.go('^')` - will go to the parent state\n * - `$state.go('^.sibling')` - if current state is `home.child`, will go to the `home.sibling` state\n * - `$state.go('.child.grandchild')` - if current state is home, will go to the `home.child.grandchild` state\n *\n * @param params A map of the parameters that will be sent to the state, will populate $stateParams.\n *\n * Any parameters that are not specified will be inherited from current parameter values (because of `inherit: true`).\n * This allows, for example, going to a sibling state that shares parameters defined by a parent state.\n *\n * @param options Transition options\n *\n * @returns {promise} A promise representing the state of the new transition.\n */\n go(to, params, options) {\n const defautGoOpts = { relative: this.$current, inherit: true };\n\n const transOpts = defaults(options, defautGoOpts, defaultTransOpts);\n\n return this.transitionTo(to, params, transOpts);\n }\n\n /**\n * Creates a [[TargetState]]\n *\n * This is a factory method for creating a TargetState\n *\n * This may be returned from a Transition Hook to redirect a transition, for example.\n */\n target(identifier, params, options = {}) {\n // If we're reloading, find the state object to reload from\n if (isObject(options.reload) && !options.reload.name)\n throw new Error(\"Invalid reload state object\");\n const reg = this.stateRegistry;\n\n options.reloadState =\n options.reload === true\n ? reg.root()\n : reg.matcher.find(options.reload, options.relative);\n\n if (options.reload && !options.reloadState)\n throw new Error(\n `No such reload state '${isString(options.reload) ? options.reload : options.reload.name}'`,\n );\n\n return new TargetState(this.stateRegistry, identifier, params, options);\n }\n\n getCurrentPath() {\n const { globals } = this;\n\n const latestSuccess = globals.successfulTransitions.peekTail();\n\n const rootPath = () => [new PathNode(this.stateRegistry.root())];\n\n return latestSuccess ? latestSuccess._treeChanges.to : rootPath();\n }\n\n /**\n * Low-level method for transitioning to a new state.\n *\n * The [[go]] method (which uses `transitionTo` internally) is recommended in most situations.\n *\n * #### Example:\n * ```js\n * let app = angular.module('app', ['ui.router']);\n *\n * app.controller('ctrl', function ($scope, $state) {\n * $scope.changeState = function () {\n * $state.transitionTo('contact.detail');\n * };\n * });\n * ```\n *\n * @param to State name or state object.\n * @param toParams A map of the parameters that will be sent to the state,\n * will populate $stateParams.\n * @param options Transition options\n *\n * @returns A promise representing the state of the new transition. See [[go]]\n */\n transitionTo(to, toParams = {}, options = {}) {\n options = defaults(options, defaultTransOpts);\n const getCurrent = () => this.globals.transition;\n\n options = Object.assign(options, { current: getCurrent });\n const ref = this.target(to, toParams, options);\n\n const currentPath = this.getCurrentPath();\n\n if (!ref.exists()) return this._handleInvalidTargetState(currentPath, ref);\n\n if (!ref.valid()) return silentRejection(ref.error());\n\n if (options.supercede === false && getCurrent()) {\n return Rejection.ignored(\n \"Another transition is in progress and supercede has been set to false in TransitionOptions for the transition. So the transition was ignored in favour of the existing one in progress.\",\n ).toPromise();\n }\n /**\n * Special handling for Ignored, Aborted, and Redirected transitions\n *\n * The semantics for the transition.run() promise and the StateService.transitionTo()\n * promise differ. For instance, the run() promise may be rejected because it was\n * IGNORED, but the transitionTo() promise is resolved because from the user perspective\n * no error occurred. Likewise, the transition.run() promise may be rejected because of\n * a Redirect, but the transitionTo() promise is chained to the new Transition's promise.\n */\n const rejectedTransitionHandler = (trans) => (error) => {\n if (error instanceof Rejection) {\n const isLatest = this.globals.lastStartedTransitionId <= trans.$id;\n\n if (error.type === RejectType._IGNORED) {\n isLatest && this.urlService.update();\n\n // Consider ignored `Transition.run()` as a successful `transitionTo`\n return Promise.resolve(this.globals.current);\n }\n const { detail } = error;\n\n if (\n error.type === RejectType._SUPERSEDED &&\n error.redirected &&\n detail instanceof TargetState\n ) {\n // If `Transition.run()` was redirected, allow the `transitionTo()` promise to resolve successfully\n // by returning the promise for the new (redirect) `Transition.run()`.\n const redirect = trans.redirect(detail);\n\n return redirect.run().catch(rejectedTransitionHandler(redirect));\n }\n\n if (error.type === RejectType._ABORTED) {\n isLatest && this.urlService.update();\n\n return Promise.reject(error);\n }\n }\n const errorHandler = this.defaultErrorHandler();\n\n errorHandler(error);\n\n return Promise.reject(error);\n };\n\n const transition = this.transitionService.create(currentPath, ref);\n\n const transitionToPromise = transition\n .run()\n .catch(rejectedTransitionHandler(transition));\n\n silenceUncaughtInPromise(transitionToPromise); // issue #2676\n\n // Return a promise for the transition, which also has the transition object on it.\n return Object.assign(transitionToPromise, { transition });\n }\n\n /**\n * Checks if the current state *is* the provided state\n *\n * Similar to [[includes]] but only checks for the full state name.\n * If params is supplied then it will be tested for strict equality against the current\n * active params object, so all params must match with none missing and no extras.\n *\n * #### Example:\n * ```js\n * $state.$current.name = 'contacts.details.item';\n *\n * // absolute name\n * $state.is('contact.details.item'); // returns true\n * $state.is(contactDetailItemStateObject); // returns true\n * ```\n *\n * // relative name (. and ^), typically from a template\n * // E.g. from the 'contacts.details' template\n * ```html\n * <div ng-class=\"{highlighted: $state.is('.item')}\">Item</div>\n * ```\n *\n * @param stateOrName The state name (absolute or relative) or state object you'd like to check.\n * @param params A param object, e.g. `{sectionId: section.id}`, that you'd like\n * to test against the current active state.\n * @param options An options object. The options are:\n * - `relative`: If `stateOrName` is a relative state name and `options.relative` is set, .is will\n * test relative to `options.relative` state (or name).\n *\n * @returns Returns true if it is the state.\n */\n is(stateOrName, params, options) {\n options = defaults(options, { relative: this.$current });\n const state = this.stateRegistry.matcher.find(\n stateOrName,\n options.relative,\n );\n\n if (!isDefined(state)) return undefined;\n\n if (this.$current !== state) return false;\n\n if (!params) return true;\n const schema = state.parameters({ inherit: true, matchingKeys: params });\n\n return Param.equals(\n schema,\n Param.values(schema, params),\n this.globals.params,\n );\n }\n\n /**\n * Checks if the current state *includes* the provided state\n *\n * A method to determine if the current active state is equal to or is the child of the\n * state stateName. If any params are passed then they will be tested for a match as well.\n * Not all the parameters need to be passed, just the ones you'd like to test for equality.\n *\n * #### Example when `$state.$current.name === 'contacts.details.item'`\n * ```js\n * // Using partial names\n * $state.includes(\"contacts\"); // returns true\n * $state.includes(\"contacts.details\"); // returns true\n * $state.includes(\"contacts.details.item\"); // returns true\n * $state.includes(\"contacts.list\"); // returns false\n * $state.includes(\"about\"); // returns false\n * ```\n *\n * #### Glob Examples when `* $state.$current.name === 'contacts.details.item.url'`:\n * ```js\n * $state.includes(\"*.details.*.*\"); // returns true\n * $state.includes(\"*.details.**\"); // returns true\n * $state.includes(\"**.item.**\"); // returns true\n * $state.includes(\"*.details.item.url\"); // returns true\n * $state.includes(\"*.details.*.url\"); // returns true\n * $state.includes(\"*.details.*\"); // returns false\n * $state.includes(\"item.**\"); // returns false\n * ```\n *\n * @param stateOrName A partial name, relative name, glob pattern,\n * or state object to be searched for within the current state name.\n * @param params A param object, e.g. `{sectionId: section.id}`,\n * that you'd like to test against the current active state.\n * @param options An options object. The options are:\n * - `relative`: If `stateOrName` is a relative state name and `options.relative` is set, .is will\n * test relative to `options.relative` state (or name).\n *\n * @returns {boolean} Returns true if it does include the state\n */\n includes(stateOrName, params, options) {\n options = defaults(options, { relative: this.$current });\n const glob = isString(stateOrName) && Glob.fromString(stateOrName);\n\n if (glob) {\n if (!glob.matches(this.$current.name)) return false;\n stateOrName = this.$current.name;\n }\n const state = this.stateRegistry.matcher.find(\n stateOrName,\n options.relative,\n );\n\n const include = this.$current.includes;\n\n if (!isDefined(state)) return undefined;\n\n if (!isDefined(include[state.name])) return false;\n\n if (!params) return true;\n const schema = state.parameters({ inherit: true, matchingKeys: params });\n\n return Param.equals(\n schema,\n Param.values(schema, params),\n this.globals.params,\n );\n }\n\n /**\n * Generates a URL for a state and parameters\n *\n * Returns the url for the given state populated with the given params.\n *\n * #### Example:\n * ```js\n * expect($state.href(\"about.person\", { person: \"bob\" })).toEqual(\"/about/bob\");\n * ```\n *\n * @param stateOrName The state name or state object you'd like to generate a url from.\n * @param params An object of parameter values to fill the state's required parameters.\n * @param options Options object. The options are:\n *\n * @returns {string} compiled state url\n */\n href(stateOrName, params, options) {\n const defaultHrefOpts = {\n lossy: true,\n inherit: true,\n absolute: false,\n relative: this.$current,\n };\n\n options = defaults(options, defaultHrefOpts);\n params = params || {};\n const state = this.stateRegistry.matcher.find(\n stateOrName,\n options.relative,\n );\n\n if (!isDefined(state)) return null;\n\n if (options.inherit)\n params = this.globals.params.$inherit(params, this.$current, state);\n const nav = state && options.lossy ? state.navigable : state;\n\n if (!nav || nav.url === undefined || nav.url === null) {\n return null;\n }\n\n return this.urlService.href(nav.url, params, {\n absolute: options.absolute,\n });\n }\n\n /**\n * Sets or gets the default [[transitionTo]] error handler.\n *\n * The error handler is called when a [[Transition]] is rejected or when any error occurred during the Transition.\n * This includes errors caused by resolves and transition hooks.\n *\n * Note:\n * This handler does not receive certain Transition rejections.\n * Redirected and Ignored Transitions are not considered to be errors by [[StateService.transitionTo]].\n *\n * The built-in default error handler logs the error to the console.\n *\n * You can provide your own custom handler.\n *\n * #### Example:\n * ```js\n * stateService.defaultErrorHandler(function() {\n * // Do not log transitionTo errors\n * });\n * ```\n *\n * @param handler a global error handler function\n * @returns the current global error handler\n */\n defaultErrorHandler(handler) {\n return (this._defaultErrorHandler = handler || this._defaultErrorHandler);\n }\n\n get(stateOrName, base) {\n const reg = this.stateRegistry;\n\n if (arguments.length === 0) return reg.get();\n\n return reg.get(stateOrName, base || this.$current);\n }\n\n /**\n * Lazy loads a state\n *\n * Explicitly runs a state's [[StateDeclaration.lazyLoad]] function.\n *\n * @param stateOrName the state that should be lazy loaded\n * @param transition the optional Transition context to use (if the lazyLoad function requires an injector, etc)\n * Note: If no transition is provided, a noop transition is created using the from the current state to the current state.\n * This noop transition is not actually run.\n *\n * @returns a promise to lazy load\n */\n lazyLoad(stateOrName, transition) {\n const state = this.get(stateOrName);\n\n if (!state || !state.lazyLoad)\n throw new Error(`Can not lazy load ${stateOrName}`);\n const currentPath = this.getCurrentPath();\n\n const target = makeTargetState(this.stateRegistry, currentPath);\n\n transition =\n transition || this.transitionService.create(currentPath, target);\n\n return lazyLoadState(transition, state);\n }\n}\n","import { $injectTokens as $t } from \"../injection-tokens.js\";\n\nexport class ViewScrollProvider {\n constructor() {\n this.enabled = false;\n }\n\n useAnchorScroll() {\n this.enabled = true;\n }\n\n $get = [\n $t.$anchorScroll,\n /**\n * @param {import('../services/anchor-scroll/anchor-scroll.js').AnchorScrollObject} $anchorScroll\n * @returns {import('../services/anchor-scroll/anchor-scroll.js').AnchorScrollObject|Function}\n */\n ($anchorScroll) => {\n if (this.enabled) {\n return $anchorScroll;\n }\n\n /**\n * @param {Element} $element\n * @returns {Promise<number>}\n */\n return async function ($element) {\n return setTimeout(() => {\n $element.scrollIntoView(false);\n }, 0);\n };\n },\n ];\n}\n","import {\n isArray,\n isDefined,\n isFunction,\n isNullOrUndefined,\n isObject,\n} from \"../shared/utils.js\";\nimport { tail, unnestR } from \"../shared/common.js\";\nimport { Resolvable } from \"./resolve/resolvable.js\";\nimport { kebobString } from \"../shared/strings.js\";\nimport { annotate } from \"../core/di/di.js\";\nimport { DirectiveSuffix } from \"../core/compile/compile.js\";\nimport { $injectTokens as $t } from \"../injection-tokens.js\";\n\n/**\n * @typedef BindingTuple\n * @property {string} name\n * @property {string} type\n */\n\n/**\n * Service which manages loading of templates from a ViewConfig.\n */\nexport class TemplateFactoryProvider {\n constructor() {\n /** @type {boolean} */\n this._useHttp = false;\n }\n\n $get = [\n $t.$http,\n $t.$templateCache,\n $t.$templateRequest,\n $t.$injector,\n /**\n * @param {ng.HttpService} $http\n * @param {ng.TemplateCacheService} $templateCache\n * @param {any} $templateRequest\n * @param {import(\"../core/di/internal-injector.js\").InjectorService} $injector\n * @returns\n */\n ($http, $templateCache, $templateRequest, $injector) => {\n this.$templateRequest = $templateRequest;\n this.$http = $http;\n this.$templateCache = $templateCache;\n this.$injector = $injector;\n\n return this;\n },\n ];\n\n /**\n * Forces the provider to use $http service directly\n * @param {boolean} value\n */\n useHttpService(value) {\n this._useHttp = value;\n }\n\n /**\n * Creates a template from a configuration object.\n *\n * @param config Configuration object for which to load a template.\n * The following properties are search in the specified order, and the first one\n * that is defined is used to create the template:\n *\n * @param {any} config\n * @param {any} params Parameters to pass to the template function.\n * @param {import(\"./resolve/resolve-context.js\").ResolveContext} context The resolve context associated with the template's view\n *\n * @return {string|object} The template html as a string, or a promise for\n * that string,or `null` if no template is configured.\n */\n fromConfig(config, params, context) {\n const defaultTemplate = \"<ng-view></ng-view>\";\n\n const asTemplate = (result) =>\n Promise.resolve(result).then((str) => ({ template: str }));\n\n const asComponent = (result) =>\n Promise.resolve(result).then((str) => ({ component: str }));\n\n const getConfigType = (configParam) => {\n if (isDefined(configParam.template)) return \"template\";\n\n if (isDefined(configParam.templateUrl)) return \"templateUrl\";\n\n if (isDefined(configParam.templateProvider)) return \"templateProvider\";\n\n if (isDefined(configParam.component)) return \"component\";\n\n if (isDefined(configParam.componentProvider)) return \"componentProvider\";\n\n return \"default\";\n };\n\n switch (getConfigType(config)) {\n case \"template\":\n return asTemplate(this.fromString(config.template, params));\n case \"templateUrl\":\n return asTemplate(this.fromUrl(config.templateUrl, params));\n case \"templateProvider\":\n return asTemplate(\n this.fromProvider(config.templateProvider, params, context),\n );\n case \"component\":\n return asComponent(config.component);\n case \"componentProvider\":\n return asComponent(\n this.fromComponentProvider(config.componentProvider, context),\n );\n default:\n return asTemplate(defaultTemplate);\n }\n }\n\n /**\n * Creates a template from a string or a function returning a string.\n *\n * @param {string | Function} template html template as a string or function that returns an html template as a string.\n * @param {any} [params] Parameters to pass to the template function.\n *\n * @return {string|object} The template html as a string, or a promise for that\n * string.\n */\n fromString(template, params) {\n return isFunction(template)\n ? /** @type {Function} */ (template)(params)\n : template;\n }\n\n /**\n * Loads a template from the a URL via `$http` and `$templateCache`.\n *\n * @param {string|Function} url url of the template to load, or a function\n * that returns a url.\n * @param {Object} params Parameters to pass to the url function.\n * @return {string|Promise.<string>} The template html as a string, or a promise\n * for that string.\n */\n fromUrl(url, params) {\n if (isFunction(url)) url = /** @type {Function} */ (url)(params);\n\n if (isNullOrUndefined(url)) return null;\n\n if (this._useHttp) {\n return this.$http\n .get(/** @type {string} */ (url), {\n cache: this.$templateCache,\n headers: { Accept: \"text/html\" },\n })\n .then(function (response) {\n return response.data;\n });\n }\n\n return this.$templateRequest(url);\n }\n\n /**\n * Creates a template by invoking an injectable provider function.\n *\n * @param {import('../interface.ts').Injectable<any>} provider Function to invoke via `locals`\n * @param {Function} params a function used to invoke the template provider\n * @param {import(\"./resolve/resolve-context.js\").ResolveContext} context\n * @return {string|Promise.<string>} The template html as a string, or a promise\n * for that string.\n */\n fromProvider(provider, params, context) {\n const deps = annotate(provider);\n\n const providerFn = isArray(provider) ? tail(provider) : provider;\n\n const resolvable = new Resolvable(\"\", providerFn, deps);\n\n return resolvable.get(context);\n }\n\n /**\n * Creates a component's template by invoking an injectable provider function.\n *\n * @param {import('../interface.ts').Injectable<any>} provider Function to invoke via `locals`\n * @return {Promise<any>} The template html as a string: \"<component-name input1='::$resolve.foo'></component-name>\".\n */\n fromComponentProvider(provider, context) {\n const deps = annotate(provider);\n\n const providerFn = isArray(provider) ? tail(provider) : provider;\n\n const resolvable = new Resolvable(\"\", providerFn, deps);\n\n return resolvable.get(context); // https://github.com/angular-ui/ui-router/pull/3165/files\n }\n\n /**\n * Creates a template from a component's name\n *\n * This implements route-to-component.\n * It works by retrieving the component (directive) metadata from the injector.\n * It analyses the component's bindings, then constructs a template that instantiates the component.\n * The template wires input and output bindings to resolves or from the parent component.\n *\n * @param {any} ngView {object} The parent ng-view (for binding outputs to callbacks)\n * @param {import(\"./resolve/resolve-context.js\").ResolveContext} context The ResolveContext (for binding outputs to callbacks returned from resolves)\n * @param {string} component {string} Component's name in camel case.\n * @param {any} [bindings] An object defining the component's bindings: {foo: '<'}\n * @return {string} The template as a string: \"<component-name input1='$resolve.foo'></component-name>\".\n */\n makeComponentTemplate(ngView, context, component, bindings) {\n bindings = bindings || {};\n // Bind once prefix\n // Convert to kebob name. Add x- prefix if the string starts with `x-` or `data-`\n const kebob = (camelCase) => {\n const kebobed = kebobString(camelCase);\n\n return /^(x|data)-/.exec(kebobed) ? `x-${kebobed}` : kebobed;\n };\n\n const attributeTpl = /** @param {BindingTuple} input*/ (input) => {\n const { name, type } = input;\n\n const attrName = kebob(name);\n\n // If the ng-view has an attribute which matches a binding on the routed component\n // then pass that attribute through to the routed component template.\n // Prefer ng-view wired mappings to resolve data, unless the resolve was explicitly bound using `bindings:`\n if (ngView.getAttribute(attrName) && !bindings[name])\n return `${attrName}='${ngView.getAttribute(attrName)}'`;\n const resolveName = bindings[name] || name;\n\n // Pre-evaluate the expression for \"@\" bindings by enclosing in {{ }}\n // some-attr=\"{{$resolve.someResolveName }}\"\n if (type === \"@\") return `${attrName}='{{s$resolve.${resolveName}}}'`;\n\n // Wire \"&\" callbacks to resolves that return a callback function\n // Get the result of the resolve (should be a function) and annotate it to get its arguments.\n // some-attr=\"$resolve.someResolveResultName(foo, bar)\"\n if (type === \"&\") {\n const res = context.getResolvable(resolveName);\n\n const fn = res && res.data;\n\n const args = (fn && annotate(fn)) || [];\n\n // account for array style injection, i.e., ['foo', function(foo) {}]\n const arrayIdxStr = isArray(fn) ? `[${fn.length - 1}]` : \"\";\n\n return `${attrName}='$resolve.${resolveName}${arrayIdxStr}(${args.join(\",\")})'`;\n }\n\n // some-attr=\"::$resolve.someResolveName\"\n return `${attrName}='$resolve.${resolveName}'`;\n };\n\n const attrs = getComponentBindings(this.$injector, component)\n .map(attributeTpl)\n .join(\" \");\n\n const kebobName = kebob(component);\n\n return `<${kebobName} ${attrs}></${kebobName}>`;\n }\n}\n\n/**\n * Gets all the directive(s)' inputs ('@', '=', and '<') and outputs ('&')\n */\nfunction getComponentBindings($injector, name) {\n const cmpDefs = $injector.get(name + DirectiveSuffix); // could be multiple\n\n if (!cmpDefs || !cmpDefs.length)\n throw new Error(`Unable to find component named '${name}'`);\n\n return cmpDefs.map(getBindings).reduce(unnestR, []);\n}\n// Given a directive definition, find its object input attributes\n// Use different properties, depending on the type of directive (component, bindToController, normal)\nconst getBindings = (def) => {\n if (isObject(def.bindToController))\n return scopeBindings(def.bindToController);\n\n return scopeBindings(def.scope);\n};\n\n// for ng 1.2 style, process the scope: { input: \"=foo\" }\n// for ng 1.3 through ng 1.5, process the component's bindToController: { input: \"=foo\" } object\nconst scopeBindings = (bindingsObj) =>\n Object.keys(bindingsObj || {})\n // [ 'input', [ '=foo', '=', 'foo' ] ]\n .map((key) => [key, /^([=<@&])[?]?(.*)/.exec(bindingsObj[key])])\n // skip malformed values\n .filter((tuple) => isDefined(tuple) && isArray(tuple[1]))\n // { name: ('foo' || 'input'), type: '=' }\n .map((tuple) => ({ name: tuple[1][2] || tuple[0], type: tuple[1][1] }));\n","import {\n allTrueR,\n arrayTuples,\n defaults,\n find,\n inherit,\n map,\n tail,\n unnest,\n unnestR,\n} from \"../../shared/common.js\";\nimport { propEq } from \"../../shared/hof.js\";\nimport {\n hasOwn,\n isArray,\n isDefined,\n isNullOrUndefined,\n isString,\n} from \"../../shared/utils.js\";\nimport { DefType, Param } from \"../params/param.js\";\nimport { joinNeighborsR, splitOnDelim } from \"../../shared/strings.js\";\n\nfunction quoteRegExp(str, param) {\n let surroundPattern = [\"\", \"\"];\n\n let result = str.replace(/[\\\\[\\]^$*+?.()|{}]/g, \"\\\\$&\");\n\n if (!param) return result;\n switch (param.squash) {\n case false:\n surroundPattern = [\"(\", `)${param.isOptional ? \"?\" : \"\"}`];\n break;\n case true:\n result = result.replace(/\\/$/, \"\");\n surroundPattern = [\"(?:/(\", \")|/)?\"];\n break;\n default:\n surroundPattern = [`(${param.squash}|`, \")?\"];\n break;\n }\n\n return (\n result + surroundPattern[0] + param.type.pattern.source + surroundPattern[1]\n );\n}\nconst memoizeTo = (obj, _prop, fn) => (obj[_prop] = obj[_prop] || fn());\n\nconst splitOnSlash = splitOnDelim(\"/\");\n\nconst defaultConfig = {\n state: { params: {} },\n strict: true,\n caseInsensitive: true,\n};\n\n/**\n * Matches URLs against patterns.\n *\n * Matches URLs against patterns and extracts named parameters from the path or the search\n * part of the URL.\n *\n * A URL pattern consists of a path pattern, optionally followed by '?' and a list of search (query)\n * parameters. Multiple search parameter names are separated by '&'. Search parameters\n * do not influence whether or not a URL is matched, but their values are passed through into\n * the matched parameters returned by [[UrlMatcher.exec]].\n *\n * - *Path parameters* are defined using curly brace placeholders (`/somepath/{param}`)\n * or colon placeholders (`/somePath/:param`).\n *\n * - *A parameter RegExp* may be defined for a param after a colon\n * (`/somePath/{param:[a-zA-Z0-9]+}`) in a curly brace placeholder.\n * The regexp must match for the url to be matched.\n * Should the regexp itself contain curly braces, they must be in matched pairs or escaped with a backslash.\n *\n * Note: a RegExp parameter will encode its value using either [[ParamTypes.path]] or [[ParamTypes.query]].\n *\n * - *Custom parameter types* may also be specified after a colon (`/somePath/{param:int}`) in curly brace parameters.\n * See [[UrlMatcherFactory.type]] for more information.\n *\n * - *Catch-all parameters* are defined using an asterisk placeholder (`/somepath/*catchallparam`).\n * A catch-all * parameter value will contain the remainder of the URL.\n *\n * ---\n *\n * Parameter names may contain only word characters (latin letters, digits, and underscore) and\n * must be unique within the pattern (across both path and search parameters).\n * A path parameter matches any number of characters other than '/'. For catch-all\n * placeholders the path parameter matches any number of characters.\n *\n * Examples:\n *\n * * `'/hello/'` - Matches only if the path is exactly '/hello/'. There is no special treatment for\n * trailing slashes, and patterns have to match the entire path, not just a prefix.\n * * `'/user/:id'` - Matches '/user/bob' or '/user/1234!!!' or even '/user/' but not '/user' or\n * '/user/bob/details'. The second path segment will be captured as the parameter 'id'.\n * * `'/user/{id}'` - Same as the previous example, but using curly brace syntax.\n * * `'/user/{id:[^/]*}'` - Same as the previous example.\n * * `'/user/{id:[0-9a-fA-F]{1,8}}'` - Similar to the previous example, but only matches if the id\n * parameter consists of 1 to 8 hex digits.\n * * `'/files/{path:.*}'` - Matches any URL starting with '/files/' and captures the rest of the\n * path into the parameter 'path'.\n * * `'/files/*path'` - ditto.\n * * `'/calendar/{start:date}'` - Matches \"/calendar/2014-11-12\" (because the pattern defined\n * in the built-in `date` ParamType matches `2014-11-12`) and provides a Date object in $stateParams.start\n *\n */\nexport class UrlMatcher {\n /** @internal Given a matcher, return an array with the matcher's path segments and path params, in order */\n static pathSegmentsAndParams(matcher) {\n const staticSegments = matcher._segments;\n\n const pathParams = matcher._params.filter(\n (path) => path.location === DefType._PATH,\n );\n\n return arrayTuples(staticSegments, pathParams.concat(undefined))\n .reduce(unnestR, [])\n .filter((x) => x !== \"\" && isDefined(x));\n }\n\n /** @internal Given a matcher, return an array with the matcher's query params */\n static queryParams(matcher) {\n return matcher._params.filter((path) => path.location === DefType._SEARCH);\n }\n\n /**\n * Compare two UrlMatchers\n *\n * This comparison function converts a UrlMatcher into static and dynamic path segments.\n * Each static path segment is a static string between a path separator (slash character).\n * Each dynamic segment is a path parameter.\n *\n * The comparison function sorts static segments before dynamic ones.\n */\n static compare(a, b) {\n /**\n * Turn a UrlMatcher and all its parent matchers into an array\n * of slash literals '/', string literals, and Param objects\n *\n * This example matcher matches strings like \"/foo/:param/tail\":\n * var matcher = $umf.compile(\"/foo\").append($umf.compile(\"/:param\")).append($umf.compile(\"/\")).append($umf.compile(\"tail\"));\n * var result = segments(matcher); // [ '/', 'foo', '/', Param, '/', 'tail' ]\n *\n * Caches the result as `matcher._cache.segments`\n */\n const segments = (matcher) =>\n (matcher._cache.segments =\n matcher._cache.segments ||\n matcher._cache.path\n .map(UrlMatcher.pathSegmentsAndParams)\n .reduce(unnestR, [])\n .reduce(joinNeighborsR, [])\n .map((x) => (isString(x) ? splitOnSlash(x) : x))\n .reduce(unnestR, []));\n\n /**\n * Gets the sort weight for each segment of a UrlMatcher\n *\n * Caches the result as `matcher._cache.weights`\n */\n const weights = (matcher) =>\n (matcher._cache.weights =\n matcher._cache.weights ||\n segments(matcher).map((segment) => {\n // Sort slashes first, then static strings, the Params\n if (segment === \"/\") return 1;\n\n if (isString(segment)) return 2;\n\n if (segment instanceof Param) return 3;\n\n return undefined;\n }));\n\n /**\n * Pads shorter array in-place (mutates)\n */\n const padArrays = (left, right, padVal) => {\n const len = Math.max(left.length, right.length);\n\n while (left.length < len) left.push(padVal);\n\n while (right.length < len) right.push(padVal);\n };\n\n const weightsA = weights(a),\n weightsB = weights(b);\n\n padArrays(weightsA, weightsB, 0);\n const _pairs = arrayTuples(weightsA, weightsB);\n\n let cmp;\n\n for (let i = 0, l = _pairs.length; i < l; i++) {\n cmp = _pairs[i][0] - _pairs[i][1];\n\n if (cmp !== 0) return cmp;\n }\n\n return 0;\n }\n\n /**\n * @param pattern The pattern to compile into a matcher.\n * @param paramTypes The [[ParamTypes]] registry\n * @param paramFactory A [[ParamFactory]] object\n * @param config A [[UrlMatcherCompileConfig]] configuration object\n */\n constructor(pattern, paramTypes, paramFactory, config) {\n this._cache = { path: [/** @type {UrlMatcher} */ (this)] };\n\n this._children = [];\n\n this._params = [];\n\n this._segments = [];\n\n this._compiled = [];\n this.config = config = defaults(config, defaultConfig);\n this.pattern = pattern;\n // Find all placeholders and create a compiled pattern, using either classic or curly syntax:\n // '*' name\n // ':' name\n // '{' name '}'\n // '{' name ':' regexp '}'\n // The regular expression is somewhat complicated due to the need to allow curly braces\n // inside the regular expression. The placeholder regexp breaks down as follows:\n // ([:*])([\\w\\[\\]]+) - classic placeholder ($1 / $2) (search version has - for snake-case)\n // \\{([\\w\\[\\]]+)(?:\\:\\s*( ... ))?\\} - curly brace placeholder ($3) with optional regexp/type ... ($4) (search version has - for snake-case\n // (?: ... | ... | ... )+ - the regexp consists of any number of atoms, an atom being either\n // [^{}\\\\]+ - anything other than curly braces or backslash\n // \\\\. - a backslash escape\n // \\{(?:[^{}\\\\]+|\\\\.)*\\} - a matched set of curly braces containing other atoms\n\n const MAX_REGEX_LENGTH = 200; // or any safe limit\n\n const placeholder = new RegExp(\n `([:*])([\\\\w[\\\\]]+)|\\\\{([\\\\w[\\\\]]+)(?::\\\\s*((?:[^{}\\\\\\\\]{1,${\n MAX_REGEX_LENGTH\n }}|\\\\\\\\.|\\\\{(?:[^{}\\\\\\\\]{1,${MAX_REGEX_LENGTH}}|\\\\\\\\.)*\\\\})+))?\\\\}`,\n \"g\",\n );\n\n const searchPlaceholder = new RegExp(\n `([:]?)([\\\\w[\\\\].-]+)|\\\\{([\\\\w[\\\\].-]+)(?::\\\\s*((?:[^{}\\\\\\\\]{1,${\n MAX_REGEX_LENGTH\n }}|\\\\\\\\.|\\\\{(?:[^{}\\\\\\\\]{1,${MAX_REGEX_LENGTH}}|\\\\\\\\.)*\\\\})+))?\\\\}`,\n \"g\",\n );\n\n const patterns = [];\n\n let last = 0;\n\n let matchArray;\n\n const checkParamErrors = (id) => {\n if (!UrlMatcher.nameValidator.test(id))\n throw new Error(\n `Invalid parameter name '${id}' in pattern '${pattern}'`,\n );\n\n if (find(this._params, propEq(\"id\", id)))\n throw new Error(\n `Duplicate parameter name '${id}' in pattern '${pattern}'`,\n );\n };\n\n // Split into static segments separated by path parameter placeholders.\n // The number of segments is always 1 more than the number of parameters.\n const matchDetails = (match, isSearch) => {\n // IE[78] returns '' for unmatched groups instead of null\n const id = match[2] || match[3];\n\n const regexp = isSearch\n ? match[4]\n : match[4] || (match[1] === \"*\" ? \"[\\\\s\\\\S]*\" : null);\n\n const makeRegexpType = (str) =>\n inherit(paramTypes.type(isSearch ? \"query\" : \"path\"), {\n pattern: new RegExp(\n str,\n this.config.caseInsensitive ? \"i\" : undefined,\n ),\n });\n\n return {\n id,\n regexp,\n segment: pattern.substring(last, match.index),\n type: !regexp\n ? null\n : paramTypes.type(regexp) || makeRegexpType(regexp),\n };\n };\n\n let details;\n\n let segment;\n\n while ((matchArray = placeholder.exec(pattern))) {\n details = matchDetails(matchArray, false);\n\n if (details.segment.indexOf(\"?\") >= 0) break; // we're into the search part\n checkParamErrors(details.id);\n this._params.push(\n paramFactory.fromPath(details.id, details.type, config.state),\n );\n this._segments.push(details.segment);\n patterns.push([details.segment, tail(this._params)]);\n last = placeholder.lastIndex;\n }\n segment = pattern.substring(last);\n // Find any search parameter names and remove them from the last segment\n const i = segment.indexOf(\"?\");\n\n if (i >= 0) {\n const search = segment.substring(i);\n\n segment = segment.substring(0, i);\n\n if (search.length > 0) {\n last = 0;\n\n while ((matchArray = searchPlaceholder.exec(search))) {\n details = matchDetails(matchArray, true);\n checkParamErrors(details.id);\n this._params.push(\n paramFactory.fromSearch(details.id, details.type, config.state),\n );\n last = placeholder.lastIndex;\n // check if ?&\n }\n }\n }\n this._segments.push(segment);\n this._compiled = patterns\n .map((_pattern) => quoteRegExp.apply(null, _pattern))\n .concat(quoteRegExp(segment));\n }\n\n /**\n * Creates a new concatenated UrlMatcher\n *\n * Builds a new UrlMatcher by appending another UrlMatcher to this one.\n *\n * @param url A `UrlMatcher` instance to append as a child of the current `UrlMatcher`.\n */\n append(url) {\n this._children.push(url);\n url._cache = {\n path: this._cache.path.concat(url),\n parent: this,\n pattern: null,\n };\n\n return url;\n }\n\n isRoot() {\n return this._cache.path[0] === this;\n }\n\n /** Returns the input pattern string */\n toString() {\n return this.pattern;\n }\n\n _getDecodedParamValue(value, param) {\n return param.value(value);\n }\n\n /**\n * Tests the specified url/path against this matcher.\n *\n * Tests if the given url matches this matcher's pattern, and returns an object containing the captured\n * parameter values. Returns null if the path does not match.\n *\n * The returned object contains the values\n * of any search parameters that are mentioned in the pattern, but their value may be null if\n * they are not present in `search`. This means that search parameters are always treated\n * as optional.\n *\n * #### Example:\n * ```js\n * new UrlMatcher('/user/{id}?q&r').exec('/user/bob', {\n * x: '1', q: 'hello'\n * });\n * // returns { id: 'bob', q: 'hello', r: null }\n * ```\n *\n * @param path The URL path to match, e.g. `$location.getPath()`.\n * @param search URL search parameters, e.g. `$location.getSearch()`.\n * @param hash URL hash e.g. `$location.getHash()`.\n *\n * @returns The captured parameter values.\n */\n exec(path, search = {}, hash) {\n const match = memoizeTo(this._cache, \"pattern\", () => {\n return new RegExp(\n [\n \"^\",\n unnest(this._cache.path.map((x) => x._compiled)).join(\"\"),\n this.config.strict === false ? \"/?\" : \"\",\n \"$\",\n ].join(\"\"),\n this.config.caseInsensitive ? \"i\" : undefined,\n );\n }).exec(path);\n\n if (!match) return null;\n // options = defaults(options, { isolate: false });\n const allParams = this.parameters(),\n pathParams = allParams.filter((param) => !param.isSearch()),\n searchParams = allParams.filter((param) => param.isSearch()),\n nPathSegments = this._cache.path\n .map((urlm) => urlm._segments.length - 1)\n .reduce((a, x) => a + x),\n values = {};\n\n if (nPathSegments !== match.length - 1)\n throw new Error(`Unbalanced capture group in route '${this.pattern}'`);\n function decodePathArray(paramVal) {\n const reverseString = (str) => str.split(\"\").reverse().join(\"\");\n\n const unquoteDashes = (str) => str.replace(/\\\\-/g, \"-\");\n\n const split = reverseString(paramVal).split(/-(?!\\\\)/);\n\n const allReversed = map(split, reverseString);\n\n return map(allReversed, unquoteDashes).reverse();\n }\n\n for (let i = 0; i < nPathSegments; i++) {\n const param = pathParams[i];\n\n let value = match[i + 1];\n\n // if the param value matches a pre-replace pair, replace the value before decoding.\n for (let j = 0; j < param.replace.length; j++) {\n if (param.replace[j].from === value) value = param.replace[j].to;\n }\n\n if (value && param.array === true) value = decodePathArray(value);\n values[param.id] = this._getDecodedParamValue(value, param);\n }\n searchParams.forEach((param) => {\n let value = search[param.id];\n\n for (let j = 0; j < param.replace.length; j++) {\n if (param.replace[j].from === value) value = param.replace[j].to;\n }\n values[param.id] = this._getDecodedParamValue(value, param);\n });\n\n if (hash) values[\"#\"] = hash;\n\n return values;\n }\n\n /**\n * @internal\n * Returns all the [[Param]] objects of all path and search parameters of this pattern in order of appearance.\n *\n * @returns {Array.<Param>} An array of [[Param]] objects. Must be treated as read-only. If the\n * pattern has no parameters, an empty array is returned.\n */\n parameters(opts = {}) {\n if (opts.inherit === false) return this._params;\n\n return unnest(this._cache.path.map((matcher) => matcher._params));\n }\n\n /**\n * @internal\n * Returns a single parameter from this UrlMatcher by id\n *\n * @param id\n * @param opts\n * @returns {Param|any|boolean|UrlMatcher|null}\n */\n parameter(id, opts = {}) {\n const findParam = () => {\n for (const param of this._params) {\n if (param.id === id) return param;\n }\n\n return undefined;\n };\n\n const { parent } = this._cache;\n\n return (\n findParam() ||\n (opts.inherit !== false && parent && parent.parameter(id, opts)) ||\n null\n );\n }\n\n /**\n * Validates the input parameter values against this UrlMatcher\n *\n * Checks an object hash of parameters to validate their correctness according to the parameter\n * types of this `UrlMatcher`.\n *\n * @param params The object hash of parameters to validate.\n * @returns Returns `true` if `params` validates, otherwise `false`.\n */\n validates(params) {\n const validParamVal = (param, val) => !param || param.validates(val);\n\n params = params || {};\n // I'm not sure why this checks only the param keys passed in, and not all the params known to the matcher\n const paramSchema = this.parameters().filter((paramDef) =>\n hasOwn(params, paramDef.id),\n );\n\n return paramSchema\n .map((paramDef) => validParamVal(paramDef, params[paramDef.id]))\n .reduce(allTrueR, true);\n }\n\n /**\n * Given a set of parameter values, creates a URL from this UrlMatcher.\n *\n * Creates a URL that matches this pattern by substituting the specified values\n * for the path and search parameters.\n *\n * #### Example:\n * ```js\n * new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });\n * // returns '/user/bob?q=yes'\n * ```\n *\n * @param values the values to substitute for the parameters in this pattern.\n * @returns the formatted URL (path and optionally search part).\n */\n format(values = {}) {\n // Build the full path of UrlMatchers (including all parent UrlMatchers)\n const urlMatchers = this._cache.path;\n\n // Extract all the static segments and Params (processed as ParamDetails)\n // into an ordered array\n const pathSegmentsAndParams = urlMatchers\n .map(UrlMatcher.pathSegmentsAndParams)\n .reduce(unnestR, [])\n .map((x) => (isString(x) ? x : getDetails(x)));\n\n // Extract the query params into a separate array\n const queryParams = urlMatchers\n .map(UrlMatcher.queryParams)\n .reduce(unnestR, [])\n .map(getDetails);\n\n const isInvalid = (param) => param.isValid === false;\n\n if (pathSegmentsAndParams.concat(queryParams).filter(isInvalid).length) {\n return null;\n }\n /**\n * Given a Param, applies the parameter value, then returns detailed information about it\n */\n function getDetails(param) {\n // Normalize to typed value\n const value = param.value(values[param.id]);\n\n const isValid = param.validates(value);\n\n const isDefaultValue = param.isDefaultValue(value);\n\n // Check if we're in squash mode for the parameter\n const squash = isDefaultValue ? param.squash : false;\n\n // Allow the Parameter's Type to encode the value\n const encoded = param.type.encode(value);\n\n return { param, value, isValid, isDefaultValue, squash, encoded };\n }\n // Build up the path-portion from the list of static segments and parameters\n const pathString = pathSegmentsAndParams.reduce((acc, x) => {\n // The element is a static segment (a raw string); just append it\n if (isString(x)) return acc + x;\n // Otherwise, it's a ParamDetails.\n const { squash, encoded, param } = x;\n\n // If squash is === true, try to remove a slash from the path\n if (squash === true) return acc.match(/\\/$/) ? acc.slice(0, -1) : acc;\n\n // If squash is a string, use the string for the param value\n if (isString(squash)) return acc + squash;\n\n if (squash !== false) return acc; // ?\n\n if (isNullOrUndefined(encoded)) return acc;\n\n // If this parameter value is an array, encode the value using encodeDashes\n if (isArray(encoded)) return acc + map(encoded, encodeDashes).join(\"-\");\n\n // If the parameter type is \"raw\", then do not encodeURIComponent\n if (param.raw) return acc + encoded;\n\n // Encode the value\n return acc + encodeURIComponent(encoded);\n }, \"\");\n\n // Build the query string by applying parameter values (array or regular)\n // then mapping to key=value, then flattening and joining using \"&\"\n const queryString = queryParams\n .map((paramDetails) => {\n const { param, squash, isDefaultValue } = paramDetails;\n\n let { encoded } = paramDetails;\n\n if (isNullOrUndefined(encoded) || (isDefaultValue && squash !== false))\n return undefined;\n\n if (!isArray(encoded)) encoded = [encoded];\n\n if (encoded.length === 0) return undefined;\n\n if (!param.raw) encoded = map(encoded, encodeURIComponent);\n\n return encoded.map((val) => `${param.id}=${val}`);\n })\n .reduce(unnestR, [])\n .join(\"&\");\n\n // Concat the pathstring with the queryString (if exists) and the hashString (if exists)\n return (\n pathString +\n (queryString ? `?${queryString}` : \"\") +\n (values[\"#\"] ? `#${values[\"#\"]}` : \"\")\n );\n }\n}\n\nUrlMatcher.nameValidator = /^\\w+([-.]+\\w+)*(?:\\[\\])?$/;\n\nfunction encodeDashes(str) {\n // Replace dashes with encoded \"\\-\"\n return encodeURIComponent(str).replace(\n /-/g,\n (char) => `%5C%${char.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n}\n","import { defaults, find } from \"../../shared/common.js\";\nimport { propEq } from \"../../shared/hof.js\";\nimport { Glob } from \"../glob/glob.js\";\nimport { hasOwn, isFunction, isObject } from \"../../shared/utils.js\";\n\n/** @typedef {import('./interface.ts').StateDeclaration} StateDeclaration */\n\n/**\n * Internal representation of a ng-router state.\n *\n * Instances of this class are created when a [[StateDeclaration]] is registered with the [[StateRegistry]].\n *\n * A registered [[StateDeclaration]] is augmented with a getter ([[StateDeclaration.$$state]]) which returns the corresponding [[StateObject]] object.\n *\n * This class prototypally inherits from the corresponding [[StateDeclaration]].\n * Each of its own properties (i.e., `hasOwnProperty`) are built using builders from the [[StateBuilder]].\n * @implements {StateDeclaration}\n */\nexport class StateObject {\n name = undefined;\n navigable = undefined;\n /** @type {?StateObject} */\n parent = undefined;\n params = undefined;\n url = undefined;\n includes = undefined;\n\n /**\n * @param {import('./interface.ts').StateDeclaration} config\n */\n constructor(config) {\n Object.assign(this, config);\n this.$$state = () => {\n return this;\n };\n /**\n * @type {import('./interface.ts').StateDeclaration}\n */\n this.self = config;\n /**\n * @type {?Glob}\n */\n const nameGlob = this.name ? Glob.fromString(this.name) : null;\n\n this.__stateObjectCache = { nameGlob };\n }\n\n /**\n * Returns true if the provided parameter is the same state.\n *\n * Compares the identity of the state against the passed value, which is either an object\n * reference to the actual `State` instance, the original definition object passed to\n * `$stateProvider.state()`, or the fully-qualified name.\n *\n * @param ref Can be one of (a) a `State` instance, (b) an object that was passed\n * into `$stateProvider.state()`, (c) the fully-qualified name of a state as a string.\n * @returns Returns `true` if `ref` matches the current `State` instance.\n */\n is(ref) {\n return this === ref || this.self === ref || this.fqn() === ref;\n }\n\n /**\n * @deprecated this does not properly handle dot notation\n * @returns Returns a dot-separated name of the state.\n */\n fqn() {\n if (!this.parent || !(this.parent instanceof this.constructor))\n return this.name;\n const name = this.parent.fqn();\n\n return name ? `${name}.${this.name}` : this.name;\n }\n\n /**\n * Returns the root node of this state's tree.\n *\n * @returns The root of this state's tree.\n */\n root() {\n return (this.parent && this.parent.root()) || this;\n }\n\n /**\n * Gets the state's `Param` objects\n *\n * Gets the list of [[Param]] objects owned by the state.\n * If `opts.inherit` is true, it also includes the ancestor states' [[Param]] objects.\n * If `opts.matchingKeys` exists, returns only `Param`s whose `id` is a key on the `matchingKeys` object\n *\n * @param opts options\n */\n parameters(opts) {\n opts = defaults(opts, { inherit: true, matchingKeys: null });\n const inherited =\n (opts.inherit && this.parent && this.parent.parameters()) || [];\n\n return inherited\n .concat(Object.values(this.params))\n .filter(\n (param) => !opts.matchingKeys || hasOwn(opts.matchingKeys, param.id),\n );\n }\n\n /**\n * Returns a single [[Param]] that is owned by the state\n *\n * If `opts.inherit` is true, it also searches the ancestor states` [[Param]]s.\n * @param id the name of the [[Param]] to return\n * @param opts options\n */\n parameter(id, opts = {}) {\n return (\n (this.url && this.url.parameter(id, opts)) ||\n find(Object.values(this.params), propEq(\"id\", id)) ||\n (opts.inherit && this.parent && this.parent.parameter(id))\n );\n }\n\n toString() {\n return this.fqn();\n }\n}\n/** Predicate which returns true if the object is a [[StateDeclaration]] object */\nStateObject.isStateDeclaration = (obj) => isFunction(obj.$$state);\n/** Predicate which returns true if the object is an internal [[StateObject]] object */\nStateObject.isState = (obj) => isObject(obj.__stateObjectCache);\n","import { UrlMatcher } from \"./url-matcher.js\";\nimport {\n assert,\n isDefined,\n isFunction,\n isString,\n isUndefined,\n} from \"../../shared/utils.js\";\nimport { is, pattern } from \"../../shared/hof.js\";\nimport { StateObject } from \"../state/state-object.js\";\n/**\n * Creates a [[UrlRule]]\n *\n * Creates a [[UrlRule]] from a:\n *\n * - `string`\n * - [[UrlMatcher]]\n * - `RegExp`\n * - [[StateObject]]\n */\n\nconst LOWEST = 0.000001;\n\nexport class UrlRuleFactory {\n /**\n * @param {import('../url/url-service.js').UrlService} urlService\n * @param {import('../state/state-service.js').StateProvider} stateService\n * @param {import('../router.js').Router} routerGlobals\n */\n constructor(urlService, stateService, routerGlobals) {\n this.urlService = urlService;\n this.stateService = stateService;\n this.routerGlobals = routerGlobals;\n }\n\n /**\n *\n * @param {*} what\n * @param {*} handler\n * @returns {BaseUrlRule}\n */\n create(what, handler) {\n const { isState, isStateDeclaration } = StateObject;\n\n const makeRule = pattern([\n [isString, (_what) => makeRule(this.urlService.compile(_what))],\n [is(UrlMatcher), (_what) => this.fromUrlMatcher(_what, handler)],\n [\n (...args) => isState(...args) || isStateDeclaration(...args),\n (_what) => this.fromState(_what, this.stateService, this.routerGlobals),\n ],\n [is(RegExp), (_what) => this.fromRegExp(_what, handler)],\n [isFunction, (_what) => new BaseUrlRule(_what, handler)],\n ]);\n\n const rule = makeRule(what);\n\n if (!rule) throw new Error(\"invalid 'what' in when()\");\n\n return rule;\n }\n\n /**\n * A UrlRule which matches based on a UrlMatcher\n *\n * The `handler` may be either a `string`, a [[UrlRuleHandlerFn]] or another [[UrlMatcher]]\n *\n * ## Handler as a function\n *\n * If `handler` is a function, the function is invoked with:\n *\n * - matched parameter values ([[RawParams]] from [[UrlMatcher.exec]])\n * - url: the current Url ([[UrlParts]])\n * - router: the router object ([[UIRouter]])\n *\n * #### Example:\n * ```js\n * var urlMatcher = $umf.compile(\"/foo/:fooId/:barId\");\n * var rule = factory.fromUrlMatcher(urlMatcher, match => \"/home/\" + match.fooId + \"/\" + match.barId);\n * var match = rule.match('/foo/123/456'); // results in { fooId: '123', barId: '456' }\n * var result = rule.handler(match); // '/home/123/456'\n * ```\n *\n * ## Handler as UrlMatcher\n *\n * If `handler` is a UrlMatcher, the handler matcher is used to create the new url.\n * The `handler` UrlMatcher is formatted using the matched param from the first matcher.\n * The url is replaced with the result.\n *\n * #### Example:\n * ```js\n * var urlMatcher = $umf.compile(\"/foo/:fooId/:barId\");\n * var handler = $umf.compile(\"/home/:fooId/:barId\");\n * var rule = factory.fromUrlMatcher(urlMatcher, handler);\n * var match = rule.match('/foo/123/456'); // results in { fooId: '123', barId: '456' }\n * var result = rule.handler(match); // '/home/123/456'\n * ```\n */\n fromUrlMatcher(urlMatcher, handler) {\n let _handler = handler;\n\n if (isString(handler)) handler = this.urlService.compile(handler);\n\n if (is(UrlMatcher)(handler)) _handler = (match) => handler.format(match);\n function matchUrlParamters(url) {\n const params = urlMatcher.exec(url.path, url.search, url.hash);\n\n return urlMatcher.validates(params) && params;\n }\n // Prioritize URLs, lowest to highest:\n // - Some optional URL parameters, but none matched\n // - No optional parameters in URL\n // - Some optional parameters, some matched\n // - Some optional parameters, all matched\n function matchPriority(params) {\n const optional = urlMatcher\n .parameters()\n .filter((param) => param.isOptional);\n\n if (!optional.length) return LOWEST;\n const matched = optional.filter((param) => params[param.id]);\n\n return matched.length / optional.length;\n }\n const details = { urlMatcher, matchPriority, type: \"URLMATCHER\" };\n\n return Object.assign(new BaseUrlRule(matchUrlParamters, _handler), details);\n }\n\n /**\n * A UrlRule which matches a state by its url\n *\n * #### Example:\n * ```js\n * var rule = factory.fromState($state.get('foo'), router);\n * var match = rule.match('/foo/123/456'); // results in { fooId: '123', barId: '456' }\n * var result = rule.handler(match);\n * // Starts a transition to 'foo' with params: { fooId: '123', barId: '456' }\n * ```\n */\n fromState(stateOrDecl, stateService, globals) {\n const state = StateObject.isStateDeclaration(stateOrDecl)\n ? stateOrDecl.$$state()\n : stateOrDecl;\n\n /**\n * Handles match by transitioning to matched state\n *\n * First checks if the router should start a new transition.\n * A new transition is not required if the current state's URL\n * and the new URL are already identical\n */\n const handler = (match) => {\n const $state = stateService;\n\n if (\n $state.href(state, match) !==\n $state.href(globals.current, globals.params)\n ) {\n $state.transitionTo(state, match, { inherit: true, source: \"url\" });\n }\n };\n\n const details = { state, type: \"STATE\" };\n\n return Object.assign(this.fromUrlMatcher(state.url, handler), details);\n }\n\n /**\n * A UrlRule which matches based on a regular expression\n *\n * The `handler` may be either a [[UrlRuleHandlerFn]] or a string.\n *\n * ## Handler as a function\n *\n * If `handler` is a function, the function is invoked with:\n *\n * - regexp match array (from `regexp`)\n * - url: the current Url ([[UrlParts]])\n * - router: the router object ([[UIRouter]])\n *\n * #### Example:\n * ```js\n * var rule = factory.fromRegExp(/^\\/foo\\/(bar|baz)$/, match => \"/home/\" + match[1])\n * var match = rule.match('/foo/bar'); // results in [ '/foo/bar', 'bar' ]\n * var result = rule.handler(match); // '/home/bar'\n * ```\n *\n * ## Handler as string\n *\n * If `handler` is a string, the url is *replaced by the string* when the Rule is invoked.\n * The string is first interpolated using `string.replace()` style pattern.\n *\n * #### Example:\n * ```js\n * var rule = factory.fromRegExp(/^\\/foo\\/(bar|baz)$/, \"/home/$1\")\n * var match = rule.match('/foo/bar'); // results in [ '/foo/bar', 'bar' ]\n * var result = rule.handler(match); // '/home/bar'\n * ```\n */\n fromRegExp(regexp, handler) {\n if (regexp.global || regexp.sticky)\n throw new Error(\"Rule RegExp must not be global or sticky\");\n /**\n * If handler is a string, the url will be replaced by the string.\n * If the string has any String.replace() style variables in it (like `$2`),\n * they will be replaced by the captures from [[match]]\n */\n const redirectUrlTo = (match) =>\n // Interpolates matched values into $1 $2, etc using a String.replace()-style pattern\n handler.replace(\n /\\$(\\$|\\d{1,2})/,\n (_, what) => match[what === \"$\" ? 0 : Number(what)],\n );\n\n const _handler = isString(handler) ? redirectUrlTo : handler;\n\n const matchParamsFromRegexp = (url) => regexp.exec(url.path);\n\n const details = { regexp, type: \"REGEXP\" };\n\n return Object.assign(\n new BaseUrlRule(matchParamsFromRegexp, _handler),\n details,\n );\n }\n}\nUrlRuleFactory.isUrlRule = (obj) =>\n obj && [\"type\", \"match\", \"handler\"].every((key) => isDefined(obj[key]));\n\n/**\n * A base rule which calls `match`\n *\n * The value from the `match` function is passed through to the `handler`.\n */\nexport class BaseUrlRule {\n constructor(match, handler) {\n this.match = match;\n this.type = \"RAW\";\n this.$id = -1;\n this._group = undefined;\n this.handler = handler || ((x) => x);\n this.priority = undefined;\n }\n\n /**\n * This function should be overridden\n * @param {*} [params]\n * @returns {number}\n */\n matchPriority(params) {\n assert(isUndefined(params));\n\n return 0 - this.$id;\n }\n}\n","import { TargetState } from \"../state/target-state.js\";\nimport { UrlMatcher } from \"./url-matcher.js\";\nimport { is, val } from \"../../shared/hof.js\";\nimport { isDefined, isFunction, isString } from \"../../shared/utils.js\";\nimport { removeFrom } from \"../../shared/common.js\";\nimport { UrlRuleFactory } from \"./url-rule.js\";\n\nfunction prioritySort(a, b) {\n return (b.priority || 0) - (a.priority || 0);\n}\n\nconst typeSort = (a, b) => {\n const weights = { STATE: 4, URLMATCHER: 4, REGEXP: 3, RAW: 2, OTHER: 1 };\n\n return (weights[a.type] || 0) - (weights[b.type] || 0);\n};\n\nconst urlMatcherSort = (a, b) =>\n !a.urlMatcher || !b.urlMatcher\n ? 0\n : UrlMatcher.compare(a.urlMatcher, b.urlMatcher);\n\nconst idSort = (a, b) => {\n // Identically sorted STATE and URLMATCHER best rule will be chosen by `matchPriority` after each rule matches the URL\n const useMatchPriority = { STATE: true, URLMATCHER: true };\n\n const equal = useMatchPriority[a.type] && useMatchPriority[b.type];\n\n return equal ? 0 : (a.$id || 0) - (b.$id || 0);\n};\n\n/**\n * Default rule priority sorting function.\n *\n * Sorts rules by:\n *\n * - Explicit priority (set rule priority using [[UrlRules.when]])\n * - Rule type (STATE: 4, URLMATCHER: 4, REGEXP: 3, RAW: 2, OTHER: 1)\n * - `UrlMatcher` specificity ([[UrlMatcher.compare]]): works for STATE and URLMATCHER types to pick the most specific rule.\n * - Rule registration order (for rule types other than STATE and URLMATCHER)\n * - Equally sorted State and UrlMatcher rules will each match the URL.\n * Then, the *best* match is chosen based on how many parameter values were matched.\n */\nfunction defaultRuleSortFn(a, b) {\n let cmp = prioritySort(a, b);\n\n if (cmp !== 0) return cmp;\n cmp = typeSort(a, b);\n\n if (cmp !== 0) return cmp;\n cmp = urlMatcherSort(a, b);\n\n if (cmp !== 0) return cmp;\n\n return idSort(a, b);\n}\n\nfunction getHandlerFn(handler) {\n if (\n !isFunction(handler) &&\n !isString(handler) &&\n !is(TargetState)(handler) &&\n !TargetState.isDef(handler)\n ) {\n throw new Error(\n \"'handler' must be a string, function, TargetState, or have a state: 'newtarget' property\",\n );\n }\n\n return isFunction(handler) ? handler : val(handler);\n}\n/**\n * API for managing URL rules\n *\n * This API is used to create and manage URL rules.\n * URL rules are a mechanism to respond to specific URL patterns.\n *\n * The most commonly used methods are [[otherwise]] and [[when]].\n *\n * This API is found at `$url.rules` (see: [[UIRouter.urlService]], [[URLService.rules]])\n */\nexport class UrlRules {\n /** @param {UrlRuleFactory} urlRuleFactory */\n constructor(urlRuleFactory) {\n this._sortFn = defaultRuleSortFn;\n this._rules = [];\n this._id = 0;\n this.urlRuleFactory = urlRuleFactory;\n }\n\n /**\n * Defines the initial state, path, or behavior to use when the app starts.\n *\n * This rule defines the initial/starting state for the application.\n *\n * This rule is triggered the first time the URL is checked (when the app initially loads).\n * The rule is triggered only when the url matches either `\"\"` or `\"/\"`.\n *\n * Note: The rule is intended to be used when the root of the application is directly linked to.\n * When the URL is *not* `\"\"` or `\"/\"` and doesn't match other rules, the [[otherwise]] rule is triggered.\n * This allows 404-like behavior when an unknown URL is deep-linked.\n *\n * #### Example:\n * Start app at `home` state.\n * ```js\n * .initial({ state: 'home' });\n * ```\n *\n * #### Example:\n * Start app at `/home` (by url)\n * ```js\n * .initial('/home');\n * ```\n *\n * #### Example:\n * When no other url rule matches, go to `home` state\n * ```js\n * .initial((matchValue, url, router) => {\n * console.log('initial state');\n * return { state: 'home' };\n * })\n * ```\n *\n * @param handler The initial state or url path, or a function which returns the state or url path (or performs custom logic).\n */\n initial(handler) {\n const handlerFn = getHandlerFn(handler);\n\n const matchFn = (urlParts, router) =>\n router.globals.transitionHistory.size() === 0 &&\n !!/^\\/?$/.exec(urlParts.path);\n\n this.rule(this.urlRuleFactory.create(matchFn, handlerFn));\n }\n\n /**\n * Defines the state, url, or behavior to use when no other rule matches the URL.\n *\n * This rule is matched when *no other rule* matches.\n * It is generally used to handle unknown URLs (similar to \"404\" behavior, but on the client side).\n *\n * - If `handler` a string, it is treated as a url redirect\n *\n * #### Example:\n * When no other url rule matches, redirect to `/index`\n * ```js\n * .otherwise('/index');\n * ```\n *\n * - If `handler` is an object with a `state` property, the state is activated.\n *\n * #### Example:\n * When no other url rule matches, redirect to `home` and provide a `dashboard` parameter value.\n * ```js\n * .otherwise({ state: 'home', params: { dashboard: 'default' } });\n * ```\n *\n * - If `handler` is a function, the function receives the current url ([[UrlParts]]) and the [[UIRouter]] object.\n * The function can perform actions, and/or return a value.\n *\n * #### Example:\n * When no other url rule matches, manually trigger a transition to the `home` state\n * ```js\n * .otherwise((matchValue, urlParts, router) => {\n * router.stateService.go('home');\n * });\n * ```\n *\n * #### Example:\n * When no other url rule matches, go to `home` state\n * ```js\n * .otherwise((matchValue, urlParts, router) => {\n * return { state: 'home' };\n * });\n * ```\n *\n * @param handler The url path to redirect to, or a function which returns the url path (or performs custom logic).\n */\n otherwise(handler) {\n const handlerFn = getHandlerFn(handler);\n\n this._otherwiseFn = this.urlRuleFactory.create(val(true), handlerFn);\n this._sorted = false;\n }\n\n /**\n * Remove a rule previously registered\n *\n * @param rule the matcher rule that was previously registered using [[rule]]\n */\n removeRule(rule) {\n removeFrom(this._rules, rule);\n }\n\n /**\n * Manually adds a URL Rule.\n *\n * Usually, a url rule is added using [[StateDeclaration.url]] or [[when]].\n * This api can be used directly for more control (to register a [[BaseUrlRule]], for example).\n * Rules can be created using [[urlRuleFactory]], or created manually as simple objects.\n *\n * A rule should have a `match` function which returns truthy if the rule matched.\n * It should also have a `handler` function which is invoked if the rule is the best match.\n *\n * @return a function that deregisters the rule\n */\n rule(rule) {\n if (!UrlRuleFactory.isUrlRule(rule)) throw new Error(\"invalid rule\");\n rule.$id = this._id++;\n rule.priority = rule.priority || 0;\n this._rules.push(rule);\n this._sorted = false;\n\n return () => this.removeRule(rule);\n }\n\n /**\n * Gets all registered rules\n *\n * @returns an array of all the registered rules\n */\n rules() {\n this.ensureSorted();\n\n return this._rules.concat(this._otherwiseFn ? [this._otherwiseFn] : []);\n }\n\n /**\n * Defines URL Rule priorities\n *\n * More than one rule ([[UrlRule]]) might match a given URL.\n * This `compareFn` is used to sort the rules by priority.\n * Higher priority rules should sort earlier.\n *\n * The [[defaultRuleSortFn]] is used by default.\n *\n * You only need to call this function once.\n * The `compareFn` will be used to sort the rules as each is registered.\n *\n * If called without any parameter, it will re-sort the rules.\n *\n * ---\n *\n * Url rules may come from multiple sources: states's urls ([[StateDeclaration.url]]), [[when]], and [[rule]].\n * Each rule has a (user-provided) [[UrlRule.priority]], a [[UrlRule.type]], and a [[UrlRule.$id]]\n * The `$id` is is the order in which the rule was registered.\n *\n * The sort function should use these data, or data found on a specific type\n * of [[UrlRule]] (such as [[StateRule.state]]), to order the rules as desired.\n *\n * #### Example:\n * This compare function prioritizes rules by the order in which the rules were registered.\n * A rule registered earlier has higher priority.\n *\n * ```js\n * function compareFn(a, b) {\n * return a.$id - b.$id;\n * }\n * ```\n *\n * @param compareFn a function that compares to [[UrlRule]] objects.\n * The `compareFn` should abide by the `Array.sort` compare function rules.\n * Given two rules, `a` and `b`, return a negative number if `a` should be higher priority.\n * Return a positive number if `b` should be higher priority.\n * Return `0` if the rules are identical.\n *\n * See the [mozilla reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Description)\n * for details.\n */\n sort(compareFn) {\n const sorted = this.stableSort(\n this._rules,\n (this._sortFn = compareFn || this._sortFn),\n );\n\n // precompute _sortGroup values and apply to each rule\n let group = 0;\n\n for (let i = 0; i < sorted.length; i++) {\n sorted[i]._group = group;\n\n if (\n i < sorted.length - 1 &&\n this._sortFn(sorted[i], sorted[i + 1]) !== 0\n ) {\n group++;\n }\n }\n this._rules = sorted;\n this._sorted = true;\n }\n\n ensureSorted() {\n this._sorted || this.sort();\n }\n\n stableSort(arr, compareFn) {\n const arrOfWrapper = arr.map((elem, idx) => ({ elem, idx }));\n\n arrOfWrapper.sort((wrapperA, wrapperB) => {\n const cmpDiff = compareFn(wrapperA.elem, wrapperB.elem);\n\n return cmpDiff === 0 ? wrapperA.idx - wrapperB.idx : cmpDiff;\n });\n\n return arrOfWrapper.map((wrapper) => wrapper.elem);\n }\n\n /**\n * Registers a `matcher` and `handler` for custom URLs handling.\n *\n * The `matcher` can be:\n *\n * - a [[UrlMatcher]]: See: [[UrlMatcherFactory.compile]]\n * - a `string`: The string is compiled to a [[UrlMatcher]]\n * - a `RegExp`: The regexp is used to match the url.\n *\n * The `handler` can be:\n *\n * - a string: The url is redirected to the value of the string.\n * - a function: The url is redirected to the return value of the function.\n *\n * ---\n *\n * When the `handler` is a `string` and the `matcher` is a `UrlMatcher` (or string), the redirect\n * string is interpolated with parameter values.\n *\n * #### Example:\n * When the URL is `/foo/123` the rule will redirect to `/bar/123`.\n * ```js\n * .when(\"/foo/:param1\", \"/bar/:param1\")\n * ```\n *\n * ---\n *\n * When the `handler` is a string and the `matcher` is a `RegExp`, the redirect string is\n * interpolated with capture groups from the RegExp.\n *\n * #### Example:\n * When the URL is `/foo/123` the rule will redirect to `/bar/123`.\n * ```js\n * .when(new RegExp(\"^/foo/(.*)$\"), \"/bar/$1\");\n * ```\n *\n * ---\n *\n * When the handler is a function, it receives the matched value, the current URL, and the `UIRouter` object (See [[UrlRuleHandlerFn]]).\n * The \"matched value\" differs based on the `matcher`.\n * For [[UrlMatcher]]s, it will be the matched state params.\n * For `RegExp`, it will be the match array from `regexp.exec()`.\n *\n * If the handler returns a string, the URL is redirected to the string.\n *\n * #### Example:\n * When the URL is `/foo/123` the rule will redirect to `/bar/123`.\n * ```js\n * .when(new RegExp(\"^/foo/(.*)$\"), match => \"/bar/\" + match[1]);\n * ```\n *\n * Note: the `handler` may also invoke arbitrary code, such as `$state.go()`\n *\n * @param matcher A pattern `string` to match, compiled as a [[UrlMatcher]], or a `RegExp`.\n * @param handler The path to redirect to, or a function that returns the path.\n * @param options `{ priority: number }`\n *\n * @return the registered [[UrlRule]]\n */\n when(matcher, handler, options) {\n const rule = this.urlRuleFactory.create(matcher, handler);\n\n if (isDefined(options && options.priority))\n rule.priority = options.priority;\n this.rule(rule);\n\n return rule;\n }\n}\n","import { DefType, Param } from \"./param.js\";\n\nexport class ParamFactory {\n /**\n * @param {import(\"../url/url-config.js\").UrlConfigProvider} urlServiceConfig\n */\n constructor(urlServiceConfig) {\n /**\n * @type {import(\"../url/url-config.js\").UrlConfigProvider}\n */\n this.urlServiceConfig = urlServiceConfig;\n }\n\n fromConfig(id, type, state) {\n return new Param(id, type, DefType._CONFIG, this.urlServiceConfig, state);\n }\n\n fromPath(id, type, state) {\n return new Param(id, type, DefType._PATH, this.urlServiceConfig, state);\n }\n\n fromSearch(id, type, state) {\n return new Param(id, type, DefType._SEARCH, this.urlServiceConfig, state);\n }\n}\n","import {\n entries,\n isDefined,\n isFunction,\n isNull,\n isObject,\n isString,\n} from \"../../shared/utils.js\";\nimport { is, pattern } from \"../../shared/hof.js\";\nimport { UrlRules } from \"./url-rules.js\";\nimport { TargetState } from \"../state/target-state.js\";\nimport { removeFrom } from \"../../shared/common.js\";\nimport { stripLastPathElement } from \"../../shared/strings.js\";\nimport { UrlMatcher } from \"./url-matcher.js\";\nimport { ParamFactory } from \"../params/param-factory.js\";\nimport { UrlRuleFactory } from \"./url-rule.js\";\nimport { getBaseHref } from \"../../shared/dom.js\";\nimport { $injectTokens as $t, provider } from \"../../injection-tokens.js\";\n\n/**\n * API for URL management\n */\nexport class UrlService {\n /* @ignore */ static $inject = provider([\n $t.$location,\n $t.$state,\n $t.$router,\n $t.$urlConfig,\n ]);\n\n /** @type {import(\"../../services/location/location\").Location} */\n $location;\n\n /**\n * @param {import(\"../../services/location/location\").LocationProvider} $locationProvider\n * @param {import(\"../../router/state/state-service.js\").StateProvider} stateService\n * @param {import(\"../router.js\").Router} globals\n * @param {import(\"../../router/url/url-config.js\").UrlConfigProvider} urlConfigProvider\n */\n constructor($locationProvider, stateService, globals, urlConfigProvider) {\n this.$locationProvider = $locationProvider;\n this.stateService = stateService;\n this.stateService.urlService = this; // circular wiring\n\n /** Provides services related to the URL */\n this.urlRuleFactory = new UrlRuleFactory(this, this.stateService, globals);\n\n /**\n * The nested [[UrlRules]] API for managing URL rules and rewrites\n * @type {UrlRules}\n */\n this.rules = new UrlRules(this.urlRuleFactory);\n /**\n * The nested [[UrlConfig]] API to configure the URL and retrieve URL information\n * @type {import(\"./url-config.js\").UrlConfigProvider}\n */\n this.config = urlConfigProvider;\n\n /** Creates a new [[Param]] for a given location (DefType) */\n this.paramFactory = new ParamFactory(this.config);\n\n this._urlListeners = [];\n }\n\n /**\n * Gets the path part of the current url\n *\n * If the current URL is `/some/path?query=value#anchor`, this returns `/some/path`\n *\n * @return {string} the path portion of the url\n */\n getPath() {\n return this.$location.getPath();\n }\n\n /**\n * Gets the search part of the current url as an object\n *\n * If the current URL is `/some/path?query=value#anchor`, this returns `{ query: 'value' }`\n *\n * @return {Object} the search (query) portion of the url, as an object\n */\n getSearch() {\n return this.$location.getSearch();\n }\n\n /**\n * Gets the hash part of the current url\n *\n * If the current URL is `/some/path?query=value#anchor`, this returns `anchor`\n *\n * @return {string} the hash (anchor) portion of the url\n */\n getHash() {\n return this.$location.getHash();\n }\n\n $get = [\n $t.$location,\n $t.$rootScope,\n /**\n *\n * @param {ng.LocationService} $location\n * @param {ng.Scope} $rootScope\n * @returns {UrlService}\n */\n ($location, $rootScope) => {\n this.$location = $location;\n $rootScope.$on(\"$locationChangeSuccess\", (evt) => {\n this._urlListeners.forEach((fn) => {\n fn(evt);\n });\n });\n this.listen(true);\n\n return this;\n },\n ];\n\n /**\n * @returns {string}\n */\n baseHref() {\n return (\n this._baseHref ||\n (this._baseHref = getBaseHref() || window.location.pathname)\n );\n }\n\n /**\n * Gets the current url, or updates the url\n *\n * ### Getting the current URL\n *\n * When no arguments are passed, returns the current URL.\n * The URL is normalized using the internal [[path]]/[[search]]/[[hash]] values.\n *\n * For example, the URL may be stored in the hash ([[HashLocationServices]]) or\n * have a base HREF prepended ([[PushStateLocationServices]]).\n *\n * The raw URL in the browser might be:\n *\n * ```\n * http://mysite.com/somepath/index.html#/internal/path/123?param1=foo#anchor\n * ```\n *\n * or\n *\n * ```\n * http://mysite.com/basepath/internal/path/123?param1=foo#anchor\n * ```\n *\n * then this method returns:\n *\n * ```\n * /internal/path/123?param1=foo#anchor\n * ```\n *\n *\n * #### Example:\n * ```js\n * locationServices.url(); // \"/some/path?query=value#anchor\"\n * ```\n *\n * ### Updating the URL\n *\n * When `newurl` arguments is provided, changes the URL to reflect `newurl`\n *\n * #### Example:\n * ```js\n * locationServices.url(\"/some/path?query=value#anchor\", true);\n * ```\n *\n * @param {string} [newUrl] The new value for the URL.\n * This url should reflect only the new internal [[path]], [[search]], and [[hash]] values.\n * It should not include the protocol, site, port, or base path of an absolute HREF.\n * @param {any} [state] The history's state object, i.e., pushState (if the LocationServices implementation supports it)\n *\n * @return the url (after potentially being processed)\n */\n url(newUrl, state) {\n if (isDefined(newUrl)) {\n const decodeUri = decodeURIComponent(newUrl);\n\n this.$location.setUrl(decodeUri);\n }\n\n if (state) this.$location.setState(state);\n\n return this.$location.getUrl();\n }\n\n /**\n * @private\n *\n * Registers a low level url change handler\n *\n * Note: Because this is a low level handler, it's not recommended for general use.\n *\n * #### Example:\n * ```js\n * let deregisterFn = locationServices.onChange((evt) => console.log(\"url change\", evt));\n * ```\n *\n * @param {Function} callback a function that will be called when the url is changing\n * @return {Function} a function that de-registers the callback\n */\n onChange(callback) {\n this._urlListeners.push(callback);\n\n return () => removeFrom(this._urlListeners, callback);\n }\n\n /**\n * Gets the current URL parts.\n *\n * Returns an object with the `path`, `search`, and `hash` components\n * of the current browser location.\n *\n * @returns {import(\"../../services/location/interface.ts\").UrlParts} The current URL's path, search, and hash.\n */\n parts() {\n return {\n path: this.$location.getPath(),\n search: this.$location.getSearch(),\n hash: this.$location.getHash(),\n };\n }\n\n /**\n * Activates the best rule for the current URL\n *\n * Checks the current URL for a matching [[UrlRule]], then invokes that rule's handler.\n * This method is called internally any time the URL has changed.\n *\n * This effectively activates the state (or redirect, etc) which matches the current URL.\n *\n * #### Example:\n * ```js\n *\n * fetch('/states.json').then(resp => resp.json()).then(data => {\n * data.forEach(state => $stateRegistry.register(state));\n * urlService.listen();\n * // Find the matching URL and invoke the handler.\n * urlService.sync();\n * });\n * ```\n */\n sync(evt) {\n if (evt && evt.defaultPrevented) return;\n const { stateService } = this;\n\n const url = {\n path: this.$location.getPath(),\n search: this.$location.getSearch(),\n hash: this.$location.getHash(),\n };\n\n /**\n * @type {*}\n */\n const best = this.match(url);\n\n const applyResult = pattern([\n [isString, (newurl) => this.url(newurl)],\n [\n TargetState.isDef,\n (def) => stateService.go(def.state, def.params, def.options),\n ],\n [\n is(TargetState),\n (target) =>\n stateService.go(target.state(), target.params(), target.options()),\n ],\n ]);\n\n applyResult(best && best.rule.handler(best.match, url));\n }\n\n /**\n * Starts or stops listening for URL changes\n *\n * Call this sometime after calling [[deferIntercept]] to start monitoring the url.\n * This causes ng-router to start listening for changes to the URL, if it wasn't already listening.\n *\n * If called with `false`, ng-router will stop listening (call listen(true) to start listening again).\n *\n * #### Example:\n * ```js\n *\n * fetch('/states.json').then(resp => resp.json()).then(data => {\n * data.forEach(state => $stateRegistry.register(state));\n * // Start responding to URL changes\n * urlService.listen();\n * urlService.sync();\n * });\n * ```\n *\n * @param {boolean} enabled `true` or `false` to start or stop listening to URL changes\n */\n listen(enabled) {\n if (enabled === false) {\n this._stopListeningFn && this._stopListeningFn();\n delete this._stopListeningFn;\n\n return undefined;\n } else {\n return (this._stopListeningFn =\n this._stopListeningFn || this.onChange((evt) => this.sync(evt)));\n }\n }\n\n /**\n * Matches a URL\n *\n * Given a URL (as a [[UrlParts]] object), check all rules and determine the best matching rule.\n * Return the result as a [[MatchResult]].\n * @returns {any}\n */\n match(url) {\n url = Object.assign({ path: \"\", search: {}, hash: \"\" }, url);\n const rules = this.rules.rules();\n\n // Checks a single rule. Returns { rule: rule, match: match, weight: weight } if it matched, or undefined\n /**\n *\n * @param {import(\"./url-rule\").BaseUrlRule} rule\n */\n const checkRule = (rule) => {\n const match = rule.match(url);\n\n return match && { match, rule, weight: rule.matchPriority(match) };\n };\n\n // The rules are pre-sorted.\n // - Find the first matching rule.\n // - Find any other matching rule that sorted *exactly the same*, according to `.sort()`.\n // - Choose the rule with the highest match weight.\n let best;\n\n for (let i = 0; i < rules.length; i++) {\n // Stop when there is a 'best' rule and the next rule sorts differently than it.\n if (best && best.rule._group !== rules[i]._group) break;\n const current = checkRule(rules[i]);\n\n // Pick the best MatchResult\n best =\n !best || (current && current.weight > best.weight) ? current : best;\n }\n\n return best;\n }\n\n update(read) {\n if (read) {\n this.location = this.url();\n\n return;\n }\n\n if (this.url() === this.location) return;\n this.url(/** @type {string} */ (this.location), true);\n }\n\n /**\n * Internal API.\n *\n * Pushes a new location to the browser history.\n *\n * @internal\n * @param urlMatcher\n * @param params\n * @param options\n */\n push(urlMatcher, params, options) {\n const replace = options && !!options.replace;\n\n this.url(urlMatcher.format(params || {}), replace);\n }\n\n /**\n * Builds and returns a URL with interpolated parameters\n *\n * #### Example:\n * ```js\n * matcher = $umf.compile(\"/about/:person\");\n * params = { person: \"bob\" };\n * $bob = $url.href(matcher, params);\n * // $bob == \"/about/bob\";\n * ```\n *\n * @param urlMatcher The [[UrlMatcher]] object which is used as the template of the URL to generate.\n * @param params An object of parameter values to fill the matcher's required parameters.\n * @param options Options object. The options are:\n *\n * - **`absolute`** - {boolean=false}, If true will generate an absolute url, e.g. \"http://www.example.com/fullurl\".\n *\n * @returns Returns the fully compiled URL, or `null` if `params` fail validation against `urlMatcher`\n */\n href(urlMatcher, params, options) {\n let url = urlMatcher.format(params);\n\n if (isNull(url)) return null;\n options = options || { absolute: false };\n const isHtml5 = this.$locationProvider.html5ModeConf.enabled;\n\n if (!isHtml5) {\n url = `#${this.$locationProvider.hashPrefixConf}${url}`;\n }\n url = appendBasePath(url, isHtml5, options.absolute, this.baseHref());\n\n if (!options.absolute || !url) {\n return url;\n }\n const slash = !isHtml5 && url ? \"/\" : \"\";\n\n return [\n `${window.location.protocol}//`,\n window.location.host,\n slash,\n url,\n ].join(\"\");\n }\n\n /**\n * Creates a [[UrlMatcher]] for the specified pattern.\n *\n * @param urlPattern The URL pattern.\n * @param config The config object hash.\n * @returns The UrlMatcher.\n */\n compile(urlPattern, config) {\n const urlConfig = this.config;\n\n // backward-compatible support for config.params -> config.state.params\n const params = config && !config.state && config.params;\n\n config = params ? Object.assign({ state: { params } }, config) : config;\n const globalConfig = {\n strict: urlConfig._isStrictMode,\n caseInsensitive: urlConfig._isCaseInsensitive,\n };\n\n return new UrlMatcher(\n urlPattern,\n urlConfig.paramTypes,\n this.paramFactory,\n Object.assign(globalConfig, config),\n );\n }\n\n /**\n * Returns true if the specified object is a [[UrlMatcher]], or false otherwise.\n *\n * @param object The object to perform the type check against.\n * @returns `true` if the object matches the `UrlMatcher` interface, by\n * implementing all the same methods.\n */\n isMatcher(object) {\n // TODO: typeof?\n if (!isObject(object)) return false;\n let result = true;\n\n entries(UrlMatcher.prototype).forEach(([name, val]) => {\n if (isFunction(val))\n result = result && isDefined(object[name]) && isFunction(object[name]);\n });\n\n return result;\n }\n}\n\nfunction appendBasePath(url, isHtml5, absolute, baseHref) {\n if (baseHref === \"/\") return url;\n\n if (isHtml5) return stripLastPathElement(baseHref) + url;\n\n if (absolute) return baseHref.slice(1) + url;\n\n return url;\n}\n","import { isString } from \"../../shared/utils.js\";\nexport class StateMatcher {\n constructor(_states) {\n this._states = _states;\n }\n\n isRelative(stateName) {\n stateName = stateName || \"\";\n\n return stateName.indexOf(\".\") === 0 || stateName.indexOf(\"^\") === 0;\n }\n\n find(stateOrName, base, matchGlob = true) {\n if (!stateOrName && stateOrName !== \"\") return undefined;\n const isStr = isString(stateOrName);\n\n let name = isStr ? stateOrName : stateOrName.name;\n\n if (this.isRelative(name)) name = this.resolvePath(name, base);\n const state = this._states[name];\n\n if (\n state &&\n (isStr ||\n (!isStr && (state === stateOrName || state.self === stateOrName)))\n ) {\n return state;\n } else if (isStr && matchGlob) {\n const _states = Object.values(this._states);\n\n const matches = _states.filter(\n (_state) =>\n _state.__stateObjectCache.nameGlob &&\n _state.__stateObjectCache.nameGlob.matches(name),\n );\n\n if (matches.length > 1) {\n throw new Error(\n `stateMatcher.find: Found multiple matches for ${name} using glob: ${matches.map((match) => match.name)}`,\n );\n }\n\n return matches[0];\n }\n\n return undefined;\n }\n\n resolvePath(name, base) {\n if (!base) throw new Error(`No reference point given for path '${name}'`);\n const baseState = this.find(base);\n\n const splitName = name.split(\".\");\n\n const pathLength = splitName.length;\n\n let i = 0,\n current = baseState;\n\n for (; i < pathLength; i++) {\n if (splitName[i] === \"\" && i === 0) {\n current = baseState;\n continue;\n }\n\n if (splitName[i] === \"^\") {\n if (!current.parent)\n throw new Error(\n `Path '${name}' not valid for state '${baseState.name}'`,\n );\n current = current.parent;\n continue;\n }\n break;\n }\n const relName = splitName.slice(i).join(\".\");\n\n return current.name + (current.name && relName ? \".\" : \"\") + relName;\n }\n}\n","import {\n applyPairs,\n copy,\n inherit,\n map,\n omit,\n tail,\n} from \"../../shared/common.js\";\nimport {\n hasOwn,\n isArray,\n isDefined,\n isFunction,\n isString,\n} from \"../../shared/utils.js\";\nimport { stringify } from \"../../shared/strings.js\";\nimport { is, pattern, val } from \"../../shared/hof.js\";\nimport { Resolvable } from \"../resolve/resolvable.js\";\nimport { annotate } from \"../../core/di/di.js\";\n\nfunction parseUrl(url) {\n if (!isString(url)) return false;\n const root = url.charAt(0) === \"^\";\n\n return { val: root ? url.substring(1) : url, root };\n}\n\nfunction selfBuilder(state) {\n state.self.$$state = () => state;\n\n return state.self;\n}\n\nfunction dataBuilder(state) {\n if (state.parent && state.parent.data) {\n state.data = state.self.data = inherit(state.parent.data, state.data);\n }\n\n return state.data;\n}\n\nfunction getUrlBuilder($url, root) {\n return function (stateObject) {\n let stateDec = stateObject.self;\n\n // For future states, i.e., states whose name ends with `.**`,\n // match anything that starts with the url prefix\n if (\n stateDec &&\n stateDec.url &&\n stateDec.name &&\n stateDec.name.match(/\\.\\*\\*$/)\n ) {\n const newStateDec = {};\n\n copy(stateDec, newStateDec);\n newStateDec.url += \"{remainder:any}\"; // match any path (.*)\n stateDec = newStateDec;\n }\n const { parent } = stateObject;\n\n const parsed = parseUrl(stateDec.url);\n\n const url = !parsed\n ? stateDec.url\n : $url.compile(parsed.val, { state: stateDec });\n\n if (!url) return null;\n\n if (!$url.isMatcher(url))\n throw new Error(`Invalid url '${url}' in state '${stateObject}'`);\n\n return parsed && parsed.root\n ? url\n : ((parent && parent.navigable) || root()).url.append(url);\n };\n}\n\nfunction getNavigableBuilder(rootFn) {\n return function (state) {\n return !rootFn(state) && state.url\n ? state\n : state.parent\n ? state.parent.navigable\n : null;\n };\n}\n\n/**\n * @param {import(\"../params/param-factory.js\").ParamFactory} paramFactory\n */\nfunction getParamsBuilder(paramFactory) {\n return function (state) {\n const makeConfigParam = (_config, id) =>\n paramFactory.fromConfig(id, null, state.self);\n\n const urlParams =\n (state.url && state.url.parameters({ inherit: false })) || [];\n\n const nonUrlParams = Object.values(\n map(\n omit(\n state.params || {},\n urlParams.map((x) => x.id),\n ),\n makeConfigParam,\n ),\n );\n\n return urlParams\n .concat(nonUrlParams)\n .map((x) => [x.id, x])\n .reduce(applyPairs, {});\n };\n}\n\nfunction pathBuilder(state) {\n return state.parent ? state.parent.path.concat(state) : [state];\n}\n\nfunction includesBuilder(state) {\n const includes = state.parent ? Object.assign({}, state.parent.includes) : {};\n\n includes[state.name] = true;\n\n return includes;\n}\n\n/**\n * This is a [[StateBuilder.builder]] function for the `resolve:` block on a [[StateDeclaration]].\n *\n * When the [[StateBuilder]] builds a [[StateObject]] object from a raw [[StateDeclaration]], this builder\n * validates the `resolve` property and converts it to a [[Resolvable]] array.\n *\n * resolve: input value can be:\n *\n * {\n * // analyzed but not injected\n * myFooResolve: function() { return \"myFooData\"; },\n *\n * // function.toString() parsed, \"DependencyName\" dep as string (not min-safe)\n * myBarResolve: function(DependencyName) { return DependencyName.fetchSomethingAsPromise() },\n *\n * // Array split; \"DependencyName\" dep as string\n * myBazResolve: [ \"DependencyName\", function(dep) { return dep.fetchSomethingAsPromise() },\n *\n * // Array split; DependencyType dep as token (compared using ===)\n * myQuxResolve: [ DependencyType, function(dep) { return dep.fetchSometingAsPromise() },\n *\n * // val.$inject used as deps\n * // where:\n * // corgeResolve.$inject = [\"DependencyName\"];\n * // function corgeResolve(dep) { dep.fetchSometingAsPromise() }\n * // then \"DependencyName\" dep as string\n * myCorgeResolve: corgeResolve,\n *\n * // inject service by name\n * // When a string is found, desugar creating a resolve that injects the named service\n * myGraultResolve: \"SomeService\"\n * }\n *\n * or:\n *\n * [\n * new Resolvable(\"myFooResolve\", function() { return \"myFooData\" }),\n * new Resolvable(\"myBarResolve\", function(dep) { return dep.fetchSomethingAsPromise() }, [ \"DependencyName\" ]),\n * { provide: \"myBazResolve\", useFactory: function(dep) { dep.fetchSomethingAsPromise() }, deps: [ \"DependencyName\" ] }\n * ]\n */\nexport function resolvablesBuilder(state) {\n /** convert resolve: {} and resolvePolicy: {} objects to an array of tuples */\n const objects2Tuples = (resolveObj, resolvePolicies) =>\n Object.keys(resolveObj || {}).map((token) => ({\n token,\n val: resolveObj[token],\n deps: undefined,\n policy: resolvePolicies[token],\n }));\n\n /** fetch DI annotations from a function or ng1-style array */\n const annotateFn = (fn) => {\n const { $injector } = window.angular;\n\n // ng1 doesn't have an $injector until runtime.\n // If the $injector doesn't exist, use \"deferred\" literal as a\n // marker indicating they should be annotated when runtime starts\n return (\n fn.$inject ||\n ($injector && annotate(fn, $injector.strictDi)) ||\n \"deferred\"\n );\n };\n\n /** true if the object has both `token` and `resolveFn`, and is probably a [[ResolveLiteral]] */\n const isResolveLiteral = (obj) => !!(obj.token && obj.resolveFn);\n\n /** true if the object looks like a tuple from obj2Tuples */\n const isTupleFromObj = (obj) =>\n !!(\n obj &&\n obj.val &&\n (isString(obj.val) || isArray(obj.val) || isFunction(obj.val))\n );\n\n // Given a literal resolve or provider object, returns a Resolvable\n const literal2Resolvable = pattern([\n [\n (x) => x.resolveFn,\n (y) => new Resolvable(getToken(y), y.resolveFn, y.deps, y.policy),\n ],\n [\n (x) => x.useFactory,\n (y) =>\n new Resolvable(\n getToken(y),\n y.useFactory,\n y.deps || y.dependencies,\n y.policy,\n ),\n ],\n [\n (x) => x.useClass,\n (y) => new Resolvable(getToken(y), () => new y.useClass(), [], y.policy),\n ],\n [\n (x) => x.useValue,\n (y) =>\n new Resolvable(getToken(y), () => y.useValue, [], y.policy, y.useValue),\n ],\n [\n (x) => x.useExisting,\n (y) => new Resolvable(getToken(y), (x) => x, [y.useExisting], y.policy),\n ],\n ]);\n\n const tuple2Resolvable = pattern([\n [\n (x) => isString(x.val),\n (tuple) =>\n new Resolvable(tuple.token, (x) => x, [tuple.val], tuple.policy),\n ],\n [\n (x) => isArray(x.val),\n (tuple) =>\n new Resolvable(\n tuple.token,\n tail(tuple.val),\n tuple.val.slice(0, -1),\n tuple.policy,\n ),\n ],\n [\n (x) => isFunction(x.val),\n (tuple) =>\n new Resolvable(\n tuple.token,\n tuple.val,\n annotateFn(tuple.val),\n tuple.policy,\n ),\n ],\n ]);\n\n const item2Resolvable = pattern([\n [is(Resolvable), (x) => x],\n [isResolveLiteral, literal2Resolvable],\n [isTupleFromObj, tuple2Resolvable],\n [\n val(true),\n (obj) => {\n throw new Error(`Invalid resolve value: ${stringify(obj)}`);\n },\n ],\n ]);\n\n // If resolveBlock is already an array, use it as-is.\n // Otherwise, assume it's an object and convert to an Array of tuples\n const decl = state.resolve;\n\n const items = isArray(decl)\n ? decl\n : objects2Tuples(decl, state.resolvePolicy || {});\n\n return items.map(item2Resolvable);\n}\n/**\n * A internal global service\n *\n * StateBuilder is a factory for the internal [[StateObject]] objects.\n *\n * When you register a state with the [[StateRegistry]], you register a plain old javascript object which\n * conforms to the [[StateDeclaration]] interface. This factory takes that object and builds the corresponding\n * [[StateObject]] object, which has an API and is used internally.\n *\n * Custom properties or API may be added to the internal [[StateObject]] object by registering a decorator function\n * using the [[builder]] method.\n */\nexport class StateBuilder {\n /**\n * @param {import('./state-matcher.js').StateMatcher} matcher\n * @param urlService\n */\n constructor(matcher, urlService) {\n this.matcher = matcher;\n this.$injector = undefined;\n const self = this;\n\n const root = () => matcher.find(\"\");\n\n function parentBuilder(state) {\n if (isRoot(state)) return null;\n\n return matcher.find(self.parentName(state)) || root();\n }\n this.builders = {\n name: [(state) => state.name],\n self: [selfBuilder],\n parent: [parentBuilder],\n data: [dataBuilder],\n // Build a URLMatcher if necessary, either via a relative or absolute URL\n url: [getUrlBuilder(urlService, root)],\n // Keep track of the closest ancestor state that has a URL (i.e. is navigable)\n navigable: [getNavigableBuilder(isRoot)],\n // TODO\n params: [getParamsBuilder(urlService.paramFactory)],\n // Each framework-specific ng-router implementation should define its own `views` builder\n // e.g., src/ng1/statebuilders/views.ts\n views: [],\n // Keep a full path from the root down to this state as this is needed for state activation.\n path: [pathBuilder],\n // Speed up $state.includes() as it's used a lot\n includes: [includesBuilder],\n resolvables: [resolvablesBuilder],\n };\n }\n\n builder(name, fn) {\n const { builders } = this;\n\n const array = builders[name] || [];\n\n // Backwards compat: if only one builder exists, return it, else return whole arary.\n if (isString(name) && !isDefined(fn))\n return array.length > 1 ? array : array[0];\n\n if (!isString(name) || !isFunction(fn)) return undefined;\n builders[name] = array;\n builders[name].push(fn);\n\n return () => builders[name].splice(builders[name].indexOf(fn, 1)) && null;\n }\n\n /**\n * Builds all of the properties on an essentially blank State object, returning a State object which has all its\n * properties and API built.\n *\n * @param state an uninitialized State object\n * @returns the built State object\n */\n build(state) {\n const { matcher, builders } = this;\n\n const parent = this.parentName(state);\n\n if (parent && !matcher.find(parent, undefined, false)) {\n return null;\n }\n\n for (const key in builders) {\n if (!hasOwn(builders, key)) continue;\n const chain = builders[key].reduce(\n (parentFn, step) => (_state) => step(_state, parentFn),\n () => {\n /* empty */\n },\n );\n\n state[key] = chain(state);\n }\n\n return state;\n }\n\n parentName(state) {\n // name = 'foo.bar.baz.**'\n const name = state.name || \"\";\n\n // segments = ['foo', 'bar', 'baz', '.**']\n const segments = name.split(\".\");\n\n // segments = ['foo', 'bar', 'baz']\n const lastSegment = segments.pop();\n\n // segments = ['foo', 'bar'] (ignore .** segment for future states)\n if (lastSegment === \"**\") segments.pop();\n\n if (segments.length) {\n if (state.parent) {\n throw new Error(\n `States that specify the 'parent:' property should not have a '.' in their name (${name})`,\n );\n }\n\n // 'foo.bar'\n return segments.join(\".\");\n }\n\n if (!state.parent) return \"\";\n\n return isString(state.parent) ? state.parent : state.parent.name;\n }\n\n name(state) {\n const { name } = state;\n\n if (name.indexOf(\".\") !== -1 || !state.parent) return name;\n const parentName = isString(state.parent)\n ? state.parent\n : state.parent.name;\n\n return parentName ? `${parentName}.${name}` : name;\n }\n}\n\nfunction isRoot(state) {\n return state.name === \"\";\n}\n\n/** extracts the token from a Provider or provide literal */\nfunction getToken(provider) {\n return provider.provide || provider.token;\n}\n","import { hasOwn, isString } from \"../../shared/utils.js\";\nimport { StateObject } from \"./state-object.js\";\n\nexport class StateQueueManager {\n /**\n * @param {import(\"./state-registry.js\").StateRegistryProvider} stateRegistry\n * @param {*} urlServiceRules\n * @param {*} states\n * @param {*} builder\n * @param {*} listeners\n */\n constructor(stateRegistry, urlServiceRules, states, builder, listeners) {\n this.stateRegistry = stateRegistry;\n this.urlServiceRules = urlServiceRules;\n this.states = states;\n this.builder = builder;\n this.listeners = listeners;\n /**\n * @type {Array<StateObject>}\n */\n this.queue = [];\n }\n\n register(stateDecl) {\n const state = new StateObject(stateDecl);\n\n if (!isString(name)) throw new Error(\"State must have a valid name\");\n\n if (\n hasOwn(this.states, state.name) ||\n this.queue.map((x) => x.name).includes(state.name)\n )\n throw new Error(`State '${state.name}' is already defined`);\n this.queue.push(state);\n this.flush();\n\n return state;\n }\n\n flush() {\n const { queue, states, builder } = this;\n\n const registered = [], // states that got registered\n orphans = [], // states that don't yet have a parent registered\n previousQueueLength = {}; // keep track of how long the queue when an orphan was first encountered\n\n const getState = (name) => hasOwn(this.states, name) && this.states[name];\n\n const notifyListeners = () => {\n if (registered.length) {\n this.listeners.forEach((listener) =>\n listener(\n \"registered\",\n registered.map((x) => x.self),\n ),\n );\n }\n };\n\n while (queue.length > 0) {\n const state = queue.shift();\n\n const { name } = state;\n\n const result = builder.build(state);\n\n const orphanIdx = orphans.indexOf(state);\n\n if (result) {\n const existingState = getState(name);\n\n if (existingState && existingState.name === name) {\n throw new Error(`State '${name}' is already defined`);\n }\n const existingFutureState = getState(`${name}.**`);\n\n if (existingFutureState) {\n // Remove future state of the same name\n this.stateRegistry.deregister(existingFutureState);\n }\n states[name] = state;\n this.attachRoute(state);\n\n if (orphanIdx >= 0) orphans.splice(orphanIdx, 1);\n registered.push(state);\n continue;\n }\n const prev = previousQueueLength[name];\n\n previousQueueLength[name] = queue.length;\n\n if (orphanIdx >= 0 && prev === queue.length) {\n // Wait until two consecutive iterations where no additional states were dequeued successfully.\n // throw new Error(`Cannot register orphaned state '${name}'`);\n queue.push(state);\n notifyListeners();\n\n return states;\n } else if (orphanIdx < 0) {\n orphans.push(state);\n }\n queue.push(state);\n }\n notifyListeners();\n\n return states;\n }\n\n attachRoute(state) {\n if (state.abstract || !state.url) return;\n const rulesApi = this.urlServiceRules;\n\n rulesApi.rule(rulesApi.urlRuleFactory.create(state));\n }\n}\n","import { StateMatcher } from \"./state-matcher.js\";\nimport { StateBuilder } from \"./state-builder.js\";\nimport { StateQueueManager } from \"./state-queue-manager.js\";\nimport { applyPairs, removeFrom } from \"../../shared/common.js\";\nimport { propEq } from \"../../shared/hof.js\";\nimport { ResolveContext } from \"../resolve/resolve-context.js\";\nimport { ng1ViewsBuilder } from \"./views.js\";\nimport { isString, keys } from \"../../shared/utils.js\";\nimport { $injectTokens as $t, provider } from \"../../injection-tokens.js\";\n\n/** @typedef {import('../../interface.ts').ServiceProvider} ServiceProvider } */\n/**\n * A registry for all of the application's [[StateDeclaration]]s\n *\n * This API is found at `$stateRegistry` ([[UIRouter.stateRegistry]])\n *\n */\nexport class StateRegistryProvider {\n /* @ignore */ static $inject = provider([\n $t.$url,\n $t.$state,\n $t.$router,\n $t.$view,\n ]);\n\n /**\n * @param urlService\n * @param stateService\n * @param {import('../router.js').Router} globals\n * @param viewService\n */\n constructor(urlService, stateService, globals, viewService) {\n this.states = {};\n stateService.stateRegistry = this; // <- circular wiring\n this.urlService = urlService;\n this.urlServiceRules = urlService.rules;\n this.$injector = undefined;\n this.listeners = [];\n this.matcher = new StateMatcher(this.states);\n this.builder = new StateBuilder(this.matcher, urlService);\n // Apply ng1 specific StateBuilder code for `views`, `resolve`, and `onExit/Retain/Enter` properties\n // TODO we can probably move this inside buildr\n this.builder.builder(\"views\", ng1ViewsBuilder);\n this.builder.builder(\"onExit\", this.getStateHookBuilder(\"onExit\"));\n this.builder.builder(\"onRetain\", this.getStateHookBuilder(\"onRetain\"));\n this.builder.builder(\"onEnter\", this.getStateHookBuilder(\"onEnter\"));\n\n this.stateQueue = new StateQueueManager(\n this,\n this.urlServiceRules,\n this.states,\n this.builder,\n this.listeners,\n );\n\n this.registerRoot();\n\n viewService.rootViewContext(this.root());\n globals.$current = this.root();\n globals.current = globals.$current.self;\n }\n\n $get = [\n $t.$injector,\n /**\n * @param {import(\"../../core/di/internal-injector\").InjectorService} $injector\n * @returns {StateRegistryProvider}\n */\n ($injector) => {\n this.$injector = $injector;\n this.builder.$injector = $injector;\n\n return this;\n },\n ];\n\n /**\n * This is a [[StateBuilder.builder]] function for angular1 `onEnter`, `onExit`,\n * `onRetain` callback hooks on a [[StateDeclaration]].\n *\n * When the [[StateBuilder]] builds a [[StateObject]] object from a raw [[StateDeclaration]], this builder\n * ensures that those hooks are injectable for @uirouter/angularjs (ng1).\n *\n * @internalapi\n */\n getStateHookBuilder(hookName) {\n const that = this;\n\n return function stateHookBuilder(stateObject) {\n const hook = stateObject[hookName];\n\n const pathname = hookName === \"onExit\" ? \"from\" : \"to\";\n\n function decoratedNg1Hook(trans, state) {\n const resolveContext = new ResolveContext(trans.treeChanges(pathname));\n\n const subContext = resolveContext.subContext(state.$$state());\n\n const locals = Object.assign(getLocals(subContext), {\n $state$: state,\n $transition$: trans,\n });\n\n return that.$injector.invoke(hook, that, locals);\n }\n\n return hook ? decoratedNg1Hook : undefined;\n };\n }\n\n /**\n * @private\n */\n registerRoot() {\n const rootStateDef = {\n name: \"\",\n url: \"^\",\n views: null,\n params: {\n \"#\": { value: null, type: \"hash\", dynamic: true },\n },\n abstract: true,\n };\n\n this._root = this.stateQueue.register(rootStateDef);\n this._root.navigable = null;\n }\n\n /**\n * Listen for a State Registry events\n *\n * Adds a callback that is invoked when states are registered or deregistered with the StateRegistry.\n *\n * #### Example:\n * ```js\n * let allStates = registry.get();\n *\n * // Later, invoke deregisterFn() to remove the listener\n * let deregisterFn = registry.onStatesChanged((event, states) => {\n * switch(event) {\n * case: 'registered':\n * states.forEach(state => allStates.push(state));\n * break;\n * case: 'deregistered':\n * states.forEach(state => {\n * let idx = allStates.indexOf(state);\n * if (idx !== -1) allStates.splice(idx, 1);\n * });\n * break;\n * }\n * });\n * ```\n *\n * @param listener a callback function invoked when the registered states changes.\n * The function receives two parameters, `event` and `state`.\n * See [[StateRegistryListener]]\n * @return a function that deregisters the listener\n */\n onStatesChanged(listener) {\n this.listeners.push(listener);\n\n return function deregisterListener() {\n removeFrom(this.listeners, listener);\n }.bind(this);\n }\n\n /**\n * Gets the implicit root state\n *\n * Gets the root of the state tree.\n * The root state is implicitly created by ng-router.\n * Note: this returns the internal [[StateObject]] representation, not a [[StateDeclaration]]\n *\n * @return the root [[StateObject]]\n */\n root() {\n return this._root;\n }\n\n /**\n * Adds a state to the registry\n *\n * Registers a [[StateDeclaration]] or queues it for registration.\n *\n * Note: a state will be queued if the state's parent isn't yet registered.\n *\n * @param stateDefinition the definition of the state to register.\n * @returns the internal [[StateObject]] object.\n * If the state was successfully registered, then the object is fully built (See: [[StateBuilder]]).\n * If the state was only queued, then the object is not fully built.\n */\n register(stateDefinition) {\n return this.stateQueue.register(stateDefinition);\n }\n\n _deregisterTree(state) {\n const all = this.get().map((x) => x.$$state());\n\n const getChildren = (states) => {\n const _children = all.filter((x) => states.indexOf(x.parent) !== -1);\n\n return _children.length === 0\n ? _children\n : _children.concat(getChildren(_children));\n };\n\n const children = getChildren([state]);\n\n const deregistered = [state].concat(children).reverse();\n\n deregistered.forEach((_state) => {\n const rulesApi = this.urlServiceRules;\n\n // Remove URL rule\n rulesApi\n .rules()\n .filter(propEq(\"state\", _state))\n .forEach((rule) => rulesApi.removeRule(rule));\n // Remove state from registry\n delete this.states[_state.name];\n });\n\n return deregistered;\n }\n\n /**\n * Removes a state from the registry\n *\n * This removes a state from the registry.\n * If the state has children, they are are also removed from the registry.\n *\n * @param stateOrName the state's name or object representation\n * @returns {import('./state-object').StateObject[]} a list of removed states\n */\n deregister(stateOrName) {\n const _state = this.get(stateOrName);\n\n if (!_state)\n throw new Error(`Can't deregister state; not found: ${stateOrName}`);\n const deregisteredStates = this._deregisterTree(_state.$$state());\n\n this.listeners.forEach((listener) =>\n listener(\n \"deregistered\",\n deregisteredStates.map((x) => x.self),\n ),\n );\n\n return deregisteredStates;\n }\n\n get(stateOrName, base) {\n if (arguments.length === 0)\n return keys(this.states).map((name) => this.states[name].self);\n const found = this.matcher.find(stateOrName, base);\n\n return (found && found.self) || null;\n }\n\n /**\n * Registers a [[BuilderFunction]] for a specific [[StateObject]] property (e.g., `parent`, `url`, or `path`).\n * More than one BuilderFunction can be registered for a given property.\n *\n * The BuilderFunction(s) will be used to define the property on any subsequently built [[StateObject]] objects.\n *\n * @param property The name of the State property being registered for.\n * @param builderFunction The BuilderFunction which will be used to build the State property\n * @returns a function which deregisters the BuilderFunction\n */\n decorator(property, builderFunction) {\n return this.builder.builder(property, builderFunction);\n }\n}\n\nexport const getLocals = (ctx) => {\n const tokens = ctx.getTokens().filter(isString);\n\n const tuples = tokens.map((key) => {\n const resolvable = ctx.getResolvable(key);\n\n const waitPolicy = ctx.getPolicy(resolvable).async;\n\n return [\n key,\n waitPolicy === \"NOWAIT\" ? resolvable.promise : resolvable.data,\n ];\n });\n\n return tuples.reduce(applyPairs, {});\n};\n","import { removeFrom, tail, uniqR, unnestR } from \"../../shared/common.js\";\nimport {\n entries,\n isArray,\n isNullOrUndefined,\n isObject,\n isString,\n} from \"../../shared/utils.js\";\nimport { parse } from \"../../shared/hof.js\";\nimport { getInheritedData } from \"../../shared/dom.js\";\n\nfunction parseStateRef(ref) {\n const paramsOnly = ref.match(/^\\s*({[^}]*})\\s*$/);\n\n if (paramsOnly) ref = `(${paramsOnly[1]})`;\n const parsed = ref\n .replace(/\\n/g, \" \")\n .match(/^\\s*([^(]*?)\\s*(\\((.*)\\))?\\s*$/);\n\n if (!parsed || parsed.length !== 4)\n throw new Error(`Invalid state ref '${ref}'`);\n\n return { state: parsed[1] || null, paramExpr: parsed[3] || null };\n}\n\nfunction stateContext(el) {\n const $ngView = getInheritedData(el, \"$ngView\");\n\n const path = parse(\"$cfg.path\")($ngView);\n\n return path ? tail(path).state.name : undefined;\n}\n\nfunction processedDef($state, $element, def) {\n const ngState = def.ngState || $state.current.name;\n\n const ngStateOpts = Object.assign(\n defaultOpts($element, $state),\n def.ngStateOpts || {},\n );\n\n const href = $state.href(ngState, def.ngStateParams, ngStateOpts);\n\n return { ngState, ngStateParams: def.ngStateParams, ngStateOpts, href };\n}\n\nfunction getTypeInfo(el) {\n // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.\n const isSvg =\n Object.prototype.toString.call(el.getAttribute(\"href\")) ===\n \"[object SVGAnimatedString]\";\n\n const isForm = el.nodeName === \"FORM\";\n\n return {\n attr: isForm ? \"action\" : isSvg ? \"xlink:href\" : \"href\",\n isAnchor: el.nodeName === \"A\",\n clickable: !isForm,\n };\n}\n\nfunction clickHook(el, $state, type, getDef, scope) {\n return function (event) {\n const button = event.which || event.button,\n target = getDef();\n\n const res =\n button > 1 ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey ||\n event.altKey ||\n el.getAttribute(\"target\");\n\n if (!res) {\n // HACK: This is to allow ng-clicks to be processed before the transition is initiated:\n const transition = setTimeout(function () {\n if (!el.getAttribute(\"disabled\")) {\n $state\n .go(target.ngState, target.ngStateParams, target.ngStateOpts)\n .then(() => {\n scope.$emit(\"$updateBrowser\");\n });\n }\n });\n\n event.preventDefault();\n // if the state has no URL, ignore one preventDefault from the <a> directive.\n let ignorePreventDefaultCount = type.isAnchor && !target.href ? 1 : 0;\n\n event.preventDefault = function () {\n if (ignorePreventDefaultCount-- <= 0) clearTimeout(transition);\n };\n } else {\n // ignored\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n}\n\nfunction defaultOpts(el, $state) {\n return {\n relative: stateContext(el) || $state.$current,\n inherit: true,\n source: \"sref\",\n };\n}\n\nfunction bindEvents(element, scope, hookFn, ngStateOpts) {\n let events = ngStateOpts ? ngStateOpts.events : undefined;\n\n if (!isArray(events)) {\n events = [\"click\"];\n }\n //const on = element.on ? \"on\" : \"bind\";\n\n for (const event of events) {\n element.addEventListener(event, hookFn);\n }\n scope.$on(\"$destroy\", function () {\n // const off = element.off ? \"off\" : \"unbind\";\n for (const event of events) {\n element.removeEventListener(event, hookFn);\n }\n });\n}\n\n// // TODO: SEPARATE THESE OUT\n\n$StateRefDirective.$inject = [\"$state\", \"$stateRegistry\", \"$transitions\"];\nexport function $StateRefDirective(\n $stateService,\n $stateRegistry,\n $transitions,\n) {\n const $state = $stateService;\n\n return {\n restrict: \"A\",\n require: [\"?^ngSrefActive\", \"?^ngSrefActiveEq\"],\n link: (scope, element, attrs, ngSrefActive) => {\n const type = getTypeInfo(element);\n\n const active = ngSrefActive[1] || ngSrefActive[0];\n\n let unlinkInfoFn = null;\n\n const rawDef = {};\n\n const getDef = () => processedDef($state, element, rawDef);\n\n const ref = parseStateRef(attrs.ngSref);\n\n rawDef.ngState = ref.state;\n rawDef.ngStateOpts = attrs.ngSrefOpts\n ? scope.$eval(attrs.ngSrefOpts)\n : {};\n\n function update() {\n rawDef.ngStateParams = Object.assign({}, scope.$eval(ref.paramExpr));\n const def = getDef();\n\n if (unlinkInfoFn) {\n unlinkInfoFn();\n }\n\n if (active) {\n unlinkInfoFn = active.$$addStateInfo(def.ngState, def.ngStateParams);\n }\n\n if (!isNullOrUndefined(def.href)) {\n attrs.$set(type.attr, def.href);\n }\n }\n\n if (ref.paramExpr) {\n scope.$watch(\n ref.paramExpr,\n function (val) {\n rawDef.ngStateParams = Object.assign({}, val);\n update();\n },\n true,\n );\n rawDef.ngStateParams = Object.assign({}, scope.$eval(ref.paramExpr));\n }\n\n update();\n scope.$on(\"$destroy\", $stateRegistry.onStatesChanged(update));\n scope.$on(\"$destroy\", $transitions.onSuccess({}, update));\n\n if (!type.clickable) {\n return;\n }\n bindEvents(\n element,\n scope,\n clickHook(element, $state, type, getDef, scope),\n rawDef.ngStateOpts,\n );\n },\n };\n}\n\n$StateRefDynamicDirective.$inject = [\n \"$state\",\n \"$stateRegistry\",\n \"$transitions\",\n];\n\n/**\n * @param $state\n * @param $stateRegistry\n * @param $transitions\n * @returns {import(\"../../interface.ts\").Directive}\n */\nexport function $StateRefDynamicDirective(\n $state,\n $stateRegistry,\n $transitions,\n) {\n return {\n restrict: \"A\",\n require: [\"?^ngSrefActive\", \"?^ngSrefActiveEq\"],\n link(scope, element, attrs, ngSrefActive) {\n const type = getTypeInfo(element);\n\n const active = ngSrefActive[1] || ngSrefActive[0];\n\n let unlinkInfoFn = null;\n\n const rawDef = {};\n\n const getDef = () => processedDef($state, element, rawDef);\n\n const inputAttrs = [\"ngState\", \"ngStateParams\", \"ngStateOpts\"];\n\n const watchDeregFns = inputAttrs.reduce(\n (acc, attr) => (\n (acc[attr] = () => {\n /* empty */\n }),\n acc\n ),\n {},\n );\n\n function update() {\n const def = getDef();\n\n if (unlinkInfoFn) {\n unlinkInfoFn();\n }\n\n if (active) {\n unlinkInfoFn = active.$$addStateInfo(def.ngState, def.ngStateParams);\n }\n\n if (!isNullOrUndefined(def.href)) {\n attrs.$set(type.attr, def.href);\n }\n }\n inputAttrs.forEach((field) => {\n rawDef[field] = attrs[field] ? scope.$eval(attrs[field]) : null;\n attrs.$observe(field, (expr) => {\n watchDeregFns[field]();\n watchDeregFns[field] = scope.$watch(expr, (newval) => {\n rawDef[field] = newval;\n update();\n });\n });\n });\n update();\n scope.$on(\"$destroy\", $stateRegistry.onStatesChanged(update));\n scope.$on(\"$destroy\", $transitions.onSuccess({}, update));\n\n if (!type.clickable) return;\n const hookFn = clickHook(element, $state, type, getDef, scope);\n\n bindEvents(element, scope, hookFn, rawDef.ngStateOpts);\n },\n };\n}\n\n$StateRefActiveDirective.$inject = [\n \"$state\",\n \"$router\",\n \"$interpolate\",\n \"$stateRegistry\",\n \"$transitions\",\n];\n\n/**\n * @param {*} $state\n * @param {import('../router.js').Router} $router\n * @param {*} $interpolate\n * @param {*} $stateRegistry\n * @param {*} $transitions\n * @returns {import(\"../../interface.ts\").Directive}\n */\nexport function $StateRefActiveDirective(\n $state,\n $router,\n $interpolate,\n $stateRegistry,\n $transitions,\n) {\n return {\n restrict: \"A\",\n controller($scope, $element, $attrs) {\n let states = [];\n\n let ngSrefActive;\n\n // There probably isn't much point in $observing this\n // ngSrefActive and ngSrefActiveEq share the same directive object with some\n // slight difference in logic routing\n const activeEqClass = $interpolate(\n $attrs.ngSrefActiveEq || \"\",\n false,\n )($scope);\n\n try {\n ngSrefActive = $scope.$eval($attrs.ngSrefActive);\n } catch {\n // Do nothing. ngSrefActive is not a valid expression.\n // Fall back to using $interpolate below\n }\n ngSrefActive =\n ngSrefActive || $interpolate($attrs.ngSrefActive || \"\", false)($scope);\n setStatesFromDefinitionObject(ngSrefActive);\n // Allow ngSref to communicate with ngSrefActive[Equals]\n this.$$addStateInfo = function (newState, newParams) {\n // we already got an explicit state provided by ng-sref-active, so we\n // shadow the one that comes from ng-sref\n if (isObject(ngSrefActive) && states.length > 0) {\n return undefined;\n }\n const deregister = addState(newState, newParams, ngSrefActive);\n\n update();\n\n return deregister;\n };\n function updateAfterTransition(trans) {\n trans.promise.then(update, () => {\n /* empty */\n });\n }\n $scope.$on(\"$destroy\", setupEventListeners());\n\n if ($router.transition) {\n updateAfterTransition($router.transition);\n }\n function setupEventListeners() {\n const deregisterStatesChangedListener =\n $stateRegistry.onStatesChanged(handleStatesChanged);\n\n const deregisterOnStartListener = $transitions.onStart(\n {},\n updateAfterTransition,\n );\n\n const deregisterStateChangeSuccessListener = $scope.$on(\n \"$stateChangeSuccess\",\n update,\n );\n\n return function cleanUp() {\n deregisterStatesChangedListener();\n deregisterOnStartListener();\n deregisterStateChangeSuccessListener();\n };\n }\n function handleStatesChanged() {\n setStatesFromDefinitionObject(ngSrefActive);\n }\n function setStatesFromDefinitionObject(statesDefinition) {\n if (isObject(statesDefinition)) {\n states = [];\n entries(statesDefinition).forEach(([activeClass, stateOrName]) => {\n // Helper function to abstract adding state.\n const addStateForClass = function (\n stateOrNameParam,\n activeClassParam,\n ) {\n const ref = parseStateRef(stateOrNameParam);\n\n addState(\n ref.state,\n $scope.$eval(ref.paramExpr),\n activeClassParam,\n );\n };\n\n if (isString(stateOrName)) {\n // If state is string, just add it.\n addStateForClass(stateOrName, activeClass);\n } else if (isArray(stateOrName)) {\n // If state is an array, iterate over it and add each array item individually.\n stateOrName.forEach((stateOrNameParam) => {\n addStateForClass(stateOrNameParam, activeClass);\n });\n }\n });\n }\n }\n function addState(stateName, stateParams, activeClass) {\n const state = $state.get(stateName, stateContext($element));\n\n const stateInfo = {\n state: state || { name: stateName },\n params: stateParams,\n activeClass,\n };\n\n states.push(stateInfo);\n\n return function removeState() {\n removeFrom(states, stateInfo);\n };\n }\n // Update route state\n function update() {\n const splitClasses = (str) => str.split(/\\s/).filter(Boolean);\n\n const getClasses = (stateList) =>\n stateList\n .map((x) => x.activeClass)\n .map(splitClasses)\n .reduce(unnestR, []);\n\n const allClasses = getClasses(states)\n .concat(splitClasses(activeEqClass))\n .reduce(uniqR, []);\n\n const fuzzyClasses = getClasses(\n states.filter((x) => $state.includes(x.state.name, x.params)),\n );\n\n const exactlyMatchesAny = !!states.filter((x) =>\n $state.is(x.state.name, x.params),\n ).length;\n\n const exactClasses = exactlyMatchesAny\n ? splitClasses(activeEqClass)\n : [];\n\n const addClasses = fuzzyClasses.concat(exactClasses).reduce(uniqR, []);\n\n const removeClasses = allClasses.filter(\n (cls) => !addClasses.includes(cls),\n );\n\n addClasses.forEach((className) => $element.classList.add(className));\n removeClasses.forEach((className) =>\n $element.classList.remove(className),\n );\n }\n update();\n },\n };\n}\n","import { filter, tail, unnestR } from \"../../shared/common.js\";\nimport { hasAnimate, isDefined, isFunction } from \"../../shared/utils.js\";\nimport { parse } from \"../../shared/hof.js\";\nimport { ResolveContext } from \"../resolve/resolve-context.js\";\nimport { trace } from \"../common/trace.js\";\nimport { ViewConfig } from \"../state/views.js\";\nimport {\n dealoc,\n getCacheData,\n getInheritedData,\n setCacheData,\n} from \"../../shared/dom.js\";\nimport { getLocals } from \"../state/state-registry.js\";\n\n/**\n * `ng-view`: A viewport directive which is filled in by a view from the active state.\n *\n * ### Attributes\n *\n * - `name`: (Optional) A view name.\n * The name should be unique amongst the other views in the same state.\n * You can have views of the same name that live in different states.\n * The ng-view can be targeted in a View using the name ([[StateDeclaration.views]]).\n *\n * - `autoscroll`: an expression. When it evaluates to true, the `ng-view` will be scrolled into view when it is activated.\n * Uses [[$viewScroll]] to do the scrolling.\n *\n * - `onload`: Expression to evaluate whenever the view updates.\n *\n * #### Example:\n * A view can be unnamed or named.\n * ```html\n * <!-- Unnamed -->\n * <div ng-view></div>\n *\n * <!-- Named -->\n * <div ng-view=\"viewName\"></div>\n *\n * <!-- Named (different style) -->\n * <ng-view name=\"viewName\"></ng-view>\n * ```\n *\n * You can only have one unnamed view within any template (or root html). If you are only using a\n * single view and it is unnamed then you can populate it like so:\n *\n * ```html\n * <div ng-view></div>\n * $stateProvider.state(\"home\", {\n * template: \"<h1>HELLO!</h1>\"\n * })\n * ```\n *\n * The above is a convenient shortcut equivalent to specifying your view explicitly with the\n * [[StateDeclaration.views]] config property, by name, in this case an empty name:\n *\n * ```js\n * $stateProvider.state(\"home\", {\n * views: {\n * \"\": {\n * template: \"<h1>HELLO!</h1>\"\n * }\n * }\n * })\n * ```\n *\n * But typically you'll only use the views property if you name your view or have more than one view\n * in the same template. There's not really a compelling reason to name a view if its the only one,\n * but you could if you wanted, like so:\n *\n * ```html\n * <div ng-view=\"main\"></div>\n * ```\n *\n * ```js\n * $stateProvider.state(\"home\", {\n * views: {\n * \"main\": {\n * template: \"<h1>HELLO!</h1>\"\n * }\n * }\n * })\n * ```\n *\n * Really though, you'll use views to set up multiple views:\n *\n * ```html\n * <div ng-view></div>\n * <div ng-view=\"chart\"></div>\n * <div ng-view=\"data\"></div>\n * ```\n *\n * ```js\n * $stateProvider.state(\"home\", {\n * views: {\n * \"\": {\n * template: \"<h1>HELLO!</h1>\"\n * },\n * \"chart\": {\n * template: \"<chart_thing/>\"\n * },\n * \"data\": {\n * template: \"<data_thing/>\"\n * }\n * }\n * })\n * ```\n *\n * #### Examples for `autoscroll`:\n * ```html\n * <!-- If autoscroll present with no expression,\n * then scroll ng-view into view -->\n * <ng-view autoscroll/>\n *\n * <!-- If autoscroll present with valid expression,\n * then scroll ng-view into view if expression evaluates to true -->\n * <ng-view autoscroll='true'/>\n * <ng-view autoscroll='false'/>\n * <ng-view autoscroll='scopeVariable'/>\n * ```\n *\n * Resolve data:\n *\n * The resolved data from the state's `resolve` block is placed on the scope as `$resolve` (this\n * can be customized using [[ViewDeclaration.resolveAs]]). This can be then accessed from the template.\n *\n * Note that when `controllerAs` is being used, `$resolve` is set on the controller instance *after* the\n * controller is instantiated. The `$onInit()` hook can be used to perform initialization code which\n * depends on `$resolve` data.\n *\n * #### Example:\n * ```js\n * $stateProvider.state('home', {\n * template: '<my-component user=\"$resolve.user\"></my-component>',\n * resolve: {\n * user: function(UserService) { return UserService.fetchUser(); }\n * }\n * });\n * ```\n */\n\n/** @type {import(\"../../interface.ts\").AnnotatedDirectiveFactory} */\nexport const ngView = [\n \"$view\",\n \"$animate\",\n \"$viewScroll\",\n \"$interpolate\",\n /**\n * @param {*} $view\n * @param {ng.AnimateService} $animate\n * @param {*} $viewScroll\n * @param {*} $interpolate\n * @returns {import(\"../../interface.ts\").Directive}\n */\n function $ViewDirective($view, $animate, $viewScroll, $interpolate) {\n function getRenderer() {\n return {\n enter(element, target, cb) {\n if (hasAnimate(element)) {\n $animate.enter(element, null, target).then(cb);\n } else {\n target.after(element);\n cb();\n }\n },\n leave(element, cb) {\n if (hasAnimate(element)) {\n $animate.leave(element).then(cb);\n } else {\n element.parentElement.removeChild(element);\n cb();\n }\n },\n };\n }\n function configsEqual(config1, config2) {\n return config1 === config2;\n }\n const rootData = {\n $cfg: { viewDecl: { $context: $view.rootViewContext() } },\n $ngView: {},\n };\n\n const directive = {\n count: 0,\n terminal: true,\n priority: 400,\n transclude: \"element\",\n compile(_tElement, _tAttrs, $transclude) {\n return function (scope, $element, attrs) {\n const onloadExp = attrs.onload || \"\",\n autoScrollExp = attrs.autoscroll,\n renderer = getRenderer(),\n inherited = getInheritedData($element, \"$ngView\") || rootData,\n name =\n $interpolate(attrs.ngView || attrs.name || \"\")(scope) ||\n \"$default\";\n\n let previousEl, currentEl, currentScope, viewConfig;\n\n const activeUIView = {\n id: directive.count++, // Global sequential ID for ng-view tags added to DOM\n name, // ng-view name (<div ng-view=\"name\"></div>\n fqn: inherited.$ngView.fqn\n ? `${inherited.$ngView.fqn}.${name}`\n : name, // fully qualified name, describes location in DOM\n config: null, // The ViewConfig loaded (from a state.views definition)\n configUpdated: configUpdatedCallback, // Called when the matching ViewConfig changes\n get creationContext() {\n // The context in which this ng-view \"tag\" was created\n const fromParentTagConfig = parse(\"$cfg.viewDecl.$context\")(\n inherited,\n );\n\n // Allow <ng-view name=\"foo\"><ng-view name=\"bar\"></ng-view></ng-view>\n // See https://github.com/angular-ui/ui-router/issues/3355\n const fromParentTag = parse(\"$ngView.creationContext\")(inherited);\n\n return fromParentTagConfig || fromParentTag;\n },\n };\n\n trace.traceUIViewEvent(\"Linking\", activeUIView);\n function configUpdatedCallback(config) {\n if (config && !(config instanceof ViewConfig)) return;\n\n if (configsEqual(viewConfig, config)) return;\n trace.traceUIViewConfigUpdated(\n activeUIView,\n config && config.viewDecl && config.viewDecl.$context,\n );\n viewConfig = config;\n updateView(config);\n }\n\n setCacheData($element, \"$ngView\", { $ngView: activeUIView });\n updateView();\n const unregister = $view.registerUIView(activeUIView);\n\n scope.$on(\"$destroy\", function () {\n trace.traceUIViewEvent(\"Destroying/Unregistering\", activeUIView);\n unregister();\n });\n function cleanupLastView() {\n if (previousEl) {\n trace.traceUIViewEvent(\n \"Removing (previous) el\",\n getCacheData(previousEl, \"$ngView\"),\n );\n previousEl.remove();\n previousEl = null;\n }\n\n if (currentScope) {\n trace.traceUIViewEvent(\"Destroying scope\", activeUIView);\n currentScope.$destroy();\n currentScope = null;\n }\n\n if (currentEl) {\n const _viewData = getCacheData(currentEl, \"$ngViewAnim\");\n\n trace.traceUIViewEvent(\"Animate out\", _viewData);\n renderer.leave(currentEl, function () {\n _viewData.$$animLeave.resolve();\n previousEl = null;\n });\n previousEl = currentEl;\n currentEl = null;\n }\n }\n function updateView(config) {\n const newScope = scope.$new();\n\n const animEnter = Promise.withResolvers();\n\n const animLeave = Promise.withResolvers();\n\n const $ngViewData = {\n $cfg: config,\n $ngView: activeUIView,\n };\n\n const $ngViewAnim = {\n $animEnter: animEnter.promise,\n $animLeave: animLeave.promise,\n $$animLeave: animLeave,\n };\n\n /**\n * Fired once the view **begins loading**, *before* the DOM is rendered.\n *\n * @param {Object} event Event object.\n * @param {string} viewName Name of the view.\n */\n newScope.$emit(\"$viewContentLoading\", name);\n currentEl = $transclude(newScope, function (clone) {\n setCacheData(clone, \"$ngViewAnim\", $ngViewAnim);\n setCacheData(clone, \"$ngView\", $ngViewData);\n renderer.enter(clone, $element, function () {\n animEnter.resolve();\n\n if (currentScope)\n currentScope.$emit(\"$viewContentAnimationEnded\");\n\n if (\n (isDefined(autoScrollExp) && !autoScrollExp) ||\n scope.$eval(autoScrollExp)\n ) {\n $viewScroll(clone);\n }\n });\n cleanupLastView();\n });\n currentScope = newScope;\n /**\n * Fired once the view is **loaded**, *after* the DOM is rendered.\n *\n * @param {Object} event Event object.\n */\n currentScope.$emit(\"$viewContentLoaded\", config || viewConfig);\n currentScope.$eval(onloadExp);\n }\n };\n },\n };\n\n return directive;\n },\n];\n\n$ViewDirectiveFill.$inject = [\"$compile\", \"$controller\", \"$transitions\"];\nexport function $ViewDirectiveFill($compile, $controller, $transitions) {\n const getControllerAs = parse(\"viewDecl.controllerAs\");\n\n const getResolveAs = parse(\"viewDecl.resolveAs\");\n\n return {\n priority: -400,\n compile(tElement) {\n const initial = tElement.innerHTML;\n\n dealoc(tElement, true);\n\n return function (scope, $element) {\n const data = getCacheData($element, \"$ngView\");\n\n if (!data) {\n $element.innerHTML = initial;\n $compile($element.contentDocument || $element.childNodes)(scope);\n\n return;\n }\n const cfg = data.$cfg || {\n viewDecl: {},\n getTemplate: () => {\n /* empty */\n },\n };\n\n const resolveCtx = cfg.path && new ResolveContext(cfg.path);\n\n $element.innerHTML = cfg.getTemplate($element, resolveCtx) || initial;\n trace.traceUIViewFill(data.$ngView, $element.innerHTML);\n const link = $compile($element.contentDocument || $element.childNodes);\n\n const { controller } = cfg;\n\n const controllerAs = getControllerAs(cfg);\n\n const resolveAs = getResolveAs(cfg);\n\n const locals = resolveCtx && getLocals(resolveCtx);\n\n if (resolveAs) {\n scope.$target[resolveAs] = locals;\n }\n\n if (controller) {\n const controllerInstance = $controller(\n controller,\n Object.assign({}, locals, { $scope: scope, $element }),\n );\n\n if (controllerAs) {\n scope.$target[controllerAs] = controllerInstance;\n scope.$target[controllerAs][resolveAs] = locals;\n }\n // TODO: Use $view service as a central point for registering component-level hooks\n // Then, when a component is created, tell the $view service, so it can invoke hooks\n // $view.componentLoaded(controllerInstance, { $scope: scope, $element: $element });\n // scope.$on('$destroy', () => $view.componentUnloaded(controllerInstance, { $scope: scope, $element: $element }));\n setCacheData($element, \"$ngControllerController\", controllerInstance);\n Array.from($element.children).forEach((ell) => {\n setCacheData(ell, \"$ngControllerController\", controllerInstance);\n });\n registerControllerCallbacks(\n $transitions,\n controllerInstance,\n scope,\n cfg,\n );\n }\n // Wait for the component to appear in the DOM\n // if (isString(cfg.component)) {\n //const kebobName = kebobString(cfg.component);\n // const tagRegexp = new RegExp(`^(x-|data-)?${kebobName}$`, \"i\");\n // const getComponentController = () => {\n // const directiveEl = [].slice\n // .call($element.children)\n // .filter((el) => el && el.tagName && tagRegexp.exec(el.tagName));\n // return (\n // directiveEl &&\n // getCacheData(directiveEl, `$${cfg.component}Controller`)\n // );\n // };\n //console.error(getComponentController());\n // const deregisterWatch = scope.$watch(\n // getComponentController,\n // function (ctrlInstance) {\n // if (!ctrlInstance) return;\n // registerControllerCallbacks(\n // $transitions,\n // ctrlInstance,\n // scope,\n // cfg,\n // );\n // deregisterWatch();\n // },\n // );\n // }\n link(scope);\n };\n },\n };\n}\n/** @ignore */\n/** @ignore incrementing id */\nlet _uiCanExitId = 0;\n\n/** @ignore TODO: move these callbacks to $view and/or `/hooks/components.ts` or something */\nfunction registerControllerCallbacks(\n $transitions,\n controllerInstance,\n $scope,\n cfg,\n) {\n // Call $onInit() ASAP\n if (\n isFunction(controllerInstance.$onInit) &&\n !(cfg.viewDecl.component || cfg.viewDecl.componentProvider)\n ) {\n controllerInstance.$onInit();\n }\n const viewState = tail(cfg.path).state.self;\n\n const hookOptions = { bind: controllerInstance };\n\n // Add component-level hook for onUiParamsChanged\n if (isFunction(controllerInstance.uiOnParamsChanged)) {\n const resolveContext = new ResolveContext(cfg.path);\n\n const viewCreationTrans = resolveContext.getResolvable(\"$transition$\").data;\n\n // Fire callback on any successful transition\n const paramsUpdated = ($transition$) => {\n // Exit early if the $transition$ is the same as the view was created within.\n // Exit early if the $transition$ will exit the state the view is for.\n if (\n $transition$ === viewCreationTrans ||\n $transition$.exiting().indexOf(viewState) !== -1\n )\n return;\n const toParams = $transition$.params(\"to\");\n\n const fromParams = $transition$.params(\"from\");\n\n const getNodeSchema = (node) => node.paramSchema;\n\n const toSchema = $transition$\n .treeChanges(\"to\")\n .map(getNodeSchema)\n .reduce(unnestR, []);\n\n const fromSchema = $transition$\n .treeChanges(\"from\")\n .map(getNodeSchema)\n .reduce(unnestR, []);\n\n // Find the to params that have different values than the from params\n const changedToParams = toSchema.filter((param) => {\n const idx = fromSchema.indexOf(param);\n\n return (\n idx === -1 ||\n !fromSchema[idx].type.equals(toParams[param.id], fromParams[param.id])\n );\n });\n\n // Only trigger callback if a to param has changed or is new\n if (changedToParams.length) {\n const changedKeys = changedToParams.map((x) => x.id);\n\n // Filter the params to only changed/new to params. `$transition$.params()` may be used to get all params.\n const newValues = filter(\n toParams,\n (val, key) => changedKeys.indexOf(key) !== -1,\n );\n\n controllerInstance.uiOnParamsChanged(newValues, $transition$);\n }\n };\n\n $scope.$on(\n \"$destroy\",\n $transitions.onSuccess({}, paramsUpdated, hookOptions),\n );\n }\n\n // Add component-level hook for uiCanExit\n if (isFunction(controllerInstance.uiCanExit)) {\n const id = _uiCanExitId++;\n\n const cacheProp = \"_uiCanExitIds\";\n\n // Returns true if a redirect transition already answered truthy\n const prevTruthyAnswer = (trans) =>\n !!trans &&\n ((trans[cacheProp] && trans[cacheProp][id] === true) ||\n prevTruthyAnswer(trans.redirectedFrom()));\n\n // If a user answered yes, but the transition was later redirected, don't also ask for the new redirect transition\n const wrappedHook = (trans) => {\n let promise;\n\n const ids = (trans[cacheProp] = trans[cacheProp] || {});\n\n if (!prevTruthyAnswer(trans)) {\n promise = Promise.resolve(controllerInstance.uiCanExit(trans));\n promise.then((val) => (ids[id] = val !== false));\n }\n\n return promise;\n };\n\n const criteria = { exiting: viewState.name };\n\n $scope.$on(\n \"$destroy\",\n $transitions.onBefore(criteria, wrappedHook, hookOptions),\n );\n }\n}\n","import { isObject } from \"../../shared/utils.js\";\nimport { $injectTokens } from \"../../injection-tokens.js\";\n\nngChannelDirective.$inject = [$injectTokens.$eventBus];\n/**\n * @param {ng.PubSubService} $eventBus\n * @returns {ng.Directive}\n */\nexport function ngChannelDirective($eventBus) {\n return {\n link: (scope, element, attrs) => {\n const channel = attrs.ngChannel;\n\n const hasTemplateContent = element.childNodes.length > 0;\n\n const unsubscribe = $eventBus.subscribe(channel, (value) => {\n if (hasTemplateContent) {\n if (isObject(value)) {\n scope.$merge(value);\n }\n } else {\n element.innerHTML = value;\n }\n });\n\n scope.$on(\"$destroy\", () => unsubscribe());\n },\n };\n}\n","import { $injectTokens as $t } from \"../../injection-tokens.js\";\n\nngSetterDirective.$inject = [$t.$parse, $t.$log];\n\n/**\n * @param {ng.ParseService} $parse\n * @param {ng.LogService} $log\n * @returns {import('interface.ts').Directive}\n */\nexport function ngSetterDirective($parse, $log) {\n return {\n restrict: \"A\",\n link(scope, element, attrs) {\n const modelExpression = attrs.ngSetter;\n\n if (!modelExpression) {\n $log.warn(\"ng-setter: expression null\");\n\n return;\n }\n\n const assignModel = $parse(modelExpression).assign;\n\n if (!assignModel) {\n $log.warn(\"ng-setter: expression invalid\");\n\n return;\n }\n\n const updateModel = (value) => {\n assignModel(scope, value.trim());\n };\n\n const observer = new MutationObserver((mutationsList) => {\n let contentChanged = false;\n\n for (const mutation of mutationsList) {\n if (\n mutation.type === \"childList\" ||\n mutation.type === \"characterData\"\n ) {\n contentChanged = true;\n break;\n }\n }\n\n if (contentChanged) {\n updateModel(element.innerHTML);\n }\n });\n\n observer.observe(element, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n\n scope.$on(\"$destroy\", () => observer.disconnect());\n updateModel(element.innerHTML);\n },\n };\n}\n","import { $injectTokens as $t } from \"../../injection-tokens.js\";\n\nngInjectDirective.$inject = [$t.$log, $t.$injector];\n\n/**\n * @param {ng.LogService} $log\n * @param {ng.InjectorService} $injector\n * @returns {ng.Directive}\n */\nexport function ngInjectDirective($log, $injector) {\n return {\n restrict: \"A\",\n link(scope, _element, attrs) {\n const expr = attrs.ngInject;\n\n if (!expr) return;\n const tokens = expr\n .split(\";\")\n .map((x) => x.trim())\n .filter(Boolean);\n\n for (const name of tokens) {\n if ($injector.has(name)) {\n scope[name] = $injector.get(name);\n } else {\n $log.warn(`Injectable ${name} not found in $injector`);\n }\n }\n },\n };\n}\n","/**\n * @returns {ng.Directive}\n */\nexport function ngElDirective() {\n return {\n restrict: \"A\",\n link(scope, element, attrs) {\n const expr = attrs.ngEl;\n\n const key = !expr ? element.id : expr;\n\n scope.$target[key] = element;\n const parent = element.parentNode;\n\n if (!parent) return;\n\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n Array.from(mutation.removedNodes).forEach((removedNode) => {\n if (removedNode === element) {\n //\n delete scope.$target[key];\n observer.disconnect();\n }\n });\n }\n });\n\n observer.observe(parent, { childList: true });\n },\n };\n}\n","import { $injectTokens } from \"../../injection-tokens.js\";\nimport { entries } from \"../../shared/utils.js\";\n\n/**\n * SSE Provider\n *\n * Usage:\n * const source = $sse('/events', {\n * onMessage: (data) => console.log(data),\n * onError: (err) => console.error(err),\n * retryDelay: 2000,\n * heartbeatTimeout: 10000,\n * });\n *\n * source.close();\n */\nexport class SseProvider {\n constructor() {\n /**\n * Optional provider-level defaults\n * @type {ng.SseConfig}\n */\n this.defaults = {\n retryDelay: 1000,\n maxRetries: Infinity,\n heartbeatTimeout: 15000, // 15 seconds\n transformMessage(data) {\n try {\n return JSON.parse(data);\n } catch {\n return data;\n }\n },\n };\n }\n\n $get = [\n $injectTokens.$log,\n /**\n * Returns the $sse service function\n * @param {ng.LogService} log\n * @returns {ng.SseService}\n */\n (log) => {\n this._$log = log;\n\n return (url, config = {}) => {\n const mergedConfig = { ...this.defaults, ...config };\n\n const finalUrl = this.#buildUrl(url, mergedConfig.params);\n\n return this.#createConnection(finalUrl, mergedConfig);\n };\n },\n ];\n\n /**\n * Build URL with query parameters\n * @param {string} url\n * @param {Record<string, any>=} params\n * @returns {string}\n */\n #buildUrl(url, params) {\n if (!params) return url;\n const query = entries(params)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join(\"&\");\n\n return url + (url.includes(\"?\") ? \"&\" : \"?\") + query;\n }\n\n /**\n * Creates a managed SSE connection with reconnect and heartbeat\n * @param {string} url\n * @param {ng.SseConfig} config\n * @returns {import(\"./interface.ts\").SseConnection}\n */\n #createConnection(url, config) {\n let es;\n\n let retryCount = 0;\n\n let closed = false;\n\n let heartbeatTimer;\n\n const connect = () => {\n if (closed) return;\n\n es = new EventSource(url, {\n withCredentials: !!config.withCredentials,\n });\n\n es.addEventListener(\"open\", (event) => {\n retryCount = 0;\n config.onOpen?.(event);\n\n if (config.heartbeatTimeout) resetHeartbeat();\n });\n\n es.addEventListener(\"message\", (event) => {\n let { data } = event;\n\n try {\n data = config.transformMessage ? config.transformMessage(data) : data;\n } catch {\n /* empty */\n }\n config.onMessage?.(data, event);\n\n if (config.heartbeatTimeout) resetHeartbeat();\n });\n\n es.addEventListener(\"error\", (err) => {\n config.onError?.(err);\n\n if (closed) return;\n es.close();\n\n if (retryCount < config.maxRetries) {\n retryCount++;\n config.onReconnect?.(retryCount);\n setTimeout(connect, config.retryDelay);\n } else {\n this._$log.warn(\"SSE: Max retries reached\");\n }\n });\n };\n\n const resetHeartbeat = () => {\n clearTimeout(heartbeatTimer);\n heartbeatTimer = setTimeout(() => {\n this._$log.warn(\"SSE: heartbeat timeout, reconnecting...\");\n es.close();\n config.onReconnect?.(++retryCount);\n connect();\n }, config.heartbeatTimeout);\n };\n\n connect();\n\n return {\n close() {\n closed = true;\n clearTimeout(heartbeatTimer);\n es.close();\n },\n connect() {\n if (closed === false) {\n close();\n }\n connect();\n },\n };\n }\n}\n","/**\n * @returns {ng.Directive}\n */\nexport function ngViewportDirective() {\n return {\n restrict: \"A\",\n link(scope, element, attrs) {\n const enterExpr = attrs.onEnter;\n\n const leaveExpr = attrs.onLeave;\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n if (enterExpr) scope.$eval(enterExpr);\n } else {\n if (leaveExpr) scope.$eval(leaveExpr);\n }\n });\n },\n {\n root: null, // viewport\n threshold: 0.1, // consider \"in view\" if 10% visible\n },\n );\n\n observer.observe(element);\n\n // Clean up when the element is removed from DOM\n const parent = element.parentNode;\n\n let mutationObserver;\n\n if (parent) {\n mutationObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n Array.from(mutation.removedNodes).forEach((removedNode) => {\n if (removedNode === element) {\n observer.disconnect();\n mutationObserver.disconnect();\n }\n });\n }\n });\n mutationObserver.observe(parent, { childList: true });\n }\n\n scope.$on(\"$destroy\", () => {\n observer.disconnect();\n\n if (mutationObserver) mutationObserver.disconnect();\n });\n },\n };\n}\n","import { instantiateWasm } from \"../../shared/utils.js\";\n\n/**\n * @return {ng.Directive}\n */\nexport function ngWasmDirective() {\n return {\n async link($scope, _, $attrs) {\n $scope.$target[$attrs.as || \"wasm\"] = (\n await instantiateWasm($attrs.src)\n ).exports;\n },\n };\n}\n","/**\n * @return {ng.Directive}\n */\nexport function ngScopeDirective() {\n return {\n scope: false,\n async link($scope, _, $attrs) {\n $scope.$scopename = $attrs.ngScope;\n },\n };\n}\n","import { $injectTokens } from \"../../injection-tokens.js\";\nimport {\n assert,\n isDefined,\n isNullOrUndefined,\n isNumber,\n isString,\n} from \"../../shared/utils.js\";\nimport {\n validateIsString,\n validateRequired,\n BADARGVALUE,\n BADARG,\n} from \"../../shared/validate.js\";\n\n/**\n * Service provider that creates a {@link CookieService $cookie} service.\n * @type {ng.ServiceProvider}\n */\nexport class CookieProvider {\n constructor() {\n this.defaults = {};\n }\n\n $get = [\n $injectTokens.$exceptionHandler,\n /** @param {ng.ExceptionHandlerService} $exceptionHandler */\n ($exceptionHandler) => new CookieService(this.defaults, $exceptionHandler),\n ];\n}\n\n/**\n *\n * Provides high-level APIs for interacting with browser cookies:\n * - Raw get/set/remove\n * - JSON serialization helpers\n * - Global defaults supplied by $cookiesProvider\n */\nexport class CookieService {\n /**\n * @param {ng.CookieOptions} defaults\n * Default cookie attributes defined by `$cookiesProvider.defaults`.\n * @param {ng.ExceptionHandlerService} $exceptionHandler\n */\n constructor(defaults, $exceptionHandler) {\n /** @type {ng.CookieOptions} */\n this._defaults = Object.freeze({ ...defaults });\n this._$exceptionHandler = $exceptionHandler;\n }\n\n /**\n * Retrieves a raw cookie value.\n *\n * @param {string} key\n * @returns {string|null}\n * @throws {URIError} – If decodeURIComponent fails.\n */\n get(key) {\n validateIsString(key, \"key\");\n\n try {\n const all = parseCookies();\n\n return all[key] || null;\n } catch (err) {\n throw this._$exceptionHandler(err);\n }\n }\n\n /**\n * Retrieves a cookie and deserializes its JSON content.\n *\n * @template T\n * @param {string} key\n * @returns {T|null}\n * @throws {SyntaxError} if cookie JSON is invalid\n */\n getObject(key) {\n validateIsString(key, \"key\");\n\n const raw = this.get(key);\n\n if (!raw) return null;\n\n try {\n return /** @type {T} */ (JSON.parse(raw));\n } catch (err) {\n throw this._$exceptionHandler(\n new SyntaxError(`badparse: \"${key}\" => ${err.message}`),\n );\n }\n }\n\n /**\n * Returns an object containing all raw cookies.\n *\n * @returns {Record<string, string>}\n * @throws {URIError} – If decodeURIComponent fails\n */\n getAll() {\n try {\n return parseCookies();\n } catch (err) {\n return this._$exceptionHandler(err);\n }\n }\n\n /**\n * Sets a raw cookie value.\n *\n * @param {string} key\n * @param {string} value\n * @param {ng.CookieOptions} [options]\n */\n put(key, value, options = {}) {\n validateIsString(key, \"key\");\n validateIsString(value, \"value\");\n const encodedKey = encodeURIComponent(key);\n\n const encodedVal = encodeURIComponent(value);\n\n try {\n document.cookie = `${encodedKey}=${encodedVal}${buildOptions({\n ...this._defaults,\n ...options,\n })}`;\n } catch (err) {\n this._$exceptionHandler(err);\n }\n }\n\n /**\n * Serializes an object as JSON and stores it as a cookie.\n *\n * @param {string} key\n * @param {any} value\n * @param {ng.CookieOptions} [options]\n * @throws {TypeError} if Object cannot be converted to JSON\n */\n putObject(key, value, options) {\n validateIsString(key, \"key\");\n validateRequired(value, \"value\");\n assert(!isNullOrUndefined(value), BADARGVALUE);\n\n try {\n const str = JSON.stringify(value);\n\n this.put(key, str, options);\n } catch (err) {\n this._$exceptionHandler(\n new TypeError(`badserialize: \"${key}\" => ${err.message}`),\n );\n }\n }\n\n /**\n * Removes a cookie by setting an expired date.\n *\n * @param {string} key\n * @param {ng.CookieOptions} [options]\n */\n remove(key, options = {}) {\n validateIsString(key, \"key\");\n this.put(key, \"\", {\n ...this._defaults,\n ...options,\n expires: new Date(0),\n });\n }\n}\n\n/*----------Helpers----------*/\n\n// Internal cache\nlet _lastCookieString = \"\";\n\n/** @type {Record<string, string>} */\nlet _lastCookieMap = Object.create(null);\n\n/**\n * @returns {Record<string,string>}\n * @throws {URIError} – If decodeURIComponent fails\n */\nfunction parseCookies() {\n const current = document.cookie;\n\n // Fast path: return cached object if nothing changed\n if (current === _lastCookieString) {\n return _lastCookieMap;\n }\n\n _lastCookieString = current;\n\n /** @type {Record<string, string>} */\n const out = Object.create(null);\n\n if (!current) {\n _lastCookieMap = out;\n\n return out;\n }\n\n const parts = current.split(\"; \");\n\n for (const part of parts) {\n const eq = part.indexOf(\"=\");\n\n if (eq === -1) continue; // skip malformed cookie\n\n const key = decodeURIComponent(part.substring(0, eq));\n\n const val = decodeURIComponent(part.substring(eq + 1));\n\n out[key] = val; // last wins\n }\n\n _lastCookieMap = out;\n\n return out;\n}\n\n/**\n * Build cookie options string from an options object.\n * Safely validates types for path, domain, expires, secure, and samesite.\n *\n * @param {ng.CookieOptions} opts\n * @returns {string}\n * @throws {TypeError} if any of options are invalid\n */\nfunction buildOptions(opts = {}) {\n const parts = [];\n\n // Path\n if (isDefined(opts.path)) {\n if (!isString(opts.path))\n throw new TypeError(`${BADARG}:path ${opts.path}`);\n parts.push(`path=${opts.path}`);\n }\n\n // Domain\n if (isDefined(opts.domain)) {\n if (!isString(opts.domain))\n throw new TypeError(`${BADARG}:domain ${opts.domain}`);\n parts.push(`domain=${opts.domain}`);\n }\n\n // Expires\n if (!isNullOrUndefined(opts.expires)) {\n let expDate;\n\n if (opts.expires instanceof Date) {\n expDate = opts.expires;\n } else if (isNumber(opts.expires) || isString(opts.expires)) {\n expDate = new Date(opts.expires);\n } else {\n throw new TypeError(`${BADARG}:expires ${String(opts.expires)}`);\n }\n\n if (isNaN(expDate.getTime())) {\n throw new TypeError(`${BADARG}:expires ${String(opts.expires)}`);\n }\n\n parts.push(`expires=${expDate.toUTCString()}`);\n }\n\n // Secure\n if (opts.secure) {\n parts.push(\"secure\");\n }\n\n // SameSite\n if (isDefined(opts.samesite)) {\n if (!isString(opts.samesite))\n throw new TypeError(`${BADARG}:samesite ${opts.samesite}`);\n const samesite = opts.samesite.toLowerCase();\n\n if (![\"lax\", \"strict\", \"none\"].includes(samesite)) {\n throw new TypeError(`${BADARG}:samesite ${opts.samesite}`);\n }\n parts.push(`samesite=${samesite}`);\n }\n\n // Join all parts with semicolons\n return parts.length ? `;${parts.join(\";\")}` : \"\";\n}\n","import { isArray } from \"../../shared/utils.js\";\n\n/**\n * RFC 6570 Level 4 URI Template expander\n *\n * Supports operators: (none), +, #, ., /, ;, ?, &\n * Supports varspec modifiers: explode (*) and prefix (:len)\n *\n * Usage:\n * expandUriTemplate(\"/users/{id}\", { id: 10 }) === \"/users/10\"\n * expandUriTemplate(\"/search{?q,lang}\", { q: \"a b\", lang: \"en\" }) === \"/search?q=a%20b&lang=en\"\n * expandUriTemplate(\"/repos/{owner}/{repo}/issues{?labels*}\", { labels: [\"bug\",\"ui\"] }) === \"/repos/x/y/issues?labels=bug&labels=ui\"\n *\n * @param {string} template\n * @param {Object<string, any>} vars\n * @returns {string}\n */\nexport function expandUriTemplate(template, vars = {}) {\n if (typeof template !== \"string\")\n throw new TypeError(\"template must be a string\");\n\n return template.replace(/\\{([^}]+)\\}/g, (match, expression) => {\n return expandExpression(expression, vars);\n });\n}\n\n/**\n * Helper: percent-encode a string. If allowReserved true, reserved chars are NOT encoded.\n * @param {string} str\n * @param {boolean} allowReserved\n * @returns {string}\n */\nexport function pctEncode(str, allowReserved) {\n // encodeURIComponent, then restore reserved if allowed\n const encoded = encodeURIComponent(String(str));\n\n if (allowReserved) {\n // Reserved characters per RFC 3986\n return encoded.replace(\n /(%3A|%2F|%3F|%23|%5B|%5D|%40|%21|%24|%26|%27|%28|%29|%2A|%2B|%2C|%3B|%3D)/gi,\n (char) => decodeURIComponent(char),\n );\n }\n\n return encoded;\n}\n\n/**\n * Parse and expand a single expression (content between { and }).\n * @param {string} expression\n * @param {Object<string, any>} vars\n * @returns {string}\n */\nexport function expandExpression(expression, vars) {\n // Operator if first char in operator set\n const operator = /^[+#./;?&]/.test(expression) ? expression[0] : \"\";\n\n const op = operator;\n\n const varlist = op ? expression.slice(1) : expression;\n\n // operator configuration (separator, prefix, named, ifEmpty, allowReserved)\n const OP = {\n \"\": {\n sep: \",\",\n prefix: \"\",\n named: false,\n ifEmpty: \"\",\n allowReserved: false,\n },\n \"+\": {\n sep: \",\",\n prefix: \"\",\n named: false,\n ifEmpty: \"\",\n allowReserved: true,\n },\n \"#\": {\n sep: \",\",\n prefix: \"#\",\n named: false,\n ifEmpty: \"\",\n allowReserved: true,\n },\n \".\": {\n sep: \".\",\n prefix: \".\",\n named: false,\n ifEmpty: \"\",\n allowReserved: false,\n },\n \"/\": {\n sep: \"/\",\n prefix: \"/\",\n named: false,\n ifEmpty: \"\",\n allowReserved: false,\n },\n \";\": {\n sep: \";\",\n prefix: \";\",\n named: true,\n ifEmpty: \"\",\n allowReserved: false,\n },\n \"?\": {\n sep: \"&\",\n prefix: \"?\",\n named: true,\n ifEmpty: \"=\",\n allowReserved: false,\n },\n \"&\": {\n sep: \"&\",\n prefix: \"&\",\n named: true,\n ifEmpty: \"=\",\n allowReserved: false,\n },\n };\n\n const conf = OP[op];\n\n if (!conf) throw new Error(`Unsupported operator: ${op}`);\n\n // split varspecs by comma, preserve whitespace trimmed\n const varspecs = varlist\n .split(\",\")\n .map((str) => str.trim())\n .filter(Boolean);\n\n const expandedParts = [];\n\n for (const spec of varspecs) {\n // parse varspec: name, explode (*), prefix (:len)\n const varspec = /^([A-Za-z0-9_.]+)(\\*|(?::(\\d+)))?$/.exec(spec);\n\n if (!varspec) throw new Error(`Invalid varspec: ${spec}`);\n const varname = varspec[1];\n\n const explode = varspec[2] === \"*\";\n\n const prefixLength = varspec[3] ? parseInt(varspec[3], 10) : undefined;\n\n const value = vars[varname];\n\n // undefined or null = skip (no expansion)\n if (value === undefined || value === null) {\n continue;\n }\n\n // PROCESS arrays\n if (isArray(value)) {\n if (value.length === 0) {\n // empty array: for named operators, emit key with empty ifEmpty, otherwise skip\n if (conf.named) {\n // emit key without value or with = depending on ifEmpty\n if (conf.ifEmpty === \"=\") {\n expandedParts.push(\n `${pctEncode(varname, conf.allowReserved)}${conf.ifEmpty}`,\n );\n } else {\n expandedParts.push(pctEncode(varname, conf.allowReserved));\n }\n }\n continue;\n }\n\n if (explode) {\n // each item becomes either 'k=v' (named) or 'v' (unnamed)\n for (const item of value) {\n if (item === null || item === undefined) continue;\n\n if (conf.named) {\n expandedParts.push(\n `${pctEncode(varname, conf.allowReserved)}=${pctEncode(item, conf.allowReserved)}`,\n );\n } else {\n expandedParts.push(pctEncode(item, conf.allowReserved));\n }\n }\n } else {\n // join by comma (or operator.sep?) — RFC: simple join with ','\n const joined = value\n .filter((val) => val !== null && val !== undefined)\n .map((val) => pctEncode(val, conf.allowReserved))\n .join(\",\");\n\n if (conf.named) {\n if (joined === \"\") {\n expandedParts.push(\n pctEncode(varname, conf.allowReserved) +\n (conf.ifEmpty === \"=\" ? conf.ifEmpty : \"\"),\n );\n } else {\n expandedParts.push(\n `${pctEncode(varname, conf.allowReserved)}=${joined}`,\n );\n }\n } else {\n expandedParts.push(joined);\n }\n }\n continue;\n }\n\n // PROCESS objects (associative arrays)\n if (typeof value === \"object\") {\n const keys = Object.keys(value);\n\n if (keys.length === 0) {\n if (conf.named) {\n expandedParts.push(\n pctEncode(varname, conf.allowReserved) +\n (conf.ifEmpty === \"=\" ? conf.ifEmpty : \"\"),\n );\n }\n continue;\n }\n\n if (explode) {\n // each key/value pair becomes k=v (named) or k,v? For explode + named, RFC says 'k=v'\n for (const key of keys) {\n const encVal = value[key];\n\n if (encVal === null || encVal === undefined) continue;\n\n if (conf.named) {\n expandedParts.push(\n `${pctEncode(key, conf.allowReserved)}=${pctEncode(encVal, conf.allowReserved)}`,\n );\n } else {\n // unnamed explode => k,encVal form pairs\n expandedParts.push(\n `${pctEncode(key, conf.allowReserved)}=${pctEncode(encVal, conf.allowReserved)}`,\n );\n }\n }\n } else {\n // not exploded: join k,v pairs by ','\n const pairs = keys\n .map(\n (key) =>\n `${pctEncode(key, conf.allowReserved)},${pctEncode(value[key], conf.allowReserved)}`,\n )\n .join(\",\");\n\n if (conf.named) {\n if (pairs === \"\") {\n expandedParts.push(\n pctEncode(varname, conf.allowReserved) +\n (conf.ifEmpty === \"=\" ? conf.ifEmpty : \"\"),\n );\n } else {\n expandedParts.push(\n `${pctEncode(varname, conf.allowReserved)}=${pairs}`,\n );\n }\n } else {\n expandedParts.push(pairs);\n }\n }\n continue;\n }\n\n // PROCESS scalar (string/number/boolean)\n let str = String(value);\n\n // apply prefix modifier if present\n if (typeof prefixLength === \"number\") {\n str = str.substring(0, prefixLength);\n }\n\n // empty string handling\n if (str === \"\") {\n if (conf.named) {\n // for named operators, emit key or key= depending on ifEmpty\n if (conf.ifEmpty === \"=\") {\n expandedParts.push(\n `${pctEncode(varname, conf.allowReserved)}${conf.ifEmpty}`,\n );\n } else {\n expandedParts.push(pctEncode(varname, conf.allowReserved));\n }\n } else {\n // unnamed operators: empty string -> nothing (skip)\n if (op === \"+\" || op === \"#\") {\n // these allow empty expansions (produce nothing)\n expandedParts.push(pctEncode(str, conf.allowReserved));\n } else {\n // skip adding anything\n expandedParts.push(pctEncode(str, conf.allowReserved));\n }\n }\n continue;\n }\n\n // default scalar behavior\n if (conf.named) {\n expandedParts.push(\n `${pctEncode(varname, conf.allowReserved)}=${pctEncode(str, conf.allowReserved)}`,\n );\n } else {\n expandedParts.push(pctEncode(str, conf.allowReserved));\n }\n } // end for varspecs\n\n if (expandedParts.length === 0) return \"\";\n\n // join parts with operator separator; prefix if needed\n return conf.prefix + expandedParts.join(conf.sep);\n}\n","import { $injectTokens } from \"../../injection-tokens.js\";\nimport {\n assert,\n isArray,\n isNullOrUndefined,\n isString,\n} from \"../../shared/utils.js\";\nimport { BADARG } from \"../../shared/validate.js\";\nimport { expandUriTemplate } from \"./rfc.js\";\n\n/**\n * @template T, ID\n */\nexport class RestService {\n static $nonscope = true;\n\n /**\n * Core REST service for CRUD operations.\n * Safe, predictable, and optionally maps raw JSON to entity class instances.\n *\n * @param {ng.HttpService} $http Angular-like $http service\n * @param {string} baseUrl Base URL or URI template\n * @param {ng.EntityClass<T>} [entityClass] Optional constructor to map JSON to objects\n * @param {Object} [options] Optional settings (interceptors, headers, etc.)\n */\n constructor($http, baseUrl, entityClass, options = {}) {\n assert(isString(baseUrl) && baseUrl.length > 0, \"baseUrl required\");\n\n /** @private */\n this._$http = $http;\n /** @private */\n this._baseUrl = baseUrl;\n /** @private */\n this._entityClass = entityClass;\n /** @private */\n this._options = options;\n }\n\n /**\n * Build full URL from template and parameters\n * @param {string} template\n * @param {Record<string, any>} params\n * @returns {string}\n */\n buildUrl(template, params) {\n // Safe: ensure params is an object\n return expandUriTemplate(template, params || {});\n }\n\n /**\n * Map raw JSON to entity instance or return as-is\n * @param {any} data\n * @returns {T|any}\n */\n #mapEntity(data) {\n if (!data) return data;\n\n return this._entityClass ? new this._entityClass(data) : data;\n }\n\n /**\n * List entities\n * @param {Record<string, any>=} params\n * @returns {Promise<T[]>}\n */\n async list(params = {}) {\n const url = this.buildUrl(this._baseUrl, params);\n\n const resp = await this.#request(\"get\", url, null, params);\n\n if (!isArray(resp.data)) return [];\n\n return resp.data.map((data) => this.#mapEntity(data));\n }\n\n /**\n * Read single entity by ID\n * @param {ID} id\n * @param {Record<string, any>=} params\n * @returns {Promise<T|null>}\n */\n async read(id, params = {}) {\n assert(!isNullOrUndefined(id), `${BADARG}:id ${id}`);\n const url = this.buildUrl(`${this._baseUrl}/${id}`, params);\n\n const resp = await this.#request(\"get\", url, null, params);\n\n return this.#mapEntity(resp.data);\n }\n\n /**\n * Create a new entity\n * @param {T} item\n * @returns {Promise<T>}\n */\n async create(item) {\n assert(!isNullOrUndefined(item), `${BADARG}:item ${item}`);\n const resp = await this.#request(\"post\", this._baseUrl, item);\n\n return this.#mapEntity(resp.data);\n }\n\n /**\n * Update entity by ID\n * @param {ID} id\n * @param {Partial<T>} item\n * @returns {Promise<T|null>}\n */\n async update(id, item) {\n assert(!isNullOrUndefined(id), `${BADARG}:id ${id}`);\n const url = `${this._baseUrl}/${id}`;\n\n try {\n const resp = await this.#request(\"put\", url, item);\n\n return this.#mapEntity(resp.data);\n } catch {\n return null;\n }\n }\n\n /**\n * Delete entity by ID\n * @param {ID} id\n * @returns {Promise<boolean>}\n */\n async delete(id) {\n assert(!isNullOrUndefined(id), `${BADARG}:id ${id}`);\n const url = `${this._baseUrl}/${id}`;\n\n try {\n await this.#request(\"delete\", url);\n\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Core HTTP request wrapper\n * @param {\"get\"|\"post\"|\"put\"|\"delete\"} method\n * @param {string} url\n * @param {any=} data\n * @param {Record<string, any>=} params\n * @returns {Promise<any>}\n */\n async #request(method, url, data = null, params = {}) {\n return await this._$http({\n method,\n url,\n data,\n params,\n ...this._options,\n });\n }\n}\n\n/**\n * Provider for registering REST endpoints during module configuration.\n */\nexport class RestProvider {\n constructor() {\n /** @private @type {ng.RestDefinition<any>[]} */\n this._definitions = [];\n }\n\n /**\n * Register a REST resource at config phase\n * @template T\n * @param {string} name Service name\n * @param {string} url Base URL or URI template\n * @param {{new(data:any):T}=} entityClass Optional entity constructor\n * @param {Object=} options Optional service options\n */\n rest(name, url, entityClass, options = {}) {\n this._definitions.push({ name, url, entityClass, options });\n }\n\n /**\n * $get factory: returns a factory function and allows access to named services\n * @returns {(baseUrl:string, entityClass?:Function, options?:object) => RestService & { get(name:string): RestService, listNames(): string[] }}\n */\n $get = [\n $injectTokens.$http,\n ($http) => {\n const services = new Map();\n\n const factory = (baseUrl, entityClass, options = {}) => {\n const svc = new RestService($http, baseUrl, entityClass, options);\n\n return svc;\n };\n\n // create services from pre-registered definitions\n for (const def of this._definitions) {\n const svc = factory(def.url, def.entityClass, def.options);\n\n services.set(def.name, svc);\n }\n\n // helpers to fetch named services\n factory.get = (name) => services.get(name);\n factory.listNames = () => Array.from(services.keys());\n\n return factory;\n },\n ];\n}\n","import { Angular } from \"./angular.js\";\n\nexport const angular = new Angular();\ndocument.addEventListener(\"DOMContentLoaded\", () => angular.init(document), {\n once: true,\n});\n","import {\n assertNotHasOwnProperty,\n errorHandlingConfig,\n getNgAttribute,\n hasOwn,\n isArray,\n minErr,\n ngAttrPrefixes,\n} from \"./shared/utils.js\";\nimport {\n getController,\n getInjector,\n getScope,\n setCacheData,\n} from \"./shared/dom.js\";\nimport { Cache } from \"./shared/cache.js\";\nimport { createInjector } from \"./core/di/injector.js\";\nimport { NgModule } from \"./core/di/ng-module/ng-module.js\";\nimport { registerNgModule } from \"./ng.js\";\nimport { unnestR } from \"./shared/common.js\";\nimport { EventBus } from \"./services/pubsub/pubsub.js\";\nimport { $injectTokens as $t } from \"./injection-tokens.js\";\nimport { annotate } from \"./core/di/di.js\";\n\nconst ngMinErr = minErr(\"ng\");\n\nconst $injectorMinErr = minErr(\"$injector\");\n\n/** @type {Object.<string, NgModule>} */\nconst moduleRegistry = {};\n\nexport class Angular {\n constructor() {\n /** @public */\n this.$cache = Cache;\n\n /** @public @type {ng.PubSubService} */\n this.$eventBus = EventBus;\n\n /**\n * @type {string} `version` from `package.json`\n */\n this.version = \"[VI]{version}[/VI]\"; //inserted via rollup plugin\n\n /** @type {!Array<string|any>} */\n this.bootsrappedModules = [];\n\n /**\n * Gets the controller instance for a given element, if exists. Defaults to \"ngControllerController\"\n *\n * @type {(element: Element, name: string?) => ng.Scope|undefined}\n */\n this.getController = getController;\n\n /**\n * Return instance of InjectorService attached to element\n * @type {(Element) => ng.InjectorService}\n */\n this.getInjector = getInjector;\n\n /**\n * Gets scope for a given element.\n * @type {(Element) => ng.Scope}\n */\n this.getScope = getScope;\n\n this.errorHandlingConfig = errorHandlingConfig;\n this.$t = $t;\n\n window.angular = this;\n registerNgModule(this);\n }\n\n /**\n *\n * The `angular.module` is a global place for creating, registering and retrieving AngularTS\n * modules.\n * All modules (AngularTS core or 3rd party) that should be available to an application must be\n * registered using this mechanism.\n *\n * Passing one argument retrieves an existing {@link ng.NgModule},\n * whereas passing more than one argument creates a new {@link ng.NgModule}\n *\n *\n * # Module\n *\n * A module is a collection of services, directives, controllers, filters, workers, WebAssembly modules, and configuration information.\n * `angular.module` is used to configure the {@link auto.$injector $injector}.\n *\n * ```js\n * // Create a new module\n * let myModule = angular.module('myModule', []);\n *\n * // register a new service\n * myModule.value('appName', 'MyCoolApp');\n *\n * // configure existing services inside initialization blocks.\n * myModule.config(['$locationProvider', function($locationProvider) {\n * // Configure existing providers\n * $locationProvider.hashPrefix('!');\n * }]);\n * ```\n *\n * Then you can create an injector and load your modules like this:\n *\n * ```js\n * let injector = angular.injector(['ng', 'myModule'])\n * ```\n *\n * However it's more likely that you'll just use\n * `ng-app` directive or\n * {@link bootstrap} to simplify this process for you.\n *\n * @param {string} name The name of the module to create or retrieve.\n * @param {Array.<string>} [requires] If specified then new module is being created. If\n * unspecified then the module is being retrieved for further configuration.\n * @param {ng.Injectable<any>} [configFn] Optional configuration function for the module that gets\n * passed to {@link NgModule.config NgModule.config()}.\n * @returns {NgModule} A newly registered module.\n */\n module(name, requires, configFn) {\n assertNotHasOwnProperty(name, \"module\");\n\n if (requires && hasOwn(moduleRegistry, name)) {\n moduleRegistry[name] = null; // force ensure to recreate the module\n }\n\n return ensure(moduleRegistry, name, () => {\n if (!requires) {\n throw $injectorMinErr(\n \"nomod\",\n \"Module '{0}' is not available. Possibly misspelled or not loaded\",\n name,\n );\n }\n\n return new NgModule(name, requires, configFn);\n });\n }\n\n /**\n * Use this function to manually start up AngularTS application.\n *\n * AngularTS will detect if it has been loaded into the browser more than once and only allow the\n * first loaded script to be bootstrapped and will report a warning to the browser console for\n * each of the subsequent scripts. This prevents strange results in applications, where otherwise\n * multiple instances of AngularTS try to work on the DOM.\n * *\n * <div class=\"alert alert-warning\">\n * **Note:** Do not bootstrap the app on an element with a directive that uses {@link ng.$compile#transclusion transclusion},\n * such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}.\n * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},\n * causing animations to stop working and making the injector inaccessible from outside the app.\n * </div>\n *\n * ```html\n * <!doctype html>\n * <html>\n * <body>\n * <div ng-controller=\"WelcomeController\">\n * {{greeting}}\n * </div>\n *\n * <script src=\"angular.js\"></script>\n * <script>\n * let app = angular.module('demo', [])\n * .controller('WelcomeController', function($scope) {\n * $scope.greeting = 'Welcome!';\n * });\n * angular.bootstrap(document, ['demo']);\n * </script>\n * </body>\n * </html>\n * ```\n *\n * @param {string | Element | Document} element DOM element which is the root of AngularTS application.\n * @param {Array<String|any>} [modules] an array of modules to load into the application.\n * Each item in the array should be the name of a predefined module or a (DI annotated)\n * function that will be invoked by the injector as a `config` block.\n * See: {@link angular.module modules}\n * @param {import(\"./interface.ts\").AngularBootstrapConfig} [config]\n * @returns {ng.InjectorService} The created injector instance for this application.\n */\n bootstrap(element, modules, config) {\n config = config || {\n strictDi: false,\n };\n\n if (\n (element instanceof Element || element instanceof Document) &&\n getInjector(/** @type {Element} */ (element))\n ) {\n throw ngMinErr(\"btstrpd\", \"App already bootstrapped\");\n }\n\n if (isArray(modules)) {\n this.bootsrappedModules = modules;\n }\n\n this.bootsrappedModules.unshift([\n \"$provide\",\n /**\n * @param {import('./interface.ts').Provider} $provide\n */\n ($provide) => {\n $provide.value(\"$rootElement\", element);\n },\n ]);\n\n this.bootsrappedModules.unshift(\"ng\");\n\n const injector = createInjector(this.bootsrappedModules, config.strictDi);\n\n injector.invoke([\n $t.$rootScope,\n $t.$rootElement,\n $t.$compile,\n $t.$injector,\n /**\n * @param {ng.Scope} scope\n * @param {Element} el\n * @param {ng.CompileService} compile\n * @param {ng.InjectorService} $injector\n */\n (scope, el, compile, $injector) => {\n this.$rootScope = scope;\n // ng-route deps\n this.$injector = $injector; // TODO refactor away as this as this prevents multiple apps from being used\n\n setCacheData(el, \"$injector\", $injector);\n\n const compileFn = compile(el);\n\n compileFn(scope);\n\n // https://github.com/angular-ui/ui-router/issues/3678\n if (!hasOwn($injector, \"strictDi\")) {\n try {\n $injector.invoke(() => {\n /* empty */\n });\n } catch (error) {\n $injector.strictDi = !!/strict mode/.exec(\n error && error.toString(),\n );\n }\n }\n\n $injector\n .get($t.$stateRegistry)\n .get()\n .map((x) => x.$$state().resolvables)\n .reduce(unnestR, [])\n .filter((x) => x.deps === \"deferred\")\n .forEach(\n (resolvable) =>\n (resolvable.deps = annotate(\n resolvable.resolveFn,\n $injector.strictDi,\n )),\n );\n },\n ]);\n\n return injector;\n }\n\n /**\n * @param {any[]} modules\n * @param {boolean?} strictDi\n * @returns {import(\"./core/di/internal-injector.js\").InjectorService}\n */\n injector(modules, strictDi) {\n return createInjector(modules, strictDi);\n }\n\n /**\n * @param {Element|Document} element\n */\n init(element) {\n let appElement;\n\n let module;\n\n const config = {};\n\n // The element `element` has priority over any other element.\n ngAttrPrefixes.forEach((prefix) => {\n const name = `${prefix}app`;\n\n if (\n /** @type {Element} */ (element).hasAttribute &&\n /** @type {Element} */ (element).hasAttribute(name)\n ) {\n appElement = element;\n module = /** @type {Element} */ (element).getAttribute(name);\n }\n });\n ngAttrPrefixes.forEach((prefix) => {\n const name = `${prefix}app`;\n\n let candidate;\n\n if (\n !appElement &&\n (candidate = element.querySelector(`[${name.replace(\":\", \"\\\\:\")}]`))\n ) {\n appElement = candidate;\n module = candidate.getAttribute(name);\n }\n });\n\n if (appElement) {\n config.strictDi = getNgAttribute(appElement, \"strict-di\") !== null;\n this.bootstrap(appElement, module ? [module] : [], config);\n }\n }\n\n /**\n * Retrieves a scope by its registered name and returns its Proxy wrapper.\n *\n * Internally, this walks down the `Scope` tree starting from `$rootScope`\n * and checks for a matching `$scopename` property. The `$scopename` property\n * may be defined statically on controllers using `as` syntax, assigned via the `ngScope` directive,\n * or defined on `$scope` injectable.\n *\n * @param {string} name\n * @returns {ProxyHandler<ng.Scope>|undefined}\n */\n getScopeByName(name) {\n const scope = this.$rootScope.$searchByName(name);\n\n if (scope) {\n return scope.$proxy;\n }\n\n return undefined;\n }\n}\n\n/**\n * @param {Object.<string, NgModule>} obj\n * @param {string} name\n * @param {Function} factory\n * @returns {NgModule}\n */\nfunction ensure(obj, name, factory) {\n return obj[name] || (obj[name] = factory());\n}\n","import { CompileProvider } from \"./core/compile/compile.js\";\nimport {\n hiddenInputBrowserCacheDirective,\n inputDirective,\n ngValueDirective,\n} from \"./directive/input/input.js\";\nimport { formDirective, ngFormDirective } from \"./directive/form/form.js\";\nimport { scriptDirective } from \"./directive/script/script.js\";\nimport { optionDirective, selectDirective } from \"./directive/select/select.js\";\nimport {\n ngBindDirective,\n ngBindHtmlDirective,\n ngBindTemplateDirective,\n} from \"./directive/bind/bind.js\";\nimport {\n ngClassDirective,\n ngClassEvenDirective,\n ngClassOddDirective,\n} from \"./directive/class/class.js\";\nimport { ngCloakDirective } from \"./directive/cloak/cloak.js\";\nimport { ngControllerDirective } from \"./directive/controller/controller.js\";\nimport {\n ngHideDirective,\n ngShowDirective,\n} from \"./directive/show-hide/show-hide.js\";\nimport { ngIfDirective } from \"./directive/if/if.js\";\nimport {\n ngIncludeDirective,\n ngIncludeFillContentDirective,\n} from \"./directive/include/include.js\";\nimport { ngInitDirective } from \"./directive/init/init.js\";\nimport { ngNonBindableDirective } from \"./directive/non-bindable/non-bindable.js\";\nimport { ngRefDirective } from \"./directive/ref/ref.js\";\nimport { ngRepeatDirective } from \"./directive/repeat/repeat.js\";\nimport { ngStyleDirective } from \"./directive/style/style.js\";\nimport {\n ngSwitchDefaultDirective,\n ngSwitchDirective,\n ngSwitchWhenDirective,\n} from \"./directive/switch/switch.js\";\nimport { ngOptionsDirective } from \"./directive/options/options.js\";\nimport { ngTranscludeDirective } from \"./directive/transclude/transclude.js\";\nimport { ngModelDirective } from \"./directive/model/model.js\";\nimport {\n maxlengthDirective,\n minlengthDirective,\n patternDirective,\n requiredDirective,\n} from \"./directive/validators/validators.js\";\nimport { ngModelOptionsDirective } from \"./directive/model-options/model-options.js\";\nimport { ngAttributeAliasDirectives } from \"./directive/attrs/attrs.js\";\nimport { ngEventDirectives } from \"./directive/events/events.js\";\nimport { AnchorScrollProvider } from \"./services/anchor-scroll/anchor-scroll.js\";\nimport { AnimateProvider } from \"./animations/animate.js\";\nimport { TemplateCacheProvider } from \"./services/template-cache/template-cache.js\";\nimport { ControllerProvider } from \"./core/controller/controller.js\";\nimport { ExceptionHandlerProvider } from \"./services/exception/exception.js\";\nimport { FilterProvider } from \"./core/filter/filter.js\";\nimport { InterpolateProvider } from \"./core/interpolate/interpolate.js\";\nimport {\n HttpParamSerializerProvider,\n HttpProvider,\n} from \"./services/http/http.js\";\nimport { LocationProvider } from \"./services/location/location.js\";\nimport { LogProvider } from \"./services/log/log.js\";\nimport { ParseProvider } from \"./core/parse/parse.js\";\nimport { RootScopeProvider } from \"./core/scope/scope.js\";\nimport { SceDelegateProvider, SceProvider } from \"./services/sce/sce.js\";\nimport { TemplateRequestProvider } from \"./services/template-request/template-request.js\";\nimport { SanitizeUriProvider } from \"./core/sanitize/sanitize-uri.js\";\nimport {\n ngMessageDefaultDirective,\n ngMessageDirective,\n ngMessageExpDirective,\n ngMessagesDirective,\n ngMessagesIncludeDirective,\n} from \"./directive/messages/messages.js\";\nimport {\n AriaProvider,\n ngCheckedAriaDirective,\n ngClickAriaDirective,\n ngDblclickAriaDirective,\n ngDisabledAriaDirective,\n ngHideAriaDirective,\n ngMessagesAriaDirective,\n ngModelAriaDirective,\n ngReadonlyAriaDirective,\n ngRequiredAriaDirective,\n ngShowAriaDirective,\n ngValueAriaDirective,\n} from \"./directive/aria/aria.js\";\nimport { AnimateCssProvider } from \"./animations/animate-css.js\";\nimport { AnimateQueueProvider } from \"./animations/queue/animate-queue.js\";\nimport { AnimateJsProvider } from \"./animations/animate-js.js\";\nimport { AnimationProvider } from \"./animations/animation.js\";\nimport { RafSchedulerProvider } from \"./animations/raf-scheduler.js\";\nimport { AnimateCacheProvider } from \"./animations/animate-cache.js\";\nimport { AnimateCssDriverProvider } from \"./animations/animate-css-driver.js\";\nimport { AnimateJsDriverProvider } from \"./animations/animate-js-driver.js\";\nimport { ngAnimateSwapDirective } from \"./animations/animate-swap.js\";\nimport { $$AnimateChildrenDirective } from \"./animations/animate-children-directive.js\";\nimport { UrlConfigProvider } from \"./router/url/url-config.js\";\nimport { Router } from \"./router/router.js\";\nimport { ViewService } from \"./router/view/view.js\";\nimport { TransitionProvider } from \"./router/transition/transition-service.js\";\nimport { StateProvider } from \"./router/state/state-service.js\";\nimport { ViewScrollProvider } from \"./router/view-scroll.js\";\nimport { TemplateFactoryProvider } from \"./router/template-factory.js\";\nimport { UrlService } from \"./router/url/url-service.js\";\nimport { StateRegistryProvider } from \"./router/state/state-registry.js\";\nimport { trace } from \"./router/common/trace.js\";\nimport {\n $StateRefActiveDirective,\n $StateRefDirective,\n $StateRefDynamicDirective,\n} from \"./router/directives/state-directives.js\";\nimport {\n $ViewDirectiveFill,\n ngView,\n} from \"./router/directives/view-directive.js\";\nimport { ngChannelDirective } from \"./directive/channel/channel.js\";\nimport { ngSetterDirective } from \"./directive/setter/setter.js\";\nimport { PubSubProvider } from \"./services/pubsub/pubsub.js\";\nimport {\n ngDeleteDirective,\n ngGetDirective,\n ngPostDirective,\n ngPutDirective,\n ngSseDirective,\n} from \"./directive/http/http.js\";\nimport { $injectTokens as $t } from \"./injection-tokens.js\";\nimport { ngInjectDirective } from \"./directive/inject/inject.js\";\nimport { ngElDirective } from \"./directive/el/el.js\";\nimport { SseProvider } from \"./services/sse/sse.js\";\nimport { ngViewportDirective } from \"./directive/viewport/viewport.js\";\nimport { ngWorkerDirective } from \"./directive/worker/worker.js\";\nimport { ngWasmDirective } from \"./directive/wasm/wasm.js\";\nimport { ngScopeDirective } from \"./directive/scope/scope.js\";\nimport { CookieProvider } from \"./services/cookie/cookie.js\";\nimport { RestProvider } from \"./services/rest/rest.js\";\n\n/**\n * Initializes core `ng` module.\n * @param {ng.Angular} angular\n * @returns {ng.NgModule} `ng` module\n */\nexport function registerNgModule(angular) {\n return angular\n .module(\n \"ng\",\n [],\n [\n $t.$provide,\n /** @param {ng.ProvideService} $provide */\n ($provide) => {\n // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.\n $provide.provider({\n $$sanitizeUri: SanitizeUriProvider,\n });\n $provide.value($t.$window, window);\n $provide.value($t.$document, document);\n $provide\n .provider($t.$compile, CompileProvider)\n .directive({\n input: inputDirective,\n textarea: inputDirective,\n form: formDirective,\n script: scriptDirective,\n select: selectDirective,\n option: optionDirective,\n ngBind: ngBindDirective,\n ngBindHtml: ngBindHtmlDirective,\n ngBindTemplate: ngBindTemplateDirective,\n ngChannel: ngChannelDirective,\n ngClass: ngClassDirective,\n ngClassEven: ngClassEvenDirective,\n ngClassOdd: ngClassOddDirective,\n ngCloak: ngCloakDirective,\n ngController: ngControllerDirective,\n ngDelete: ngDeleteDirective,\n ngDisabled: ngDisabledAriaDirective,\n ngEl: ngElDirective,\n ngForm: ngFormDirective,\n ngGet: ngGetDirective,\n ngHide: ngHideDirective,\n ngIf: ngIfDirective,\n ngInclude: ngIncludeDirective,\n ngInject: ngInjectDirective,\n ngInit: ngInitDirective,\n ngMessages: ngMessagesDirective,\n ngMessage: ngMessageDirective,\n ngMessageExp: ngMessageExpDirective,\n ngMessagesInclude: ngMessagesIncludeDirective,\n ngMessageDefault: ngMessageDefaultDirective,\n ngNonBindable: ngNonBindableDirective,\n ngPost: ngPostDirective,\n ngPut: ngPutDirective,\n ngRef: ngRefDirective,\n ngRepeat: ngRepeatDirective,\n ngSetter: ngSetterDirective,\n ngShow: ngShowDirective,\n ngStyle: ngStyleDirective,\n ngSse: ngSseDirective,\n ngSwitch: ngSwitchDirective,\n ngSwitchWhen: ngSwitchWhenDirective,\n ngSwitchDefault: ngSwitchDefaultDirective,\n ngOptions: ngOptionsDirective,\n ngTransclude: ngTranscludeDirective,\n ngModel: ngModelDirective,\n pattern: patternDirective,\n ngPattern: patternDirective,\n required: requiredDirective,\n ngRequired: requiredDirective,\n ngMinlength: minlengthDirective,\n minlength: minlengthDirective,\n ngMaxlength: maxlengthDirective,\n maxlength: maxlengthDirective,\n ngValue: ngValueDirective,\n ngModelOptions: ngModelOptionsDirective,\n ngViewport: ngViewportDirective,\n ngWasm: ngWasmDirective,\n ngWorker: ngWorkerDirective,\n ngScope: ngScopeDirective,\n })\n .directive({\n input: hiddenInputBrowserCacheDirective,\n ngAnimateSwap: ngAnimateSwapDirective,\n ngAnimateChildren: $$AnimateChildrenDirective,\n // aria directives\n ngChecked: ngCheckedAriaDirective,\n ngClick: ngClickAriaDirective,\n ngDblclick: ngDblclickAriaDirective,\n ngInclude: ngIncludeFillContentDirective,\n ngHide: ngHideAriaDirective,\n ngShow: ngShowAriaDirective,\n ngMessages: ngMessagesAriaDirective,\n ngModel: ngModelAriaDirective,\n ngReadonly: ngReadonlyAriaDirective,\n ngRequired: ngRequiredAriaDirective,\n ngValue: ngValueAriaDirective,\n // router directives\n ngSref: $StateRefDirective,\n ngSrefActive: $StateRefActiveDirective,\n ngSrefActiveEq: $StateRefActiveDirective,\n ngState: $StateRefDynamicDirective,\n ngView,\n })\n .directive({\n ngView: $ViewDirectiveFill,\n })\n .directive(ngAttributeAliasDirectives)\n .directive(ngEventDirectives);\n $provide.provider({\n $aria: AriaProvider,\n $anchorScroll: AnchorScrollProvider,\n $animate: AnimateProvider,\n $$animation: AnimationProvider,\n $animateCss: AnimateCssProvider,\n $$animateCssDriver: AnimateCssDriverProvider,\n $$animateJs: AnimateJsProvider,\n $$animateJsDriver: AnimateJsDriverProvider,\n $$animateCache: AnimateCacheProvider,\n $$animateQueue: AnimateQueueProvider,\n $controller: ControllerProvider,\n $cookie: CookieProvider,\n $exceptionHandler: ExceptionHandlerProvider,\n $filter: FilterProvider,\n $interpolate: InterpolateProvider,\n $http: HttpProvider,\n $httpParamSerializer: HttpParamSerializerProvider,\n $location: LocationProvider,\n $log: LogProvider,\n $parse: ParseProvider,\n $$rAFScheduler: RafSchedulerProvider,\n $rest: RestProvider,\n $rootScope: RootScopeProvider,\n $router: Router,\n $sce: SceProvider,\n $sceDelegate: SceDelegateProvider,\n $sse: SseProvider,\n $templateCache: TemplateCacheProvider,\n $templateRequest: TemplateRequestProvider,\n $urlConfig: UrlConfigProvider,\n $view: ViewService,\n $transitions: TransitionProvider,\n $state: StateProvider,\n $viewScroll: ViewScrollProvider,\n $templateFactory: TemplateFactoryProvider,\n $url: UrlService,\n $stateRegistry: StateRegistryProvider,\n $eventBus: PubSubProvider,\n });\n },\n ],\n )\n .factory(\"$stateParams\", [\n $t.$router,\n /**\n * @param {import('./router/router.js').Router} globals\n * @returns {import('./router/params/state-params.js').StateParams }\n */\n (globals) => globals.params,\n ])\n .value(\"$trace\", trace);\n}\n"],"names":["VALID_CLASS","INVALID_CLASS","PRISTINE_CLASS","DIRTY_CLASS","UNTOUCHED_CLASS","TOUCHED_CLASS","EMPTY_CLASS","PREFIX_REGEXP","ALIASED_ATTR","ngMinlength","ngMaxlength","ngMin","ngMax","ngPattern","ngStep","NodeType","Node","ELEMENT_NODE","DOCUMENT_NODE","TEXT_NODE","COMMENT_NODE","DOCUMENT_FRAGMENT_NODE","isProxy","value","isProxySymbol","uid$1","lowercase","string","isString","toLowerCase","isArrayLike","obj","isNumber","length","item","isUndefined","isDefined","isArray","array","Array","isObject","isNull","isNullOrUndefined","notNullOrUndefined","isDate","toString","call","Error","isFunction","isRegExp","isWindow","window","isScope","$watch","isBoolean","isPromiseLike","then","trim","snakeCase","name","separator","replace","letter","pos","modseparator","baseExtend","dst","objs","deep","i","ii","j","jj","keyList","src","key","valueOf","cloneNode","hashkey","$$hashKey","extend","isNumberNaN","num","Number","isNaN","inherit$1","parent","extra","Object","create","hasCustomToString","getNodeName","element","nodeName","includes","prototype","indexOf","splice","index","simpleCompare","val1","val2","equals$1","o1","equals","o2","getTime","keySet","assertNotHasOwnProperty","context","ngMinErr","ngMinErr$1","stringify$1","toJson","concat","array1","slice","array2","sliceArgs","args","startIndex","bind","fn","RegExp","curryArgs","arguments","apply","toJsonReplacer","charAt","val","undefined","document","pretty","JSON","stringify","parseKeyValue","keyValue","split","forEach","splitPoint","substring","hasOwn","push","toKeyValue","entries","arrayValue","parts","encodeUriQuery","join","tryDecodeURIComponent","decodeURIComponent","encodeUriSegment","pctEncodeSpaces","encodeURIComponent","shallowCopy","startsWith","assert","argument","errorMsg","assertArg","arg","reason","assertArgFn","acceptArrayAnnotation","constructor","minErrConfig","objectMaxDepth","urlErrorParamsEnabled","errorHandlingConfig","config","maxDepth","NaN","minErr","module","copyObj","seen","message","template","match","templateArgs","hashKey","objType","nextUid","mergeClasses","firstClass","secondClass","normalizeStringArray","arr","trimmed","cleaned","directiveNormalize","SPECIAL_CHARS_REGEXP","offset","toUpperCase","hasAnimate","node","attr","nodeType","dataset","getAttribute","hasCustomOrDataAttribute","isObjectEmpty","keys","hasOwnProperty","callBackAfterFirst","calledOnce","wait","timeout","Promise","resolve","setTimeout","str","search","async","imports","instance","WebAssembly","instantiateStreaming","res","clone","exports","ASTType","ADD_CLASS_SUFFIX","REMOVE_CLASS_SUFFIX","ACTIVE_CLASS_SUFFIX","NG_ANIMATE_CLASSNAME","NG_ANIMATE_CHILDREN_DATA","TRANSITION_PROP","TRANSITIONEND_EVENT","ANIMATION_PROP","ontransitionend","onwebkittransitionend","onanimationend","onwebkitanimationend","ANIMATIONEND_EVENT","DURATION_KEY","DELAY_KEY","TIMING_KEY","ANIMATION_DELAY_PROP","ANIMATION_DURATION_PROP","TRANSITION_DELAY_PROP","pendClasses","classes","fix","isPrefix","klass","className","extractElementNode","elm","prepareAnimationOptions","options","$$prepared","domOperation","applyAnimationStyles","applyAnimationFromStyles","applyAnimationToStyles","from","assign","style","to","mergeAnimationDetails","newAnimation","existing","toAdd","toRemove","splitClassesToLookup","flags","addClass","removeClass","cls","prop","allow","resolveElementClasses","newOptions","preparationClasses","target","concatWithSpace","oldAnimation","blockKeyframeAnimations","applyInlineStyle","styleTuple","a","b","BOOLEAN_ATTR","BOOLEAN_ELEMENTS","fnCamelCaseReplace","_all","kebabToCamel","DASH_LOWERCASE_REGEXP","snakeToCamel","UNDERSCORE_LOWERCASE_REGEXP","removeElementData","expandoStore","data","Cache","expandoId","EXPANDO","removeIfEmptyData","getExpando","createIfNecessary","elId","set","isTextNode","html","test","elementAcceptsData","dealoc","onlyDescendants","cleanElementData","querySelectorAll","innerHTML","getOrSetCacheData","isSimpleSetter","isSimpleGetter","setCacheData","parentElement","getCacheData","getScope","SCOPE_KEY","setScope","scope","setIsolateScope","getController","getInheritedData","documentElement","parentNode","host","removeElement","keepData","removeChild","startingTag","elementOrStr","body","firstChild","divWrapper","appendChild","elemHtml","_match","getBlockNodes","nodes","endNode","nextSibling","blockNodes","getBooleanAttrName","normalizedName","getInjector","htmlString","content","childNodes","emptyElement","replaceChildren","domInsert","afterElement","afterNode","previousSibling","after","prepend","animatedomInsert","visibility","position","pointerEvents","requestAnimationFrame","originalVisibility","originalPosition","originalPointerEvents","getBaseHref","href","$injectTokens","freeze","$attrs","$scope","$element","$$animateCache","$$animateCssDriver","$$animateJs","$$animateJsDriver","$$animateQueue","$$animation","$$rAFScheduler","$$taskTrackerFactory","$anchorScroll","$animate","$animateCss","$aria","$compile","$cookie","$controller","$document","$eventBus","$exceptionHandler","$filter","$http","$httpParamSerializer","$interpolate","$location","$log","$viewScroll","$parse","$rest","$rootScope","$rootElement","$router","$sce","$sceDelegate","$state","$stateRegistry","$sse","$$sanitizeUri","$$sanitizeUriProvider","$templateCache","$templateFactory","$templateRequest","$transitions","$urlConfig","$url","$view","$window","$provide","$injector","$compileProvider","$animateProvider","$filterProvider","$controllerProvider","provider","services","map","x","stringifyFn","Function","annotate","strictDi","$inject","$injectorMinErr$3","argDecl","fnText","ARROW_ARG","FN_ARGS","extractArgs","FN_ARG","_underscore","injName","last","AbstractInjector","this","cache","path","modules","get","serviceName","$injectorMinErr","INSTANTIATING","$injectorMinErr$2","unshift","factory","err","injectionArgs","locals","invoke","self","instantiate","type","ctor","loadNewModules","_serviceName","ProviderInjector","super","caller","InjectorService","providerInjector","$get","has","hasProvider","providerSuffix","providerSuffix$1","hasCache","storage","saved","deserialize","Proxy","deleteProperty","deleted","head","filter","injectable","tail","isPromise","BADARG","reasons","Map","isInjectable","validate","v","String","TypeError","getReason","validateRequired","validateIsString","createInjector","supportObject","service","providerCache","constant","protoInstanceInjector","store","backendOrConfig","createPersistentProxy","sessionStorage","localStorage","getItem","raw","setItem","k","put","cookieOpts","removeItem","remove","serialize","backend","decorator","decorFn","origProvider","instanceInjector","$delegate","origInstance","$injectorProvider","mods","newProvider","$injectorMinErr$1","factoryFn","result","loadModules","moduleFn","angular","moduleRunBlocks","_requires","_invokeQueue","_configBlocks","invokeArgs","providerInstance","stack","delegate","urlResolve","url","urlParsingNode","URL","location","hostname","protocol","hash","port","pathname","urlsAreSameOrigin","url1","url2","trimEmptyHash","APPLICATION_JSON","serializeValue","toISOString","HttpParamSerializerProvider","params","sort","defaultHttpResponseTransform","headers","hasJsonContentType","jsonStart","JSON_ENDS","isJsonLike","tempData","json","parse","$httpMinErr","fillInParsed","parsed","line","headerKey","headerVal","headersGetter","headersObj","transformData","status","fns","isSuccess","Http","HttpProvider","defaults","transformRequest","isBlob","isFormData","common","Accept","post","CONTENT_TYPE_APPLICATION_JSON","patch","xsrfCookieName","paramSerializer","useApplyAsync","defineProperty","xsrfTrustedOrigins","origins","$t","that","interceptors","interceptorFactory","reversedInterceptors","urlIsAllowedOrigin","trustedOriginUrls","parsedAllowedOriginUrls","some","parsedUrl","urlIsAllowedOriginFactory","requestConfig","method","transformResponse","configParam","defHeaders","defHeaderName","reqHeaders","reqHeaderName","lowercaseDefHeaderName","header","headerFn","headerContent","processedHeaders","executeHeaderFns","interceptor","request","requestError","requestInterceptors","response","responseError","responseInterceptors","promise","chainInterceptors","reqData","withCredentials","serializedParams","defaultCache","cachedResp","resolvePromiseWithResult","resolvePromise","xsrfValue","getAll","xsrfHeaderName","callback","responseType","eventHandlers","uploadEventHandlers","xhr","setRequestHeader","completeRequest","getAllResponseHeaders","statusText","onerror","onabort","abortedByTimeout","handler","addEventListener","upload","timeoutRequest","abort","headersString","xhrStatus","timeoutId","clearTimeout","http","resolveHttpPromise","parseHeaders","delete","createApplyHandlers","eventHandler","applyHandlers","event","callEventHandler","reject","removePendingReq","idx","pendingRequests","sendReq","promiseParam","thenFn","rejectFn","resp","defineDirective","attrOverride","attrName","collectFormData","form","hasAttribute","formId","maybeForm","tagName","HTMLInputElement","HTMLTextAreaElement","HTMLSelectElement","formData","restrict","link","attrs","latch","$observe","dispatchEvent","Event","eventName","interval","intervalId","setInterval","parseInt","loading","$set","loadingClass","$removeClass","success","$res","go","stateSuccess","error","stateError","$eval","$merge","swap","scopeParam","attrsParam","elmenetParam","animate","animationEnabled","compiled","DocumentFragment","targetSelector","querySelector","replaceChild","frag","placeholder","display","leave","done","insertedNodes","enter","insertBefore","$flushQueue","textContent","reverse","handleSwapResponse","delay","throttle","throttled","$addClass","enctype","catch","ngSse","transformMessage","onOpen","onMessage","onError","onReconnect","count","$count","$on","info","source","close","clearInterval","directive","tag","ngWorkerDirective","workerName","worker","createWorkerConnection","logger","dataOnResult","$result","temp","insertAdjacentHTML","handleSwap","dataOnError","$error","scriptPath","autoRestart","autoTerminate","reconnect","terminated","cfg","terminate","Worker","wire","workerParam","onmessage","warn","postMessage","log","restart","NgModule","requires","configFn","_restDefinitions","object","run","component","providerFunction","serviceFunction","_services","providerType","directiveFactory","animation","animationFactory","filterFn","controller","ctlFn","wasm","instantiateWasm","rest","entityClass","NodeRef","static","Element","NodeList","_nodes","_isList","_node","_element","el","nodelist","fragment","dom","size","_getAny","_getAll","_collection","_getIndex","_setIndex","_clone","cloned","_isElement","controllers","register","expression","later","ident","$controllerMinErr","identifier","controllerPrototype","$controllerIdentifier","addIdentifier","$scopename","SCE_CONTEXTS","JS","adjustMatcher","matcher","$sceMinErr","trustedResourceUrlList","bannedResourceUrlList","htmlSanitizer","matchUrl","originUrl","baseURI","exec","generateHolderType","holderType","trustedValue","Base","$$unwrapTrustedValue","byType","HTML","trustedValueHolderBase","CSS","MEDIA_URL","RESOURCE_URL","trustAs","Constructor","getTrusted","maybeTrusted","allowed","SceProvider","enabled","sce","expr","literal","enumValue","createEventDirective","directiveName","compile","$event","removeEventListener","createWindowEventDirective","ngEventDirectives","Attributes","nodeRef","attributesToCopy","_$animate","_$exceptionHandler","l","$attr","$nodeRef","$$element","classVal","classList","add","$updateClass","newClasses","oldClasses","writeAttr","booleanKey","aliasedKey","observer","sanitizeSrcset","elem","removeAttribute","SIMPLE_ATTR_NAME","toggleAttribute","setAttribute","setSpecialAttr","$$observers","listeners","$$inter","arrayRemove","specialAttrHolder","attributes","removeNamedItem","attribute","setNamedItem","invokeType","$compileMinErr","$compileMinErr$1","nbrUrisWith2parts","_$sce","getTrustedMediaUrl","rawUris","innerIdx","lastTuple","tokenDifference","str1","str2","ngObserveDirective","normalized","MutationObserver","mutations","newValue","observe","attributeFilter","disconnect","CompileProvider","parseIsolateBindings","isController","scopeName","definition","bindingCache","bindings","mode","collection","optional","isolateScope","bindToController","getDirectiveRequire","require","len","entryList","getDirectiveRestrict","registerDirective","assertValidDirectiveName","hasDirectives","DirectiveSuffix","valueFn","priority","directives","makeInjectable","tElement","tAttrs","ddo","controllerAs","identifierForController","templateUrl","transclude","aHrefSanitizationTrustedUrlList","regexp","imgSrcSanitizationTrustedUrlList","strictComponentBindingsEnabled","addPropertySecurityContext","elementName","propertyName","ctx","PROP_CONTEXTS","registerContext","values","flushOnChangesQueue","onChangesQueue","denormalizeTemplate","startSymbol","endSymbol","transcludeFn","maxPriority","ignoreDirective","previousCompileContext","compositeLinkFn","compileNodes","cloneConnectFn","needsNewScope","$parent","$new","parentBoundTranscludeFn","$$boundTransclude","namespace","detectNamespaceForChildElements","futureParentElement","append","wrappedTemplate","wrapTemplate","$linkNode","transcludeControllers","controllerName","nodeRefList","collectDirectives","nodeLinkFnCtx","applyDirectivesToNode","parentNodeRef","ctxNodeRef","nodeLinkFn","terminal","childLinkFn","transcluded","transcludeOnThisElement","templateOnThisElement","linkFnsList","linkFnFound","nodeLinkFnFound","stableNodeList","stableLength","stable","childBoundTranscludeFn","createBoundTranscludeFn","childScope","previousBoundTranscludeFn","boundTranscludeFn","transcludedScope","cloneFn","containingScope","$transcluded","$$transcluded","slotName","$$slots","boundSlots","addDirective","isNgAttr","ngPrefixMatch","isNgProp","isNgEvent","isNgObserve","addPropertyDirective","nName","addAttrInterpolateDirective","text","interpolateFn","expressions","$target","nodeValue","addTextInterpolateDirective","compilationGenerator","eager","compileNode","templateAttrs","originalReplaceDirective","preLinkFns","postLinkFns","newScopeDirective","controllerDirectives","newIsolateScopeDirective","templateDirective","nonTlbTranscludeDirective","hasElementTranscludeDirective","compileNodeRef","linkNode","$newIsolate","controllerScope","newTrancludeFn","cloneAttachFn","elementControllers","slotTranscludeFn","scopeToChild","isSlotFilled","controllerKey","$$isolateScope","$transclude","controllerInstance","setupControllers","$$isolateBindings","scopeBindingInfo","initializeDirectiveBindings","removeWatches","controllerDirective","bindingInfo","getControllers","$onChanges","initialChanges","$onInit","$onDestroy","preLinkFn","postLinkFn","$postLink","terminalPriority","directiveValue","assertNoDuplicate","hasReplacedTemplate","shouldTransclude","didScanForMultipleTransclusion","candidateDirective","EXCLUDED_DIRECTIVES","mightHaveMultipleTransclusionError","$template","createComment","replaceWith","childTranscludeFn","replaceDirective","elementSelector","filledSlots","slotMap","slots","filled","slotCompileNodes","$$newScope","hasTemplate","removeComments","templateNamespace","createNodelistFromHTML","templateDirectives","newTemplateAttrs","unprocessedDirectives","markDirectiveScope","compileTemplateUrl","hasTranscludeDirective","linkFn","addLinkFns","pre","Math","max","newScope","cloneAndAnnotateFn","inheritType","dataName","property","inherit","tDirectives","$$bindings","mergeTemplateAttributes","srcAttr","dstAttr","$compileNode","derivedSyncDirective","origAsyncDirective","$$originalDirective","tempTemplateAttrs","afterTemplateNodeLinkFnCtx","afterTemplateChildLinkFn","$$destroyed","beforeTemplateLinkNode","beforeTemplateCompileNode","afterTemplateNodeLinkFn","linkQueue","isError","_ignoreChildLinkFn","rootElement","diff","what","previousDirective","wrapper","propName","trustedContext","sanitizer","_","applyPropValue","propValue","attrNormalizedName","mustHaveExpression","allOrNothing","outerHTML","$$scope","newInterpolatedValue","elementsToRemove","newNode","oldChild","annotation","destination","recordChanges","currentValue","initial","$postUpdate","changes","triggerOnChangesHook","firstChange","strictBindingsCheck","removeWatch","firstCall","lastValue","removeWatchCollection","compare","parentGet","parentSet","parentValueWatch","parentValue","inputs","$handler","watchFn","listenerFn","jqNodes","nullFormCtrl","$nonscope","$addControl","$getControls","$$renameControl","control","$name","$removeControl","$setValidity","$setDirty","$setPristine","$setSubmitted","$$setSubmitted","PENDING_CLASS","FormController","$pristine","$valid","$invalid","$submitted","$$animate","$$success","$pending","$$classCache","isValid","$rollbackViewValue","$$controls","$commitViewValue","$$parentForm","newName","oldName","$dirty","setClass","SUBMITTED_CLASS","$setUntouched","rootForm","list","unset","validationErrorKey","state","cachedToggleClass","ctrl","switchValue","validationErrorKeyParam","controllerParam","createAndSet","unsetAndCleanup","toggleValidationCss","combinedState","formDirectiveFactory","isNgForm","formElement","nameAttr","ngForm","formElementParam","attrParam","ctrls","handleFormSubmission","preventDefault","setter","formDirective","NgModelOptionsController","$$attrs","parentCtrl","parentOptions","$options","modelOptionsDefinition","ngModelOptions","createChild","ModelOptions","$$options","getOption","option","inheritAll","updateOnDefault","DEFAULT_REGEXP","defaults$1","defaultModelOptions","updateOn","debounce","getterSetter","allowInvalid","ngModelOptionsDirective","NgModelController","$modelValue","$$updateEvents","$$parsedNgModel","ngModel","$$ngModelGet","$$ngModelSet","$$parsedNgModelAssign","$$pendingDebounce","$$attr","$$parse","modelValue","$$setModelValue","$$initGetterSetters","invokeModelGetter","invokeModelSetter","$$$p","ngModelMinErr","$render","$isEmpty","$$updateEmptyClasses","NOT_EMPTY_CLASS","$touched","$setTouched","$viewValue","$$lastCommittedViewValue","$validate","$$runValidators","viewValue","allValid","prevValid","prevModelValue","$$writeModelToScope","doneCallback","$$currentValidationRunId","setValidity","validationDone","localValidationRunId","$$parserValid","errorKey","$validators","$asyncValidators","processParseErrors","validator","syncValidatorsValid","processSyncValidators","validatorPromises","all","$$hasNativeValidators","$$parseAndValidate","$$parserName","$parsers","writeToModelIfNeeded","$viewChangeListeners","listener","$$exceptionHandler","$setViewValue","trigger","$$debounceViewValueCommit","debounceDelay","default","$overrideModelOptions","$$removeAllEventListeners","$$setUpdateOnEvents","$processModelValue","$$format","formatters","$$rawModelValue","$$eventRemovers","removeCallback","clear","ev","$$updateEventHandler","ngModelDirective","modelCtrl","optionsCtrl","deregisterWatch","elementPost","_attr","change","ISO_DATE_REGEXP","URL_REGEXP","EMAIL_REGEXP","DATETIMELOCAL_REGEXP","PARTIAL_VALIDATION_TYPES","inputType","baseInputType","stringBasedInputType","date","createDateInputType","DATE_REGEXP","createDateParser","time","TIME_REGEXP","week","WEEK_REGEXP","isoWeek","existingDate","lastIndex","year","Date","dayOfWeekOnFirst","hours","getHours","minutes","getMinutes","seconds","getSeconds","milliseconds","getMilliseconds","firstThurs","getDate","addDays","month","MONTH_REGEXP","number","badInputChecker","numberFormatterParser","min","parsedMinVal","minVal","parseNumberAttrVal","parsedMaxVal","maxVal","step","parsedStepVal","isValidForStep","stepVal","email","radio","checked","doTrim","deproxy","range","setInitialValueAndObserver","htmlAttrName","changeFn","oldVal","supportsRange","validity","rangeUnderflow","rangeOverflow","originalRender","elVal","stepMismatch","checkbox","trueValue","parseConstantExpr","ngTrueValue","falseValue","ngFalseValue","hidden","button","submit","reset","file","$formatters","composing","ngTrim","badInput","origBadInput","typeMismatch","origTypeMismatch","iso","previousDate","yyyy","getFullYear","MM","getMonth","dd","HH","mm","ss","sss","part","mapping","setFullYear","parseDate","parseDateAndConvertTimeZoneToLocal","isValidDate","parseObservedDateValue","previousDateParam","parsedDate","timezone","fallback","requestedTimezoneOffset","newDate","addDateMinutes","timezoneOffset","dateTimezoneOffset","convertTimezoneToLocal","parserName","parseFloat","isNumberInteger","countDecimals","decimalSymbolIndex","numString","stepBase","isNonIntegerValue","isNonIntegerStepBase","valueDecimals","stepBaseDecimals","stepDecimals","multiplier","isNonIntegerStep","round","parseFn","inputDirective","valueProperty","configurable","enumerable","_scope","ngValueDirective","updateElementValue","tplAttr","ngValue","scriptDirective","id","innerText","SelectController","renderUnknownOption","unknownOption","unknownVal","selected","updateUnknownOption","generateUnknownOptionValue","removeUnknownOption","selectEmptyOption","emptyOption","unselectEmptyOption","hasEmptyOption","readValue","hasOption","realVal","writeValue","currentlySelectedOption","hashedVal","selectValueMap","selectedOption","selectUnknownOrEmptyOption","addOption","optionsMap","scheduleRender","removeOption","$hasEmptyOption","$isUnknownOptionSelected","$isEmptyOptionSelected","selectedIndex","renderScheduled","ngModelCtrl","scheduleViewValueUpdate","renderAfter","updateScheduled","registerOption","optionScope","optionElement","optionAttrs","interpolateValueFn","interpolateTextFn","newVal","removal","previouslySelected","multiple","removeValue","selectDirective","selectCtrl","disabled","shouldBeSelected","lastViewRef","lastView","_attrs","optionDirective","elemParam","ngBindDirective","lazy","ngBindTemplateDirective","ngBindHtmlDirective","_tElement","ngBindHtml","classDirective","selector","digestClassCounts","classArray","classCounts","classesToUpdate","newModulo","classString","$index","oldClassString","removeClasses","oldModulo","newClassString","toClassString","oldClassStringParam","toAddString","toRemoveString","updateClasses","arrayDifference","tokens2","outer","tokens1","token","classValue","ngClassDirective","ngClassOddDirective","ngCloakDirective","ngControllerDirective","ngShowDirective","ngShow","NG_HIDE_CLASS","tempClasses","NG_HIDE_IN_PROGRESS_CLASS","ngHideDirective","ngHide","ngIfDirective","_ctrl","ngIf","previousElements","block","nextElementSibling","ngIncludeDirective","_$attr","maybeScroll","autoScrollExp","cleanupLastIncludeContent","previousElement","currentScope","currentElement","srcExp","afterAnimation","changeCounter","cloneParam","onloadExp","$emit","ngIncludeFillContentDirective","ngInitDirective","ngInit","ngNonBindableDirective","ngRefDirective","getter","ngRefMinErr","ngRef","ngRefRead","refValue","VAR_OR_TUPLE_REGEX","updateScope","valueIdentifier","keyIdentifier","arrayLength","$first","$last","$middle","$odd","$even","getBlockStart","getBlockEnd","trackByIdArrayFn","_$scope","_key","trackByIdObjFn","_$element","ngRepeatMinErr","lhs","aliasAs","called","callBackOnce","rhs","previousNode","trackById","trackByIdFn","collectionKeys","itemKey","collectionLength","lastBlockMap","nextBlockMap","nextBlockOrder","blockKey","NG_REMOVED","$destroy","nextNode","move","ngStyleDirective","newStyles","oldStyles","removeProperty","setProperty","ngSwitchDirective","cases","ngSwitchController","spliceFactory","watchExpr","previousLeaveAnimations","cancel","pop","selectedScopes","selectedElements","selectedTranscludes","selectedTransclude","selectedScope","caseElement","comment","anchor","ngSwitchWhenDirective","ngSwitchWhen","ngSwitchWhenSeparator","elementParam","whenCase","ngSwitchDefaultDirective","NG_OPTIONS_REGEXP","ngOptionsDirective","selectElement","children","ngOptions","optionsExp","ngOptionsMinErr","getTrackByValueFn","trackBy","trackByFn","getTrackByValue","getLocals","keyName","Option","selectValue","label","group","getOptionValuesKeys","optionValues","optionValuesKeys","getWatchables","valuesFn","optionValuesLength","watchedArray","disableWhen","getOptions","optionItem","optionItems","items","getOptionFromViewValue","getViewValueFromOption","structuredClone","parseOptionsExpression","selectedOptions","selectedValues","selections","providedEmptyOption","optionEl","needsRerender","addOptionElement","optionTemplate","updateOptionElement","decoratedNode","groupElement","optGroupTemplate","groupElementMap","listFragment","previousValue","nextValue","ngTranscludeDirective","_controller","ngTranscludeMinErr","ngTransclude","useFallbackContent","fallbackLinkFn","defaultLinkFn","ngAttributeAliasDirectives","ngAttr","_elm","ngRequired","required","_modelValue","_Elm","tAttr","REGEX_STRING_REGEXP","attrVal","patternExp","pattern","oldRegexp","maxlength","maxlengthParsed","parseLength","minlengthParsed","minlength","parsePatternAttr","regex","intVal","autoScrollingEnabled","getBoundingClientRect","bottom","scrollBy","elemTop","scrollTo","scroll","getHash","getElementById","getFirstAnchor","getElementsByName","readyState","queueMicrotask","action","prepareAnimateOptions","AnimateProvider","$animateMinErr","$$registeredAnimations","customFilter","classNameFilter","runner","exception","filterFilter","comparator","anyPropertyKey","getTypeForFilter","predicateFn","matchAgainstAnyProp","actual","expected","deepCompare","createPredicateFn","dontMatchWholeObject","expectedType","actualType","expectedVal","matchAnyProperty","jsonFilter","spacing","limitToFilter","input","limit","begin","abs","Infinity","sliceFn","end","orderByFilter","sortPredicate","reverseOrder","compareFn","predicate","descending","tieBreaker","predicateValues","predicates","isPrimitive","objectValue","getPredicateValue","compareValues","v1","v2","defaultCompare","type1","type2","value1","value2","isFilter","includesFilter","FilterProvider","limitTo","orderBy","isState","$IsStateFilter","includedByState","$IncludedByStateFilter","SUFFIX","ASTInterpreter","ast","assignable","isAssignable","left","right","operator","assignableAST","recurse","candidate","lastExpression","toWatch","watch","isPure","watchId","exp","alternate","consequent","computed","computedMember","nonComputedMember","elements","properties","$proxy","base","findConstantAndWatchExpressions","parentIsPure","decoratedLeft","decoratedRight","decoratedTest","decoratedAlternate","decoratedConsequent","decoratedObject","decoratedProperty","allConstants","decorated","astIsPure","isStatelessFilter","$stateful","isStateless","callee","argsToWatch","decoratedKey","ESCAPE","n","f","r","t","OPERATORS","Set","Lexer","_options","_lex","_text","_index","ch","_readString","_isNumber","_peek","_readNumber","_isIdentifierStart","_peekMultichar","_readIdent","_is","_tokens","_isWhitespace","op1","op2","op3","_throwError","chars","isIdentifierStart","_codePointAt","_isIdentifierContinue","isIdentifierContinue","charCodeAt","cp1","cp2","peek","_isExpOperator","start","colStr","$parseMinErr$1","peekCh","quote","escape","_handleUnicodeEscape","hex","fromCharCode","literals","true","false","null","AST","lexer","_lexer","_selfReferential","$locals","_ast","_program","hasMore","_expressionStatement","_filterChain","_expect","_filter","_assignment","$parseMinErr","_ternary","_consume","_logicalOR","_logicalAND","_equality","_relational","_additive","_multiplicative","_unary","prefix","_primary","primary","_arrayDeclaration","_object","_identifier","_constant","next","_parseArguments","baseExpression","_peekToken","msg","e1","txt","Parser","_astCompiler","_parse","getAst","setIdentifierFns","identifierStart","identifierContinue","identStart","identContinue","interceptorFn","cacheKey","addWatchDelegate","parsedExpression","addInterceptor","$$interceptor","first","second","chainedInterceptor","$$intercepted","useInputs","oneTime","$$pure","constantWatchDelegate","objectEquality","unwatch","$$watchDelegate","inputsWatchDelegate","inputExpressions","expressionInputDirtyCheck","newInputValue","oldInputValueOf","inputExpression","lastResult","getValueOf","oldValueOfValue","compareObjectIdentity","interr","$interpolateMinErr","escapedStartRegexp","escapedEndRegexp","unescapeText","contextAllowsConcatenation","unescapedText","constantInterp","textLength","endIndex","startSymbolLength","endSymbolLength","expressionPositions","singleExpression","throwNoconcat","cb","watchProp","vals","compute","parseFns","oldValues","currValue","Location","appBase","appBaseNoFile","html5","$$updateBrowser","setUrl","setPath","setSearch","getUrl","$$url","$$path","newPath","getPath","setHash","$$hash","paramValue","$$search","$locationMinErr","getSearch","$$compose","pathValue","hashValue","decodedSegment","segments","normalizePath","absUrl","hashPrefix","urlUpdatedByLocation","setState","$$state","getState","parseLinkUrl","relHref","appUrl","stripBaseUrl","rewrittenUrl","basePrefix","prevAppUrl","stripHash","pathUrl","removeWindowsDriveName","urlParam","firstPathSegmentMatch","withoutBaseUrl","withoutHashUrl","html5ModeConf","requireBase","rewriteLinks","urlChangeListeners","cachedState","lastHistoryState","lastBrowserUrl","cacheState","history","pushState","getBrowserUrl","currentState","lastCachedState","fireStateOrUrlChange","prevLastHistoryState","onUrlChange","urlChangeInit","slashIndex","serverBase","initialUrl","baseHref","lastIndexOf","hashPrefixConf","oldState","ctrlKey","metaKey","shiftKey","absHref","animVal","defaultPrevented","newState","newUrl","$broadcast","oldUrl","setBrowserUrlWithFallback","initializing","afterLocationChange","updateBrowser","urlOrStateChanged","y","normalizeUrl","parseAppUrl","html5Mode","prefixed","decodePath","endsWith","LogProvider","debug","_override","setLogger","formatError","sourceURL","consoleLog","logFn","console","formattedArgs","rootScope","createScope","exceptionHandler","NONSCOPE","global","frames","Window","Document","EventTarget","HTMLCollection","toString$1","wStr","ctorNonScope","proxy","Scope","uid","$root","propertyMap","$apply","$isRoot","isRoot","$getById","$searchByName","$children","$id","oldValue","scheduleListener","foreignListeners","objectListeners","checkeListenersForAllKeys","currentListeners","foreignProxies","watchers","jl","keyListeners","expectedTarget","lengthListeners","propListeners","scheduled","expectedHandler","wrapperExpr","originalTarget","model","child","ids","scopeId","filteredListeners","foreignListener","notifyListener","registerKey","deregisterKey","potentialProxy","registerForeignKey","currentKey","listenerObject","childInstance","getPrototypeOf","setPrototypeOf","parentInstance","listenerList","namedListeners","$$listeners","eventHelper","broadcast","targetScope","stopped","stopPropagation","currentLength","$postUpdateQueue","shift","found","getByName","nameParam","TemplateRequestProvider","httpOptions","handleRequestFn","tpl","ignoreRequestError","transformer","finally","totalPendingRequests","$templateRequestMinErr","_aHrefSanitizationTrustedUrlList","_imgSrcSanitizationTrustedUrlList","uri","isMediaUrl","normalizedVal","NgMessageCtrl","latestKey","nextAttachId","messages","renderLater","ngMessages","for","render","getAttachId","isAttrTruthy","ngMessagesMultiple","totalMessages","messageFound","messageUsed","messageCtrl","matchedKeys","attach","unmatchedMessages","messageItem","detach","attachDefault","messageMatched","ACTIVE_CLASS","INACTIVE_CLASS","reRender","cachedCollection","isDefault","nextKey","insertMessageNode","$$ngMessageNode","deregister","findPreviousMessage","prevNode","prevKey","parentLookup","messageNode","removeMessageNode","ngMessagesDirective","truthy","ngMessagesIncludeDirective","contents","ngMessageDirective","ngMessageDirectiveFactory","ngMessageExpDirective","ngMessageDirectiveFn","ngMessagesCtrl","commentNode","staticExp","ngMessage","when","records","dynamicExp","assignRecords","contains","$$attachId","nativeAriaNodeNames","isNodeOneOf","nodeTypeArray","ariaHidden","ariaChecked","ariaReadonly","ariaDisabled","ariaRequired","ariaInvalid","ariaValue","tabindex","bindKeydown","bindRoleForClick","ariaAttr","nativeAriaNodeNamesParam","negate","ariaCamelName","boolVal","newConfig","$$watchExpr","ngDisabledAriaDirective","ngShowAriaDirective","ngMessagesAriaDirective","ngClickAriaDirective","ngKeydown","ngKeypress","ngKeyup","keyCode","ngRequiredAriaDirective","ngCheckedAriaDirective","ngValueAriaDirective","ngHideAriaDirective","ngReadonlyAriaDirective","ngModelAriaDirective","shouldAttachAttr","normalizedAttr","allowNonAriaNodes","shouldAttachRole","role","attrPost","needsTabIndex","shape","needsAriaValuemin","needsAriaValuemax","needsAriaValuenow","ngDblclickAriaDirective","flush","queue","tasks","schedule","AnimateRunner","_chain","runners","ok","remaining","_schedule","setHost","_host","_state","_doneCallbacks","progress","pause","resume","_finish","complete","getPromise","_promise","onFulfilled","onRejected","onFinally","callbacks","DETECT_CSS_PROPERTIES","transitionDuration","TRANSITION_DURATION_PROP","transitionDelay","transitionProperty","animationDuration","animationDelay","animationIterationCount","DETECT_STAGGER_CSS_PROPERTIES","isKeyframeAnimation","formalStyleName","char","maxValue","parseMaxTime","styles","actualStyleName","truthyTimingValue","getCssTransitionDurationStyle","duration","applyOnlyDuration","backup","getPropertyValue","AnimateCssProvider","waitUntilQuiet","rafWaitQueue","_waitUntilQuiet","pageWidth","computeTimings","allowNoDuration","timings","hasDuration","computeCachedCssStyles","maxDelay","aD","tD","initialOptions","$$skipPreparationClasses","closeAndReturnNoopAnimator","isStructural","structuralClassName","addRemoveClassName","applyClassesEarly","applyAnimationClasses","hasToStyles","containsCachedAnimationWithoutDuration","stagger","staggerVal","staggerClassName","staggerCacheKey","computeCachedCssStaggerStyles","temporaryStyles","transitionStyle","durationStyle","keyframeStyle","itemIndex","staggerIndex","isFirst","skipBlocking","blockTransitions","relativeDelay","hasTransitions","hasAnimations","hasTransitionAll","applyTransitionDuration","applyAnimationDuration","applyTransitionDelay","applyAnimationDelay","maxDuration","delayStyle","getCssDelayStyle","recalculateTimingStyles","maxDelayTime","ONE_SECOND","blockTransition","blockKeyframeAnimation","cleanupStyles","registerRestorableStyles","restoreStyles","applyBlocking","$$willAnimate","endFn","runnerHost","cancelFn","rejected","animationClosed","animationCompleted","animationPaused","activeClasses","entry","onDone","events","onAnimationProgress","animationTimerData","ANIMATE_TIMER_KEY","elapsedTime","toFixed","startTime","playPause","playAnimation","removeFromArray","maxStagger","triggerAnimationStart","easing","easeProp","easeVal","now","timerTime","setupFallbackTimer","currentTimerData","timer","animationsData","expectedEndTime","endTime","floor","AnimateQueueProvider","rules","skip","getEventData","hasMatchingClasses","currentClassString","currentClassMap","isAllowed","ruleType","currentAnimation","previousAnimation","hasAnimationClasses","and","structural","nA","nR","cA","cR","isAnimatableClassName","returnTrue","normalizeAnimationDetails","filterFromRegistry","matchContainer","containerNode","phase","off","on","container","callbackRegistry","eventType","pin","NG_ANIMATE_PIN_DATA","originalElement","postDigestCalled","isAnimatableByFilter","skipAnimations","existingAnimation","hasExistingAnimation","parentHost","rootNodeDetected","rootNode","parentAnimationDetected","parentNodeDisabled","elementDisabled","details","animateChildren","bodyNodeDetected","bodyNode","areAnimationsAllowed","animationDetails","activeAnimationsLookup","closeChildAnimations","applyGeneratedPreparationClasses","isValidAnimation","markElementAnimationState","isCurrentAnimationValid","animationCancelled","counter","clearElementAnimationState","realRunner","notifyProgress","runnerParam","eventParam","runInNextPostDigestOrNow","targetParentNode","targetNode","matches","cleanupEventListeners","clearGeneratedClasses","queueAnimation","NG_ANIMATE_ATTR_NAME","AnimateJsProvider","flagMap","beforeFn","afterFn","before","packageAnimations","animations","runnerBefore","chain","runnerApplyOptions","applyOptions","runnerAfter","endAnimations","onComplete","cancelled","groupEventedAnimations","optionsParam","animationsParam","fnName","operations","newRunner","onAnimationComplete","endProgressCb","classesToAdd","classesToRemove","executeAnimationFn","resolved","animateFn","AnimationProvider","getRunner","RUNNER_STORAGE_KEY","PREPARE_CLASSES_KEY","animationQueue","beforeStart","prepareClassName","$$domOperationFired","anchorNodes","NG_ANIMATE_REF_ATTR","nodeItem","anchors","getAnchorNodes","refLookup","direction","animationID","preparedAnimations","usedIndicesLookup","indexKey","anchorGroups","lookupKey","fromAnimation","toAnimation","cssClassesIntersection","out","in","groupedAnimations","animationEntry","fromElement","extraClasses","toBeSortedAnimations","domNode","drivers","driver","operation","startAnimationFn","animationRunner","closeFn","update","updateAnimationRunners","lookup","processNode","theeParam","remainingLevelEntries","nextLevelEntries","row","childEntry","processed","parentEntry","finalAnimations","innerArray","aa","deleteCacheData","_cancelFn","_nextTick","scheduler","_queue","cancelAnimationFrame","animateCache","total","AnimateCacheProvider","$$animationProvider","rootBodyElement","outAnchor","inAnchor","NG_ANIMATE_SHIM_CLASS_NAME","animator","NG_OUT_ANCHOR_CLASS_NAME","calculateAnchorStyles","animatorOut","animatorIn","scrollTop","scrollLeft","getClassVal","anchorAnimations","animationRunners","runnerItem","prepareFromToAnchorAnimation","prepareRegularAnimation","filterCssClasses","getUniqueValues","endFnFactory","prepareAnimation","ngAnimateSwapDirective","previousScope","$$AnimateChildrenDirective","setData","t1","a1","a2","tup","newObj","removeFrom","opts","defaultsList","defaultVals","pick","propNames","_prop","objCopy","omit","reduce","acc","accept","find","AnimateCssDriverProvider","AnimateJsDriverProvider","allTrueR","memo","anyTrueR","unnestR","pushR","uniqR","maxArrayLen","MAX_SAFE_INTEGER","applyPairs","keyValTuple","dest","silenceUncaughtInPromise","silentRejection","curry","curried","nextArgs","propEq","_val","is","struct","ParamType","def","encode","decode","$subPattern","sub","$normalize","$asArray","ArrayType","arrayWrap","arrayHandler","allTruthyMode","arrayUnwrap","arrayEqualsHandler","wrapperFn","paramTypeFn","dynamic","$arrayMode","enqueue","typeQueue","defaultTypes","ParamTypes","types","definitionFn","_flushTypeQueue","makeDefaultType","valToString","defaultTypeBase","query","int","bool","Boolean","capture","any","paramTypes","_isCaseInsensitive","_isStrictMode","_defaultSquashPolicy","pathType","caseInsensitive","defaultSquashPolicy","strictMode","StateParams","$inherit","$current","$to","parents","ancestors","inherited","parentParamsKeys","parentParams","inheritList","newParams","Queue","_evictListeners","onEvict","_limit","_items","evict","dequeue","cleared","peekTail","peekHead","transition","maxLength","DOTS","functionToString","toStr","fnToString","_fn","stringifyPattern","reg","_transitionRejection","format","joinNeighborsR","ngViewString","ngView","creationContext","fqn","normalizedCat","Category","_RESOLVE","_TRANSITION","_HOOK","_UIVIEW","_VIEWCONFIG","_enabled","approximateDigests","$logger","_set","categories","category","enable","disable","traceTransitionStart","trans","transLbl","traceTransitionIgnored","traceHookInvocation","traceHookResult","hookResult","traceResolvePath","traceResolvableResolved","resolvable","traceError","traceSuccess","finalState","traceUIViewEvent","viewData","padString","traceUIViewConfigUpdated","traceUIViewFill","traceViewSync","pairs","viewConfig","uivheader","uiv","cfgheader","table","traceViewServiceEvent","view","$ngViewName","$ngViewContextAnchor","viewConfigString","traceViewServiceUIViewEvent","Resolvable","arg1","resolveFn","deps","policy","getPolicy","thisPolicy","statePolicy","resolveContext","getDependencies","resolvedDeps","customAsyncPolicy","resolvedValue","fromData","TargetState","_stateRegistry","_params","_definition","relative","exists","valid","stateName","withState","withParams","withOptions","newOpts","isDef","Param","urlConfig","paramName","noReloadOnSearch","reloadOnSearch","paramConfig","getStaticDefaultValue","isShorthand","$$fn","unwrapShorthand","defaultConfig","urlType","getType","arrayDefaults","arrayParamNomenclature","arrayMode","isOptional","squash","defaultPolicy","getSquashPolicy","configuredKeys","isDefaultValue","tuple","defaultValue","__cacheable","_defaultValueCache","getDefaultValue","isSearch","validates","encoded","paramValues","param","changed","values1","values2","PathNode","stateOrNode","paramSchema","resolvables","views","parameters","applyRawParams","pDef","paramDef","parameter","paramsFn","PathUtils","targetState","toParams","buildToPath","fromPath","inheritParams","toPath","applyViewConfigs","states","viewConfigs","viewDecls","createViewConfig","subPath","toKeys","noInherit","toNode","toParamVals","fromParamVals","nodeParamVals","ownParamVals","incomingParamVals","treeChanges","reloadState","nodesMatch","node1","node2","keep","retainedNode","retained","retainedWithToParams","exiting","entering","matching","pathA","pathB","nodeA","nodeB","elementIdx","nonDynamicParams","makeTargetState","registry","at","resolvePolicies","ResolveContext","_path","getTokens","getResolvable","subContext","addResolvables","newResolvables","resolvePath","matchedWhens","trace","matchesPolicy","acceptedVals","whenOrAsync","nodeResolvables","getResult","promises","findNode","fromInjector","hasAnyKey","ng1ViewsBuilder","compKeys","nonCompKeys","allViewKeys","resolveAs","$context","ViewConfig","normalizeUIViewTarget","ngViewName","ngViewContextAnchor","viewDecl","id$1","loaded","makeComponentTemplate","load","fromConfig","results","rawViewName","viewAtContext","relativeViewNameSugar","anchorState","_ngViews","_viewConfigs","_listeners","viewConfigFactory","templateFactory","getViewConfigFactory","rootViewContext","_rootContext","decl","cfgFactory","$type","deactivateViewConfig","activateViewConfig","sync","ngViewsByFqn","viewConfigDepth","depthCompare","depthFn","posNeg","configureUIView","configUpdated","stateDepth","ViewService","matchingConfigs","unmatchedConfigTuples","matchedViewConfigs","ngViewTuples","allTuples","registerUIView","ngViews","available","active","vcSegments","uivSegments","vc","ngViewContext","Rejection","detail","redirected","rejection","superseded","invalid","ignored","aborted","errored","toPromise","eventBus","EventBus","_disposed","isDisposed","dispose","_topics","subscribe","topic","unsubscribe","subscribeOnce","unsub","getCount","publish","snapshot","defaultOptions","current","traceData","TransitionHookScope","_STATE","TransitionHook","hooks","waitFor","prev","nextHook","invokeHooks","remainingHooks","runAllHooks","hook","invokeHook","stateContext","registeredHook","isSuperseded","hookPhase","isActive","logError","_deregistered","notCurrent","invokeCallback","handleResult","synchronous","normalizeErr","handleError","normalize","invokeLimit","invokeCount","handleHookResult","getNotCurrentRejection","HANDLE_RESULT","LOG_REJECTED_RESULT","LOG_ERROR","REJECT_ERROR","THROW_ERROR","Glob","fromString","hasGlobs","regexpString","seg","matchState","criterion","globStrings","glob","RegisteredHook","tranSvc","matchCriteria","removeHookFromRegistry","_matchingNodes","_getDefaultMatchCriteria","_getPathTypes","_getMatchingNodes","criteria","mn","pathtype","makeEvent","transitionService","_registeredHooks","hookRegistrationFn","matchObject","removeHookFn","HookBuilder","buildHooksForPhase","_getEvents","buildHooks","hookType","matchingHooks","getMatchingHooks","baseHookOptions","criteriaMatchPath","transitionHook","reverseDepthSort","depthDelta","tupleSort","isCreate","getHooks","predicateOrMap","errMsg","assertPredicate","Transition","globals","_deferred","withResolvers","_hookBuilder","_treeChanges","onCreateHooks","onStart","onBefore","onSuccess","onEnter","onRetain","onExit","onFinish","createTransitionHookRegFns","hookName","enteringStates","$from","_targetState","getResolveTokens","addResolvable","topath","redirectedFrom","originalTransition","rf","redirect","redirects","redirectOpts","newTransition","redirectEnteringNodes","originalEnteringNodes","_changedParams","tc","toValues","fromValues","schema","toVals","fromVals","_ignoredReason","same","pendTC","newTC","allBeforeHooks","lastStartedTransitionId","transitionHistory","allRunHooks","_error","_aborted","abstract","invalidParams","paramDefs","invalidValues","avoidEmptyHash","fromStateOrName","toStateOrName","treeChangesCleanup","TRANSITION_TOKENS","replaceTransitionWithNull","makeEnterExitRetainHook","hookFn","RESOLVE_HOOK_PRIORITY","eagerResolvePath","lazyResolveState","resolveRemaining","loadEnteringViews","enteringViews","updateGlobalState","clearCurrentTransition","successfulTransitions","copy","registerLazyLoadHook","stateService","urlService","stateRegistry","lazyLoad","orig","rule","lazyLoadFn","TransitionEventType","hookOrder","reverseSort","getResultHandler","getErrorHandler","ignoredHook","ignoredReason","pending","invalidTransitionHook","defaultTransOpts","notify","reload","supercede","custom","TransitionProvider","viewService","_transitionCount","_eventTypes","_criteriaPaths","_deregisterHookFns","_defineCorePaths","_defineCoreEvents","updateUrl","navigable","urlOptions","registerUpdateUrl","redirectTo","registerRedirectToHook","activateViews","exitingViews","registerActivateViews","NORMAL_SORT","_defineEvent","paths","TH","SYNCHRONOUS","_definePathType","TRANSITION","STATE","cmpByPhase","hookScope","_registerCoreTransitionHooks","addCoreResolves","onCreate","registerIgnoredTransitionHook","onExitHook","onRetainHook","registerOnRetainHook","onEnterHook","registerOnEnterHook","eagerResolve","registerEagerResolvePath","lazyResolve","registerLazyResolveState","resolveAll","registerResolveRemaining","updateGlobals","registerUpdateGlobalState","StateProvider","_defaultErrorHandler","$error$","defaultErrorHandler","func","stdErr","_handleInvalidTargetState","toState","checkForRedirect","transitionTo","invokeNextCallback","nextCallback","fromState","injector","onInvalid","invalidCallbacks","transOpts","root","getCurrentPath","latestSuccess","rootPath","getCurrent","rejectedTransitionHandler","transitionToPromise","stateOrName","lossy","absolute","nav","lazyLoadState","useAnchorScroll","scrollIntoView","_useHttp","useHttpService","asTemplate","fromUrl","fromProvider","templateProvider","asComponent","fromComponentProvider","componentProvider","camelCase","$1","kebobed","cmpDefs","getBindings","getComponentBindings","resolveName","kebobName","scopeBindings","bindingsObj","quoteRegExp","surroundPattern","re","strict","UrlMatcher","pathSegmentsAndParams","arrayTuples","weights","_cache","splitOnSlash","segment","weightsA","padArrays","weightsB","_pairs","cmp","paramFactory","_compiled","searchPlaceholder","checkParamErrors","nameValidator","matchDetails","makeRegexpType","patterns","matchArray","fromSearch","_segments","_pattern","_children","_getDecodedParamValue","unnest","allParams","pathParams","searchParams","nPathSegments","urlm","decodePathArray","paramVal","allReversed","findParam","urlMatchers","queryParams","getDetails","pathString","queryString","paramDetails","encodeDashes","StateObject","__stateObjectCache","nameGlob","ref","matchingKeys","isStateDeclaration","UrlRuleFactory","routerGlobals","makeRule","_what","fromUrlMatcher","fromRegExp","BaseUrlRule","urlMatcher","_handler","stateOrDecl","isUrlRule","_group","matchPriority","defaultRuleSortFn","idSort","getHandlerFn","UrlRules","urlRuleFactory","_sortFn","_rules","_id","urlParts","router","handlerFn","otherwise","_otherwiseFn","_sorted","removeRule","sorted","stableSort","ensureSorted","arrOfWrapper","wrapperA","wrapperB","cmpDiff","ParamFactory","urlServiceConfig","UrlService","$locationProvider","urlConfigProvider","_urlListeners","evt","_baseHref","decodeUri","onChange","newurl","applyResult","best","listen","_stopListeningFn","checkRule","weight","isHtml5","slash","urlPattern","globalConfig","isMatcher","StateMatcher","_states","isRelative","isStr","matchGlob","pathLength","splitName","baseState","relName","selfBuilder","dataBuilder","getUrlBuilder","stateObject","stateDec","newStateDec","pathBuilder","resolvablesBuilder","literal2Resolvable","getToken","useFactory","dependencies","useClass","useValue","useExisting","tuple2Resolvable","annotateFn","item2Resolvable","resolveObj","StateBuilder","rootFn","builders","parentName","urlParams","nonUrlParams","_config","includesBuilder","builder","build","parentFn","provide","StateQueueManager","urlServiceRules","stateDecl","registered","orphans","notifyListeners","existingState","existingFutureState","orphanIdx","attachRoute","rulesApi","StateRegistryProvider","getStateHookBuilder","stateQueue","$state$","$transition$","registerRoot","_root","onStatesChanged","stateDefinition","_deregisterTree","getChildren","deregistered","deregisteredStates","builderFunction","paramsOnly","paramExpr","processedDef","ngStateOpts","defaultOpts","ngState","ngStateParams","getTypeInfo","isSvg","isAnchor","clickable","isForm","clickHook","getDef","which","altKey","stopImmediatePropagation","ignorePreventDefaultCount","$StateRefDirective","$stateService","rawDef","unlinkInfoFn","$$addStateInfo","ngSrefOpts","bindEvents","$StateRefDynamicDirective","watchDeregFns","inputAttrs","field","newval","$StateRefActiveDirective","activeEqClass","ngSrefActiveEq","ngSrefActive","updateAfterTransition","handleStatesChanged","setStatesFromDefinitionObject","statesDefinition","activeClass","addStateForClass","stateOrNameParam","activeClassParam","addState","stateParams","stateInfo","getClasses","stateList","splitClasses","allClasses","fuzzyClasses","exactClasses","addClasses","deregisterStatesChangedListener","deregisterOnStartListener","deregisterStateChangeSuccessListener","rootData","$cfg","$ngView","_tAttrs","onload","autoscroll","renderer","activeUIView","updateView","fromParentTagConfig","fromParentTag","$ngViewData","$ngViewAnim","$animEnter","animEnter","$animLeave","$$animLeave","animLeave","currentEl","previousEl","_viewData","cleanupLastView","unregister","$ViewDirectiveFill","getTemplate","resolveCtx","ell","paramsUpdated","viewCreationTrans","viewState","toSchema","getNodeSchema","fromSchema","changedToParams","fromParams","newValues","changedKeys","uiOnParamsChanged","hookOptions","uiCanExit","prevTruthyAnswer","cacheProp","wrappedHook","registerControllerCallbacks","ngChannelDirective","channel","hasTemplateContent","ngSetterDirective","modelExpression","assignModel","updateModel","mutationsList","mutation","contentChanged","childList","subtree","characterData","ngInjectDirective","tokens","ngElDirective","removedNodes","removedNode","retryDelay","maxRetries","heartbeatTimeout","createConnection","finalUrl","mergedConfig","buildUrl","connect","es","retryCount","resetHeartbeat","closed","_$log","heartbeatTimer","ngViewportDirective","IntersectionObserver","enterExpr","leaveExpr","threshold","mutationObserver","ngWasmDirective","as","ngScopeDirective","ngScope","CookieService","_defaults","getObject","SyntaxError","parseCookies","cookie","encodedKey","encodedVal","domain","expires","expDate","toUTCString","secure","samesite","buildOptions","putObject","_lastCookieString","_lastCookieMap","pctEncode","allowReserved","RestService","_$http","_baseUrl","baseUrl","_entityClass","vars","sep","named","ifEmpty","varspecs","varlist","spec","conf","expandedParts","varname","explode","joined","encVal","prefixLength","expandExpression","expandUriTemplate","mapEntity","_definitions","svc","SanitizeUriProvider","textarea","script","select","ngBind","ngBindTemplate","ngChannel","ngClass","ngClassEven","ngClassEvenDirective","ngClassOdd","ngCloak","ngController","ngDelete","ngDeleteDirective","ngDisabled","ngEl","ngFormDirective","ngGet","ngInclude","ngInject","ngMessageExp","ngMessagesInclude","ngMessageDefault","ngMessageDefaultDirective","ngNonBindable","ngPost","ngPostDirective","ngPut","ngPutDirective","ngRepeat","ngRepeatDirective","ngSetter","ngStyle","ngSseDirective","ngSwitch","ngSwitchDefault","patternDirective","requiredDirective","minlengthDirective","maxlengthDirective","ngViewport","ngWasm","ngWorker","hiddenInputBrowserCacheDirective","ngAnimateSwap","ngAnimateChildren","ngChecked","ngClick","ngDblclick","ngReadonly","ngSref","AriaProvider","AnchorScrollProvider","ControllerProvider","CookieProvider","ExceptionHandlerProvider","InterpolateProvider","LocationProvider","ParseProvider","RafSchedulerProvider","RestProvider","RootScopeProvider","Router","SceDelegateProvider","SseProvider","TemplateCacheProvider","UrlConfigProvider","ViewScrollProvider","TemplateFactoryProvider","PubSubProvider","registerNgModule","moduleRegistry","ensure","bootstrap","bootsrappedModules","init","ngAttrPrefixes","appElement","getScopeByName","once"],"mappings":"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"}
|