kdu-router 4.1.6 → 4.2.0

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.
@@ -1,12 +1,10 @@
1
1
  /*!
2
- * kdu-router v4.1.6
3
- * (c) 2023 NKDuy
2
+ * kdu-router v4.2.0
3
+ * (c) 2024 NKDuy
4
4
  * @license MIT
5
5
  */
6
6
  'use strict';
7
7
 
8
- Object.defineProperty(exports, '__esModule', { value: true });
9
-
10
8
  var kdu = require('kdu');
11
9
  var devtoolsApi = require('@kdujs/devtools-api');
12
10
 
@@ -107,6 +105,7 @@ function stripBase(pathname, base) {
107
105
  * pointing towards the same {@link RouteRecord} and that all `params`, `query`
108
106
  * parameters and `hash` are the same
109
107
  *
108
+ * @param stringifyQuery - A function that takes a query object of type LocationQueryRaw and returns a string representation of it.
110
109
  * @param a - first {@link RouteLocation}
111
110
  * @param b - second {@link RouteLocation}
112
111
  */
@@ -178,6 +177,12 @@ function resolveRelativePath(to, from) {
178
177
  return from;
179
178
  const fromSegments = from.split('/');
180
179
  const toSegments = to.split('/');
180
+ const lastToSegment = toSegments[toSegments.length - 1];
181
+ // make . and ./ the same (../ === .., ../../ === ../..)
182
+ // this is the same behavior as new URL()
183
+ if (lastToSegment === '..' || lastToSegment === '.') {
184
+ toSegments.push('');
185
+ }
181
186
  let position = fromSegments.length - 1;
182
187
  let toPosition;
183
188
  let segment;
@@ -364,7 +369,8 @@ function getSavedScrollPosition(key) {
364
369
  let createBaseLocation = () => location.protocol + '//' + location.host;
365
370
  /**
366
371
  * Creates a normalized history location from a window.location object
367
- * @param location -
372
+ * @param base - The base path
373
+ * @param location - The window.location object
368
374
  */
369
375
  function createCurrentLocation(base, location) {
370
376
  const { pathname, search, hash } = location;
@@ -454,7 +460,11 @@ function useHistoryListeners(base, historyState, currentLocation, replace) {
454
460
  }
455
461
  // set up the listeners and prepare teardown callbacks
456
462
  window.addEventListener('popstate', popStateHandler);
457
- window.addEventListener('beforeunload', beforeUnloadListener);
463
+ // TODO: could we use 'pagehide' or 'visibilitychange' instead?
464
+ // https://developer.chrome.com/blog/page-lifecycle-api/
465
+ window.addEventListener('beforeunload', beforeUnloadListener, {
466
+ passive: true,
467
+ });
458
468
  return {
459
469
  pauseListeners,
460
470
  listen,
@@ -1176,6 +1186,7 @@ function tokenizePath(path) {
1176
1186
  case 2 /* TokenizerState.ParamRegExp */:
1177
1187
  // TODO: is it worth handling nested regexp? like :p(?:prefix_([^/]+)_suffix)
1178
1188
  // it already works by escaping the closing )
1189
+ // https://paths.esm.dev/?p=AAMeJbiAwQEcDKbAoAAkP60PG2R6QAvgNaA6AFACM2ABuQBB#
1179
1190
  // is this really something people need since you can also write
1180
1191
  // /prefix_:p()_suffix
1181
1192
  if (char === ')') {
@@ -2461,8 +2472,11 @@ const RouterView = RouterViewImpl;
2461
2472
  function warnDeprecatedUsage() {
2462
2473
  const instance = kdu.getCurrentInstance();
2463
2474
  const parentName = instance.parent && instance.parent.type.name;
2475
+ const parentSubTreeType = instance.parent && instance.parent.subTree && instance.parent.subTree.type;
2464
2476
  if (parentName &&
2465
- (parentName === 'KeepAlive' || parentName.includes('Transition'))) {
2477
+ (parentName === 'KeepAlive' || parentName.includes('Transition')) &&
2478
+ typeof parentSubTreeType === 'object' &&
2479
+ parentSubTreeType.name === 'RouterView') {
2466
2480
  const comp = parentName === 'KeepAlive' ? 'keep-alive' : 'transition';
2467
2481
  warn(`<router-view> can no longer be used directly inside <transition> or <keep-alive>.\n` +
2468
2482
  `Use slot props instead:\n\n` +
@@ -3002,9 +3016,7 @@ function createRouter(options) {
3002
3016
  !('name' in rawLocation) &&
3003
3017
  // @ts-expect-error: the type is never
3004
3018
  Object.keys(rawLocation.params).length) {
3005
- warn(`Path "${
3006
- // @ts-expect-error: the type is never
3007
- rawLocation.path}" was passed with params but they will be ignored. Use a named route alongside params instead.`);
3019
+ warn(`Path "${rawLocation.path}" was passed with params but they will be ignored. Use a named route alongside params instead.`);
3008
3020
  }
3009
3021
  matcherLocation = assign({}, rawLocation, {
3010
3022
  path: parseURL(parseQuery$1, rawLocation.path, currentLocation.path).path,
@@ -3020,7 +3032,7 @@ function createRouter(options) {
3020
3032
  }
3021
3033
  // pass encoded values to the matcher, so it can produce encoded path and fullPath
3022
3034
  matcherLocation = assign({}, rawLocation, {
3023
- params: encodeParams(rawLocation.params),
3035
+ params: encodeParams(targetParams),
3024
3036
  });
3025
3037
  // current location params are decoded, we need to encode them in case the
3026
3038
  // matcher merges the params
@@ -3164,8 +3176,8 @@ function createRouter(options) {
3164
3176
  (redirectedFrom._count = redirectedFrom._count
3165
3177
  ? // @ts-expect-error
3166
3178
  redirectedFrom._count + 1
3167
- : 1) > 10) {
3168
- warn(`Detected an infinite redirection in a navigation guard when going from "${from.fullPath}" to "${toLocation.fullPath}". Aborting to avoid a Stack Overflow. This will break in production if not fixed.`);
3179
+ : 1) > 30) {
3180
+ warn(`Detected a possibly infinite redirection in a navigation guard when going from "${from.fullPath}" to "${toLocation.fullPath}". Aborting to avoid a Stack Overflow.\n Are you always returning a new location within a navigation guard? That would lead to this error. Only return when redirecting or aborting, that should fix this. This might break in production if not fixed.`);
3169
3181
  return Promise.reject(new Error('Infinite redirect in navigation guard'));
3170
3182
  }
3171
3183
  return pushWithRedirect(
@@ -3200,6 +3212,13 @@ function createRouter(options) {
3200
3212
  const error = checkCanceledNavigation(to, from);
3201
3213
  return error ? Promise.reject(error) : Promise.resolve();
3202
3214
  }
3215
+ function runWithContext(fn) {
3216
+ const app = installedApps.values().next().value;
3217
+ // support Kdu < 3.3
3218
+ return app && typeof app.runWithContext === 'function'
3219
+ ? app.runWithContext(fn)
3220
+ : fn();
3221
+ }
3203
3222
  // TODO: refactor the whole before guards by internally using router.beforeEach
3204
3223
  function navigate(to, from) {
3205
3224
  let guards;
@@ -3283,8 +3302,9 @@ function createRouter(options) {
3283
3302
  function triggerAfterEach(to, from, failure) {
3284
3303
  // navigation is confirmed, call afterGuards
3285
3304
  // TODO: wrap with error handlers
3286
- for (const guard of afterGuards.list())
3287
- guard(to, from, failure);
3305
+ for (const guard of afterGuards.list()) {
3306
+ runWithContext(() => guard(to, from, failure));
3307
+ }
3288
3308
  }
3289
3309
  /**
3290
3310
  * - Cleans up any navigation guards
@@ -3542,11 +3562,12 @@ function createRouter(options) {
3542
3562
  }
3543
3563
  },
3544
3564
  };
3565
+ // TODO: type this as NavigationGuardReturn or similar instead of any
3566
+ function runGuardQueue(guards) {
3567
+ return guards.reduce((promise, guard) => promise.then(() => runWithContext(guard)), Promise.resolve());
3568
+ }
3545
3569
  return router;
3546
3570
  }
3547
- function runGuardQueue(guards) {
3548
- return guards.reduce((promise, guard) => promise.then(() => guard()), Promise.resolve());
3549
- }
3550
3571
  function extractChangingRecords(to, from) {
3551
3572
  const leavingRecords = [];
3552
3573
  const updatingRecords = [];
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * kdu-router v4.1.6
3
- * (c) 2023 NKDuy
2
+ * kdu-router v4.2.0
3
+ * (c) 2024 NKDuy
4
4
  * @license MIT
5
5
  */
6
6
  import { getCurrentInstance, inject, onUnmounted, onDeactivated, onActivated, computed, unref, watchEffect, defineComponent, reactive, h, provide, ref, watch, shallowRef, nextTick } from 'kdu';
@@ -103,6 +103,7 @@ function stripBase(pathname, base) {
103
103
  * pointing towards the same {@link RouteRecord} and that all `params`, `query`
104
104
  * parameters and `hash` are the same
105
105
  *
106
+ * @param stringifyQuery - A function that takes a query object of type LocationQueryRaw and returns a string representation of it.
106
107
  * @param a - first {@link RouteLocation}
107
108
  * @param b - second {@link RouteLocation}
108
109
  */
@@ -174,6 +175,12 @@ function resolveRelativePath(to, from) {
174
175
  return from;
175
176
  const fromSegments = from.split('/');
176
177
  const toSegments = to.split('/');
178
+ const lastToSegment = toSegments[toSegments.length - 1];
179
+ // make . and ./ the same (../ === .., ../../ === ../..)
180
+ // this is the same behavior as new URL()
181
+ if (lastToSegment === '..' || lastToSegment === '.') {
182
+ toSegments.push('');
183
+ }
177
184
  let position = fromSegments.length - 1;
178
185
  let toPosition;
179
186
  let segment;
@@ -360,7 +367,8 @@ function getSavedScrollPosition(key) {
360
367
  let createBaseLocation = () => location.protocol + '//' + location.host;
361
368
  /**
362
369
  * Creates a normalized history location from a window.location object
363
- * @param location -
370
+ * @param base - The base path
371
+ * @param location - The window.location object
364
372
  */
365
373
  function createCurrentLocation(base, location) {
366
374
  const { pathname, search, hash } = location;
@@ -450,7 +458,11 @@ function useHistoryListeners(base, historyState, currentLocation, replace) {
450
458
  }
451
459
  // set up the listeners and prepare teardown callbacks
452
460
  window.addEventListener('popstate', popStateHandler);
453
- window.addEventListener('beforeunload', beforeUnloadListener);
461
+ // TODO: could we use 'pagehide' or 'visibilitychange' instead?
462
+ // https://developer.chrome.com/blog/page-lifecycle-api/
463
+ window.addEventListener('beforeunload', beforeUnloadListener, {
464
+ passive: true,
465
+ });
454
466
  return {
455
467
  pauseListeners,
456
468
  listen,
@@ -1172,6 +1184,7 @@ function tokenizePath(path) {
1172
1184
  case 2 /* TokenizerState.ParamRegExp */:
1173
1185
  // TODO: is it worth handling nested regexp? like :p(?:prefix_([^/]+)_suffix)
1174
1186
  // it already works by escaping the closing )
1187
+ // https://paths.esm.dev/?p=AAMeJbiAwQEcDKbAoAAkP60PG2R6QAvgNaA6AFACM2ABuQBB#
1175
1188
  // is this really something people need since you can also write
1176
1189
  // /prefix_:p()_suffix
1177
1190
  if (char === ')') {
@@ -2457,8 +2470,11 @@ const RouterView = RouterViewImpl;
2457
2470
  function warnDeprecatedUsage() {
2458
2471
  const instance = getCurrentInstance();
2459
2472
  const parentName = instance.parent && instance.parent.type.name;
2473
+ const parentSubTreeType = instance.parent && instance.parent.subTree && instance.parent.subTree.type;
2460
2474
  if (parentName &&
2461
- (parentName === 'KeepAlive' || parentName.includes('Transition'))) {
2475
+ (parentName === 'KeepAlive' || parentName.includes('Transition')) &&
2476
+ typeof parentSubTreeType === 'object' &&
2477
+ parentSubTreeType.name === 'RouterView') {
2462
2478
  const comp = parentName === 'KeepAlive' ? 'keep-alive' : 'transition';
2463
2479
  warn(`<router-view> can no longer be used directly inside <transition> or <keep-alive>.\n` +
2464
2480
  `Use slot props instead:\n\n` +
@@ -2998,9 +3014,7 @@ function createRouter(options) {
2998
3014
  !('name' in rawLocation) &&
2999
3015
  // @ts-expect-error: the type is never
3000
3016
  Object.keys(rawLocation.params).length) {
3001
- warn(`Path "${
3002
- // @ts-expect-error: the type is never
3003
- rawLocation.path}" was passed with params but they will be ignored. Use a named route alongside params instead.`);
3017
+ warn(`Path "${rawLocation.path}" was passed with params but they will be ignored. Use a named route alongside params instead.`);
3004
3018
  }
3005
3019
  matcherLocation = assign({}, rawLocation, {
3006
3020
  path: parseURL(parseQuery$1, rawLocation.path, currentLocation.path).path,
@@ -3016,7 +3030,7 @@ function createRouter(options) {
3016
3030
  }
3017
3031
  // pass encoded values to the matcher, so it can produce encoded path and fullPath
3018
3032
  matcherLocation = assign({}, rawLocation, {
3019
- params: encodeParams(rawLocation.params),
3033
+ params: encodeParams(targetParams),
3020
3034
  });
3021
3035
  // current location params are decoded, we need to encode them in case the
3022
3036
  // matcher merges the params
@@ -3160,8 +3174,8 @@ function createRouter(options) {
3160
3174
  (redirectedFrom._count = redirectedFrom._count
3161
3175
  ? // @ts-expect-error
3162
3176
  redirectedFrom._count + 1
3163
- : 1) > 10) {
3164
- warn(`Detected an infinite redirection in a navigation guard when going from "${from.fullPath}" to "${toLocation.fullPath}". Aborting to avoid a Stack Overflow. This will break in production if not fixed.`);
3177
+ : 1) > 30) {
3178
+ warn(`Detected a possibly infinite redirection in a navigation guard when going from "${from.fullPath}" to "${toLocation.fullPath}". Aborting to avoid a Stack Overflow.\n Are you always returning a new location within a navigation guard? That would lead to this error. Only return when redirecting or aborting, that should fix this. This might break in production if not fixed.`);
3165
3179
  return Promise.reject(new Error('Infinite redirect in navigation guard'));
3166
3180
  }
3167
3181
  return pushWithRedirect(
@@ -3196,6 +3210,13 @@ function createRouter(options) {
3196
3210
  const error = checkCanceledNavigation(to, from);
3197
3211
  return error ? Promise.reject(error) : Promise.resolve();
3198
3212
  }
3213
+ function runWithContext(fn) {
3214
+ const app = installedApps.values().next().value;
3215
+ // support Kdu < 3.3
3216
+ return app && typeof app.runWithContext === 'function'
3217
+ ? app.runWithContext(fn)
3218
+ : fn();
3219
+ }
3199
3220
  // TODO: refactor the whole before guards by internally using router.beforeEach
3200
3221
  function navigate(to, from) {
3201
3222
  let guards;
@@ -3279,8 +3300,9 @@ function createRouter(options) {
3279
3300
  function triggerAfterEach(to, from, failure) {
3280
3301
  // navigation is confirmed, call afterGuards
3281
3302
  // TODO: wrap with error handlers
3282
- for (const guard of afterGuards.list())
3283
- guard(to, from, failure);
3303
+ for (const guard of afterGuards.list()) {
3304
+ runWithContext(() => guard(to, from, failure));
3305
+ }
3284
3306
  }
3285
3307
  /**
3286
3308
  * - Cleans up any navigation guards
@@ -3538,11 +3560,12 @@ function createRouter(options) {
3538
3560
  }
3539
3561
  },
3540
3562
  };
3563
+ // TODO: type this as NavigationGuardReturn or similar instead of any
3564
+ function runGuardQueue(guards) {
3565
+ return guards.reduce((promise, guard) => promise.then(() => runWithContext(guard)), Promise.resolve());
3566
+ }
3541
3567
  return router;
3542
3568
  }
3543
- function runGuardQueue(guards) {
3544
- return guards.reduce((promise, guard) => promise.then(() => guard()), Promise.resolve());
3545
- }
3546
3569
  function extractChangingRecords(to, from) {
3547
3570
  const leavingRecords = [];
3548
3571
  const updatingRecords = [];
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * kdu-router v4.1.6
3
- * (c) 2023 NKDuy
2
+ * kdu-router v4.2.0
3
+ * (c) 2024 NKDuy
4
4
  * @license MIT
5
5
  */
6
6
  var KduRouter = (function (exports, kdu) {
@@ -103,6 +103,7 @@ var KduRouter = (function (exports, kdu) {
103
103
  * pointing towards the same {@link RouteRecord} and that all `params`, `query`
104
104
  * parameters and `hash` are the same
105
105
  *
106
+ * @param stringifyQuery - A function that takes a query object of type LocationQueryRaw and returns a string representation of it.
106
107
  * @param a - first {@link RouteLocation}
107
108
  * @param b - second {@link RouteLocation}
108
109
  */
@@ -174,6 +175,12 @@ var KduRouter = (function (exports, kdu) {
174
175
  return from;
175
176
  const fromSegments = from.split('/');
176
177
  const toSegments = to.split('/');
178
+ const lastToSegment = toSegments[toSegments.length - 1];
179
+ // make . and ./ the same (../ === .., ../../ === ../..)
180
+ // this is the same behavior as new URL()
181
+ if (lastToSegment === '..' || lastToSegment === '.') {
182
+ toSegments.push('');
183
+ }
177
184
  let position = fromSegments.length - 1;
178
185
  let toPosition;
179
186
  let segment;
@@ -360,7 +367,8 @@ var KduRouter = (function (exports, kdu) {
360
367
  let createBaseLocation = () => location.protocol + '//' + location.host;
361
368
  /**
362
369
  * Creates a normalized history location from a window.location object
363
- * @param location -
370
+ * @param base - The base path
371
+ * @param location - The window.location object
364
372
  */
365
373
  function createCurrentLocation(base, location) {
366
374
  const { pathname, search, hash } = location;
@@ -450,7 +458,11 @@ var KduRouter = (function (exports, kdu) {
450
458
  }
451
459
  // set up the listeners and prepare teardown callbacks
452
460
  window.addEventListener('popstate', popStateHandler);
453
- window.addEventListener('beforeunload', beforeUnloadListener);
461
+ // TODO: could we use 'pagehide' or 'visibilitychange' instead?
462
+ // https://developer.chrome.com/blog/page-lifecycle-api/
463
+ window.addEventListener('beforeunload', beforeUnloadListener, {
464
+ passive: true,
465
+ });
454
466
  return {
455
467
  pauseListeners,
456
468
  listen,
@@ -1172,6 +1184,7 @@ var KduRouter = (function (exports, kdu) {
1172
1184
  case 2 /* TokenizerState.ParamRegExp */:
1173
1185
  // TODO: is it worth handling nested regexp? like :p(?:prefix_([^/]+)_suffix)
1174
1186
  // it already works by escaping the closing )
1187
+ // https://paths.esm.dev/?p=AAMeJbiAwQEcDKbAoAAkP60PG2R6QAvgNaA6AFACM2ABuQBB#
1175
1188
  // is this really something people need since you can also write
1176
1189
  // /prefix_:p()_suffix
1177
1190
  if (char === ')') {
@@ -2457,8 +2470,11 @@ var KduRouter = (function (exports, kdu) {
2457
2470
  function warnDeprecatedUsage() {
2458
2471
  const instance = kdu.getCurrentInstance();
2459
2472
  const parentName = instance.parent && instance.parent.type.name;
2473
+ const parentSubTreeType = instance.parent && instance.parent.subTree && instance.parent.subTree.type;
2460
2474
  if (parentName &&
2461
- (parentName === 'KeepAlive' || parentName.includes('Transition'))) {
2475
+ (parentName === 'KeepAlive' || parentName.includes('Transition')) &&
2476
+ typeof parentSubTreeType === 'object' &&
2477
+ parentSubTreeType.name === 'RouterView') {
2462
2478
  const comp = parentName === 'KeepAlive' ? 'keep-alive' : 'transition';
2463
2479
  warn(`<router-view> can no longer be used directly inside <transition> or <keep-alive>.\n` +
2464
2480
  `Use slot props instead:\n\n` +
@@ -3165,9 +3181,7 @@ var KduRouter = (function (exports, kdu) {
3165
3181
  !('name' in rawLocation) &&
3166
3182
  // @ts-expect-error: the type is never
3167
3183
  Object.keys(rawLocation.params).length) {
3168
- warn(`Path "${
3169
- // @ts-expect-error: the type is never
3170
- rawLocation.path}" was passed with params but they will be ignored. Use a named route alongside params instead.`);
3184
+ warn(`Path "${rawLocation.path}" was passed with params but they will be ignored. Use a named route alongside params instead.`);
3171
3185
  }
3172
3186
  matcherLocation = assign({}, rawLocation, {
3173
3187
  path: parseURL(parseQuery$1, rawLocation.path, currentLocation.path).path,
@@ -3183,7 +3197,7 @@ var KduRouter = (function (exports, kdu) {
3183
3197
  }
3184
3198
  // pass encoded values to the matcher, so it can produce encoded path and fullPath
3185
3199
  matcherLocation = assign({}, rawLocation, {
3186
- params: encodeParams(rawLocation.params),
3200
+ params: encodeParams(targetParams),
3187
3201
  });
3188
3202
  // current location params are decoded, we need to encode them in case the
3189
3203
  // matcher merges the params
@@ -3327,8 +3341,8 @@ var KduRouter = (function (exports, kdu) {
3327
3341
  (redirectedFrom._count = redirectedFrom._count
3328
3342
  ? // @ts-expect-error
3329
3343
  redirectedFrom._count + 1
3330
- : 1) > 10) {
3331
- warn(`Detected an infinite redirection in a navigation guard when going from "${from.fullPath}" to "${toLocation.fullPath}". Aborting to avoid a Stack Overflow. This will break in production if not fixed.`);
3344
+ : 1) > 30) {
3345
+ warn(`Detected a possibly infinite redirection in a navigation guard when going from "${from.fullPath}" to "${toLocation.fullPath}". Aborting to avoid a Stack Overflow.\n Are you always returning a new location within a navigation guard? That would lead to this error. Only return when redirecting or aborting, that should fix this. This might break in production if not fixed.`);
3332
3346
  return Promise.reject(new Error('Infinite redirect in navigation guard'));
3333
3347
  }
3334
3348
  return pushWithRedirect(
@@ -3363,6 +3377,13 @@ var KduRouter = (function (exports, kdu) {
3363
3377
  const error = checkCanceledNavigation(to, from);
3364
3378
  return error ? Promise.reject(error) : Promise.resolve();
3365
3379
  }
3380
+ function runWithContext(fn) {
3381
+ const app = installedApps.values().next().value;
3382
+ // support Kdu < 3.3
3383
+ return app && typeof app.runWithContext === 'function'
3384
+ ? app.runWithContext(fn)
3385
+ : fn();
3386
+ }
3366
3387
  // TODO: refactor the whole before guards by internally using router.beforeEach
3367
3388
  function navigate(to, from) {
3368
3389
  let guards;
@@ -3446,8 +3467,9 @@ var KduRouter = (function (exports, kdu) {
3446
3467
  function triggerAfterEach(to, from, failure) {
3447
3468
  // navigation is confirmed, call afterGuards
3448
3469
  // TODO: wrap with error handlers
3449
- for (const guard of afterGuards.list())
3450
- guard(to, from, failure);
3470
+ for (const guard of afterGuards.list()) {
3471
+ runWithContext(() => guard(to, from, failure));
3472
+ }
3451
3473
  }
3452
3474
  /**
3453
3475
  * - Cleans up any navigation guards
@@ -3705,11 +3727,12 @@ var KduRouter = (function (exports, kdu) {
3705
3727
  }
3706
3728
  },
3707
3729
  };
3730
+ // TODO: type this as NavigationGuardReturn or similar instead of any
3731
+ function runGuardQueue(guards) {
3732
+ return guards.reduce((promise, guard) => promise.then(() => runWithContext(guard)), Promise.resolve());
3733
+ }
3708
3734
  return router;
3709
3735
  }
3710
- function runGuardQueue(guards) {
3711
- return guards.reduce((promise, guard) => promise.then(() => guard()), Promise.resolve());
3712
- }
3713
3736
  function extractChangingRecords(to, from) {
3714
3737
  const leavingRecords = [];
3715
3738
  const updatingRecords = [];
@@ -3772,8 +3795,6 @@ var KduRouter = (function (exports, kdu) {
3772
3795
  exports.useRouter = useRouter;
3773
3796
  exports.viewDepthKey = viewDepthKey;
3774
3797
 
3775
- Object.defineProperty(exports, '__esModule', { value: true });
3776
-
3777
3798
  return exports;
3778
3799
 
3779
3800
  })({}, Kdu);
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * kdu-router v4.1.6
3
- * (c) 2023 NKDuy
2
+ * kdu-router v4.2.0
3
+ * (c) 2024 NKDuy
4
4
  * @license MIT
5
5
  */
6
- var KduRouter=function(e,t){"use strict";const n="undefined"!=typeof window;function r(e){return e.__esModule||"Module"===e[Symbol.toStringTag]}const o=Object.assign;function a(e,t){const n={};for(const r in t){const o=t[r];n[r]=s(o)?o.map(e):e(o)}return n}const c=()=>{},s=Array.isArray,i=/\/$/;function l(e,t,n="/"){let r,o={},a="",c="";const s=t.indexOf("#");let i=t.indexOf("?");return s<i&&s>=0&&(i=-1),i>-1&&(r=t.slice(0,i),a=t.slice(i+1,s>-1?s:t.length),o=e(a)),s>-1&&(r=r||t.slice(0,s),c=t.slice(s,t.length)),r=function(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),r=e.split("/");let o,a,c=n.length-1;for(o=0;o<r.length;o++)if(a=r[o],"."!==a){if(".."!==a)break;c>1&&c--}return n.slice(0,c).join("/")+"/"+r.slice(o-(o===r.length?1:0)).join("/")}(null!=r?r:t,n),{fullPath:r+(a&&"?")+a+c,path:r,query:o,hash:c}}function u(e,t){return t&&e.toLowerCase().startsWith(t.toLowerCase())?e.slice(t.length)||"/":e}function f(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function p(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!h(e[n],t[n]))return!1;return!0}function h(e,t){return s(e)?d(e,t):s(t)?d(t,e):e===t}function d(e,t){return s(t)?e.length===t.length&&e.every(((e,n)=>e===t[n])):1===e.length&&e[0]===t}var m,g;!function(e){e.pop="pop",e.push="push"}(m||(m={})),function(e){e.back="back",e.forward="forward",e.unknown=""}(g||(g={}));function v(e){if(!e)if(n){const t=document.querySelector("base");e=(e=t&&t.getAttribute("href")||"/").replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return"/"!==e[0]&&"#"!==e[0]&&(e="/"+e),e.replace(i,"")}const y=/^[^#]+#/;function b(e,t){return e.replace(y,"#")+t}const w=()=>({left:window.pageXOffset,top:window.pageYOffset});function E(e){let t;if("el"in e){const n=e.el,r="string"==typeof n&&n.startsWith("#"),o="string"==typeof n?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!o)return;t=function(e,t){const n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}(o,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(null!=t.left?t.left:window.pageXOffset,null!=t.top?t.top:window.pageYOffset)}function R(e,t){return(history.state?history.state.position-t:-1)+e}const k=new Map;let O=()=>location.protocol+"//"+location.host;function j(e,t){const{pathname:n,search:r,hash:o}=t,a=e.indexOf("#");if(a>-1){let t=o.includes(e.slice(a))?e.slice(a).length:1,n=o.slice(t);return"/"!==n[0]&&(n="/"+n),u(n,"")}return u(n,e)+r+o}function P(e,t,n,r=!1,o=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:o?w():null}}function C(e){const t=function(e){const{history:t,location:n}=window,r={value:j(e,n)},a={value:t.state};function c(r,o,c){const s=e.indexOf("#"),i=s>-1?(n.host&&document.querySelector("base")?e:e.slice(s))+r:O()+e+r;try{t[c?"replaceState":"pushState"](o,"",i),a.value=o}catch(e){console.error(e),n[c?"replace":"assign"](i)}}return a.value||c(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0),{location:r,state:a,push:function(e,n){const s=o({},a.value,t.state,{forward:e,scroll:w()});c(s.current,s,!0),c(e,o({},P(r.value,e,null),{position:s.position+1},n),!1),r.value=e},replace:function(e,n){c(e,o({},t.state,P(a.value.back,e,a.value.forward,!0),n,{position:a.value.position}),!0),r.value=e}}}(e=v(e)),n=function(e,t,n,r){let a=[],c=[],s=null;const i=({state:o})=>{const c=j(e,location),i=n.value,l=t.value;let u=0;if(o){if(n.value=c,t.value=o,s&&s===i)return void(s=null);u=l?o.position-l.position:0}else r(c);a.forEach((e=>{e(n.value,i,{delta:u,type:m.pop,direction:u?u>0?g.forward:g.back:g.unknown})}))};function l(){const{history:e}=window;e.state&&e.replaceState(o({},e.state,{scroll:w()}),"")}return window.addEventListener("popstate",i),window.addEventListener("beforeunload",l),{pauseListeners:function(){s=n.value},listen:function(e){a.push(e);const t=()=>{const t=a.indexOf(e);t>-1&&a.splice(t,1)};return c.push(t),t},destroy:function(){for(const e of c)e();c=[],window.removeEventListener("popstate",i),window.removeEventListener("beforeunload",l)}}}(e,t.state,t.location,t.replace);const r=o({location:"",base:e,go:function(e,t=!0){t||n.pauseListeners(),history.go(e)},createHref:b.bind(null,e)},t,n);return Object.defineProperty(r,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(r,"state",{enumerable:!0,get:()=>t.state.value}),r}function x(e){return"string"==typeof e||"symbol"==typeof e}const $={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},S=Symbol("");var A;function L(e,t){return o(new Error,{type:e,[S]:!0},t)}function M(e,t){return e instanceof Error&&S in e&&(null==t||!!(e.type&t))}e.NavigationFailureType=void 0,(A=e.NavigationFailureType||(e.NavigationFailureType={}))[A.aborted=4]="aborted",A[A.cancelled=8]="cancelled",A[A.duplicated=16]="duplicated";const q="[^/]+?",B={sensitive:!1,strict:!1,start:!0,end:!0},T=/[.+*?^${}()[\]/\\]/g;function _(e,t){let n=0;for(;n<e.length&&n<t.length;){const r=t[n]-e[n];if(r)return r;n++}return e.length<t.length?1===e.length&&80===e[0]?-1:1:e.length>t.length?1===t.length&&80===t[0]?1:-1:0}function G(e,t){let n=0;const r=e.score,o=t.score;for(;n<r.length&&n<o.length;){const e=_(r[n],o[n]);if(e)return e;n++}if(1===Math.abs(o.length-r.length)){if(K(r))return 1;if(K(o))return-1}return o.length-r.length}function K(e){const t=e[e.length-1];return e.length>0&&t[t.length-1]<0}const F={type:0,value:""},D=/[a-zA-Z0-9_]/;function I(e,t,n){const r=function(e,t){const n=o({},B,t),r=[];let a=n.start?"^":"";const c=[];for(const t of e){const e=t.length?[]:[90];n.strict&&!t.length&&(a+="/");for(let r=0;r<t.length;r++){const o=t[r];let s=40+(n.sensitive?.25:0);if(0===o.type)r||(a+="/"),a+=o.value.replace(T,"\\$&"),s+=40;else if(1===o.type){const{value:e,repeatable:n,optional:i,regexp:l}=o;c.push({name:e,repeatable:n,optional:i});const u=l||q;if(u!==q){s+=10;try{new RegExp(`(${u})`)}catch(t){throw new Error(`Invalid custom RegExp for param "${e}" (${u}): `+t.message)}}let f=n?`((?:${u})(?:/(?:${u}))*)`:`(${u})`;r||(f=i&&t.length<2?`(?:/${f})`:"/"+f),i&&(f+="?"),a+=f,s+=20,i&&(s+=-8),n&&(s+=-20),".*"===u&&(s+=-50)}e.push(s)}r.push(e)}if(n.strict&&n.end){const e=r.length-1;r[e][r[e].length-1]+=.7000000000000001}n.strict||(a+="/?"),n.end?a+="$":n.strict&&(a+="(?:/|$)");const i=new RegExp(a,n.sensitive?"":"i");return{re:i,score:r,keys:c,parse:function(e){const t=e.match(i),n={};if(!t)return null;for(let e=1;e<t.length;e++){const r=t[e]||"",o=c[e-1];n[o.name]=r&&o.repeatable?r.split("/"):r}return n},stringify:function(t){let n="",r=!1;for(const o of e){r&&n.endsWith("/")||(n+="/"),r=!1;for(const e of o)if(0===e.type)n+=e.value;else if(1===e.type){const{value:a,repeatable:c,optional:i}=e,l=a in t?t[a]:"";if(s(l)&&!c)throw new Error(`Provided param "${a}" is an array but it is not repeatable (* or + modifiers)`);const u=s(l)?l.join("/"):l;if(!u){if(!i)throw new Error(`Missing required param "${a}"`);o.length<2&&(n.endsWith("/")?n=n.slice(0,-1):r=!0)}n+=u}}return n||"/"}}}(function(e){if(!e)return[[]];if("/"===e)return[[F]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(e){throw new Error(`ERR (${n})/"${l}": ${e}`)}let n=0,r=n;const o=[];let a;function c(){a&&o.push(a),a=[]}let s,i=0,l="",u="";function f(){l&&(0===n?a.push({type:0,value:l}):1===n||2===n||3===n?(a.length>1&&("*"===s||"+"===s)&&t(`A repeatable param (${l}) must be alone in its segment. eg: '/:ids+.`),a.push({type:1,value:l,regexp:u,repeatable:"*"===s||"+"===s,optional:"*"===s||"?"===s})):t("Invalid state to consume buffer"),l="")}function p(){l+=s}for(;i<e.length;)if(s=e[i++],"\\"!==s||2===n)switch(n){case 0:"/"===s?(l&&f(),c()):":"===s?(f(),n=1):p();break;case 4:p(),n=r;break;case 1:"("===s?n=2:D.test(s)?p():(f(),n=0,"*"!==s&&"?"!==s&&"+"!==s&&i--);break;case 2:")"===s?"\\"==u[u.length-1]?u=u.slice(0,-1)+s:n=3:u+=s;break;case 3:f(),n=0,"*"!==s&&"?"!==s&&"+"!==s&&i--,u="";break;default:t("Unknown state")}else r=n,n=4;return 2===n&&t(`Unfinished custom RegExp for param "${l}"`),f(),c(),o}(e.path),n),a=o(r,{record:e,parent:t,children:[],alias:[]});return t&&!a.record.aliasOf==!t.record.aliasOf&&t.children.push(a),a}function U(e,t){const n=[],r=new Map;function a(e,n,r){const l=!r,u=function(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:W(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}(e);u.aliasOf=r&&r.record;const f=z(t,e),p=[u];if("alias"in e){const t="string"==typeof e.alias?[e.alias]:e.alias;for(const e of t)p.push(o({},u,{components:r?r.record.components:u.components,path:e,aliasOf:r?r.record:u}))}let h,d;for(const t of p){const{path:o}=t;if(n&&"/"!==o[0]){const e=n.record.path,r="/"===e[e.length-1]?"":"/";t.path=n.record.path+(o&&r+o)}if(h=I(t,n,f),r?r.alias.push(h):(d=d||h,d!==h&&d.alias.push(h),l&&e.name&&!N(h)&&s(e.name)),u.children){const e=u.children;for(let t=0;t<e.length;t++)a(e[t],h,r&&r.children[t])}r=r||h,(h.record.components&&Object.keys(h.record.components).length||h.record.name||h.record.redirect)&&i(h)}return d?()=>{s(d)}:c}function s(e){if(x(e)){const t=r.get(e);t&&(r.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(s),t.alias.forEach(s))}else{const t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&r.delete(e.record.name),e.children.forEach(s),e.alias.forEach(s))}}function i(e){let t=0;for(;t<n.length&&G(e,n[t])>=0&&(e.record.path!==n[t].record.path||!Q(e,n[t]));)t++;n.splice(t,0,e),e.record.name&&!N(e)&&r.set(e.record.name,e)}return t=z({strict:!1,end:!0,sensitive:!1},t),e.forEach((e=>a(e))),{addRoute:a,resolve:function(e,t){let a,c,s,i={};if("name"in e&&e.name){if(a=r.get(e.name),!a)throw L(1,{location:e});s=a.record.name,i=o(H(t.params,a.keys.filter((e=>!e.optional)).map((e=>e.name))),e.params&&H(e.params,a.keys.map((e=>e.name)))),c=a.stringify(i)}else if("path"in e)c=e.path,a=n.find((e=>e.re.test(c))),a&&(i=a.parse(c),s=a.record.name);else{if(a=t.name?r.get(t.name):n.find((e=>e.re.test(t.path))),!a)throw L(1,{location:e,currentLocation:t});s=a.record.name,i=o({},t.params,e.params),c=a.stringify(i)}const l=[];let u=a;for(;u;)l.unshift(u.record),u=u.parent;return{name:s,path:c,params:i,matched:l,meta:V(l)}},removeRoute:s,getRoutes:function(){return n},getRecordMatcher:function(e){return r.get(e)}}}function H(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}function W(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const r in e.components)t[r]="boolean"==typeof n?n:n[r];return t}function N(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function V(e){return e.reduce(((e,t)=>o(e,t.meta)),{})}function z(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];return n}function Q(e,t){return t.children.some((t=>t===e||Q(e,t)))}const X=/#/g,Y=/&/g,Z=/\//g,J=/=/g,ee=/\?/g,te=/\+/g,ne=/%5B/g,re=/%5D/g,oe=/%5E/g,ae=/%60/g,ce=/%7B/g,se=/%7C/g,ie=/%7D/g,le=/%20/g;function ue(e){return encodeURI(""+e).replace(se,"|").replace(ne,"[").replace(re,"]")}function fe(e){return ue(e).replace(te,"%2B").replace(le,"+").replace(X,"%23").replace(Y,"%26").replace(ae,"`").replace(ce,"{").replace(ie,"}").replace(oe,"^")}function pe(e){return null==e?"":function(e){return ue(e).replace(X,"%23").replace(ee,"%3F")}(e).replace(Z,"%2F")}function he(e){try{return decodeURIComponent(""+e)}catch(e){}return""+e}function de(e){const t={};if(""===e||"?"===e)return t;const n=("?"===e[0]?e.slice(1):e).split("&");for(let e=0;e<n.length;++e){const r=n[e].replace(te," "),o=r.indexOf("="),a=he(o<0?r:r.slice(0,o)),c=o<0?null:he(r.slice(o+1));if(a in t){let e=t[a];s(e)||(e=t[a]=[e]),e.push(c)}else t[a]=c}return t}function me(e){let t="";for(let n in e){const r=e[n];if(n=fe(n).replace(J,"%3D"),null==r){void 0!==r&&(t+=(t.length?"&":"")+n);continue}(s(r)?r.map((e=>e&&fe(e))):[r&&fe(r)]).forEach((e=>{void 0!==e&&(t+=(t.length?"&":"")+n,null!=e&&(t+="="+e))}))}return t}function ge(e){const t={};for(const n in e){const r=e[n];void 0!==r&&(t[n]=s(r)?r.map((e=>null==e?null:""+e)):null==r?r:""+r)}return t}const ve=Symbol(""),ye=Symbol(""),be=Symbol(""),we=Symbol(""),Ee=Symbol("");function Re(){let e=[];return{add:function(t){return e.push(t),()=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)}},list:()=>e,reset:function(){e=[]}}}function ke(e,n,r){const o=()=>{e[n].delete(r)};t.onUnmounted(o),t.onDeactivated(o),t.onActivated((()=>{e[n].add(r)})),e[n].add(r)}function Oe(e,t,n,r,o){const a=r&&(r.enterCallbacks[o]=r.enterCallbacks[o]||[]);return()=>new Promise(((c,s)=>{const i=e=>{var i;!1===e?s(L(4,{from:n,to:t})):e instanceof Error?s(e):"string"==typeof(i=e)||i&&"object"==typeof i?s(L(2,{from:t,to:e})):(a&&r.enterCallbacks[o]===a&&"function"==typeof e&&a.push(e),c())},l=e.call(r&&r.instances[o],t,n,i);let u=Promise.resolve(l);e.length<3&&(u=u.then(i)),u.catch((e=>s(e)))}))}function je(e,t,n,o){const a=[];for(const s of e)for(const e in s.components){let i=s.components[e];if("beforeRouteEnter"===t||s.instances[e])if("object"==typeof(c=i)||"displayName"in c||"props"in c||"__kccOpts"in c){const r=(i.__kccOpts||i)[t];r&&a.push(Oe(r,n,o,s,e))}else{let c=i();a.push((()=>c.then((a=>{if(!a)return Promise.reject(new Error(`Couldn't resolve component "${e}" at "${s.path}"`));const c=r(a)?a.default:a;s.components[e]=c;const i=(c.__kccOpts||c)[t];return i&&Oe(i,n,o,s,e)()}))))}}var c;return a}function Pe(e){const n=t.inject(be),r=t.inject(we),o=t.computed((()=>n.resolve(t.unref(e.to)))),a=t.computed((()=>{const{matched:e}=o.value,{length:t}=e,n=e[t-1],a=r.matched;if(!n||!a.length)return-1;const c=a.findIndex(f.bind(null,n));if(c>-1)return c;const s=xe(e[t-2]);return t>1&&xe(n)===s&&a[a.length-1].path!==s?a.findIndex(f.bind(null,e[t-2])):c})),i=t.computed((()=>a.value>-1&&function(e,t){for(const n in t){const r=t[n],o=e[n];if("string"==typeof r){if(r!==o)return!1}else if(!s(o)||o.length!==r.length||r.some(((e,t)=>e!==o[t])))return!1}return!0}(r.params,o.value.params))),l=t.computed((()=>a.value>-1&&a.value===r.matched.length-1&&p(r.params,o.value.params)));return{route:o,href:t.computed((()=>o.value.href)),isActive:i,isExactActive:l,navigate:function(r={}){return function(e){if(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)return;if(e.defaultPrevented)return;if(void 0!==e.button&&0!==e.button)return;if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}e.preventDefault&&e.preventDefault();return!0}(r)?n[t.unref(e.replace)?"replace":"push"](t.unref(e.to)).catch(c):Promise.resolve()}}}const Ce=t.defineComponent({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Pe,setup(e,{slots:n}){const r=t.reactive(Pe(e)),{options:o}=t.inject(be),a=t.computed((()=>({[$e(e.activeClass,o.linkActiveClass,"router-link-active")]:r.isActive,[$e(e.exactActiveClass,o.linkExactActiveClass,"router-link-exact-active")]:r.isExactActive})));return()=>{const o=n.default&&n.default(r);return e.custom?o:t.h("a",{"aria-current":r.isExactActive?e.ariaCurrentValue:null,href:r.href,onClick:r.navigate,class:a.value},o)}}});function xe(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const $e=(e,t,n)=>null!=e?e:null!=t?t:n;function Se(e,t){if(!e)return null;const n=e(t);return 1===n.length?n[0]:n}const Ae=t.defineComponent({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:n,slots:r}){const a=t.inject(Ee),c=t.computed((()=>e.route||a.value)),s=t.inject(ye,0),i=t.computed((()=>{let e=t.unref(s);const{matched:n}=c.value;let r;for(;(r=n[e])&&!r.components;)e++;return e})),l=t.computed((()=>c.value.matched[i.value]));t.provide(ye,t.computed((()=>i.value+1))),t.provide(ve,l),t.provide(Ee,c);const u=t.ref();return t.watch((()=>[u.value,l.value,e.name]),(([e,t,n],[r,o,a])=>{t&&(t.instances[n]=e,o&&o!==t&&e&&e===r&&(t.leaveGuards.size||(t.leaveGuards=o.leaveGuards),t.updateGuards.size||(t.updateGuards=o.updateGuards))),!e||!t||o&&f(t,o)&&r||(t.enterCallbacks[n]||[]).forEach((t=>t(e)))}),{flush:"post"}),()=>{const a=c.value,s=e.name,i=l.value,f=i&&i.components[s];if(!f)return Se(r.default,{Component:f,route:a});const p=i.props[s],h=p?!0===p?a.params:"function"==typeof p?p(a):p:null,d=t.h(f,o({},h,n,{onKnodeUnmounted:e=>{e.component.isUnmounted&&(i.instances[s]=null)},ref:u}));return Se(r.default,{Component:d,route:a})||d}}});function Le(e){return e.reduce(((e,t)=>e.then((()=>t()))),Promise.resolve())}return e.RouterLink=Ce,e.RouterView=Ae,e.START_LOCATION=$,e.createMemoryHistory=function(e=""){let t=[],n=[""],r=0;function o(e){r++,r===n.length||n.splice(r),n.push(e)}const a={location:"",state:{},base:e=v(e),createHref:b.bind(null,e),replace(e){n.splice(r--,1),o(e)},push(e,t){o(e)},listen:e=>(t.push(e),()=>{const n=t.indexOf(e);n>-1&&t.splice(n,1)}),destroy(){t=[],n=[""],r=0},go(e,o=!0){const a=this.location,c=e<0?g.back:g.forward;r=Math.max(0,Math.min(r+e,n.length-1)),o&&function(e,n,{direction:r,delta:o}){const a={direction:r,delta:o,type:m.pop};for(const r of t)r(e,n,a)}(this.location,a,{direction:c,delta:e})}};return Object.defineProperty(a,"location",{enumerable:!0,get:()=>n[r]}),a},e.createRouter=function(e){const r=U(e.routes,e),i=e.parseQuery||de,u=e.stringifyQuery||me,h=e.history,d=Re(),g=Re(),v=Re(),y=t.shallowRef($);let b=$;n&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const O=a.bind(null,(e=>""+e)),j=a.bind(null,pe),P=a.bind(null,he);function C(e,t){if(t=o({},t||y.value),"string"==typeof e){const n=l(i,e,t.path),a=r.resolve({path:n.path},t),c=h.createHref(n.fullPath);return o(n,a,{params:P(a.params),hash:he(n.hash),redirectedFrom:void 0,href:c})}let n;if("path"in e)n=o({},e,{path:l(i,e.path,t.path).path});else{const r=o({},e.params);for(const e in r)null==r[e]&&delete r[e];n=o({},e,{params:j(e.params)}),t.params=j(t.params)}const a=r.resolve(n,t),c=e.hash||"";a.params=O(P(a.params));const s=function(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}(u,o({},e,{hash:(f=c,ue(f).replace(ce,"{").replace(ie,"}").replace(oe,"^")),path:a.path}));var f;const p=h.createHref(s);return o({fullPath:s,hash:c,query:u===me?ge(e.query):e.query||{}},a,{redirectedFrom:void 0,href:p})}function S(e){return"string"==typeof e?l(i,e,y.value.path):o({},e)}function A(e,t){if(b!==e)return L(8,{from:t,to:e})}function q(e){return T(e)}function B(e){const t=e.matched[e.matched.length-1];if(t&&t.redirect){const{redirect:n}=t;let r="function"==typeof n?n(e):n;return"string"==typeof r&&(r=r.includes("?")||r.includes("#")?r=S(r):{path:r},r.params={}),o({query:e.query,hash:e.hash,params:"path"in r?{}:e.params},r)}}function T(e,t){const n=b=C(e),r=y.value,a=e.state,c=e.force,s=!0===e.replace,i=B(n);if(i)return T(o(S(i),{state:"object"==typeof i?o({},a,i.state):a,force:c,replace:s}),t||n);const l=n;let h;return l.redirectedFrom=t,!c&&function(e,t,n){const r=t.matched.length-1,o=n.matched.length-1;return r>-1&&r===o&&f(t.matched[r],n.matched[o])&&p(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}(u,r,n)&&(h=L(16,{to:l,from:r}),Q(r,r,!0,!1)),(h?Promise.resolve(h):G(l,r)).catch((e=>M(e)?M(e,2)?e:z(e):V(e,l,r))).then((e=>{if(e){if(M(e,2))return T(o({replace:s},S(e.to),{state:"object"==typeof e.to?o({},a,e.to.state):a,force:c}),t||l)}else e=F(l,r,!0,s,a);return K(l,r,e),e}))}function _(e,t){const n=A(e,t);return n?Promise.reject(n):Promise.resolve()}function G(e,t){let n;const[r,o,a]=function(e,t){const n=[],r=[],o=[],a=Math.max(t.matched.length,e.matched.length);for(let c=0;c<a;c++){const a=t.matched[c];a&&(e.matched.find((e=>f(e,a)))?r.push(a):n.push(a));const s=e.matched[c];s&&(t.matched.find((e=>f(e,s)))||o.push(s))}return[n,r,o]}(e,t);n=je(r.reverse(),"beforeRouteLeave",e,t);for(const o of r)o.leaveGuards.forEach((r=>{n.push(Oe(r,e,t))}));const c=_.bind(null,e,t);return n.push(c),Le(n).then((()=>{n=[];for(const r of d.list())n.push(Oe(r,e,t));return n.push(c),Le(n)})).then((()=>{n=je(o,"beforeRouteUpdate",e,t);for(const r of o)r.updateGuards.forEach((r=>{n.push(Oe(r,e,t))}));return n.push(c),Le(n)})).then((()=>{n=[];for(const r of e.matched)if(r.beforeEnter&&!t.matched.includes(r))if(s(r.beforeEnter))for(const o of r.beforeEnter)n.push(Oe(o,e,t));else n.push(Oe(r.beforeEnter,e,t));return n.push(c),Le(n)})).then((()=>(e.matched.forEach((e=>e.enterCallbacks={})),n=je(a,"beforeRouteEnter",e,t),n.push(c),Le(n)))).then((()=>{n=[];for(const r of g.list())n.push(Oe(r,e,t));return n.push(c),Le(n)})).catch((e=>M(e,8)?e:Promise.reject(e)))}function K(e,t,n){for(const r of v.list())r(e,t,n)}function F(e,t,r,a,c){const s=A(e,t);if(s)return s;const i=t===$,l=n?history.state:{};r&&(a||i?h.replace(e.fullPath,o({scroll:i&&l&&l.scroll},c)):h.push(e.fullPath,c)),y.value=e,Q(e,t,r,i),z()}let D;function I(){D||(D=h.listen(((e,t,r)=>{if(!J.listening)return;const a=C(e),s=B(a);if(s)return void T(o(s,{replace:!0}),a).catch(c);b=a;const i=y.value;var l,u;n&&(l=R(i.fullPath,r.delta),u=w(),k.set(l,u)),G(a,i).catch((e=>M(e,12)?e:M(e,2)?(T(e.to,a).then((e=>{M(e,20)&&!r.delta&&r.type===m.pop&&h.go(-1,!1)})).catch(c),Promise.reject()):(r.delta&&h.go(-r.delta,!1),V(e,a,i)))).then((e=>{(e=e||F(a,i,!1))&&(r.delta&&!M(e,8)?h.go(-r.delta,!1):r.type===m.pop&&M(e,20)&&h.go(-1,!1)),K(a,i,e)})).catch(c)})))}let H,W=Re(),N=Re();function V(e,t,n){z(e);const r=N.list();return r.length?r.forEach((r=>r(e,t,n))):console.error(e),Promise.reject(e)}function z(e){return H||(H=!e,I(),W.list().forEach((([t,n])=>e?n(e):t())),W.reset()),e}function Q(r,o,a,c){const{scrollBehavior:s}=e;if(!n||!s)return Promise.resolve();const i=!a&&function(e){const t=k.get(e);return k.delete(e),t}(R(r.fullPath,0))||(c||!a)&&history.state&&history.state.scroll||null;return t.nextTick().then((()=>s(r,o,i))).then((e=>e&&E(e))).catch((e=>V(e,r,o)))}const X=e=>h.go(e);let Y;const Z=new Set,J={currentRoute:y,listening:!0,addRoute:function(e,t){let n,o;return x(e)?(n=r.getRecordMatcher(e),o=t):o=e,r.addRoute(o,n)},removeRoute:function(e){const t=r.getRecordMatcher(e);t&&r.removeRoute(t)},hasRoute:function(e){return!!r.getRecordMatcher(e)},getRoutes:function(){return r.getRoutes().map((e=>e.record))},resolve:C,options:e,push:q,replace:function(e){return q(o(S(e),{replace:!0}))},go:X,back:()=>X(-1),forward:()=>X(1),beforeEach:d.add,beforeResolve:g.add,afterEach:v.add,onError:N.add,isReady:function(){return H&&y.value!==$?Promise.resolve():new Promise(((e,t)=>{W.add([e,t])}))},install(e){e.component("RouterLink",Ce),e.component("RouterView",Ae),e.config.globalProperties.$router=this,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>t.unref(y)}),n&&!Y&&y.value===$&&(Y=!0,q(h.location).catch((e=>{})));const r={};for(const e in $)r[e]=t.computed((()=>y.value[e]));e.provide(be,this),e.provide(we,t.reactive(r)),e.provide(Ee,y);const o=e.unmount;Z.add(e),e.unmount=function(){Z.delete(e),Z.size<1&&(b=$,D&&D(),D=null,y.value=$,Y=!1,H=!1),o()}}};return J},e.createRouterMatcher=U,e.createWebHashHistory=function(e){return(e=location.host?e||location.pathname+location.search:"").includes("#")||(e+="#"),C(e)},e.createWebHistory=C,e.isNavigationFailure=M,e.loadRouteLocation=function(e){return e.matched.every((e=>e.redirect))?Promise.reject(new Error("Cannot load a route that redirects.")):Promise.all(e.matched.map((e=>e.components&&Promise.all(Object.keys(e.components).reduce(((t,n)=>{const o=e.components[n];return"function"!=typeof o||"displayName"in o||t.push(o().then((t=>{if(!t)return Promise.reject(new Error(`Couldn't resolve component "${n}" at "${e.path}". Ensure you passed a function that returns a promise.`));const o=r(t)?t.default:t;e.components[n]=o}))),t}),[]))))).then((()=>e))},e.matchedRouteKey=ve,e.onBeforeRouteLeave=function(e){const n=t.inject(ve,{}).value;n&&ke(n,"leaveGuards",e)},e.onBeforeRouteUpdate=function(e){const n=t.inject(ve,{}).value;n&&ke(n,"updateGuards",e)},e.parseQuery=de,e.routeLocationKey=we,e.routerKey=be,e.routerViewLocationKey=Ee,e.stringifyQuery=me,e.useLink=Pe,e.useRoute=function(){return t.inject(we)},e.useRouter=function(){return t.inject(be)},e.viewDepthKey=ye,Object.defineProperty(e,"__esModule",{value:!0}),e}({},Kdu);
6
+ var KduRouter=function(e,t){"use strict";const n="undefined"!=typeof window;function r(e){return e.__esModule||"Module"===e[Symbol.toStringTag]}const o=Object.assign;function a(e,t){const n={};for(const r in t){const o=t[r];n[r]=s(o)?o.map(e):e(o)}return n}const c=()=>{},s=Array.isArray,i=/\/$/,u=e=>e.replace(i,"");function l(e,t,n="/"){let r,o={},a="",c="";const s=t.indexOf("#");let i=t.indexOf("?");return s<i&&s>=0&&(i=-1),i>-1&&(r=t.slice(0,i),a=t.slice(i+1,s>-1?s:t.length),o=e(a)),s>-1&&(r=r||t.slice(0,s),c=t.slice(s,t.length)),r=function(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),r=e.split("/"),o=r[r.length-1];".."!==o&&"."!==o||r.push("");let a,c,s=n.length-1;for(a=0;a<r.length;a++)if(c=r[a],"."!==c){if(".."!==c)break;s>1&&s--}return n.slice(0,s).join("/")+"/"+r.slice(a-(a===r.length?1:0)).join("/")}(null!=r?r:t,n),{fullPath:r+(a&&"?")+a+c,path:r,query:o,hash:c}}function f(e,t){return t&&e.toLowerCase().startsWith(t.toLowerCase())?e.slice(t.length)||"/":e}function p(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function h(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!d(e[n],t[n]))return!1;return!0}function d(e,t){return s(e)?m(e,t):s(t)?m(t,e):e===t}function m(e,t){return s(t)?e.length===t.length&&e.every(((e,n)=>e===t[n])):1===e.length&&e[0]===t}var g,v;!function(e){e.pop="pop",e.push="push"}(g||(g={})),function(e){e.back="back",e.forward="forward",e.unknown=""}(v||(v={}));const y="";function b(e){if(!e)if(n){const t=document.querySelector("base");e=(e=t&&t.getAttribute("href")||"/").replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return"/"!==e[0]&&"#"!==e[0]&&(e="/"+e),u(e)}const w=/^[^#]+#/;function E(e,t){return e.replace(w,"#")+t}const R=()=>({left:window.pageXOffset,top:window.pageYOffset});function k(e){let t;if("el"in e){const n=e.el,r="string"==typeof n&&n.startsWith("#"),o="string"==typeof n?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!o)return;t=function(e,t){const n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}(o,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(null!=t.left?t.left:window.pageXOffset,null!=t.top?t.top:window.pageYOffset)}function O(e,t){return(history.state?history.state.position-t:-1)+e}const j=new Map;let P=()=>location.protocol+"//"+location.host;function C(e,t){const{pathname:n,search:r,hash:o}=t,a=e.indexOf("#");if(a>-1){let t=o.includes(e.slice(a))?e.slice(a).length:1,n=o.slice(t);return"/"!==n[0]&&(n="/"+n),f(n,"")}return f(n,e)+r+o}function x(e,t,n,r=!1,o=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:o?R():null}}function $(e){const t=function(e){const{history:t,location:n}=window,r={value:C(e,n)},a={value:t.state};function c(r,o,c){const s=e.indexOf("#"),i=s>-1?(n.host&&document.querySelector("base")?e:e.slice(s))+r:P()+e+r;try{t[c?"replaceState":"pushState"](o,"",i),a.value=o}catch(e){console.error(e),n[c?"replace":"assign"](i)}}return a.value||c(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0),{location:r,state:a,push:function(e,n){const s=o({},a.value,t.state,{forward:e,scroll:R()});c(s.current,s,!0),c(e,o({},x(r.value,e,null),{position:s.position+1},n),!1),r.value=e},replace:function(e,n){c(e,o({},t.state,x(a.value.back,e,a.value.forward,!0),n,{position:a.value.position}),!0),r.value=e}}}(e=b(e)),n=function(e,t,n,r){let a=[],c=[],s=null;const i=({state:o})=>{const c=C(e,location),i=n.value,u=t.value;let l=0;if(o){if(n.value=c,t.value=o,s&&s===i)return void(s=null);l=u?o.position-u.position:0}else r(c);a.forEach((e=>{e(n.value,i,{delta:l,type:g.pop,direction:l?l>0?v.forward:v.back:v.unknown})}))};function u(){const{history:e}=window;e.state&&e.replaceState(o({},e.state,{scroll:R()}),"")}return window.addEventListener("popstate",i),window.addEventListener("beforeunload",u,{passive:!0}),{pauseListeners:function(){s=n.value},listen:function(e){a.push(e);const t=()=>{const t=a.indexOf(e);t>-1&&a.splice(t,1)};return c.push(t),t},destroy:function(){for(const e of c)e();c=[],window.removeEventListener("popstate",i),window.removeEventListener("beforeunload",u)}}}(e,t.state,t.location,t.replace);const r=o({location:"",base:e,go:function(e,t=!0){t||n.pauseListeners(),history.go(e)},createHref:E.bind(null,e)},t,n);return Object.defineProperty(r,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(r,"state",{enumerable:!0,get:()=>t.state.value}),r}function S(e){return"string"==typeof e||"symbol"==typeof e}const A={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},L=Symbol("");var M;function q(e,t){return o(new Error,{type:e,[L]:!0},t)}function B(e,t){return e instanceof Error&&L in e&&(null==t||!!(e.type&t))}e.NavigationFailureType=void 0,(M=e.NavigationFailureType||(e.NavigationFailureType={}))[M.aborted=4]="aborted",M[M.cancelled=8]="cancelled",M[M.duplicated=16]="duplicated";const T="[^/]+?",G={sensitive:!1,strict:!1,start:!0,end:!0},K=/[.+*?^${}()[\]/\\]/g;function _(e,t){let n=0;for(;n<e.length&&n<t.length;){const r=t[n]-e[n];if(r)return r;n++}return e.length<t.length?1===e.length&&80===e[0]?-1:1:e.length>t.length?1===t.length&&80===t[0]?1:-1:0}function F(e,t){let n=0;const r=e.score,o=t.score;for(;n<r.length&&n<o.length;){const e=_(r[n],o[n]);if(e)return e;n++}if(1===Math.abs(o.length-r.length)){if(W(r))return 1;if(W(o))return-1}return o.length-r.length}function W(e){const t=e[e.length-1];return e.length>0&&t[t.length-1]<0}const D={type:0,value:""},I=/[a-zA-Z0-9_]/;function U(e,t,n){const r=function(e,t){const n=o({},G,t),r=[];let a=n.start?"^":"";const c=[];for(const t of e){const e=t.length?[]:[90];n.strict&&!t.length&&(a+="/");for(let r=0;r<t.length;r++){const o=t[r];let s=40+(n.sensitive?.25:0);if(0===o.type)r||(a+="/"),a+=o.value.replace(K,"\\$&"),s+=40;else if(1===o.type){const{value:e,repeatable:n,optional:i,regexp:u}=o;c.push({name:e,repeatable:n,optional:i});const l=u||T;if(l!==T){s+=10;try{new RegExp(`(${l})`)}catch(t){throw new Error(`Invalid custom RegExp for param "${e}" (${l}): `+t.message)}}let f=n?`((?:${l})(?:/(?:${l}))*)`:`(${l})`;r||(f=i&&t.length<2?`(?:/${f})`:"/"+f),i&&(f+="?"),a+=f,s+=20,i&&(s+=-8),n&&(s+=-20),".*"===l&&(s+=-50)}e.push(s)}r.push(e)}if(n.strict&&n.end){const e=r.length-1;r[e][r[e].length-1]+=.7000000000000001}n.strict||(a+="/?"),n.end?a+="$":n.strict&&(a+="(?:/|$)");const i=new RegExp(a,n.sensitive?"":"i");return{re:i,score:r,keys:c,parse:function(e){const t=e.match(i),n={};if(!t)return null;for(let e=1;e<t.length;e++){const r=t[e]||"",o=c[e-1];n[o.name]=r&&o.repeatable?r.split("/"):r}return n},stringify:function(t){let n="",r=!1;for(const o of e){r&&n.endsWith("/")||(n+="/"),r=!1;for(const e of o)if(0===e.type)n+=e.value;else if(1===e.type){const{value:a,repeatable:c,optional:i}=e,u=a in t?t[a]:"";if(s(u)&&!c)throw new Error(`Provided param "${a}" is an array but it is not repeatable (* or + modifiers)`);const l=s(u)?u.join("/"):u;if(!l){if(!i)throw new Error(`Missing required param "${a}"`);o.length<2&&(n.endsWith("/")?n=n.slice(0,-1):r=!0)}n+=l}}return n||"/"}}}(function(e){if(!e)return[[]];if("/"===e)return[[D]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(e){throw new Error(`ERR (${n})/"${u}": ${e}`)}let n=0,r=n;const o=[];let a;function c(){a&&o.push(a),a=[]}let s,i=0,u="",l="";function f(){u&&(0===n?a.push({type:0,value:u}):1===n||2===n||3===n?(a.length>1&&("*"===s||"+"===s)&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),a.push({type:1,value:u,regexp:l,repeatable:"*"===s||"+"===s,optional:"*"===s||"?"===s})):t("Invalid state to consume buffer"),u="")}function p(){u+=s}for(;i<e.length;)if(s=e[i++],"\\"!==s||2===n)switch(n){case 0:"/"===s?(u&&f(),c()):":"===s?(f(),n=1):p();break;case 4:p(),n=r;break;case 1:"("===s?n=2:I.test(s)?p():(f(),n=0,"*"!==s&&"?"!==s&&"+"!==s&&i--);break;case 2:")"===s?"\\"==l[l.length-1]?l=l.slice(0,-1)+s:n=3:l+=s;break;case 3:f(),n=0,"*"!==s&&"?"!==s&&"+"!==s&&i--,l="";break;default:t("Unknown state")}else r=n,n=4;return 2===n&&t(`Unfinished custom RegExp for param "${u}"`),f(),c(),o}(e.path),n),a=o(r,{record:e,parent:t,children:[],alias:[]});return t&&!a.record.aliasOf==!t.record.aliasOf&&t.children.push(a),a}function H(e,t){const n=[],r=new Map;function a(e,n,r){const u=!r,l=function(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:V(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}(e);l.aliasOf=r&&r.record;const f=X(t,e),p=[l];if("alias"in e){const t="string"==typeof e.alias?[e.alias]:e.alias;for(const e of t)p.push(o({},l,{components:r?r.record.components:l.components,path:e,aliasOf:r?r.record:l}))}let h,d;for(const t of p){const{path:o}=t;if(n&&"/"!==o[0]){const e=n.record.path;t.path=n.record.path+(o&&("/"===e[e.length-1]?"":"/")+o)}if(h=U(t,n,f),r?r.alias.push(h):(d=d||h,d!==h&&d.alias.push(h),u&&e.name&&!z(h)&&s(e.name)),l.children){const e=l.children;for(let t=0;t<e.length;t++)a(e[t],h,r&&r.children[t])}r=r||h,(h.record.components&&Object.keys(h.record.components).length||h.record.name||h.record.redirect)&&i(h)}return d?()=>{s(d)}:c}function s(e){if(S(e)){const t=r.get(e);t&&(r.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(s),t.alias.forEach(s))}else{const t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&r.delete(e.record.name),e.children.forEach(s),e.alias.forEach(s))}}function i(e){let t=0;for(;t<n.length&&F(e,n[t])>=0&&(e.record.path!==n[t].record.path||!Y(e,n[t]));)t++;n.splice(t,0,e),e.record.name&&!z(e)&&r.set(e.record.name,e)}return t=X({strict:!1,end:!0,sensitive:!1},t),e.forEach((e=>a(e))),{addRoute:a,resolve:function(e,t){let a,c,s,i={};if("name"in e&&e.name){if(a=r.get(e.name),!a)throw q(1,{location:e});s=a.record.name,i=o(N(t.params,a.keys.filter((e=>!e.optional)).map((e=>e.name))),e.params&&N(e.params,a.keys.map((e=>e.name)))),c=a.stringify(i)}else if("path"in e)c=e.path,a=n.find((e=>e.re.test(c))),a&&(i=a.parse(c),s=a.record.name);else{if(a=t.name?r.get(t.name):n.find((e=>e.re.test(t.path))),!a)throw q(1,{location:e,currentLocation:t});s=a.record.name,i=o({},t.params,e.params),c=a.stringify(i)}const u=[];let l=a;for(;l;)u.unshift(l.record),l=l.parent;return{name:s,path:c,params:i,matched:u,meta:Q(u)}},removeRoute:s,getRoutes:function(){return n},getRecordMatcher:function(e){return r.get(e)}}}function N(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}function V(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const r in e.components)t[r]="boolean"==typeof n?n:n[r];return t}function z(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Q(e){return e.reduce(((e,t)=>o(e,t.meta)),{})}function X(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];return n}function Y(e,t){return t.children.some((t=>t===e||Y(e,t)))}const Z=/#/g,J=/&/g,ee=/\//g,te=/=/g,ne=/\?/g,re=/\+/g,oe=/%5B/g,ae=/%5D/g,ce=/%5E/g,se=/%60/g,ie=/%7B/g,ue=/%7C/g,le=/%7D/g,fe=/%20/g;function pe(e){return encodeURI(""+e).replace(ue,"|").replace(oe,"[").replace(ae,"]")}function he(e){return pe(e).replace(re,"%2B").replace(fe,"+").replace(Z,"%23").replace(J,"%26").replace(se,"`").replace(ie,"{").replace(le,"}").replace(ce,"^")}function de(e){return null==e?"":function(e){return pe(e).replace(Z,"%23").replace(ne,"%3F")}(e).replace(ee,"%2F")}function me(e){try{return decodeURIComponent(""+e)}catch(e){}return""+e}function ge(e){const t={};if(""===e||"?"===e)return t;const n=("?"===e[0]?e.slice(1):e).split("&");for(let e=0;e<n.length;++e){const r=n[e].replace(re," "),o=r.indexOf("="),a=me(o<0?r:r.slice(0,o)),c=o<0?null:me(r.slice(o+1));if(a in t){let e=t[a];s(e)||(e=t[a]=[e]),e.push(c)}else t[a]=c}return t}function ve(e){let t="";for(let n in e){const r=e[n];if(n=he(n).replace(te,"%3D"),null==r){void 0!==r&&(t+=(t.length?"&":"")+n);continue}(s(r)?r.map((e=>e&&he(e))):[r&&he(r)]).forEach((e=>{void 0!==e&&(t+=(t.length?"&":"")+n,null!=e&&(t+="="+e))}))}return t}function ye(e){const t={};for(const n in e){const r=e[n];void 0!==r&&(t[n]=s(r)?r.map((e=>null==e?null:""+e)):null==r?r:""+r)}return t}const be=Symbol(""),we=Symbol(""),Ee=Symbol(""),Re=Symbol(""),ke=Symbol("");function Oe(){let e=[];return{add:function(t){return e.push(t),()=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)}},list:()=>e,reset:function(){e=[]}}}function je(e,n,r){const o=()=>{e[n].delete(r)};t.onUnmounted(o),t.onDeactivated(o),t.onActivated((()=>{e[n].add(r)})),e[n].add(r)}function Pe(e,t,n,r,o){const a=r&&(r.enterCallbacks[o]=r.enterCallbacks[o]||[]);return()=>new Promise(((c,s)=>{const i=e=>{var i;!1===e?s(q(4,{from:n,to:t})):e instanceof Error?s(e):"string"==typeof(i=e)||i&&"object"==typeof i?s(q(2,{from:t,to:e})):(a&&r.enterCallbacks[o]===a&&"function"==typeof e&&a.push(e),c())},u=e.call(r&&r.instances[o],t,n,i);let l=Promise.resolve(u);e.length<3&&(l=l.then(i)),l.catch((e=>s(e)))}))}function Ce(e,t,n,o){const a=[];for(const s of e)for(const e in s.components){let i=s.components[e];if("beforeRouteEnter"===t||s.instances[e])if("object"==typeof(c=i)||"displayName"in c||"props"in c||"__kccOpts"in c){const r=(i.__kccOpts||i)[t];r&&a.push(Pe(r,n,o,s,e))}else{let c=i();a.push((()=>c.then((a=>{if(!a)return Promise.reject(new Error(`Couldn't resolve component "${e}" at "${s.path}"`));const c=r(a)?a.default:a;s.components[e]=c;const i=(c.__kccOpts||c)[t];return i&&Pe(i,n,o,s,e)()}))))}}var c;return a}function xe(e){const n=t.inject(Ee),r=t.inject(Re),o=t.computed((()=>n.resolve(t.unref(e.to)))),a=t.computed((()=>{const{matched:e}=o.value,{length:t}=e,n=e[t-1],a=r.matched;if(!n||!a.length)return-1;const c=a.findIndex(p.bind(null,n));if(c>-1)return c;const s=Se(e[t-2]);return t>1&&Se(n)===s&&a[a.length-1].path!==s?a.findIndex(p.bind(null,e[t-2])):c})),i=t.computed((()=>a.value>-1&&function(e,t){for(const n in t){const r=t[n],o=e[n];if("string"==typeof r){if(r!==o)return!1}else if(!s(o)||o.length!==r.length||r.some(((e,t)=>e!==o[t])))return!1}return!0}(r.params,o.value.params))),u=t.computed((()=>a.value>-1&&a.value===r.matched.length-1&&h(r.params,o.value.params)));return{route:o,href:t.computed((()=>o.value.href)),isActive:i,isExactActive:u,navigate:function(r={}){return function(e){if(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)return;if(e.defaultPrevented)return;if(void 0!==e.button&&0!==e.button)return;if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}e.preventDefault&&e.preventDefault();return!0}(r)?n[t.unref(e.replace)?"replace":"push"](t.unref(e.to)).catch(c):Promise.resolve()}}}const $e=t.defineComponent({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:xe,setup(e,{slots:n}){const r=t.reactive(xe(e)),{options:o}=t.inject(Ee),a=t.computed((()=>({[Ae(e.activeClass,o.linkActiveClass,"router-link-active")]:r.isActive,[Ae(e.exactActiveClass,o.linkExactActiveClass,"router-link-exact-active")]:r.isExactActive})));return()=>{const o=n.default&&n.default(r);return e.custom?o:t.h("a",{"aria-current":r.isExactActive?e.ariaCurrentValue:null,href:r.href,onClick:r.navigate,class:a.value},o)}}});function Se(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Ae=(e,t,n)=>null!=e?e:null!=t?t:n;function Le(e,t){if(!e)return null;const n=e(t);return 1===n.length?n[0]:n}const Me=t.defineComponent({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:n,slots:r}){const a=t.inject(ke),c=t.computed((()=>e.route||a.value)),s=t.inject(we,0),i=t.computed((()=>{let e=t.unref(s);const{matched:n}=c.value;let r;for(;(r=n[e])&&!r.components;)e++;return e})),u=t.computed((()=>c.value.matched[i.value]));t.provide(we,t.computed((()=>i.value+1))),t.provide(be,u),t.provide(ke,c);const l=t.ref();return t.watch((()=>[l.value,u.value,e.name]),(([e,t,n],[r,o,a])=>{t&&(t.instances[n]=e,o&&o!==t&&e&&e===r&&(t.leaveGuards.size||(t.leaveGuards=o.leaveGuards),t.updateGuards.size||(t.updateGuards=o.updateGuards))),!e||!t||o&&p(t,o)&&r||(t.enterCallbacks[n]||[]).forEach((t=>t(e)))}),{flush:"post"}),()=>{const a=c.value,s=e.name,i=u.value,f=i&&i.components[s];if(!f)return Le(r.default,{Component:f,route:a});const p=i.props[s],h=p?!0===p?a.params:"function"==typeof p?p(a):p:null,d=t.h(f,o({},h,n,{onKnodeUnmounted:e=>{e.component.isUnmounted&&(i.instances[s]=null)},ref:l}));return Le(r.default,{Component:d,route:a})||d}}});return e.RouterLink=$e,e.RouterView=Me,e.START_LOCATION=A,e.createMemoryHistory=function(e=""){let t=[],n=[y],r=0;function o(e){r++,r===n.length||n.splice(r),n.push(e)}e=b(e);const a={location:y,state:{},base:e,createHref:E.bind(null,e),replace(e){n.splice(r--,1),o(e)},push(e,t){o(e)},listen:e=>(t.push(e),()=>{const n=t.indexOf(e);n>-1&&t.splice(n,1)}),destroy(){t=[],n=[y],r=0},go(e,o=!0){const a=this.location,c=e<0?v.back:v.forward;r=Math.max(0,Math.min(r+e,n.length-1)),o&&function(e,n,{direction:r,delta:o}){const a={direction:r,delta:o,type:g.pop};for(const r of t)r(e,n,a)}(this.location,a,{direction:c,delta:e})}};return Object.defineProperty(a,"location",{enumerable:!0,get:()=>n[r]}),a},e.createRouter=function(e){const r=H(e.routes,e),i=e.parseQuery||ge,u=e.stringifyQuery||ve,f=e.history,d=Oe(),m=Oe(),v=Oe(),y=t.shallowRef(A);let b=A;n&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const w=a.bind(null,(e=>""+e)),E=a.bind(null,de),P=a.bind(null,me);function C(e,t){if(t=o({},t||y.value),"string"==typeof e){const n=l(i,e,t.path),a=r.resolve({path:n.path},t),c=f.createHref(n.fullPath);return o(n,a,{params:P(a.params),hash:me(n.hash),redirectedFrom:void 0,href:c})}let n;if("path"in e)n=o({},e,{path:l(i,e.path,t.path).path});else{const r=o({},e.params);for(const e in r)null==r[e]&&delete r[e];n=o({},e,{params:E(r)}),t.params=E(t.params)}const a=r.resolve(n,t),c=e.hash||"";a.params=w(P(a.params));const s=function(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}(u,o({},e,{hash:(p=c,pe(p).replace(ie,"{").replace(le,"}").replace(ce,"^")),path:a.path}));var p;const h=f.createHref(s);return o({fullPath:s,hash:c,query:u===ve?ye(e.query):e.query||{}},a,{redirectedFrom:void 0,href:h})}function x(e){return"string"==typeof e?l(i,e,y.value.path):o({},e)}function $(e,t){if(b!==e)return q(8,{from:t,to:e})}function L(e){return T(e)}function M(e){const t=e.matched[e.matched.length-1];if(t&&t.redirect){const{redirect:n}=t;let r="function"==typeof n?n(e):n;return"string"==typeof r&&(r=r.includes("?")||r.includes("#")?r=x(r):{path:r},r.params={}),o({query:e.query,hash:e.hash,params:"path"in r?{}:e.params},r)}}function T(e,t){const n=b=C(e),r=y.value,a=e.state,c=e.force,s=!0===e.replace,i=M(n);if(i)return T(o(x(i),{state:"object"==typeof i?o({},a,i.state):a,force:c,replace:s}),t||n);const l=n;let f;return l.redirectedFrom=t,!c&&function(e,t,n){const r=t.matched.length-1,o=n.matched.length-1;return r>-1&&r===o&&p(t.matched[r],n.matched[o])&&h(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}(u,r,n)&&(f=q(16,{to:l,from:r}),X(r,r,!0,!1)),(f?Promise.resolve(f):_(l,r)).catch((e=>B(e)?B(e,2)?e:Q(e):z(e,l,r))).then((e=>{if(e){if(B(e,2))return T(o({replace:s},x(e.to),{state:"object"==typeof e.to?o({},a,e.to.state):a,force:c}),t||l)}else e=W(l,r,!0,s,a);return F(l,r,e),e}))}function G(e,t){const n=$(e,t);return n?Promise.reject(n):Promise.resolve()}function K(e){const t=J.values().next().value;return t&&"function"==typeof t.runWithContext?t.runWithContext(e):e()}function _(e,t){let n;const[r,o,a]=function(e,t){const n=[],r=[],o=[],a=Math.max(t.matched.length,e.matched.length);for(let c=0;c<a;c++){const a=t.matched[c];a&&(e.matched.find((e=>p(e,a)))?r.push(a):n.push(a));const s=e.matched[c];s&&(t.matched.find((e=>p(e,s)))||o.push(s))}return[n,r,o]}(e,t);n=Ce(r.reverse(),"beforeRouteLeave",e,t);for(const o of r)o.leaveGuards.forEach((r=>{n.push(Pe(r,e,t))}));const c=G.bind(null,e,t);return n.push(c),te(n).then((()=>{n=[];for(const r of d.list())n.push(Pe(r,e,t));return n.push(c),te(n)})).then((()=>{n=Ce(o,"beforeRouteUpdate",e,t);for(const r of o)r.updateGuards.forEach((r=>{n.push(Pe(r,e,t))}));return n.push(c),te(n)})).then((()=>{n=[];for(const r of e.matched)if(r.beforeEnter&&!t.matched.includes(r))if(s(r.beforeEnter))for(const o of r.beforeEnter)n.push(Pe(o,e,t));else n.push(Pe(r.beforeEnter,e,t));return n.push(c),te(n)})).then((()=>(e.matched.forEach((e=>e.enterCallbacks={})),n=Ce(a,"beforeRouteEnter",e,t),n.push(c),te(n)))).then((()=>{n=[];for(const r of m.list())n.push(Pe(r,e,t));return n.push(c),te(n)})).catch((e=>B(e,8)?e:Promise.reject(e)))}function F(e,t,n){for(const r of v.list())K((()=>r(e,t,n)))}function W(e,t,r,a,c){const s=$(e,t);if(s)return s;const i=t===A,u=n?history.state:{};r&&(a||i?f.replace(e.fullPath,o({scroll:i&&u&&u.scroll},c)):f.push(e.fullPath,c)),y.value=e,X(e,t,r,i),Q()}let D;function I(){D||(D=f.listen(((e,t,r)=>{if(!ee.listening)return;const a=C(e),s=M(a);if(s)return void T(o(s,{replace:!0}),a).catch(c);b=a;const i=y.value;var u,l;n&&(u=O(i.fullPath,r.delta),l=R(),j.set(u,l)),_(a,i).catch((e=>B(e,12)?e:B(e,2)?(T(e.to,a).then((e=>{B(e,20)&&!r.delta&&r.type===g.pop&&f.go(-1,!1)})).catch(c),Promise.reject()):(r.delta&&f.go(-r.delta,!1),z(e,a,i)))).then((e=>{(e=e||W(a,i,!1))&&(r.delta&&!B(e,8)?f.go(-r.delta,!1):r.type===g.pop&&B(e,20)&&f.go(-1,!1)),F(a,i,e)})).catch(c)})))}let U,N=Oe(),V=Oe();function z(e,t,n){Q(e);const r=V.list();return r.length?r.forEach((r=>r(e,t,n))):console.error(e),Promise.reject(e)}function Q(e){return U||(U=!e,I(),N.list().forEach((([t,n])=>e?n(e):t())),N.reset()),e}function X(r,o,a,c){const{scrollBehavior:s}=e;if(!n||!s)return Promise.resolve();const i=!a&&function(e){const t=j.get(e);return j.delete(e),t}(O(r.fullPath,0))||(c||!a)&&history.state&&history.state.scroll||null;return t.nextTick().then((()=>s(r,o,i))).then((e=>e&&k(e))).catch((e=>z(e,r,o)))}const Y=e=>f.go(e);let Z;const J=new Set,ee={currentRoute:y,listening:!0,addRoute:function(e,t){let n,o;return S(e)?(n=r.getRecordMatcher(e),o=t):o=e,r.addRoute(o,n)},removeRoute:function(e){const t=r.getRecordMatcher(e);t&&r.removeRoute(t)},hasRoute:function(e){return!!r.getRecordMatcher(e)},getRoutes:function(){return r.getRoutes().map((e=>e.record))},resolve:C,options:e,push:L,replace:function(e){return L(o(x(e),{replace:!0}))},go:Y,back:()=>Y(-1),forward:()=>Y(1),beforeEach:d.add,beforeResolve:m.add,afterEach:v.add,onError:V.add,isReady:function(){return U&&y.value!==A?Promise.resolve():new Promise(((e,t)=>{N.add([e,t])}))},install(e){e.component("RouterLink",$e),e.component("RouterView",Me),e.config.globalProperties.$router=this,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>t.unref(y)}),n&&!Z&&y.value===A&&(Z=!0,L(f.location).catch((e=>{})));const r={};for(const e in A)r[e]=t.computed((()=>y.value[e]));e.provide(Ee,this),e.provide(Re,t.reactive(r)),e.provide(ke,y);const o=e.unmount;J.add(e),e.unmount=function(){J.delete(e),J.size<1&&(b=A,D&&D(),D=null,y.value=A,Z=!1,U=!1),o()}}};function te(e){return e.reduce(((e,t)=>e.then((()=>K(t)))),Promise.resolve())}return ee},e.createRouterMatcher=H,e.createWebHashHistory=function(e){return(e=location.host?e||location.pathname+location.search:"").includes("#")||(e+="#"),$(e)},e.createWebHistory=$,e.isNavigationFailure=B,e.loadRouteLocation=function(e){return e.matched.every((e=>e.redirect))?Promise.reject(new Error("Cannot load a route that redirects.")):Promise.all(e.matched.map((e=>e.components&&Promise.all(Object.keys(e.components).reduce(((t,n)=>{const o=e.components[n];return"function"!=typeof o||"displayName"in o||t.push(o().then((t=>{if(!t)return Promise.reject(new Error(`Couldn't resolve component "${n}" at "${e.path}". Ensure you passed a function that returns a promise.`));const o=r(t)?t.default:t;e.components[n]=o}))),t}),[]))))).then((()=>e))},e.matchedRouteKey=be,e.onBeforeRouteLeave=function(e){const n=t.inject(be,{}).value;n&&je(n,"leaveGuards",e)},e.onBeforeRouteUpdate=function(e){const n=t.inject(be,{}).value;n&&je(n,"updateGuards",e)},e.parseQuery=ge,e.routeLocationKey=Re,e.routerKey=Ee,e.routerViewLocationKey=ke,e.stringifyQuery=ve,e.useLink=xe,e.useRoute=function(){return t.inject(Re)},e.useRouter=function(){return t.inject(Ee)},e.viewDepthKey=we,e}({},Kdu);
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * kdu-router v4.1.6
3
- * (c) 2023 NKDuy
2
+ * kdu-router v4.2.0
3
+ * (c) 2024 NKDuy
4
4
  * @license MIT
5
5
  */
6
6
  import { getCurrentInstance, inject, onUnmounted, onDeactivated, onActivated, computed, unref, watchEffect, defineComponent, reactive, h, provide, ref, watch, shallowRef, nextTick } from 'kdu';
@@ -103,6 +103,7 @@ function stripBase(pathname, base) {
103
103
  * pointing towards the same {@link RouteRecord} and that all `params`, `query`
104
104
  * parameters and `hash` are the same
105
105
  *
106
+ * @param stringifyQuery - A function that takes a query object of type LocationQueryRaw and returns a string representation of it.
106
107
  * @param a - first {@link RouteLocation}
107
108
  * @param b - second {@link RouteLocation}
108
109
  */
@@ -174,6 +175,12 @@ function resolveRelativePath(to, from) {
174
175
  return from;
175
176
  const fromSegments = from.split('/');
176
177
  const toSegments = to.split('/');
178
+ const lastToSegment = toSegments[toSegments.length - 1];
179
+ // make . and ./ the same (../ === .., ../../ === ../..)
180
+ // this is the same behavior as new URL()
181
+ if (lastToSegment === '..' || lastToSegment === '.') {
182
+ toSegments.push('');
183
+ }
177
184
  let position = fromSegments.length - 1;
178
185
  let toPosition;
179
186
  let segment;
@@ -361,7 +368,8 @@ function getSavedScrollPosition(key) {
361
368
  let createBaseLocation = () => location.protocol + '//' + location.host;
362
369
  /**
363
370
  * Creates a normalized history location from a window.location object
364
- * @param location -
371
+ * @param base - The base path
372
+ * @param location - The window.location object
365
373
  */
366
374
  function createCurrentLocation(base, location) {
367
375
  const { pathname, search, hash } = location;
@@ -451,7 +459,11 @@ function useHistoryListeners(base, historyState, currentLocation, replace) {
451
459
  }
452
460
  // set up the listeners and prepare teardown callbacks
453
461
  window.addEventListener('popstate', popStateHandler);
454
- window.addEventListener('beforeunload', beforeUnloadListener);
462
+ // TODO: could we use 'pagehide' or 'visibilitychange' instead?
463
+ // https://developer.chrome.com/blog/page-lifecycle-api/
464
+ window.addEventListener('beforeunload', beforeUnloadListener, {
465
+ passive: true,
466
+ });
455
467
  return {
456
468
  pauseListeners,
457
469
  listen,
@@ -1183,6 +1195,7 @@ function tokenizePath(path) {
1183
1195
  case 2 /* TokenizerState.ParamRegExp */:
1184
1196
  // TODO: is it worth handling nested regexp? like :p(?:prefix_([^/]+)_suffix)
1185
1197
  // it already works by escaping the closing )
1198
+ // https://paths.esm.dev/?p=AAMeJbiAwQEcDKbAoAAkP60PG2R6QAvgNaA6AFACM2ABuQBB#
1186
1199
  // is this really something people need since you can also write
1187
1200
  // /prefix_:p()_suffix
1188
1201
  if (char === ')') {
@@ -2471,8 +2484,11 @@ const RouterView = RouterViewImpl;
2471
2484
  function warnDeprecatedUsage() {
2472
2485
  const instance = getCurrentInstance();
2473
2486
  const parentName = instance.parent && instance.parent.type.name;
2487
+ const parentSubTreeType = instance.parent && instance.parent.subTree && instance.parent.subTree.type;
2474
2488
  if (parentName &&
2475
- (parentName === 'KeepAlive' || parentName.includes('Transition'))) {
2489
+ (parentName === 'KeepAlive' || parentName.includes('Transition')) &&
2490
+ typeof parentSubTreeType === 'object' &&
2491
+ parentSubTreeType.name === 'RouterView') {
2476
2492
  const comp = parentName === 'KeepAlive' ? 'keep-alive' : 'transition';
2477
2493
  warn(`<router-view> can no longer be used directly inside <transition> or <keep-alive>.\n` +
2478
2494
  `Use slot props instead:\n\n` +
@@ -3013,9 +3029,7 @@ function createRouter(options) {
3013
3029
  !('name' in rawLocation) &&
3014
3030
  // @ts-expect-error: the type is never
3015
3031
  Object.keys(rawLocation.params).length) {
3016
- warn(`Path "${
3017
- // @ts-expect-error: the type is never
3018
- rawLocation.path}" was passed with params but they will be ignored. Use a named route alongside params instead.`);
3032
+ warn(`Path "${rawLocation.path}" was passed with params but they will be ignored. Use a named route alongside params instead.`);
3019
3033
  }
3020
3034
  matcherLocation = assign({}, rawLocation, {
3021
3035
  path: parseURL(parseQuery$1, rawLocation.path, currentLocation.path).path,
@@ -3031,7 +3045,7 @@ function createRouter(options) {
3031
3045
  }
3032
3046
  // pass encoded values to the matcher, so it can produce encoded path and fullPath
3033
3047
  matcherLocation = assign({}, rawLocation, {
3034
- params: encodeParams(rawLocation.params),
3048
+ params: encodeParams(targetParams),
3035
3049
  });
3036
3050
  // current location params are decoded, we need to encode them in case the
3037
3051
  // matcher merges the params
@@ -3177,8 +3191,8 @@ function createRouter(options) {
3177
3191
  (redirectedFrom._count = redirectedFrom._count
3178
3192
  ? // @ts-expect-error
3179
3193
  redirectedFrom._count + 1
3180
- : 1) > 10) {
3181
- warn(`Detected an infinite redirection in a navigation guard when going from "${from.fullPath}" to "${toLocation.fullPath}". Aborting to avoid a Stack Overflow. This will break in production if not fixed.`);
3194
+ : 1) > 30) {
3195
+ warn(`Detected a possibly infinite redirection in a navigation guard when going from "${from.fullPath}" to "${toLocation.fullPath}". Aborting to avoid a Stack Overflow.\n Are you always returning a new location within a navigation guard? That would lead to this error. Only return when redirecting or aborting, that should fix this. This might break in production if not fixed.`);
3182
3196
  return Promise.reject(new Error('Infinite redirect in navigation guard'));
3183
3197
  }
3184
3198
  return pushWithRedirect(
@@ -3213,6 +3227,13 @@ function createRouter(options) {
3213
3227
  const error = checkCanceledNavigation(to, from);
3214
3228
  return error ? Promise.reject(error) : Promise.resolve();
3215
3229
  }
3230
+ function runWithContext(fn) {
3231
+ const app = installedApps.values().next().value;
3232
+ // support Kdu < 3.3
3233
+ return app && typeof app.runWithContext === 'function'
3234
+ ? app.runWithContext(fn)
3235
+ : fn();
3236
+ }
3216
3237
  // TODO: refactor the whole before guards by internally using router.beforeEach
3217
3238
  function navigate(to, from) {
3218
3239
  let guards;
@@ -3296,8 +3317,9 @@ function createRouter(options) {
3296
3317
  function triggerAfterEach(to, from, failure) {
3297
3318
  // navigation is confirmed, call afterGuards
3298
3319
  // TODO: wrap with error handlers
3299
- for (const guard of afterGuards.list())
3300
- guard(to, from, failure);
3320
+ for (const guard of afterGuards.list()) {
3321
+ runWithContext(() => guard(to, from, failure));
3322
+ }
3301
3323
  }
3302
3324
  /**
3303
3325
  * - Cleans up any navigation guards
@@ -3556,11 +3578,12 @@ function createRouter(options) {
3556
3578
  }
3557
3579
  },
3558
3580
  };
3581
+ // TODO: type this as NavigationGuardReturn or similar instead of any
3582
+ function runGuardQueue(guards) {
3583
+ return guards.reduce((promise, guard) => promise.then(() => runWithContext(guard)), Promise.resolve());
3584
+ }
3559
3585
  return router;
3560
3586
  }
3561
- function runGuardQueue(guards) {
3562
- return guards.reduce((promise, guard) => promise.then(() => guard()), Promise.resolve());
3563
- }
3564
3587
  function extractChangingRecords(to, from) {
3565
3588
  const leavingRecords = [];
3566
3589
  const updatingRecords = [];
@@ -1,12 +1,10 @@
1
1
  /*!
2
- * kdu-router v4.1.6
3
- * (c) 2023 NKDuy
2
+ * kdu-router v4.2.0
3
+ * (c) 2024 NKDuy
4
4
  * @license MIT
5
5
  */
6
6
  'use strict';
7
7
 
8
- Object.defineProperty(exports, '__esModule', { value: true });
9
-
10
8
  var kdu = require('kdu');
11
9
 
12
10
  const isBrowser = typeof window !== 'undefined';
@@ -100,6 +98,7 @@ function stripBase(pathname, base) {
100
98
  * pointing towards the same {@link RouteRecord} and that all `params`, `query`
101
99
  * parameters and `hash` are the same
102
100
  *
101
+ * @param stringifyQuery - A function that takes a query object of type LocationQueryRaw and returns a string representation of it.
103
102
  * @param a - first {@link RouteLocation}
104
103
  * @param b - second {@link RouteLocation}
105
104
  */
@@ -167,6 +166,12 @@ function resolveRelativePath(to, from) {
167
166
  return from;
168
167
  const fromSegments = from.split('/');
169
168
  const toSegments = to.split('/');
169
+ const lastToSegment = toSegments[toSegments.length - 1];
170
+ // make . and ./ the same (../ === .., ../../ === ../..)
171
+ // this is the same behavior as new URL()
172
+ if (lastToSegment === '..' || lastToSegment === '.') {
173
+ toSegments.push('');
174
+ }
170
175
  let position = fromSegments.length - 1;
171
176
  let toPosition;
172
177
  let segment;
@@ -314,7 +319,8 @@ function getSavedScrollPosition(key) {
314
319
  let createBaseLocation = () => location.protocol + '//' + location.host;
315
320
  /**
316
321
  * Creates a normalized history location from a window.location object
317
- * @param location -
322
+ * @param base - The base path
323
+ * @param location - The window.location object
318
324
  */
319
325
  function createCurrentLocation(base, location) {
320
326
  const { pathname, search, hash } = location;
@@ -404,7 +410,11 @@ function useHistoryListeners(base, historyState, currentLocation, replace) {
404
410
  }
405
411
  // set up the listeners and prepare teardown callbacks
406
412
  window.addEventListener('popstate', popStateHandler);
407
- window.addEventListener('beforeunload', beforeUnloadListener);
413
+ // TODO: could we use 'pagehide' or 'visibilitychange' instead?
414
+ // https://developer.chrome.com/blog/page-lifecycle-api/
415
+ window.addEventListener('beforeunload', beforeUnloadListener, {
416
+ passive: true,
417
+ });
408
418
  return {
409
419
  pauseListeners,
410
420
  listen,
@@ -1117,6 +1127,7 @@ function tokenizePath(path) {
1117
1127
  case 2 /* TokenizerState.ParamRegExp */:
1118
1128
  // TODO: is it worth handling nested regexp? like :p(?:prefix_([^/]+)_suffix)
1119
1129
  // it already works by escaping the closing )
1130
+ // https://paths.esm.dev/?p=AAMeJbiAwQEcDKbAoAAkP60PG2R6QAvgNaA6AFACM2ABuQBB#
1120
1131
  // is this really something people need since you can also write
1121
1132
  // /prefix_:p()_suffix
1122
1133
  if (char === ')') {
@@ -2287,7 +2298,7 @@ function createRouter(options) {
2287
2298
  }
2288
2299
  // pass encoded values to the matcher, so it can produce encoded path and fullPath
2289
2300
  matcherLocation = assign({}, rawLocation, {
2290
- params: encodeParams(rawLocation.params),
2301
+ params: encodeParams(targetParams),
2291
2302
  });
2292
2303
  // current location params are decoded, we need to encode them in case the
2293
2304
  // matcher merges the params
@@ -2439,6 +2450,13 @@ function createRouter(options) {
2439
2450
  const error = checkCanceledNavigation(to, from);
2440
2451
  return error ? Promise.reject(error) : Promise.resolve();
2441
2452
  }
2453
+ function runWithContext(fn) {
2454
+ const app = installedApps.values().next().value;
2455
+ // support Kdu < 3.3
2456
+ return app && typeof app.runWithContext === 'function'
2457
+ ? app.runWithContext(fn)
2458
+ : fn();
2459
+ }
2442
2460
  // TODO: refactor the whole before guards by internally using router.beforeEach
2443
2461
  function navigate(to, from) {
2444
2462
  let guards;
@@ -2522,8 +2540,9 @@ function createRouter(options) {
2522
2540
  function triggerAfterEach(to, from, failure) {
2523
2541
  // navigation is confirmed, call afterGuards
2524
2542
  // TODO: wrap with error handlers
2525
- for (const guard of afterGuards.list())
2526
- guard(to, from, failure);
2543
+ for (const guard of afterGuards.list()) {
2544
+ runWithContext(() => guard(to, from, failure));
2545
+ }
2527
2546
  }
2528
2547
  /**
2529
2548
  * - Cleans up any navigation guards
@@ -2773,11 +2792,12 @@ function createRouter(options) {
2773
2792
  };
2774
2793
  },
2775
2794
  };
2795
+ // TODO: type this as NavigationGuardReturn or similar instead of any
2796
+ function runGuardQueue(guards) {
2797
+ return guards.reduce((promise, guard) => promise.then(() => runWithContext(guard)), Promise.resolve());
2798
+ }
2776
2799
  return router;
2777
2800
  }
2778
- function runGuardQueue(guards) {
2779
- return guards.reduce((promise, guard) => promise.then(() => guard()), Promise.resolve());
2780
- }
2781
2801
  function extractChangingRecords(to, from) {
2782
2802
  const leavingRecords = [];
2783
2803
  const updatingRecords = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kdu-router",
3
- "version": "4.1.6",
3
+ "version": "4.2.0",
4
4
  "main": "index.js",
5
5
  "unpkg": "dist/kdu-router.global.js",
6
6
  "jsdelivr": "dist/kdu-router.global.js",
@@ -48,10 +48,9 @@
48
48
  "README.md"
49
49
  ],
50
50
  "scripts": {
51
- "build": "rimraf dist && rollup -c rollup.config.js",
51
+ "build": "rimraf dist && rollup -c rollup.config.mjs",
52
52
  "build:dts": "api-extractor run --local --verbose && tail -n +10 src/globalExtensions.ts >> dist/kdu-router.d.ts",
53
- "build:size": "pnpm run build && rollup -c size-checks/rollup.config.js",
54
- "test:types": "tsc --build tsconfig.json"
53
+ "build:size": "pnpm run build && rollup -c size-checks/rollup.config.mjs"
55
54
  },
56
55
  "peerDependencies": {
57
56
  "kdu": "^3.2.0"
@@ -64,26 +63,31 @@
64
63
  "@kdujs/devtools-api": "^6.4.5"
65
64
  },
66
65
  "devDependencies": {
67
- "@kdujs/compiler-sfc": "^3.2.45",
68
- "@kdujs/server-renderer": "^3.2.45",
69
- "@microsoft/api-extractor": "^7.29.2",
70
- "@rollup/plugin-alias": "^3.1.4",
71
- "@rollup/plugin-commonjs": "^22.0.2",
72
- "@rollup/plugin-node-resolve": "^13.0.5",
73
- "@rollup/plugin-replace": "^4.0.0",
74
- "@types/jsdom": "^16.2.13",
75
- "browserstack-local": "^1.4.5",
76
- "chromedriver": "^106.0.1",
66
+ "@kdujs/compiler-sfc": "^3.3.1",
67
+ "@kdujs/server-renderer": "^3.3.1",
68
+ "@lahmjs/plugin-kdu": "^4.0.0",
69
+ "@microsoft/api-extractor": "^7.34.4",
70
+ "@rollup/plugin-alias": "^4.0.3",
71
+ "@rollup/plugin-commonjs": "^24.0.1",
72
+ "@rollup/plugin-node-resolve": "^15.0.1",
73
+ "@rollup/plugin-replace": "^5.0.2",
74
+ "@sucrase/jest-plugin": "^3.0.0",
75
+ "@types/jest": "^29.4.0",
76
+ "@types/jsdom": "^20.0.1",
77
+ "@types/nightwatch": "^2.3.19",
78
+ "browserstack-local": "^1.5.2",
77
79
  "connect-history-api-fallback": "^1.6.0",
78
80
  "dotenv": "^16.0.3",
79
81
  "faked-promise": "^2.2.2",
80
82
  "geckodriver": "^3.2.0",
81
- "kdu": "^3.2.45",
83
+ "kdu": "^3.3.1",
84
+ "lahm": "^5.0.0",
82
85
  "rimraf": "^3.0.2",
83
- "rollup": "^2.78.0",
86
+ "rollup": "^3.17.2",
84
87
  "rollup-plugin-analyzer": "^4.0.0",
85
88
  "rollup-plugin-terser": "^7.0.2",
86
- "rollup-plugin-typescript2": "^0.32.1",
87
- "typescript": "~4.7.4"
89
+ "rollup-plugin-typescript2": "^0.34.1",
90
+ "sucrase": "^3.29.0",
91
+ "typescript": "~4.9.4"
88
92
  }
89
93
  }