-
Notifications
You must be signed in to change notification settings - Fork 0
/
29-es2015.js.map
1 lines (1 loc) · 27.1 KB
/
29-es2015.js.map
1
{"version":3,"sources":["./node_modules/@ionic/core/dist/esm/ion-route_4.entry.js"],"names":[],"mappings":";;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA6G;AAChD;AACP;AACsB;;AAE5E;AACA;AACA,IAAI,4DAAgB;AACpB,+BAA+B,4DAAW;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA,IAAI,4DAAgB;AACpB,mCAAmC,4DAAW;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,mBAAmB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qCAAqC,cAAc;AACnD;AACA;AACA;AACA;AACA,wBAAwB,mBAAmB,sBAAsB,kCAAkC,eAAe;AAClH;AACA;AACA;AACA;AACA,wCAAwC,iBAAiB;AACzD;AACA;AACA,oCAAoC,4BAA4B,uCAAuC,0BAA0B;AACjI;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,aAAa;AACrE,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAAS,WAAW;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,SAAS;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAkB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI,4DAAgB;AACpB,8BAA8B,4DAAW;AACzC,6BAA6B,4DAAW;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,8DAAQ;AAC/D,mDAAmD,8DAAQ;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,cAAc;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ,4DAAU,OAAO;AACrC;;AAEA,6BAA6B,yBAAyB,0CAA0C,6BAA6B,mBAAmB,kBAAkB,4BAA4B,EAAE,oBAAoB,kBAAkB,mBAAmB,oBAAoB,uBAAuB,wBAAwB,oBAAoB,sBAAsB,uBAAuB,mBAAmB,oBAAoB,cAAc;;AAElb;AACA;AACA,IAAI,4DAAgB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,4DAAO;AACb;AACA;AACA;AACA,iBAAiB,mEAAU;AAC3B;AACA;AACA;AACA;AACA;AACA,YAAY,4DAAC,CAAC,oDAAI,GAAG,+BAA+B,4DAAkB;AACtE;AACA;AACA,OAAO,GAAG,EAAE,4DAAC,sBAAsB,UAAU,4DAAC;AAC9C;AACA;AACA;;AAEwH","file":"29-es2015.js","sourcesContent":["import { r as registerInstance, e as createEvent, i as getElement, h, H as Host } from './index-e806d1f6.js';\nimport { b as getIonMode } from './ionic-global-9d5c8ee3.js';\nimport { m as debounce } from './helpers-90f46169.js';\nimport { o as openURL, c as createColorClasses } from './theme-ff3fc52f.js';\n\nconst Route = class {\n constructor(hostRef) {\n registerInstance(this, hostRef);\n this.ionRouteDataChanged = createEvent(this, \"ionRouteDataChanged\", 7);\n /**\n * Relative path that needs to match in order for this route to apply.\n *\n * Accepts paths similar to expressjs so that you can define parameters\n * in the url /foo/:bar where bar would be available in incoming props.\n */\n this.url = '';\n }\n onUpdate(newValue) {\n this.ionRouteDataChanged.emit(newValue);\n }\n onComponentProps(newValue, oldValue) {\n if (newValue === oldValue) {\n return;\n }\n const keys1 = newValue ? Object.keys(newValue) : [];\n const keys2 = oldValue ? Object.keys(oldValue) : [];\n if (keys1.length !== keys2.length) {\n this.onUpdate(newValue);\n return;\n }\n for (const key of keys1) {\n if (newValue[key] !== oldValue[key]) {\n this.onUpdate(newValue);\n return;\n }\n }\n }\n connectedCallback() {\n this.ionRouteDataChanged.emit();\n }\n static get watchers() { return {\n \"url\": [\"onUpdate\"],\n \"component\": [\"onUpdate\"],\n \"componentProps\": [\"onComponentProps\"]\n }; }\n};\n\nconst RouteRedirect = class {\n constructor(hostRef) {\n registerInstance(this, hostRef);\n this.ionRouteRedirectChanged = createEvent(this, \"ionRouteRedirectChanged\", 7);\n }\n propDidChange() {\n this.ionRouteRedirectChanged.emit();\n }\n connectedCallback() {\n this.ionRouteRedirectChanged.emit();\n }\n static get watchers() { return {\n \"from\": [\"propDidChange\"],\n \"to\": [\"propDidChange\"]\n }; }\n};\n\nconst ROUTER_INTENT_NONE = 'root';\nconst ROUTER_INTENT_FORWARD = 'forward';\nconst ROUTER_INTENT_BACK = 'back';\n\nconst generatePath = (segments) => {\n const path = segments\n .filter(s => s.length > 0)\n .join('/');\n return '/' + path;\n};\nconst chainToPath = (chain) => {\n const path = [];\n for (const route of chain) {\n for (const segment of route.path) {\n if (segment[0] === ':') {\n const param = route.params && route.params[segment.slice(1)];\n if (!param) {\n return null;\n }\n path.push(param);\n }\n else if (segment !== '') {\n path.push(segment);\n }\n }\n }\n return path;\n};\nconst writePath = (history, root, useHash, path, direction, state, queryString) => {\n let url = generatePath([\n ...parsePath(root),\n ...path\n ]);\n if (useHash) {\n url = '#' + url;\n }\n if (queryString !== undefined) {\n url = url + '?' + queryString;\n }\n if (direction === ROUTER_INTENT_FORWARD) {\n history.pushState(state, '', url);\n }\n else {\n history.replaceState(state, '', url);\n }\n};\nconst removePrefix = (prefix, path) => {\n if (prefix.length > path.length) {\n return null;\n }\n if (prefix.length <= 1 && prefix[0] === '') {\n return path;\n }\n for (let i = 0; i < prefix.length; i++) {\n if (prefix[i].length > 0 && prefix[i] !== path[i]) {\n return null;\n }\n }\n if (path.length === prefix.length) {\n return [''];\n }\n return path.slice(prefix.length);\n};\nconst readPath = (loc, root, useHash) => {\n let pathname = loc.pathname;\n if (useHash) {\n const hash = loc.hash;\n pathname = (hash[0] === '#')\n ? hash.slice(1)\n : '';\n }\n const prefix = parsePath(root);\n const path = parsePath(pathname);\n return removePrefix(prefix, path);\n};\nconst parsePath = (path) => {\n if (path == null) {\n return [''];\n }\n const removeQueryString = path.split('?')[0];\n const segments = removeQueryString.split('/')\n .map(s => s.trim())\n .filter(s => s.length > 0);\n if (segments.length === 0) {\n return [''];\n }\n else {\n return segments;\n }\n};\n\nconst printRoutes = (routes) => {\n console.group(`[ion-core] ROUTES[${routes.length}]`);\n for (const chain of routes) {\n const path = [];\n chain.forEach(r => path.push(...r.path));\n const ids = chain.map(r => r.id);\n console.debug(`%c ${generatePath(path)}`, 'font-weight: bold; padding-left: 20px', '=>\\t', `(${ids.join(', ')})`);\n }\n console.groupEnd();\n};\nconst printRedirects = (redirects) => {\n console.group(`[ion-core] REDIRECTS[${redirects.length}]`);\n for (const redirect of redirects) {\n if (redirect.to) {\n console.debug('FROM: ', `$c ${generatePath(redirect.from)}`, 'font-weight: bold', ' TO: ', `$c ${generatePath(redirect.to)}`, 'font-weight: bold');\n }\n }\n console.groupEnd();\n};\n\nconst writeNavState = async (root, chain, direction, index, changed = false, animation) => {\n try {\n // find next navigation outlet in the DOM\n const outlet = searchNavNode(root);\n // make sure we can continue interacting the DOM, otherwise abort\n if (index >= chain.length || !outlet) {\n return changed;\n }\n await outlet.componentOnReady();\n const route = chain[index];\n const result = await outlet.setRouteId(route.id, route.params, direction, animation);\n // if the outlet changed the page, reset navigation to neutral (no direction)\n // this means nested outlets will not animate\n if (result.changed) {\n direction = ROUTER_INTENT_NONE;\n changed = true;\n }\n // recursively set nested outlets\n changed = await writeNavState(result.element, chain, direction, index + 1, changed, animation);\n // once all nested outlets are visible let's make the parent visible too,\n // using markVisible prevents flickering\n if (result.markVisible) {\n await result.markVisible();\n }\n return changed;\n }\n catch (e) {\n console.error(e);\n return false;\n }\n};\nconst readNavState = async (root) => {\n const ids = [];\n let outlet;\n let node = root;\n // tslint:disable-next-line:no-constant-condition\n while (true) {\n outlet = searchNavNode(node);\n if (outlet) {\n const id = await outlet.getRouteId();\n if (id) {\n node = id.element;\n id.element = undefined;\n ids.push(id);\n }\n else {\n break;\n }\n }\n else {\n break;\n }\n }\n return { ids, outlet };\n};\nconst waitUntilNavNode = () => {\n if (searchNavNode(document.body)) {\n return Promise.resolve();\n }\n return new Promise(resolve => {\n window.addEventListener('ionNavWillLoad', resolve, { once: true });\n });\n};\nconst QUERY = ':not([no-router]) ion-nav, :not([no-router]) ion-tabs, :not([no-router]) ion-router-outlet';\nconst searchNavNode = (root) => {\n if (!root) {\n return undefined;\n }\n if (root.matches(QUERY)) {\n return root;\n }\n const outlet = root.querySelector(QUERY);\n return outlet ? outlet : undefined;\n};\n\nconst matchesRedirect = (input, route) => {\n const { from, to } = route;\n if (to === undefined) {\n return false;\n }\n if (from.length > input.length) {\n return false;\n }\n for (let i = 0; i < from.length; i++) {\n const expected = from[i];\n if (expected === '*') {\n return true;\n }\n if (expected !== input[i]) {\n return false;\n }\n }\n return from.length === input.length;\n};\nconst routeRedirect = (path, routes) => {\n return routes.find(route => matchesRedirect(path, route));\n};\nconst matchesIDs = (ids, chain) => {\n const len = Math.min(ids.length, chain.length);\n let i = 0;\n for (; i < len; i++) {\n if (ids[i].toLowerCase() !== chain[i].id) {\n break;\n }\n }\n return i;\n};\nconst matchesPath = (inputPath, chain) => {\n const segments = new RouterSegments(inputPath);\n let matchesDefault = false;\n let allparams;\n for (let i = 0; i < chain.length; i++) {\n const path = chain[i].path;\n if (path[0] === '') {\n matchesDefault = true;\n }\n else {\n for (const segment of path) {\n const data = segments.next();\n // data param\n if (segment[0] === ':') {\n if (data === '') {\n return null;\n }\n allparams = allparams || [];\n const params = allparams[i] || (allparams[i] = {});\n params[segment.slice(1)] = data;\n }\n else if (data !== segment) {\n return null;\n }\n }\n matchesDefault = false;\n }\n }\n const matches = (matchesDefault)\n ? matchesDefault === (segments.next() === '')\n : true;\n if (!matches) {\n return null;\n }\n if (allparams) {\n return chain.map((route, i) => ({\n id: route.id,\n path: route.path,\n params: mergeParams(route.params, allparams[i]),\n beforeEnter: route.beforeEnter,\n beforeLeave: route.beforeLeave\n }));\n }\n return chain;\n};\nconst mergeParams = (a, b) => {\n if (!a && b) {\n return b;\n }\n else if (a && !b) {\n return a;\n }\n else if (a && b) {\n return Object.assign(Object.assign({}, a), b);\n }\n return undefined;\n};\nconst routerIDsToChain = (ids, chains) => {\n let match = null;\n let maxMatches = 0;\n const plainIDs = ids.map(i => i.id);\n for (const chain of chains) {\n const score = matchesIDs(plainIDs, chain);\n if (score > maxMatches) {\n match = chain;\n maxMatches = score;\n }\n }\n if (match) {\n return match.map((route, i) => ({\n id: route.id,\n path: route.path,\n params: mergeParams(route.params, ids[i] && ids[i].params)\n }));\n }\n return null;\n};\nconst routerPathToChain = (path, chains) => {\n let match = null;\n let matches = 0;\n for (const chain of chains) {\n const matchedChain = matchesPath(path, chain);\n if (matchedChain !== null) {\n const score = computePriority(matchedChain);\n if (score > matches) {\n matches = score;\n match = matchedChain;\n }\n }\n }\n return match;\n};\nconst computePriority = (chain) => {\n let score = 1;\n let level = 1;\n for (const route of chain) {\n for (const path of route.path) {\n if (path[0] === ':') {\n score += Math.pow(1, level);\n }\n else if (path !== '') {\n score += Math.pow(2, level);\n }\n level++;\n }\n }\n return score;\n};\nclass RouterSegments {\n constructor(path) {\n this.path = path.slice();\n }\n next() {\n if (this.path.length > 0) {\n return this.path.shift();\n }\n return '';\n }\n}\n\nconst readRedirects = (root) => {\n return Array.from(root.children)\n .filter(el => el.tagName === 'ION-ROUTE-REDIRECT')\n .map(el => {\n const to = readProp(el, 'to');\n return {\n from: parsePath(readProp(el, 'from')),\n to: to == null ? undefined : parsePath(to),\n };\n });\n};\nconst readRoutes = (root) => {\n return flattenRouterTree(readRouteNodes(root));\n};\nconst readRouteNodes = (root, node = root) => {\n return Array.from(node.children)\n .filter(el => el.tagName === 'ION-ROUTE' && el.component)\n .map(el => {\n const component = readProp(el, 'component');\n if (component == null) {\n throw new Error('component missing in ion-route');\n }\n return {\n path: parsePath(readProp(el, 'url')),\n id: component.toLowerCase(),\n params: el.componentProps,\n beforeLeave: el.beforeLeave,\n beforeEnter: el.beforeEnter,\n children: readRouteNodes(root, el)\n };\n });\n};\nconst readProp = (el, prop) => {\n if (prop in el) {\n return el[prop];\n }\n if (el.hasAttribute(prop)) {\n return el.getAttribute(prop);\n }\n return null;\n};\nconst flattenRouterTree = (nodes) => {\n const routes = [];\n for (const node of nodes) {\n flattenNode([], routes, node);\n }\n return routes;\n};\nconst flattenNode = (chain, routes, node) => {\n const s = chain.slice();\n s.push({\n id: node.id,\n path: node.path,\n params: node.params,\n beforeLeave: node.beforeLeave,\n beforeEnter: node.beforeEnter\n });\n if (node.children.length === 0) {\n routes.push(s);\n return;\n }\n for (const sub of node.children) {\n flattenNode(s, routes, sub);\n }\n};\n\nconst Router = class {\n constructor(hostRef) {\n registerInstance(this, hostRef);\n this.ionRouteWillChange = createEvent(this, \"ionRouteWillChange\", 7);\n this.ionRouteDidChange = createEvent(this, \"ionRouteDidChange\", 7);\n this.previousPath = null;\n this.busy = false;\n this.state = 0;\n this.lastState = 0;\n /**\n * By default `ion-router` will match the routes at the root path (\"/\").\n * That can be changed when\n *\n */\n this.root = '/';\n /**\n * The router can work in two \"modes\":\n * - With hash: `/index.html#/path/to/page`\n * - Without hash: `/path/to/page`\n *\n * Using one or another might depend in the requirements of your app and/or where it's deployed.\n *\n * Usually \"hash-less\" navigation works better for SEO and it's more user friendly too, but it might\n * requires additional server-side configuration in order to properly work.\n *\n * On the otherside hash-navigation is much easier to deploy, it even works over the file protocol.\n *\n * By default, this property is `true`, change to `false` to allow hash-less URLs.\n */\n this.useHash = true;\n }\n async componentWillLoad() {\n console.debug('[ion-router] router will load');\n await waitUntilNavNode();\n console.debug('[ion-router] found nav');\n await this.onRoutesChanged();\n }\n componentDidLoad() {\n window.addEventListener('ionRouteRedirectChanged', debounce(this.onRedirectChanged.bind(this), 10));\n window.addEventListener('ionRouteDataChanged', debounce(this.onRoutesChanged.bind(this), 100));\n }\n async onPopState() {\n const direction = this.historyDirection();\n let path = this.getPath();\n const canProceed = await this.runGuards(path);\n if (canProceed !== true) {\n if (typeof canProceed === 'object') {\n path = parsePath(canProceed.redirect);\n }\n return false;\n }\n console.debug('[ion-router] URL changed -> update nav', path, direction);\n return this.writeNavStateRoot(path, direction);\n }\n onBackButton(ev) {\n ev.detail.register(0, processNextHandler => {\n this.back();\n processNextHandler();\n });\n }\n /** @internal */\n async canTransition() {\n const canProceed = await this.runGuards();\n if (canProceed !== true) {\n if (typeof canProceed === 'object') {\n return canProceed.redirect;\n }\n else {\n return false;\n }\n }\n return true;\n }\n /**\n * Navigate to the specified URL.\n *\n * @param url The url to navigate to.\n * @param direction The direction of the animation. Defaults to `\"forward\"`.\n */\n async push(url, direction = 'forward', animation) {\n if (url.startsWith('.')) {\n url = (new URL(url, window.location.href)).pathname;\n }\n console.debug('[ion-router] URL pushed -> updating nav', url, direction);\n let path = parsePath(url);\n let queryString = url.split('?')[1];\n const canProceed = await this.runGuards(path);\n if (canProceed !== true) {\n if (typeof canProceed === 'object') {\n path = parsePath(canProceed.redirect);\n queryString = canProceed.redirect.split('?')[1];\n }\n else {\n return false;\n }\n }\n this.setPath(path, direction, queryString);\n return this.writeNavStateRoot(path, direction, animation);\n }\n /**\n * Go back to previous page in the window.history.\n */\n back() {\n window.history.back();\n return Promise.resolve(this.waitPromise);\n }\n /** @internal */\n async printDebug() {\n console.debug('CURRENT PATH', this.getPath());\n console.debug('PREVIOUS PATH', this.previousPath);\n printRoutes(readRoutes(this.el));\n printRedirects(readRedirects(this.el));\n }\n /** @internal */\n async navChanged(direction) {\n if (this.busy) {\n console.warn('[ion-router] router is busy, navChanged was cancelled');\n return false;\n }\n const { ids, outlet } = await readNavState(window.document.body);\n const routes = readRoutes(this.el);\n const chain = routerIDsToChain(ids, routes);\n if (!chain) {\n console.warn('[ion-router] no matching URL for ', ids.map(i => i.id));\n return false;\n }\n const path = chainToPath(chain);\n if (!path) {\n console.warn('[ion-router] router could not match path because some required param is missing');\n return false;\n }\n console.debug('[ion-router] nav changed -> update URL', ids, path);\n this.setPath(path, direction);\n await this.safeWriteNavState(outlet, chain, ROUTER_INTENT_NONE, path, null, ids.length);\n return true;\n }\n onRedirectChanged() {\n const path = this.getPath();\n if (path && routeRedirect(path, readRedirects(this.el))) {\n this.writeNavStateRoot(path, ROUTER_INTENT_NONE);\n }\n }\n onRoutesChanged() {\n return this.writeNavStateRoot(this.getPath(), ROUTER_INTENT_NONE);\n }\n historyDirection() {\n const win = window;\n if (win.history.state === null) {\n this.state++;\n win.history.replaceState(this.state, win.document.title, win.document.location && win.document.location.href);\n }\n const state = win.history.state;\n const lastState = this.lastState;\n this.lastState = state;\n if (state > lastState || (state >= lastState && lastState > 0)) {\n return ROUTER_INTENT_FORWARD;\n }\n else if (state < lastState) {\n return ROUTER_INTENT_BACK;\n }\n else {\n return ROUTER_INTENT_NONE;\n }\n }\n async writeNavStateRoot(path, direction, animation) {\n if (!path) {\n console.error('[ion-router] URL is not part of the routing set');\n return false;\n }\n // lookup redirect rule\n const redirects = readRedirects(this.el);\n const redirect = routeRedirect(path, redirects);\n let redirectFrom = null;\n if (redirect) {\n this.setPath(redirect.to, direction);\n redirectFrom = redirect.from;\n path = redirect.to;\n }\n // lookup route chain\n const routes = readRoutes(this.el);\n const chain = routerPathToChain(path, routes);\n if (!chain) {\n console.error('[ion-router] the path does not match any route');\n return false;\n }\n // write DOM give\n return this.safeWriteNavState(document.body, chain, direction, path, redirectFrom, 0, animation);\n }\n async safeWriteNavState(node, chain, direction, path, redirectFrom, index = 0, animation) {\n const unlock = await this.lock();\n let changed = false;\n try {\n changed = await this.writeNavState(node, chain, direction, path, redirectFrom, index, animation);\n }\n catch (e) {\n console.error(e);\n }\n unlock();\n return changed;\n }\n async lock() {\n const p = this.waitPromise;\n let resolve;\n this.waitPromise = new Promise(r => resolve = r);\n if (p !== undefined) {\n await p;\n }\n return resolve;\n }\n async runGuards(to = this.getPath(), from = parsePath(this.previousPath)) {\n if (!to || !from) {\n return true;\n }\n const routes = readRoutes(this.el);\n const toChain = routerPathToChain(to, routes);\n const fromChain = routerPathToChain(from, routes);\n const beforeEnterHook = toChain && toChain[toChain.length - 1].beforeEnter;\n const beforeLeaveHook = fromChain && fromChain[fromChain.length - 1].beforeLeave;\n const canLeave = beforeLeaveHook ? await beforeLeaveHook() : true;\n if (canLeave === false || typeof canLeave === 'object') {\n return canLeave;\n }\n const canEnter = beforeEnterHook ? await beforeEnterHook() : true;\n if (canEnter === false || typeof canEnter === 'object') {\n return canEnter;\n }\n return true;\n }\n async writeNavState(node, chain, direction, path, redirectFrom, index = 0, animation) {\n if (this.busy) {\n console.warn('[ion-router] router is busy, transition was cancelled');\n return false;\n }\n this.busy = true;\n // generate route event and emit will change\n const routeEvent = this.routeChangeEvent(path, redirectFrom);\n if (routeEvent) {\n this.ionRouteWillChange.emit(routeEvent);\n }\n const changed = await writeNavState(node, chain, direction, index, false, animation);\n this.busy = false;\n if (changed) {\n console.debug('[ion-router] route changed', path);\n }\n // emit did change\n if (routeEvent) {\n this.ionRouteDidChange.emit(routeEvent);\n }\n return changed;\n }\n setPath(path, direction, queryString) {\n this.state++;\n writePath(window.history, this.root, this.useHash, path, direction, this.state, queryString);\n }\n getPath() {\n return readPath(window.location, this.root, this.useHash);\n }\n routeChangeEvent(path, redirectFromPath) {\n const from = this.previousPath;\n const to = generatePath(path);\n this.previousPath = to;\n if (to === from) {\n return null;\n }\n const redirectedFrom = redirectFromPath ? generatePath(redirectFromPath) : null;\n return {\n from,\n redirectedFrom,\n to,\n };\n }\n get el() { return getElement(this); }\n};\n\nconst routerLinkCss = \":host{--background:transparent;--color:var(--ion-color-primary, #3880ff);background:var(--background);color:var(--color)}:host(.ion-color){color:var(--ion-color-base)}a{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit}\";\n\nconst RouterLink = class {\n constructor(hostRef) {\n registerInstance(this, hostRef);\n /**\n * When using a router, it specifies the transition direction when navigating to\n * another page using `href`.\n */\n this.routerDirection = 'forward';\n this.onClick = (ev) => {\n openURL(this.href, ev, this.routerDirection, this.routerAnimation);\n };\n }\n render() {\n const mode = getIonMode(this);\n const attrs = {\n href: this.href,\n rel: this.rel,\n target: this.target\n };\n return (h(Host, { onClick: this.onClick, class: createColorClasses(this.color, {\n [mode]: true,\n 'ion-activatable': true\n }) }, h(\"a\", Object.assign({}, attrs), h(\"slot\", null))));\n }\n};\nRouterLink.style = routerLinkCss;\n\nexport { Route as ion_route, RouteRedirect as ion_route_redirect, Router as ion_router, RouterLink as ion_router_link };\n"],"sourceRoot":"webpack:///"}