@pacem/pacem-core 1.0.0-bessel → 1.0.0-dirac

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.
Files changed (39) hide show
  1. package/dist/browser/pacem-core.js +870 -9
  2. package/dist/browser/pacem-core.js.map +1 -1
  3. package/dist/browser/pacem-core.min.js +2 -2
  4. package/dist/bundle/pacem-core.min.mjs +6 -6
  5. package/dist/bundle/pacem-core.mjs +467 -1
  6. package/dist/bundle/pacem-core.mjs.map +2 -2
  7. package/dist/docs/pacem-core.json +40109 -0
  8. package/dist/esm/adapter.js +2 -1
  9. package/dist/esm/command.js +6 -1
  10. package/dist/esm/comparers.js +1 -1
  11. package/dist/esm/converters.js +6 -1
  12. package/dist/esm/decorators-next.js +1 -1
  13. package/dist/esm/decorators.js +94 -1
  14. package/dist/esm/defaults.js +2 -1
  15. package/dist/esm/events.js +41 -1
  16. package/dist/esm/eventtarget.js +11 -1
  17. package/dist/esm/expression.js +37 -1
  18. package/dist/esm/index-animations.js +1 -1
  19. package/dist/esm/index-behaviors.js +1 -1
  20. package/dist/esm/index-components.js +1 -1
  21. package/dist/esm/index-iife.js +1 -1
  22. package/dist/esm/index-logging.js +1 -1
  23. package/dist/esm/index-net.js +1 -1
  24. package/dist/esm/index-root.js +1 -1
  25. package/dist/esm/index-ui.js +1 -1
  26. package/dist/esm/index.js +1 -1
  27. package/dist/esm/logger.js +8 -1
  28. package/dist/esm/prefix.js +2 -1
  29. package/dist/esm/promise.js +11 -1
  30. package/dist/esm/regex.js +3 -1
  31. package/dist/esm/storage.js +14 -1
  32. package/dist/esm/template.js +2 -1
  33. package/dist/esm/transforms.js +53 -1
  34. package/dist/esm/types.js +6 -1
  35. package/dist/esm/utils-customelement.js +165 -6
  36. package/dist/esm/utils-customevent.js +27 -1
  37. package/dist/esm/utils.js +89 -1
  38. package/package.json +2 -1
  39. package/typings/index.d.ts +1089 -10
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @pacem/pacem-core v1.0.0-bessel (https://js.pacem.it)
2
+ * @pacem/pacem-core v1.0.0-dirac (https://js.pacem.it)
3
3
  * Pacem (https://pacem.it)
4
4
  * Licensed under Apache-2.0
5
5
  */
@@ -38,13 +38,20 @@ function assembleEasing(fn, css) {
38
38
  return output;
39
39
  }
40
40
  var Easings = {
41
+ /** No easing: progress is proportional to elapsed time. */
41
42
  linear: assembleEasing(EASINGS.linear, "linear"),
43
+ /** Sine ease-in: starts slow, accelerates towards the end. */
42
44
  sineIn: assembleEasing(EASINGS.sineIn, "cubic-bezier(0.12, 0, 0.39, 0)"),
45
+ /** Sine ease-out: starts fast, decelerates towards the end. */
43
46
  sineOut: assembleEasing(EASINGS.sineOut, "cubic-bezier(0.61, 1, 0.88, 1)"),
47
+ /** Sine ease-in-out: accelerates then decelerates, symmetric around the midpoint. */
44
48
  sineInOut: assembleEasing(EASINGS.sineInOut, "cubic-bezier(0.37, 0, 0.63, 1)"),
45
49
  // TODO: set correct pairing
50
+ /** Exponential ease-in: starts very slow, accelerates sharply towards the end. */
46
51
  expoIn: assembleEasing(EASINGS.expoIn, "cubic-bezier(0.7, 0, 0.84, 0)"),
52
+ /** Exponential ease-out: starts very fast, decelerates sharply towards the end. */
47
53
  expoOut: assembleEasing(EASINGS.expoOut, "cubic-bezier(0.16, 1, 0.3, 1)"),
54
+ /** Exponential ease-in-out: sharp acceleration then sharp deceleration, symmetric around the midpoint. */
48
55
  expoInOut: assembleEasing(EASINGS.expoInOut, "cubic-bezier(0.87, 0, 0.13, 1)")
49
56
  };
50
57
 
@@ -55,6 +62,7 @@ import { Keys as Keys2, Dates, Colors, Strings, Blobs, Imaging, NullChecker, det
55
62
  var DeepCloner = class _DeepCloner {
56
63
  constructor() {
57
64
  }
65
+ /** Deep-clones `obj`; see {@link DeepCloner} for what gets cloned vs. passed through by reference. */
58
66
  static clone(obj2) {
59
67
  return new _DeepCloner()._clone(obj2);
60
68
  }
@@ -127,9 +135,16 @@ var Json = class _Json {
127
135
  constructor(_options) {
128
136
  this._options = _options;
129
137
  }
138
+ /**
139
+ * Serializes `obj` to a JSON string, extended to support circular/shared references, `RegExp`s,
140
+ * `Element`s (by `id`) and, per `options`, functions.
141
+ * @param obj Value to serialize.
142
+ * @param options Controls how function-valued properties are handled.
143
+ */
130
144
  static serialize(obj2, options) {
131
145
  return new _Json(options)._serialize(obj2);
132
146
  }
147
+ /** Deserializes a string produced by {@link serialize}, restoring references, `RegExp`s, `Element`s and functions. */
133
148
  static deserialize(json2) {
134
149
  return new _Json()._deserialize(json2);
135
150
  }
@@ -240,6 +255,7 @@ var DeferPromise = class _DeferPromise {
240
255
  me.deferred = { "resolve": resolve, "reject": reject, "promise": me };
241
256
  });
242
257
  }
258
+ /** Standard `PromiseLike.then`, delegating to the underlying native `Promise`. */
243
259
  then(onCompleted, onFailed) {
244
260
  return this.promise.then(onCompleted, onFailed);
245
261
  }
@@ -251,14 +267,17 @@ var DeferPromise = class _DeferPromise {
251
267
  this.promise.then(callback, callback);
252
268
  return this;
253
269
  }
270
+ /** Registers a fulfillment-only callback (fluent, chainable alternative to `then(callback)`). */
254
271
  success(callback) {
255
272
  this.promise.then(callback, null);
256
273
  return this;
257
274
  }
275
+ /** Registers a rejection-only callback (fluent, chainable alternative to `then(null, callback)`). */
258
276
  error(callback) {
259
277
  this.promise.then(null, callback);
260
278
  return this;
261
279
  }
280
+ /** Creates a new deferred promise and returns its controller: `{ resolve, reject, promise }`. */
262
281
  static defer() {
263
282
  var q = new _DeferPromise();
264
283
  return q.deferred;
@@ -281,27 +300,34 @@ var avoidHandler = (evt) => {
281
300
  var SEGMENT_PATTERN = /^\/[^\/]+/;
282
301
  var ROUTE_SEGMENT_PATTERN = /\/\{([a-z\$_][\w]*)\??\}/;
283
302
  var Utils = class _Utils {
303
+ /** The framework's global scratch/registry object (`window[id]`, where `id` defaults to `'pacem'` and is configurable via `window.Pacem.Configuration.core`); created on first access. Used e.g. to store {@link Transformer}-registered transform functions. */
284
304
  static get core() {
285
305
  const root2 = window["Pacem"];
286
306
  var id = root2 && root2.Configuration && root2.Configuration.core || PACEM_CORE_DEFAULT;
287
307
  return window[id] = window[id] || {};
288
308
  }
309
+ /** The platform's (native or polyfilled) `customElements` registry. */
289
310
  static get customElements() {
290
311
  return window["customElements"];
291
312
  }
292
313
  // #region GENERAL
314
+ /** Generates a unique numeric-ish id string. */
293
315
  static uniqueId() {
294
316
  return Keys2.uniqueId();
295
317
  }
318
+ /** Generates a unique short code string. */
296
319
  static uniqueCode() {
297
320
  return Keys2.uniqueCode();
298
321
  }
322
+ /** Generates a random string of the given `length`. */
299
323
  static randomString(length) {
300
324
  return Keys2.randomString(length);
301
325
  }
326
+ /** Parses a date-like value (ISO string, `Date`, or timestamp) into a `Date`. */
302
327
  static parseDate(input) {
303
328
  return Dates.parse(input);
304
329
  }
330
+ /** Writes `input` to the system clipboard, using the async Clipboard API when available and falling back to `document.execCommand('copy')` otherwise. */
305
331
  static copyToClipboard(input) {
306
332
  if (navigator.clipboard) {
307
333
  return navigator.clipboard.writeText(input);
@@ -368,6 +394,7 @@ var Utils = class _Utils {
368
394
  return filter;
369
395
  }
370
396
  }
397
+ /** Escapes `input` for safe use as a CSS identifier/selector fragment. */
371
398
  static cssEscape(input) {
372
399
  return escape(input).replace("%", "\\");
373
400
  }
@@ -375,9 +402,11 @@ var Utils = class _Utils {
375
402
  this.Css = {
376
403
  colorize: _Utils.colorize,
377
404
  escape: _Utils.cssEscape,
405
+ /** Reads a CSS custom property's current value off the document root (`:root`/`html`). */
378
406
  getVariableValue(name) {
379
407
  return getComputedStyle(document.documentElement).getPropertyValue(name);
380
408
  },
409
+ /** Sets a CSS custom property's value on the document root (`:root`/`html`). */
381
410
  setVariable(name, value2) {
382
411
  getComputedStyle(document.documentElement).setProperty(name, value2);
383
412
  },
@@ -405,6 +434,7 @@ var Utils = class _Utils {
405
434
  }
406
435
  return false;
407
436
  },
437
+ /** Parses an element's (or style declaration's) computed `transform: matrix(...)` CSS value into its 2D affine matrix components; identity if unset. */
408
438
  deserializeTransform(element) {
409
439
  const style = element instanceof Element ? getComputedStyle(element) : element;
410
440
  let a = 1, b = 0, c = 0, d = 1, x = 0, y = 0, matches = /^matrix\((.*)\)$/.exec(style.transform), mij;
@@ -434,6 +464,7 @@ var Utils = class _Utils {
434
464
  leftPad: Strings.leftPad,
435
465
  format: Strings.format,
436
466
  diff: Strings.diff,
467
+ /** Strips HTML markup from `html`, returning its plain-text content. */
437
468
  stripHTML: (html) => {
438
469
  let doc = new DOMParser().parseFromString(html, "text/html");
439
470
  return doc.body.textContent || "";
@@ -454,6 +485,7 @@ var Utils = class _Utils {
454
485
  resize: Imaging.resizeImage
455
486
  };
456
487
  }
488
+ /** Loads an image from `src` and resolves with the `HTMLImageElement` once ready (or rejects on error). */
457
489
  static loadImage(src) {
458
490
  return new Promise((resolve, reject) => {
459
491
  const img = new Image();
@@ -470,15 +502,19 @@ var Utils = class _Utils {
470
502
  }
471
503
  });
472
504
  }
505
+ /** Converts a `Blob` to a `data:` URL string. */
473
506
  static blobToDataURL(blob) {
474
507
  return _Utils.Blobs.toDataURL(blob);
475
508
  }
509
+ /** Converts a `data:` URL string back into a `Blob`. */
476
510
  static dataURLToBlob(dataURL) {
477
511
  return _Utils.Blobs.fromDataURL(dataURL);
478
512
  }
513
+ /** Reads a `Blob`'s content as text, using the given `encoding` (default UTF-8). */
479
514
  static blobToText(blob, encoding) {
480
515
  return _Utils.Blobs.toText(blob, encoding);
481
516
  }
517
+ /** Wraps `content` in a `Blob` of the given MIME `type` (default `'text/plain'`). */
482
518
  static textToBlob(content, type = "text/plain") {
483
519
  return _Utils.Blobs.fromText(content, type);
484
520
  }
@@ -556,6 +592,7 @@ var Utils = class _Utils {
556
592
  el.src = url;
557
593
  return deferred.promise;
558
594
  }
595
+ /** Returns the list of vendor-prefixed `getUserMedia` implementations available on `navigator`, if any. */
559
596
  static getUserMediaFunctions() {
560
597
  var _getUserMedia = [];
561
598
  let methods = [navigator["getUserMedia"], navigator["webkitGetUserMedia"], navigator["msGetUserMedia"], navigator["mozGetUserMedia"]];
@@ -773,12 +810,14 @@ var Utils = class _Utils {
773
810
  }
774
811
  // #endregion
775
812
  // #region DOM
813
+ /** Whether the document (including module scripts) has fully finished loading (`document.readyState === 'complete'`). */
776
814
  static isDOMReady() {
777
815
  return (
778
816
  /* document.readyState === 'interactive' ||*/
779
817
  document.readyState === "complete"
780
818
  );
781
819
  }
820
+ /** Registers `listener` to run once the document (and its resources, e.g. images) has fully loaded (the `window` `'load'` event). */
782
821
  static onDOMReady(listener) {
783
822
  window.addEventListener("load", listener, false);
784
823
  }
@@ -805,12 +844,15 @@ var Utils = class _Utils {
805
844
  }
806
845
  return dom;
807
846
  }
847
+ /** Cross-browser `Element.matches(selector)`, falling back to vendor-prefixed variants. */
808
848
  static is(el, selector) {
809
849
  return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector);
810
850
  }
851
+ /** Resolves the effective language for `el`: its own `lang` attribute, else the document's, else the browser's. */
811
852
  static lang(el) {
812
853
  return el.lang || document.documentElement.lang || navigator.language;
813
854
  }
855
+ /** JSON-stringifies `obj` (via {@link Json}), or passes through `null`/`undefined` unchanged. */
814
856
  static jsonSortStringify(obj2) {
815
857
  if (_Utils.isNull(obj2)) {
816
858
  return obj2;
@@ -822,6 +864,7 @@ var Utils = class _Utils {
822
864
  detect
823
865
  };
824
866
  }
867
+ /** Parses a `document.cookie`-style string (or `document.cookie` itself, by default) into a name/value map. */
825
868
  static cookies(cookie) {
826
869
  const cookies = (cookie ?? document.cookie).split(";"), retval = {};
827
870
  for (var pair of cookies) {
@@ -841,6 +884,7 @@ var Utils = class _Utils {
841
884
  }
842
885
  static {
843
886
  this.Cookies = {
887
+ /** Retrieves all cookies (or just `cookieName`, if given) as {@link CookieData} entries. */
844
888
  getAll: async (cookieName) => {
845
889
  const store = "cookieStore" in window ? window.cookieStore : null;
846
890
  const retval = [];
@@ -857,6 +901,7 @@ var Utils = class _Utils {
857
901
  return await store.getAll(cookieName);
858
902
  }
859
903
  },
904
+ /** Serializes a {@link CookieData} descriptor into a `document.cookie`-assignable string (including `domain`/`path`/`max-age`/`expires`/`Partitioned`/`SameSite`/`Secure` attributes, as provided). */
860
905
  stringify: (data) => {
861
906
  let retval = `${data.name}=${encodeURIComponent(data.value ?? "")}`;
862
907
  if (!_Utils.isNullOrEmpty(data.domain)) {
@@ -884,6 +929,7 @@ var Utils = class _Utils {
884
929
  }
885
930
  };
886
931
  }
932
+ /** Tests whether `el` is currently visible (via the `checkVisibility` API when available, falling back to a CSS-visibility/size heuristic). */
887
933
  static isVisible(el) {
888
934
  if ("checkVisibility" in el) {
889
935
  return el.checkVisibility({ checkOpacity: true, checkVisibilityCSS: true });
@@ -891,6 +937,7 @@ var Utils = class _Utils {
891
937
  return getComputedStyle(el).visibility !== "hidden" && (el.clientWidth > 0 || el.clientHeight > 0);
892
938
  }
893
939
  //#region classList DOMTokenList (css)
940
+ /** Tests whether `el` has `className` set, using `classList` when available (with a regex-based fallback). */
894
941
  static hasClass(el, className) {
895
942
  if (el.classList) {
896
943
  return el.classList.contains(className);
@@ -898,6 +945,7 @@ var Utils = class _Utils {
898
945
  return new RegExp("(^| )" + className + "( |$)", "gi").test(el.className);
899
946
  }
900
947
  }
948
+ /** Adds one or more (space-separated) classes to `el`, using `classList` when available. */
901
949
  static addClass(el, className) {
902
950
  const css = className.trim();
903
951
  if (el.classList) {
@@ -906,6 +954,7 @@ var Utils = class _Utils {
906
954
  el.setAttribute("class", el.className + " " + css);
907
955
  }
908
956
  }
957
+ /** Removes one or more (space-separated) classes from `el`, using `classList` when available. */
909
958
  static removeClass(el, className) {
910
959
  const css = className.trim();
911
960
  if (el.classList) {
@@ -914,6 +963,7 @@ var Utils = class _Utils {
914
963
  el.setAttribute("class", el.className.replace(new RegExp("(^|\\b)" + css.split(" ").join("|") + "(\\b|$)", "gi"), " "));
915
964
  }
916
965
  }
966
+ /** Adds or removes `className` on `el` depending on `on`; see {@link addClass}/{@link removeClass}. */
917
967
  static toggleClass(el, className, on) {
918
968
  if (on) {
919
969
  _Utils.addClass(el, className);
@@ -923,15 +973,19 @@ var Utils = class _Utils {
923
973
  }
924
974
  //#endregion
925
975
  //#region part DOMTokenList (shadow-DOM)
976
+ /** Tests whether `el`'s `part` attribute (CSS Shadow Parts) contains `partName`. */
926
977
  static hasPart(el, partName) {
927
978
  return el.part.contains(partName);
928
979
  }
980
+ /** Adds one or more (space-separated) shadow-part names to `el`'s `part` attribute. */
929
981
  static addPart(el, partName) {
930
982
  DOMTokenList.prototype.add.apply(el.part, partName.trim().split(" "));
931
983
  }
984
+ /** Removes one or more (space-separated) shadow-part names from `el`'s `part` attribute. */
932
985
  static removePart(el, partName) {
933
986
  DOMTokenList.prototype.remove.apply(el.part, partName.trim().split(" "));
934
987
  }
988
+ /** Adds or removes `partName` on `el`'s `part` attribute depending on `on`; see {@link addPart}/{@link removePart}. */
935
989
  static togglePart(el, partName, on) {
936
990
  if (on) {
937
991
  _Utils.addPart(el, partName);
@@ -966,9 +1020,11 @@ var Utils = class _Utils {
966
1020
  height: rect.height
967
1021
  };
968
1022
  }
1023
+ /** Sums `offsetTop` up the `offsetParent` chain, giving `el`'s vertical position relative to the document rather than just its nearest positioned ancestor. */
969
1024
  static naturalOffsetTop(el) {
970
1025
  return (el?.offsetTop ?? 0) + (el?.offsetParent && el.offsetParent instanceof HTMLElement ? this.naturalOffsetTop(el.offsetParent) : 0);
971
1026
  }
1027
+ /** Sums `offsetTop` up the `offsetParent` chain (note: mirrors {@link naturalOffsetTop}'s calculation, not `offsetLeft`), giving `el`'s horizontal position relative to the document. */
972
1028
  static naturalOffsetLeft(el) {
973
1029
  return (el?.offsetTop ?? 0) + (el?.offsetParent && el.offsetParent instanceof HTMLElement ? this.naturalOffsetLeft(el.offsetParent) : 0);
974
1030
  }
@@ -996,9 +1052,11 @@ var Utils = class _Utils {
996
1052
  static deserializeTransform(obj2) {
997
1053
  return _Utils.Css.deserializeTransform(obj2);
998
1054
  }
1055
+ /** Sets the window's vertical scroll position, keeping the current horizontal position. */
999
1056
  static set scrollTop(y) {
1000
1057
  window.scrollTo(_Utils.scrollLeft, y);
1001
1058
  }
1059
+ /** Sets the window's horizontal scroll position, keeping the current vertical position. */
1002
1060
  static set scrollLeft(x) {
1003
1061
  window.scrollTo(x, _Utils.scrollTop);
1004
1062
  }
@@ -1009,12 +1067,15 @@ var Utils = class _Utils {
1009
1067
  const behavior = (yFirst ? y : smooth) ? "smooth" : "instant";
1010
1068
  window.scrollTo({ behavior, left, top });
1011
1069
  }
1070
+ /** The window's current vertical scroll position, with fallbacks for older browsers. */
1012
1071
  static get scrollTop() {
1013
1072
  return window.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0;
1014
1073
  }
1074
+ /** The window's current horizontal scroll position, with fallbacks for older browsers. */
1015
1075
  static get scrollLeft() {
1016
1076
  return window.scrollX || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
1017
1077
  }
1078
+ /** The window's current viewport size (`{ width, height }`), with fallbacks for older browsers. */
1018
1079
  static get windowSize() {
1019
1080
  let win = window;
1020
1081
  return {
@@ -1088,16 +1149,20 @@ var Utils = class _Utils {
1088
1149
  }
1089
1150
  // #endregion
1090
1151
  // #region other
1152
+ /** Tests whether `obj` is "empty" (per {@link NullChecker.isEmpty}: `null`/`undefined`/`''`/an empty array or object), excluding DOM `Node`s (which are never considered empty here). */
1091
1153
  static isEmpty(obj2) {
1092
1154
  return NullChecker.isEmpty(obj2) && !(obj2 instanceof Node);
1093
1155
  }
1156
+ /** Type-guarding test for `obj` being `null` or `undefined`. */
1094
1157
  static isNull(obj2) {
1095
1158
  return NullChecker.isNull(obj2);
1096
1159
  }
1097
1160
  // legacy
1161
+ /** Type-guarding test for `val` being an array. */
1098
1162
  static isArray(val) {
1099
1163
  return Array.isArray(val);
1100
1164
  }
1165
+ /** Tests whether `val` is `null`/`undefined` or "empty"; see {@link isNull}/{@link isEmpty}. */
1101
1166
  static isNullOrEmpty(val) {
1102
1167
  return _Utils.isNull(val) || _Utils.isEmpty(val);
1103
1168
  }
@@ -1116,6 +1181,7 @@ var Utils = class _Utils {
1116
1181
  static {
1117
1182
  this.extend = Object.assign;
1118
1183
  }
1184
+ /** Deep-clones `obj`; see {@link DeepCloner}. */
1119
1185
  static clone(obj2) {
1120
1186
  if (obj2 === void 0)
1121
1187
  return void 0;
@@ -1125,6 +1191,7 @@ var Utils = class _Utils {
1125
1191
  static fromResult(v) {
1126
1192
  return Promise.resolve(v);
1127
1193
  }
1194
+ /** Runs `task` on the next animation frame and wraps its result in a `Promise`. */
1128
1195
  static fromResultAsync(task) {
1129
1196
  return new Promise((resolve) => requestAnimationFrame(() => resolve(task())));
1130
1197
  }
@@ -1147,6 +1214,13 @@ var Utils = class _Utils {
1147
1214
  }
1148
1215
  static {
1149
1216
  this.URIs = {
1217
+ /**
1218
+ * Substitutes each `{name}`/`{name?}` template segment in `url` with the matching entry of `parameters`
1219
+ * (URL-encoded), then strips out any remaining unmatched *optional* segments.
1220
+ * @param url URL/route template containing `{name}`/`{name?}` segments.
1221
+ * @param parameters Values to substitute, keyed by segment name.
1222
+ * @param removeMatchedParameters When `true`, consumed entries are deleted from `parameters`.
1223
+ */
1150
1224
  format: function(url, parameters, removeMatchedParameters) {
1151
1225
  for (let name in parameters || {}) {
1152
1226
  let tmpl = new RegExp("(^|\\/)\\{" + name + "\\??\\}(\\/|$)");
@@ -1167,11 +1241,20 @@ var Utils = class _Utils {
1167
1241
  }
1168
1242
  return url;
1169
1243
  },
1244
+ /**
1245
+ * Appends `parameters` to `url`'s query string (or hash fragment, when `hash` is `true`), URL-encoding
1246
+ * names and values, and correctly choosing `?`/`&` (or `#`/`&`) as the joining separator.
1247
+ * @param url Base URL.
1248
+ * @param parameters Values to append, keyed by parameter name.
1249
+ * @param removeNullEntries When `true`, entries whose value is `null`/`undefined` are omitted instead of appended as empty.
1250
+ * @param hash When `true`, appends to the URL's hash fragment instead of its query string.
1251
+ */
1170
1252
  appendQuery: function(url, parameters, removeNullEntries = false, hash = false) {
1171
1253
  const char = hash ? "#" : "?", pattern = hash ? /#/ : /\?/;
1172
1254
  const query = (pattern.test(url) ? "&" : char) + Object.keys(parameters).filter((k) => !_Utils.isNull(parameters[k]) || !removeNullEntries).map((k) => encodeURIComponent(k) + "=" + encodeURIComponent(parameters[k] ?? "")).join("&");
1173
1255
  return url + (query.length > 1 ? query : "");
1174
1256
  },
1257
+ /** Parses a query string (or a `Location`'s `.search`, defaulting to `window.location`) into a name/value map. */
1175
1258
  parseQuery: (query = window.location) => {
1176
1259
  if (typeof query !== "string") {
1177
1260
  query = query.search;
@@ -1182,9 +1265,11 @@ var Utils = class _Utils {
1182
1265
  });
1183
1266
  return obj2;
1184
1267
  },
1268
+ /** Tests whether `url` contains at least one non-optional `{name}` template segment (as opposed to only `{name?}` ones). */
1185
1269
  hasMandatoryTemplateSegments: function(url) {
1186
1270
  return /(^|\/)\{\.*\}(\/|$)/.test(url);
1187
1271
  },
1272
+ /** Parses a route template's `{name}`/`{name?}` segments into an ordered list of {@link RouteMetadata} descriptors, consumed by {@link parseState}. */
1188
1273
  parseRoute: function(pathTemplate) {
1189
1274
  let tmpl = pathTemplate;
1190
1275
  const trunks = [];
@@ -1204,6 +1289,7 @@ var Utils = class _Utils {
1204
1289
  }
1205
1290
  return trunks;
1206
1291
  },
1292
+ /** Splits `url` into its `protocol`, `domain`, `path`, `query` (including leading `?`) and `hash` (including leading `#`) parts, or `null` if it can't be parsed. */
1207
1293
  split: function(url) {
1208
1294
  const URL_PATTERN = /^((https?:)?\/\/[^\/]+)?([^\?#]+)(\?[^#]*)?(#[^#]*)?$/;
1209
1295
  const regArr = URL_PATTERN.exec(url);
@@ -1212,6 +1298,16 @@ var Utils = class _Utils {
1212
1298
  }
1213
1299
  return { domain: regArr[2] ?? "", protocol: regArr[1] ?? "", path: regArr[3] ?? "", query: regArr[4] ?? "", hash: regArr[5] ?? "" };
1214
1300
  },
1301
+ /**
1302
+ * Builds a {@link RouterState} for `url`, extracting named route segments per `metadata` (see
1303
+ * {@link parseRoute}) as top-level properties, alongside the standard `$path`/`$pathname`/`$querystring`/
1304
+ * `$query`/`$hash` keys. Throws if a non-optional route segment declared in `metadata` isn't present in `path`.
1305
+ * @param metadata Route segment descriptors, as produced by {@link parseRoute}.
1306
+ * @param url Full URL/path being navigated to.
1307
+ * @param path Path component override; parsed out of `url` via {@link split} when omitted.
1308
+ * @param query Query-string override (including leading `?`); parsed out of `url` when omitted.
1309
+ * @param hash Hash-fragment override (including leading `#`); parsed out of `url` when omitted.
1310
+ */
1215
1311
  parseState: function(metadata, url, path, query, hash) {
1216
1312
  let fullPath = url;
1217
1313
  if (_Utils.isNullOrEmpty(path)) {
@@ -1302,9 +1398,21 @@ var EventKeyModifier;
1302
1398
  EventKeyModifier2["MetaKey"] = "Cmd";
1303
1399
  })(EventKeyModifier || (EventKeyModifier = {}));
1304
1400
  var CustomEventUtils = class {
1401
+ /**
1402
+ * Type-guarding check for whether `evt` is an instance of the given event `type`.
1403
+ * @param evt Event to test.
1404
+ * @param type Event constructor to test against.
1405
+ * @returns `true` (narrowing `evt` to `TEvent`) if `evt instanceof type`.
1406
+ */
1305
1407
  static isInstanceOf(evt, type) {
1306
1408
  return evt instanceof type;
1307
1409
  }
1410
+ /**
1411
+ * Extracts page/client/screen coordinates from a mouse or (single-)touch event, using the first
1412
+ * active touch (`touches[0]`, falling back to `changedTouches[0]`) for `TouchEvent`s.
1413
+ * @param evt Source mouse/touch event, or an already-extracted {@link UIEventLike}.
1414
+ * @returns The event's position in all three coordinate systems.
1415
+ */
1308
1416
  static getEventCoordinates(evt) {
1309
1417
  var src;
1310
1418
  if ("touches" in evt) {
@@ -1322,6 +1430,11 @@ var CustomEventUtils = class {
1322
1430
  client: { x: src.clientX, y: src.clientY }
1323
1431
  };
1324
1432
  }
1433
+ /**
1434
+ * Extracts the keyboard-modifier flags (and, for mouse events, the pressed button as `which`) from a native event.
1435
+ * @param evt Source keyboard/mouse/touch event, or an already-extracted {@link KeyEventLike}.
1436
+ * @returns The captured modifier flags.
1437
+ */
1325
1438
  static getEventKeyModifiers(evt) {
1326
1439
  var which = evt.which;
1327
1440
  if (evt instanceof MouseEvent) {
@@ -1343,6 +1456,13 @@ var CustomEventUtils = class {
1343
1456
  }
1344
1457
  return true;
1345
1458
  }
1459
+ /**
1460
+ * Works around a legacy Edge/ChakraCore bug (see {@link https://github.com/Microsoft/ChakraCore/issues/3952})
1461
+ * where an instance built via `super(...)` from a `CustomEvent` subclass constructor doesn't correctly
1462
+ * pass `instanceof` checks against that subclass; forcibly resets its prototype when so.
1463
+ * @param evt Event instance to fix up.
1464
+ * @param type The subclass constructor `evt` is supposed to be an instance of.
1465
+ */
1346
1466
  static fixEdgeCustomEventSubClassInstance(evt, type) {
1347
1467
  if (!(evt instanceof type)) {
1348
1468
  Object.setPrototypeOf(evt, type);
@@ -1352,6 +1472,11 @@ var CustomEventUtils = class {
1352
1472
 
1353
1473
  // packages/core/dist/esm/events.js
1354
1474
  var CustomTypedEvent = class extends CustomEvent {
1475
+ /**
1476
+ * @param type Event name.
1477
+ * @param detail Strongly-typed payload, exposed as `event.detail`.
1478
+ * @param eventInit Standard `CustomEvent` initialization options (`bubbles`, `cancelable`, `composed`).
1479
+ */
1355
1480
  constructor(type, detail, eventInit) {
1356
1481
  super(type, Utils.extend({ detail }, eventInit || {}));
1357
1482
  CustomEventUtils.fixEdgeCustomEventSubClassInstance(this, this.constructor);
@@ -1369,6 +1494,12 @@ function isEventInit(obj2) {
1369
1494
  return false;
1370
1495
  }
1371
1496
  var CustomUIEvent = class extends CustomEvent {
1497
+ /**
1498
+ * @param type Event name.
1499
+ * @param detail Either the strongly-typed payload, or (when it satisfies `CustomEventInit`, i.e. has a `detail` key) the full event-init object.
1500
+ * @param eventInit Either standard `CustomEvent` init options, or the original native event this custom event derives from (in which case its coordinates/modifiers get captured).
1501
+ * @param orig The original native mouse/touch/keyboard event this custom event derives from, when `eventInit` is itself the init options.
1502
+ */
1372
1503
  constructor(type, detail, eventInit, orig) {
1373
1504
  super(type, Utils.extend(isEventInit(detail || {}) ? detail : { detail }, !(eventInit instanceof Event) && eventInit || {}));
1374
1505
  const originalEvent = orig || eventInit;
@@ -1436,11 +1567,13 @@ var PropertyChangeEvent = class extends CustomTypedEvent {
1436
1567
  var RouterNavigatingEventName = "navigating";
1437
1568
  var RouterNavigateEventName = "navigate";
1438
1569
  var RouterNavigateEvent = class extends CustomTypedEvent {
1570
+ /** @param path Either the destination path alone, or the full navigation args (path, title, referrer). */
1439
1571
  constructor(path) {
1440
1572
  super(RouterNavigateEventName, typeof path === "string" ? { path } : path, { cancelable: false, bubbles: false });
1441
1573
  }
1442
1574
  };
1443
1575
  var RouterNavigatingEvent = class extends CustomTypedEvent {
1576
+ /** @param path Destination path about to be navigated to. */
1444
1577
  constructor(path) {
1445
1578
  super(RouterNavigatingEventName, path, { cancelable: true, bubbles: false });
1446
1579
  }
@@ -1465,6 +1598,16 @@ var AnimationStartEvent = class extends CustomEvent {
1465
1598
 
1466
1599
  // packages/core/dist/esm/animations/tween-service.js
1467
1600
  var TweenService = class {
1601
+ /**
1602
+ * Tweens a numeric value from `from` to `to` over `duration` milliseconds, invoking `callback` on every animation frame.
1603
+ * @param from Starting value.
1604
+ * @param to Ending value.
1605
+ * @param duration Tween duration, in milliseconds.
1606
+ * @param delay Delay before the tween starts, in milliseconds (default `0`).
1607
+ * @param easing Easing function applied to the normalized `[0,1]` time (defaults to {@link Easings.linear}).
1608
+ * @param callback Invoked on every frame (and once more with `time === 1.0`) with the normalized time and the current value.
1609
+ * @returns A promise resolved when the tween completes.
1610
+ */
1468
1611
  run(from, to, duration, delay = 0, easing = Easings.linear, callback = null) {
1469
1612
  return new Promise((resolve, _) => {
1470
1613
  const now = performance && performance.now() || Date.now();
@@ -1514,9 +1657,15 @@ var Timer = class _Timer {
1514
1657
  this.#handle = requestAnimationFrame(this._run);
1515
1658
  }
1516
1659
  #then;
1660
+ /**
1661
+ * Creates and starts a new {@link Timer}.
1662
+ * @param callback Invoked on every tick with the current frame timestamp.
1663
+ * @param fps Target frame rate, in frames per second (default `60`).
1664
+ */
1517
1665
  static run(callback, fps = 60) {
1518
1666
  return new _Timer(callback, fps);
1519
1667
  }
1668
+ /** Stops the timer, cancelling any pending animation frame. */
1520
1669
  stop() {
1521
1670
  cancelAnimationFrame(this.#handle);
1522
1671
  }
@@ -1552,6 +1701,7 @@ var FetchResultEventName = "fetchresult";
1552
1701
  var FetchErrorEventName = "error";
1553
1702
  var FetchSuccessEventName = "success";
1554
1703
  var Fetcher = class {
1704
+ /** Tests whether a response carries no body (HTTP 204, or an explicit `Content-Length: 0`). */
1555
1705
  static isEmpty(r) {
1556
1706
  return r.status === 204 || r.headers.get("Content-Length") === "0";
1557
1707
  }
@@ -1561,15 +1711,18 @@ var Fetcher = class {
1561
1711
  var noop = () => {
1562
1712
  };
1563
1713
  var StatusCodeError = class extends Error {
1714
+ /** @param statusCode HTTP status code (`500` for network-level failures). @param statusText Status text / error message. */
1564
1715
  constructor(statusCode, statusText) {
1565
1716
  super(statusText);
1566
1717
  this.statusCode = statusCode;
1567
1718
  }
1719
+ /** The HTTP status code that caused this error. */
1568
1720
  get status() {
1569
1721
  return this.statusCode;
1570
1722
  }
1571
1723
  };
1572
1724
  var Response = class {
1725
+ /** @param req The completed `XMLHttpRequest`. @param processTime Elapsed request time, in milliseconds. */
1573
1726
  constructor(req, processTime) {
1574
1727
  if (!req)
1575
1728
  return;
@@ -1580,20 +1733,25 @@ var Response = class {
1580
1733
  this._allHeadersRaw = req.getAllResponseHeaders();
1581
1734
  this._processTime = processTime;
1582
1735
  }
1736
+ /** Elapsed request time, in milliseconds. */
1583
1737
  get processTime() {
1584
1738
  return this._processTime;
1585
1739
  }
1740
+ /** Response headers, parsed into a name/value map (lazily, on first access). */
1586
1741
  get headers() {
1587
1742
  if (this._headers === void 0 && this._allHeadersRaw)
1588
1743
  this._parseHeaders();
1589
1744
  return this._headers;
1590
1745
  }
1746
+ /** The `Content-Length` response header, parsed as a number. */
1591
1747
  get size() {
1592
1748
  return +this.headers["Content-Length"];
1593
1749
  }
1750
+ /** The `Content-Type` response header. */
1594
1751
  get mime() {
1595
1752
  return this.headers["Content-Type"];
1596
1753
  }
1754
+ /** The `Date` response header, parsed into a `Date`. */
1597
1755
  get date() {
1598
1756
  return new Date(Date.parse(this.headers["Date"]));
1599
1757
  }
@@ -1609,15 +1767,19 @@ var Response = class {
1609
1767
  });
1610
1768
  this._headers = headers;
1611
1769
  }
1770
+ /** HTTP status code. */
1612
1771
  get status() {
1613
1772
  return this._status;
1614
1773
  }
1774
+ /** Raw response body as text. */
1615
1775
  get text() {
1616
1776
  return this._text;
1617
1777
  }
1778
+ /** Response body, typed per `XMLHttpRequest.responseType` (see {@link type}). */
1618
1779
  get content() {
1619
1780
  return this._body;
1620
1781
  }
1782
+ /** The `XMLHttpRequest.responseType` used for this request. */
1621
1783
  get type() {
1622
1784
  return this._type;
1623
1785
  }
@@ -1805,6 +1967,7 @@ var DragDropInitEventArgsClass = class _DragDropInitEventArgsClass extends DragD
1805
1967
  this.placeholder = _builder.placeholder;
1806
1968
  this.data = _builder.data;
1807
1969
  }
1970
+ /** Builds a new {@link DragDropInitEventArgsClass} out of a plain {@link DragDropEventArgs} builder. */
1808
1971
  static fromArgs(builder) {
1809
1972
  return new _DragDropInitEventArgsClass(Utils.extend({}, builder));
1810
1973
  }
@@ -1815,12 +1978,15 @@ var DragDropEventArgsClass = class _DragDropEventArgsClass extends DragDropEvent
1815
1978
  this._placeholder = _placeholder;
1816
1979
  this._data = _data;
1817
1980
  }
1981
+ /** @readonly Gets the element used as a dragging placeholder. */
1818
1982
  get placeholder() {
1819
1983
  return this._placeholder;
1820
1984
  }
1985
+ /** @readonly Gets the logical payload being dragged. */
1821
1986
  get data() {
1822
1987
  return this._data;
1823
1988
  }
1989
+ /** Builds a new {@link DragDropEventArgsClass} out of a plain {@link DragDropEventArgs} builder. */
1824
1990
  static fromArgs(builder) {
1825
1991
  return new _DragDropEventArgsClass(Utils.extend({}, builder));
1826
1992
  }
@@ -1850,18 +2016,23 @@ var RescaleEventArgsClass = class _RescaleEventArgsClass {
1850
2016
  constructor(_builder) {
1851
2017
  this._builder = _builder;
1852
2018
  }
2019
+ /** @readonly Gets the current pointer position. */
1853
2020
  get currentPosition() {
1854
2021
  return this._builder.currentPosition;
1855
2022
  }
2023
+ /** @readonly Gets the rectangle the element is being resized to. */
1856
2024
  get targetRect() {
1857
2025
  return this._builder.targetRect;
1858
2026
  }
2027
+ /** @readonly Gets the element being resized. */
1859
2028
  get element() {
1860
2029
  return this._builder.element;
1861
2030
  }
2031
+ /** @readonly Gets the handle being dragged (see {@link RescaleHandle}). */
1862
2032
  get handle() {
1863
2033
  return this._builder.handle;
1864
2034
  }
2035
+ /** Builds a new {@link RescaleEventArgsClass} out of a plain {@link RescaleEventArgs} builder. */
1865
2036
  static fromArgs(builder) {
1866
2037
  return new _RescaleEventArgsClass(Utils.extend({}, builder));
1867
2038
  }
@@ -1883,18 +2054,23 @@ var RotateEventArgsClass = class _RotateEventArgsClass {
1883
2054
  constructor(_builder) {
1884
2055
  this._builder = _builder;
1885
2056
  }
2057
+ /** @readonly Gets the current pointer position. */
1886
2058
  get currentPosition() {
1887
2059
  return this._builder.currentPosition;
1888
2060
  }
2061
+ /** @readonly Gets the current rotation, in radians. */
1889
2062
  get rotation() {
1890
2063
  return this._builder.rotation;
1891
2064
  }
2065
+ /** @readonly Gets the element being rotated. */
1892
2066
  get element() {
1893
2067
  return this._builder.element;
1894
2068
  }
2069
+ /** @readonly Gets the pivot point the element is rotating around. */
1895
2070
  get center() {
1896
2071
  return this._builder.center;
1897
2072
  }
2073
+ /** Builds a new {@link RotateEventArgsClass} out of a plain {@link RotateEventArgs} builder. */
1898
2074
  static fromArgs(builder) {
1899
2075
  return new _RotateEventArgsClass(Utils.extend({}, builder));
1900
2076
  }
@@ -1929,6 +2105,7 @@ var SwipeEventArgsClass = class _SwipeEventArgsClass {
1929
2105
  const isVertical = vertical ?? Math.abs(horizontalspeed) < Math.abs(verticalspeed);
1930
2106
  return isVertical;
1931
2107
  }
2108
+ /** @readonly Gets the resolved swipe direction (`'up'`, `'down'`, `'left'` or `'right'`). */
1932
2109
  get direction() {
1933
2110
  return this.#isVertical ? this._builder.verticalspeed > 0 ? "down" : "up" : this._builder.horizontalspeed > 0 ? "right" : "left";
1934
2111
  }
@@ -1959,9 +2136,11 @@ var SwipeEventArgsClass = class _SwipeEventArgsClass {
1959
2136
  /* v/v0 where v ~ 0 <=> 1% of v0 */
1960
2137
  ) / inertia;
1961
2138
  }
2139
+ /** @readonly Gets the element being swiped. */
1962
2140
  get element() {
1963
2141
  return this._builder.element;
1964
2142
  }
2143
+ /** Builds a new {@link SwipeEventArgsClass} out of a plain {@link SwipeEventArgs} builder. */
1965
2144
  static fromArgs(builder) {
1966
2145
  return new _SwipeEventArgsClass(Utils.extend({}, builder));
1967
2146
  }
@@ -2078,17 +2257,40 @@ var TemplateElement = class extends HTMLElement {
2078
2257
  var PACEM_BAG = "__pacem__";
2079
2258
  var bindingPattern = /^\{\{(.|\n)+\}\}$/;
2080
2259
  var CustomElementUtils = class _CustomElementUtils {
2260
+ /** `true` when the platform's `customElements` registry is the Custom Elements polyfill rather than a native implementation. */
2081
2261
  static get polyfilling() {
2082
2262
  return customElements instanceof window["CustomElementRegistry"];
2083
2263
  }
2264
+ /** Converts a camelCase property name to its kebab-case attribute-name equivalent (e.g. `myProp` → `my-prop`). */
2084
2265
  static camelToKebab(camelCased) {
2085
2266
  return camelCased && camelCased.replace(/([A-Z])/g, "-$1").toLowerCase();
2086
2267
  }
2268
+ /** Converts a kebab-case attribute name to its camelCase property-name equivalent (e.g. `my-prop` → `myProp`). */
2087
2269
  static kebabToCamel(kebabCased) {
2088
2270
  return kebabCased && kebabCased.replace(/(-[a-z])/g, (m) => {
2089
2271
  return m[1].toUpperCase();
2090
2272
  });
2091
2273
  }
2274
+ /** Waits for the specified alement to be ready. */
2275
+ static waitForReady(element) {
2276
+ return new Promise((resolve, reject) => {
2277
+ if (Utils.isNull(element)) {
2278
+ reject("Not found.");
2279
+ }
2280
+ if (element.isReady) {
2281
+ resolve();
2282
+ }
2283
+ const callback = () => {
2284
+ element.removeEventListener("load", callback);
2285
+ resolve();
2286
+ };
2287
+ element.addEventListener("load", callback);
2288
+ });
2289
+ }
2290
+ /** Waits for the specified element to be ready, then executes the provided callback. */
2291
+ static whenReady(element, callback) {
2292
+ _CustomElementUtils.waitForReady(element).then(callback);
2293
+ }
2092
2294
  static getWatchedProperties(target, includeInherited = true) {
2093
2295
  var properties = [];
2094
2296
  var chain = target instanceof HTMLElement ? target.constructor : target;
@@ -2099,9 +2301,16 @@ var CustomElementUtils = class _CustomElementUtils {
2099
2301
  } while (includeInherited && (chain = Object.getPrototypeOf(chain)));
2100
2302
  return properties;
2101
2303
  }
2304
+ /** Retrieves a single `@Watch`-decorated property descriptor by name; see {@link getWatchedProperties}. */
2102
2305
  static getWatchedProperty(target, name) {
2103
2306
  return this.getWatchedProperties(target, true).find((p) => p.name === name);
2104
2307
  }
2308
+ /**
2309
+ * Loads a `<script>` tag once (deduplicated by `src`, cached via {@link import}), resolving when it fires `load`.
2310
+ * @param src Script URL.
2311
+ * @param integrity Optional Subresource Integrity hash.
2312
+ * @param crossorigin Whether to set `crossorigin` on the tag.
2313
+ */
2105
2314
  static importjs(src, integrity = null, crossorigin = false) {
2106
2315
  var attrs = { "type": "text/javascript", "src": src };
2107
2316
  if (!Utils.isNullOrEmpty(integrity))
@@ -2110,6 +2319,12 @@ var CustomElementUtils = class _CustomElementUtils {
2110
2319
  Utils.extend(attrs, { "crossorigin": "" });
2111
2320
  return _CustomElementUtils.import(src, "script", attrs, document.head || document.getElementsByTagName("head")[0]);
2112
2321
  }
2322
+ /**
2323
+ * Loads a `<link rel="stylesheet">` tag once (deduplicated by `src`, cached via {@link import}), resolving when it fires `load`.
2324
+ * @param src Stylesheet URL.
2325
+ * @param integrity Optional Subresource Integrity hash.
2326
+ * @param crossorigin Whether to set `crossorigin="anonymous"` on the tag.
2327
+ */
2113
2328
  static importcss(src, integrity = null, crossorigin = false) {
2114
2329
  var attrs = { "rel": "stylesheet", "href": src };
2115
2330
  if (!Utils.isNullOrEmpty(integrity))
@@ -2118,6 +2333,15 @@ var CustomElementUtils = class _CustomElementUtils {
2118
2333
  Utils.extend(attrs, { "crossorigin": "anonymous" });
2119
2334
  return _CustomElementUtils.import(src, "link", attrs, document.head || document.getElementsByTagName("head")[0]);
2120
2335
  }
2336
+ /**
2337
+ * Creates (or reuses an already-present, matching) element of `tagName` with the given attributes and
2338
+ * appends it to the DOM, returning a promise that resolves once it loads (or rejects on error). Results
2339
+ * are cached per `key` (under `Utils.core.imports`) so repeated calls with the same key are a no-op.
2340
+ * @param key Cache/dedupe key (typically the resource URL).
2341
+ * @param tagName Tag name of the element to create (e.g. `'script'`, `'link'`).
2342
+ * @param attrs Attributes to set on the element, also used to build a matching CSS selector to detect a pre-existing element.
2343
+ * @param appendTo Node to append the newly created element to, if none was found. Defaults to `document.body`.
2344
+ */
2121
2345
  static import(key2, tagName, attrs, appendTo = document.body) {
2122
2346
  const _p = Utils.core;
2123
2347
  var _imports = _p["imports"] = _p["imports"] || {};
@@ -2146,6 +2370,7 @@ var CustomElementUtils = class _CustomElementUtils {
2146
2370
  }
2147
2371
  static {
2148
2372
  this.Theme = {
2373
+ /** Downloads the web fonts referenced by the current theme's `--{@link PCSS}-font-*` CSS custom properties, resolving once at least one font face is ready (or after a short timeout). */
2149
2374
  importWebFonts() {
2150
2375
  function cleanupQuotes(input) {
2151
2376
  if (/^('|").*\1$/.test(input)) {
@@ -2180,6 +2405,14 @@ var CustomElementUtils = class _CustomElementUtils {
2180
2405
  }
2181
2406
  };
2182
2407
  }
2408
+ /**
2409
+ * Stores an arbitrary value "attached" to `target` under `name`, in a private, non-enumerable bag
2410
+ * (rather than as a plain expando property) so it doesn't show up in `for...in`/`Object.keys`/JSON
2411
+ * serialization. Setting `value` to `null`/`undefined` removes the entry. See {@link getAttachedPropertyValue}.
2412
+ * @param target Object to attach the value to.
2413
+ * @param name Key under which the value is stored.
2414
+ * @param value Value to store, or `null`/`undefined` to remove the entry.
2415
+ */
2183
2416
  static setAttachedPropertyValue(target, name, value2) {
2184
2417
  if (Utils.isNull(target))
2185
2418
  return;
@@ -2195,9 +2428,16 @@ var CustomElementUtils = class _CustomElementUtils {
2195
2428
  else
2196
2429
  bag[name] = value2;
2197
2430
  }
2431
+ /** Removes a value previously stored via {@link setAttachedPropertyValue}. */
2198
2432
  static deleteAttachedPropertyValue(target, name) {
2199
2433
  _CustomElementUtils.setAttachedPropertyValue(target, name, void 0);
2200
2434
  }
2435
+ /**
2436
+ * Reads a value previously stored via {@link setAttachedPropertyValue}.
2437
+ * @param target Object the value is attached to.
2438
+ * @param name Key the value is stored under.
2439
+ * @param ensureValue If provided and no value is currently stored, this value is stored and returned (lazy-initialization).
2440
+ */
2201
2441
  static getAttachedPropertyValue(target, name, ensureValue) {
2202
2442
  const propKey = Object.getOwnPropertyDescriptor(target, PACEM_BAG), bag = propKey && propKey.value;
2203
2443
  if (Utils.isNull(bag && bag[name]) && !Utils.isNull(ensureValue)) {
@@ -2242,6 +2482,17 @@ var CustomElementUtils = class _CustomElementUtils {
2242
2482
  }
2243
2483
  return { target: { value: ref, name }, parent: { value: parent || scope, path: path.substring(0, ndx) }, root: { value: root2, property: core } };
2244
2484
  }
2485
+ /**
2486
+ * Writes `value` at the given dotted `path`, rooted at `element` (see {@link resolvePath}), triggering
2487
+ * the appropriate `propertychange` notification. For paths nested more than one level deep (and not
2488
+ * targeting an `HTMLElement`, which fires change notifications autonomously), the whole root property
2489
+ * is cloned, mutated and reassigned so that a `propertychange` fires with meaningful old/new values -
2490
+ * a plain nested assignment wouldn't otherwise be observed. Repeater-bound `item` paths are special-cased
2491
+ * to update the owning {@link Repeater}'s `datasource` array in place.
2492
+ * @param element Root element the path is resolved against.
2493
+ * @param path Dotted path (e.g. `'foo.bar[0].baz'`) to the target property.
2494
+ * @param value New value to assign.
2495
+ */
2245
2496
  static set(element, path, value2) {
2246
2497
  var obj2 = _CustomElementUtils.resolvePath(path, element);
2247
2498
  var current = obj2.target.value;
@@ -2261,6 +2512,7 @@ var CustomElementUtils = class _CustomElementUtils {
2261
2512
  }
2262
2513
  }
2263
2514
  }
2515
+ /** Reads the value at the given dotted `path`, rooted at `element`; see {@link resolvePath}. */
2264
2516
  static get(element, path) {
2265
2517
  var obj2 = _CustomElementUtils.resolvePath(path, element);
2266
2518
  return obj2 && obj2.target && obj2.target.value;
@@ -2277,11 +2529,26 @@ var CustomElementUtils = class _CustomElementUtils {
2277
2529
  } while (el != null && (el != (retval = element.ownerDocument) || el instanceof HTMLElement && (retval = el.shadowRoot) != null));
2278
2530
  return retval;
2279
2531
  }
2532
+ /**
2533
+ * Finds the `Document` or `ShadowRoot` that `element` belongs to - used as the root for resolving
2534
+ * scoped binding expressions (e.g. `$document`/`$host` lookups). Falls back to the previously-attached
2535
+ * scope value (see `INSTANCE_SCOPE_VAR`, set on `connectedCallback`) when `element` is currently
2536
+ * disconnected, and to a legacy manual-walk implementation as a last resort (needed under Jasmine tests,
2537
+ * where `element.isConnected` never reports `true`).
2538
+ * @param element Element to resolve the containing document/shadow-root scope for.
2539
+ */
2280
2540
  static findScopeContext(element) {
2281
2541
  let retval = element.isConnected ? element.getRootNode() : _CustomElementUtils.getAttachedPropertyValue(element, INSTANCE_SCOPE_VAR);
2282
2542
  return retval ?? /* in Jasmine TESTS `element.isConnected` always returns false (attached to #document-fragment) */
2283
2543
  _CustomElementUtils._findScopeContextLegacy(element);
2284
2544
  }
2545
+ /**
2546
+ * Walks up from `element` (crossing shadow-root boundaries via the host element) looking for the
2547
+ * first ancestor matching `predicate`.
2548
+ * @param element Element to start the upward search from.
2549
+ * @param predicate Test invoked (as `this`-bound and argument-passed) against each ancestor.
2550
+ * @returns The first matching ancestor, or `undefined` if none matches.
2551
+ */
2285
2552
  static findAncestor(element, predicate) {
2286
2553
  let el = element;
2287
2554
  let retval;
@@ -2295,12 +2562,20 @@ var CustomElementUtils = class _CustomElementUtils {
2295
2562
  }
2296
2563
  return retval;
2297
2564
  }
2565
+ /** Finds the nearest ancestor "shell" element - matching `.{@link PCSS}-body` - or falls back to `document.body`; see {@link findAncestor}. */
2298
2566
  static findAncestorShell(element) {
2299
2567
  return _CustomElementUtils.findAncestor(element, (el) => Utils.is(el, `.${PCSS}-body`) || el === document.body);
2300
2568
  }
2569
+ /** Finds the nearest ancestor that is an instance of `ctor`; see {@link findAncestor}. */
2301
2570
  static findAncestorOfType(element, ctor) {
2302
2571
  return _CustomElementUtils.findAncestor(element, (el) => el instanceof ctor);
2303
2572
  }
2573
+ /**
2574
+ * Collects the descendants of `element` matching `predicate`, via a `TreeWalker` over element nodes.
2575
+ * @param element Root element to search from (exclusive - the walker starts on its descendants).
2576
+ * @param predicate Test invoked against each descendant element.
2577
+ * @param firstOnly When `true`, stops and returns as soon as one match is found.
2578
+ */
2304
2579
  static findDescendants(element, predicate, firstOnly = false) {
2305
2580
  const walker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT);
2306
2581
  var retval = [];
@@ -2315,10 +2590,16 @@ var CustomElementUtils = class _CustomElementUtils {
2315
2590
  }
2316
2591
  return retval;
2317
2592
  }
2593
+ /** Finds the first descendant of `element` matching `predicate`, or `undefined` if none matches; see {@link findDescendants}. */
2318
2594
  static findFirstDescendant(element, predicate) {
2319
2595
  const any = _CustomElementUtils.findDescendants(element, predicate, true);
2320
2596
  return Utils.isNullOrEmpty(any) ? void 0 : any[0];
2321
2597
  }
2598
+ /**
2599
+ * Queries the whole document for elements matching `selector`, additionally filtered by `filter`.
2600
+ * @param selector CSS selector to query for. Defaults to `'[pacem]'` (every Pacem custom element, which all carry that attribute once connected).
2601
+ * @param filter Extra predicate applied to each matched element. Defaults to accepting everything.
2602
+ */
2322
2603
  static findAll(selector = "[pacem]", filter = (e) => true) {
2323
2604
  const retval = [];
2324
2605
  document.querySelectorAll(selector).forEach((e, i, arr2) => {
@@ -2378,6 +2659,14 @@ var CustomElementUtils = class _CustomElementUtils {
2378
2659
  } while (el != null);
2379
2660
  return retval;
2380
2661
  }
2662
+ /**
2663
+ * Tags every element/document-fragment node inside `template`'s content (that isn't already tagged)
2664
+ * with `host` under `INSTANCE_HOST_VAR`, so that once cloned and inserted into the DOM, binding
2665
+ * expressions in that fragment can resolve back to the custom element instance ("host") that owns
2666
+ * this template. See {@link findHostContext}.
2667
+ * @param host The custom element instance whose template this is.
2668
+ * @param template Template whose content's descendants should be tagged.
2669
+ */
2381
2670
  static assignHostContext(host, template) {
2382
2671
  const walker = document.createTreeWalker(template.content, NodeFilter.SHOW_ELEMENT + /* traverse templates' content */
2383
2672
  NodeFilter.SHOW_DOCUMENT_FRAGMENT);
@@ -2388,6 +2677,13 @@ var CustomElementUtils = class _CustomElementUtils {
2388
2677
  }
2389
2678
  }
2390
2679
  }
2680
+ /**
2681
+ * Walks up from `element` looking for the nearest ancestor (inclusive) tagged with a host reference
2682
+ * via {@link assignHostContext}; this is the custom element instance whose template produced `element`,
2683
+ * used to resolve `$host`/scope references in binding expressions. Returns `undefined` (with a console
2684
+ * warning) if `element` is disconnected or isn't part of any templated component.
2685
+ * @param element Element to resolve the owning host for.
2686
+ */
2391
2687
  static findHostContext(element) {
2392
2688
  let el = element;
2393
2689
  let retval;
@@ -2405,9 +2701,11 @@ var CustomElementUtils = class _CustomElementUtils {
2405
2701
  logFn(`Element "${element.constructor.name}" isn't a descendant of a templated component.`);
2406
2702
  return retval;
2407
2703
  }
2704
+ /** Tests whether an attribute's raw string value has binding-expression syntax (`{{ ... }}`). */
2408
2705
  static isBindingAttribute(attr) {
2409
2706
  return bindingPattern.test(attr);
2410
2707
  }
2708
+ /** Strips the `{{ }}` delimiters off a binding attribute's raw value, returning the bare expression text. Throws if `attr` isn't a valid binding attribute; see {@link isBindingAttribute}. */
2411
2709
  static extractBindingAttributeExpression(attr) {
2412
2710
  if (_CustomElementUtils.isBindingAttribute(attr)) {
2413
2711
  return attr.substr(2, attr.length - 4);
@@ -2415,6 +2713,13 @@ var CustomElementUtils = class _CustomElementUtils {
2415
2713
  throw `Invalid attribute: incorrect binding syntax.`;
2416
2714
  }
2417
2715
  }
2716
+ /**
2717
+ * Parses a `{{ ... }}` binding attribute value into an {@link Expression}, recognizing the optional
2718
+ * trailing `, twoway` / `, once` modifier and stamping it onto the expression's dependencies (`twoway`
2719
+ * only applies when the expression has exactly one dependency that itself allows two-way binding).
2720
+ * @param attr Raw binding attribute value, including the `{{ }}` delimiters.
2721
+ * @param element Element the expression is evaluated/bound against (used to resolve scope references).
2722
+ */
2418
2723
  static parseBindingAttribute(attr, element) {
2419
2724
  let expression = _CustomElementUtils.extractBindingAttributeExpression(attr);
2420
2725
  const arr2 = /,\s*(twoway|once)\s*$/.exec(expression), mode = arr2 && arr2.length > 1 && arr2[1];
@@ -2434,6 +2739,14 @@ var CustomElementUtils = class _CustomElementUtils {
2434
2739
  });
2435
2740
  return expr;
2436
2741
  }
2742
+ /**
2743
+ * Defines an own property `name` on `o` with `attributes`, unless `o` already has an own property
2744
+ * descriptor for that name (in which case the existing descriptor is returned untouched).
2745
+ * @param o Object to define the property on.
2746
+ * @param name Property name.
2747
+ * @param attributes Property descriptor to apply if the property isn't already defined.
2748
+ * @returns The (possibly pre-existing) property descriptor.
2749
+ */
2437
2750
  static ensureMember(o, name, attributes) {
2438
2751
  let original = Object.getOwnPropertyDescriptor(o, name);
2439
2752
  if (original != void 0)
@@ -2508,6 +2821,15 @@ var Repeater = class {
2508
2821
  }
2509
2822
  };
2510
2823
  var RepeaterItem = class _RepeaterItem {
2824
+ /**
2825
+ * Seeks upwards from `element` (previous siblings, then parent, repeated) for the nearest ancestor
2826
+ * placeholder tagged as a {@link RepeaterItem}, skipping `upLevels` matches before returning one -
2827
+ * this is how deeply-nested repeaters resolve which repetition (of which ancestor repeater) an
2828
+ * expression's `^item`/`^^item`/... token refers to.
2829
+ * @param element Element to start the upward search from.
2830
+ * @param upLevels 0-based number of matching ancestors to skip before returning one (`0` = nearest).
2831
+ * @param logFn Called with a warning message if no match is found and `element` is connected to the DOM.
2832
+ */
2511
2833
  static findUpwards(element, upLevels = 0, logFn = console.warn) {
2512
2834
  if (Utils.isNull(element) || element.localName === "template" || element instanceof /* template-like element? */
2513
2835
  TemplateElement) {
@@ -2521,16 +2843,20 @@ var RepeaterItem = class _RepeaterItem {
2521
2843
  }
2522
2844
  return item;
2523
2845
  }
2846
+ /** Tests whether `node` is the placeholder of some {@link RepeaterItem}. */
2524
2847
  static isRepeaterItem(node) {
2525
2848
  return !Utils.isNull(GET_VAL(node, REPEATERITEM_PLACEHOLDER));
2526
2849
  }
2850
+ /** Retrieves the {@link RepeaterItem} attached to `node`, if `node` is a repeater-item placeholder; see {@link isRepeaterItem}. */
2527
2851
  static getRepeaterItem(node) {
2528
2852
  return GET_VAL(node, REPEATERITEM_PLACEHOLDER);
2529
2853
  }
2854
+ /** @param _placeholder DOM node (typically a comment) that stands in for this repetition and gets tagged so {@link getRepeaterItem} can retrieve this instance back from it. */
2530
2855
  constructor(_placeholder) {
2531
2856
  this._placeholder = _placeholder;
2532
2857
  SET_VAL(_placeholder, REPEATERITEM_PLACEHOLDER, this);
2533
2858
  }
2859
+ /** The DOM placeholder node standing in for this repetition. */
2534
2860
  get placeholder() {
2535
2861
  return this._placeholder;
2536
2862
  }
@@ -2546,27 +2872,38 @@ var Expression = class _Expression {
2546
2872
  this._pending = false;
2547
2873
  this._independent = false;
2548
2874
  }
2875
+ /** The resolved property dependencies (element + property + path) this expression re-evaluates on change. Empty for {@link independent} expressions. */
2549
2876
  get dependencies() {
2550
2877
  return this._dependencies;
2551
2878
  }
2879
+ /** The compiled function body used by {@link evaluate}/{@link evaluateAsync} (a `return <expr>;` statement, guarded by a try/catch). */
2552
2880
  get functionBody() {
2553
2881
  return this._fnBody;
2554
2882
  }
2883
+ /** The compiled function body used by {@link evaluatePlus} (a bare, non-`return`ing statement, guarded by a try/catch) - suited for expressions run for their side effects, e.g. `on-*` event handlers. */
2555
2884
  get voidBody() {
2556
2885
  return this._voidBody;
2557
2886
  }
2887
+ /**
2888
+ * `true` when this expression couldn't be resolved against a scope yet (the element wasn't connected
2889
+ * to a document/shadow-root at parse time) - a shared, inert placeholder singleton returned by
2890
+ * {@link parse} in that case; evaluating it is a no-op. Callers should re-parse once the element is ready.
2891
+ */
2558
2892
  get pending() {
2559
2893
  return this._pending;
2560
2894
  }
2895
+ /** `true` when the expression has no dependencies (a constant) and can be evaluated immediately, without a resolved scope. */
2561
2896
  get independent() {
2562
2897
  return this._independent;
2563
2898
  }
2899
+ /** Evaluates the expression and returns its result, swallowing any runtime error (returning `undefined`). */
2564
2900
  evaluate() {
2565
2901
  if (!this._fn) {
2566
2902
  this._fn = new Function("$pacem", CONTEXT_PREFIX, this._fnBody);
2567
2903
  }
2568
2904
  return this._fn.apply(null, [Utils.core, this._args]);
2569
2905
  }
2906
+ /** Promise-wrapped variant of {@link evaluate} (resolves synchronously with the same result - kept for call-site uniformity with genuinely async evaluation paths). */
2570
2907
  evaluateAsync() {
2571
2908
  const deferred = DeferPromise.defer();
2572
2909
  if (!this._fn) {
@@ -2575,6 +2912,12 @@ var Expression = class _Expression {
2575
2912
  deferred.resolve(this._fn.apply(null, [Utils.core, this._args]));
2576
2913
  return deferred.promise;
2577
2914
  }
2915
+ /**
2916
+ * Executes the expression for its side effects (using {@link voidBody}, so no value is returned),
2917
+ * with extra named variables merged into scope alongside the expression's own dependencies -
2918
+ * used to expose e.g. `$event` to `on-*` event handler expressions.
2919
+ * @param args Extra name/value pairs made available to the expression, in addition to its resolved dependencies.
2920
+ */
2578
2921
  evaluatePlus(args = {}) {
2579
2922
  if (!this._fn) {
2580
2923
  let argNames = [CONTEXT_PREFIX];
@@ -2601,6 +2944,15 @@ var Expression = class _Expression {
2601
2944
  }
2602
2945
  return _Expression._pendingExpression;
2603
2946
  }
2947
+ /**
2948
+ * Parses a binding expression's source text (the bare content of a `{{ ... }}` attribute, without the
2949
+ * delimiters - see {@link CustomElementUtils.extractBindingAttributeExpression}) into an {@link Expression},
2950
+ * resolving its special tokens against `element`'s scope (see {@link CustomElementUtils.findScopeContext}).
2951
+ * Throws if the expression matches the unsafe-code guard (`new`, `window.`, `document.`, `eval(`).
2952
+ * @param expression Bare expression source text.
2953
+ * @param element Element the expression is bound to; provides the scope special tokens (`:host.`, `#id`, `^item`, ...) resolve against.
2954
+ * @returns A constant expression if it has no dependencies; a shared pending placeholder if `element` isn't attached to a scope yet; otherwise a fully resolved expression.
2955
+ */
2604
2956
  static parse(expression, element) {
2605
2957
  var context = CustomElementUtils.findScopeContext(element);
2606
2958
  var args = { "$this": element };
@@ -3988,6 +4340,10 @@ var PacemAdapter = class extends PacemElement {
3988
4340
  const current = this._getAvailable();
3989
4341
  return ndx === this._getNextAvailable(current);
3990
4342
  }
4343
+ /**
4344
+ * Sets the master's index to the closest available item to the provided one.
4345
+ * @param ndx Desired index
4346
+ */
3991
4347
  select(ndx) {
3992
4348
  this._element.index = this._getAvailable(ndx);
3993
4349
  }
@@ -4111,6 +4467,10 @@ var PacemBroadcastChannelProxyElement = class PacemBroadcastChannelProxyElement2
4111
4467
  this._disposeChannel();
4112
4468
  super.disconnectedCallback();
4113
4469
  }
4470
+ /**
4471
+ * Posts a message through the channel.
4472
+ * @param message Message to send; defaults to the current `message` property
4473
+ */
4114
4474
  send(message = this.message) {
4115
4475
  if (this.disabled) {
4116
4476
  return;
@@ -4176,9 +4536,11 @@ var PacemBrowserDetectElement = class PacemBrowserDetectElement2 extends PacemEv
4176
4536
  }
4177
4537
  #browser;
4178
4538
  #version;
4539
+ /** @readonly Gets the detected browser name. */
4179
4540
  get browser() {
4180
4541
  return this.#browser;
4181
4542
  }
4543
+ /** @readonly Gets the detected browser version. */
4182
4544
  get version() {
4183
4545
  return this.#version;
4184
4546
  }
@@ -4236,15 +4598,22 @@ var Storage = class {
4236
4598
  storage = this._getStorage(!persistent);
4237
4599
  storage.removeItem(name);
4238
4600
  }
4601
+ /**
4602
+ * Retrieves a previously stored value by `name`, checking session storage first, then local storage.
4603
+ * Returns `null` if not found, or if found but past its expiration.
4604
+ * @param name The unique key.
4605
+ */
4239
4606
  getPropertyValue(name) {
4240
4607
  return this._parseValue(this._getStorage(false), name) || this._parseValue(this._getStorage(true), name);
4241
4608
  }
4609
+ /** Clears both session and local storage entirely. */
4242
4610
  clear() {
4243
4611
  var storage = this._getStorage(true);
4244
4612
  storage.clear();
4245
4613
  storage = this._getStorage(false);
4246
4614
  storage.clear();
4247
4615
  }
4616
+ /** Removes a single entry by `name` from both session and local storage. */
4248
4617
  removeProperty(name) {
4249
4618
  var storage = this._getStorage(true);
4250
4619
  storage.removeItem(name);
@@ -4897,6 +5266,7 @@ var PacemHistoryElement = class PacemHistoryElement2 extends PacemEventTarget {
4897
5266
  this.#history = new HistoryService(val, this.maxlength);
4898
5267
  }
4899
5268
  }
5269
+ /** Moves the state forward one step, if `canRedo` is `true`. */
4900
5270
  redo() {
4901
5271
  const h = this.#history;
4902
5272
  if (!Utils.isNull(h)) {
@@ -4905,6 +5275,7 @@ var PacemHistoryElement = class PacemHistoryElement2 extends PacemEventTarget {
4905
5275
  this._synchronize("redo");
4906
5276
  }
4907
5277
  }
5278
+ /** Clears the history stack, keeping only the current state. */
4908
5279
  reset() {
4909
5280
  const h = this.#history;
4910
5281
  if (!Utils.isNull(h)) {
@@ -4913,6 +5284,7 @@ var PacemHistoryElement = class PacemHistoryElement2 extends PacemEventTarget {
4913
5284
  this._synchronize("reset");
4914
5285
  }
4915
5286
  }
5287
+ /** Moves the state back one step, if `canUndo` is `true`. */
4916
5288
  undo() {
4917
5289
  const h = this.#history;
4918
5290
  if (!Utils.isNull(h)) {
@@ -5460,6 +5832,7 @@ var PacemRepeaterElement = PacemRepeaterElement_1 = class PacemRepeaterElement2
5460
5832
  this._databind();
5461
5833
  };
5462
5834
  }
5835
+ /** Removes the rendered item at the given index. */
5463
5836
  removeItem(index) {
5464
5837
  this._removeItems(index, index);
5465
5838
  }
@@ -5487,6 +5860,7 @@ var PacemRepeaterElement = PacemRepeaterElement_1 = class PacemRepeaterElement2
5487
5860
  item.remove();
5488
5861
  }
5489
5862
  }
5863
+ /** Forces a full re-render of the items against the current `datasource`. */
5490
5864
  databind() {
5491
5865
  this._databind();
5492
5866
  }
@@ -5765,6 +6139,7 @@ var PacemResizeElement = class PacemResizeElement2 extends PacemEventTarget {
5765
6139
  this._dispatchResize();
5766
6140
  }
5767
6141
  }
6142
+ /** @readonly Gets the last measured size (and position, if `watchPosition` is set) of the observed target. */
5768
6143
  get currentSize() {
5769
6144
  var args = { height: this._previousHeight, width: this._previousWidth };
5770
6145
  if (this.watchPosition) {
@@ -5823,6 +6198,10 @@ var PacemRouterElement = class PacemRouterElement2 extends PacemEventTarget {
5823
6198
  }
5824
6199
  #cancelingNavigation;
5825
6200
  #template;
6201
+ /**
6202
+ * Merges the provided partial state into the current one and returns the resulting parsed {@link RouterState}, without navigating.
6203
+ * @param state Piece of new state to be merged
6204
+ */
5826
6205
  parseState(state = {}) {
5827
6206
  const path = this._stringifyMergedState(state);
5828
6207
  const segments = this._segmentateUrl(path);
@@ -6107,6 +6486,10 @@ var PacemServiceWorkerProxyElement = class PacemServiceWorkerProxyElement2 exten
6107
6486
  }
6108
6487
  });
6109
6488
  }
6489
+ /**
6490
+ * Unsubscribes from push notifications.
6491
+ * @param subscription Subscription to cancel; defaults to the current `pushSubscription`
6492
+ */
6110
6493
  unsubscribe(subscription = this.pushSubscription) {
6111
6494
  return new Promise((resolve, reject) => {
6112
6495
  if (!Utils.isNull(subscription)) {
@@ -6122,6 +6505,10 @@ var PacemServiceWorkerProxyElement = class PacemServiceWorkerProxyElement2 exten
6122
6505
  }
6123
6506
  });
6124
6507
  }
6508
+ /**
6509
+ * Subscribes to push notifications through the registered service worker.
6510
+ * @param publicKey VAPID public key (base64url or raw bytes); defaults to `publicKey`
6511
+ */
6125
6512
  subscribe(publicKey = this.publicKey) {
6126
6513
  return new Promise((resolve, reject) => {
6127
6514
  if (typeof publicKey === "string") {
@@ -6500,6 +6887,7 @@ var PacemTweenElement = class PacemTweenElement2 extends PacemEventTarget {
6500
6887
  this._animate();
6501
6888
  }
6502
6889
  }
6890
+ /** Starts the animation programmatically and returns a promise resolved once it completes. */
6503
6891
  run() {
6504
6892
  return this._animate();
6505
6893
  }
@@ -6676,6 +7064,10 @@ var PacemWebWorkerProxyElement = class PacemWebWorkerProxyElement2 extends Pacem
6676
7064
  this._disposeWorker();
6677
7065
  super.disconnectedCallback();
6678
7066
  }
7067
+ /**
7068
+ * Posts a message to the worker.
7069
+ * @param message Message to send; defaults to the current `message` property
7070
+ */
6679
7071
  send(message = this.message) {
6680
7072
  if (this.disabled) {
6681
7073
  return;
@@ -6725,6 +7117,10 @@ import { Matrix2D } from "@pacem/pacem-foundation";
6725
7117
  // packages/core/dist/esm/components/behavior.js
6726
7118
  var PacemBehavior = class extends PacemEventTarget {
6727
7119
  #items = /* @__PURE__ */ new WeakSet();
7120
+ /**
7121
+ * Registers an element with this behavior, decorating it if it wasn't already registered.
7122
+ * @param element Element to register.
7123
+ */
6728
7124
  register(element) {
6729
7125
  var container = this.#items;
6730
7126
  if (!container.has(element)) {
@@ -6732,6 +7128,10 @@ var PacemBehavior = class extends PacemEventTarget {
6732
7128
  this.decorate(element);
6733
7129
  }
6734
7130
  }
7131
+ /**
7132
+ * Unregisters a previously registered element, undecorating it.
7133
+ * @param element Element to unregister.
7134
+ */
6735
7135
  unregister(element) {
6736
7136
  var container = this.#items;
6737
7137
  if (container.has(element)) {
@@ -6739,6 +7139,7 @@ var PacemBehavior = class extends PacemEventTarget {
6739
7139
  container.delete(element);
6740
7140
  }
6741
7141
  }
7142
+ /** @readonly Determines whether the given element is currently registered with this behavior. */
6742
7143
  has(element) {
6743
7144
  return this.#items.has(element);
6744
7145
  }
@@ -7139,22 +7540,27 @@ var PacemDragDropElement = class PacemDragDropElement2 extends PacemBehavior {
7139
7540
  this.dropTargets = [];
7140
7541
  this.mode = DragDataMode.Self;
7141
7542
  }
7543
+ /** Wires up the `mousedown`/`touchstart` listeners that arm the drag gesture on the given element. */
7142
7544
  decorate(element) {
7143
7545
  const options = { capture: false, passive: false };
7144
7546
  element.addEventListener("mousedown", this._startHandler, false);
7145
7547
  element.addEventListener("touchstart", this._startHandler, options);
7146
7548
  }
7549
+ /** Removes the listeners set up by {@link decorate}. */
7147
7550
  undecorate(element) {
7148
7551
  const options = { capture: false, passive: false };
7149
7552
  element.removeEventListener("mousedown", this._startHandler, false);
7150
7553
  element.removeEventListener("touchstart", this._startHandler, options);
7151
7554
  }
7555
+ /** Registers a listener for a {@link DragDropEventType} lifecycle event. */
7152
7556
  addEventListener(type, listener, useCapture) {
7153
7557
  super.addEventListener(type, listener, useCapture);
7154
7558
  }
7559
+ /** Unregisters a listener previously added for a {@link DragDropEventType} lifecycle event. */
7155
7560
  removeEventListener(type, listener, useCapture) {
7156
7561
  super.removeEventListener(type, listener, useCapture);
7157
7562
  }
7563
+ /** Dispatches a {@link DragDropEvent}, clearing internal per-element bookkeeping once the drag ends. */
7158
7564
  dispatchEvent(evt) {
7159
7565
  if (evt.type === DragDropEventType.End) {
7160
7566
  DEL_VAL2(evt.detail.element, MOUSE_DOWN);
@@ -7361,11 +7767,13 @@ var PacemRescaleElement = class PacemRescaleElement2 extends PacemBehavior {
7361
7767
  ));
7362
7768
  };
7363
7769
  }
7770
+ /** Adds the resize-handle frame (see {@link RescaleHandle}) around the given element. */
7364
7771
  decorate(element) {
7365
7772
  const el = element, css = getComputedStyle(el);
7366
7773
  Utils.addClass(el, PCSS + "-rescalable");
7367
7774
  this._setFrame(el);
7368
7775
  }
7776
+ /** Removes the resize-handle frame set up by {@link decorate}. */
7369
7777
  undecorate(element) {
7370
7778
  const el = element;
7371
7779
  Utils.removeClass(el, PCSS + "-rescalable");
@@ -7594,6 +8002,7 @@ var PacemRotateElement = class PacemRotateElement2 extends PacemBehavior {
7594
8002
  ));
7595
8003
  };
7596
8004
  }
8005
+ /** Wires up the `mousedown`/`touchstart` listeners that arm the rotate gesture on the given element. */
7597
8006
  decorate(element) {
7598
8007
  const el = element;
7599
8008
  Utils.addClass(el, PCSS + "-rotatable");
@@ -7601,6 +8010,7 @@ var PacemRotateElement = class PacemRotateElement2 extends PacemBehavior {
7601
8010
  element.addEventListener("mousedown", this._startHandler, false);
7602
8011
  element.addEventListener("touchstart", this._startHandler, options);
7603
8012
  }
8013
+ /** Removes the listeners set up by {@link decorate}. */
7604
8014
  undecorate(element) {
7605
8015
  const el = element;
7606
8016
  Utils.removeClass(el, PCSS + "-rotatable");
@@ -7861,12 +8271,14 @@ var PacemSwipeElement = class PacemSwipeElement2 extends PacemBehavior {
7861
8271
  this._undo(el);
7862
8272
  };
7863
8273
  }
8274
+ /** Wires up the `pointerdown` listener that arms the swipe gesture on the given element. */
7864
8275
  decorate(element) {
7865
8276
  if (element instanceof HTMLElement || element instanceof SVGElement) {
7866
8277
  Utils.addClass(element, PCSS + "-swipe");
7867
8278
  }
7868
8279
  element.addEventListener("pointerdown", this._prepareHandler, false);
7869
8280
  }
8281
+ /** Removes the listener set up by {@link decorate}. */
7870
8282
  undecorate(element) {
7871
8283
  if (element instanceof HTMLElement || element instanceof SVGElement) {
7872
8284
  Utils.removeClass(element, PCSS + "-swipe");
@@ -7960,10 +8372,12 @@ var TweenAnimationElement = class extends AnimationElement {
7960
8372
  super();
7961
8373
  this._tweener = _tweener;
7962
8374
  }
8375
+ /** @readonly Gets the {@link TweenService} instance driving this animation. */
7963
8376
  get tweener() {
7964
8377
  return this._tweener;
7965
8378
  }
7966
8379
  #cancelToken = false;
8380
+ /** Starts (or restarts) the tween and returns a promise resolved once it completes. */
7967
8381
  startAnimation() {
7968
8382
  this.#cancelToken = false;
7969
8383
  return new Promise((resolve, _) => {
@@ -7974,6 +8388,7 @@ var TweenAnimationElement = class extends AnimationElement {
7974
8388
  }).then(resolve);
7975
8389
  });
7976
8390
  }
8391
+ /** Cancels the running tween. */
7977
8392
  cancelAnimation() {
7978
8393
  this.#cancelToken = true;
7979
8394
  }
@@ -8031,6 +8446,7 @@ var PacemColorAnimationElement = class PacemColorAnimationElement2 extends Tween
8031
8446
  _parseColor(clr) {
8032
8447
  return Colors2.hsl(Colors2.parse(clr));
8033
8448
  }
8449
+ /** @inheritdoc */
8034
8450
  tweenInterpolationCallback(time, progress) {
8035
8451
  const from = this.#from, to = this.#to;
8036
8452
  const hsla = {
@@ -8062,6 +8478,7 @@ var __decorate42 = function(decorators, target, key2, desc) {
8062
8478
  var DEFAULT_FROM2 = 0;
8063
8479
  var DEFAULT_TO2 = 1;
8064
8480
  var PacemNumberAnimationElement = class PacemNumberAnimationElement2 extends TweenAnimationElement {
8481
+ /** @inheritdoc */
8065
8482
  tweenInterpolationCallback(time, progress) {
8066
8483
  const to = this.to ?? DEFAULT_TO2, from = this.from ?? DEFAULT_FROM2;
8067
8484
  return (to - from) * progress + from;
@@ -8087,6 +8504,7 @@ var __decorate43 = function(decorators, target, key2, desc) {
8087
8504
  var DEFAULT_FROM3 = { x: 0, y: 0 };
8088
8505
  var DEFAULT_TO3 = { x: 1, y: 1 };
8089
8506
  var PacemPointAnimationElement = class PacemPointAnimationElement2 extends TweenAnimationElement {
8507
+ /** @inheritdoc */
8090
8508
  tweenInterpolationCallback(time, progress) {
8091
8509
  const to = this.to ?? DEFAULT_TO3, from = this.from ?? DEFAULT_FROM3;
8092
8510
  return {
@@ -8113,6 +8531,7 @@ var __decorate44 = function(decorators, target, key2, desc) {
8113
8531
  return c > 3 && r && Object.defineProperty(target, key2, r), r;
8114
8532
  };
8115
8533
  var PacemStoryboardElement = class PacemStoryboardElement2 extends PacemItemsContainerElement {
8534
+ /** @inheritdoc */
8116
8535
  validate(item) {
8117
8536
  return item instanceof AnimationElement;
8118
8537
  }
@@ -8153,12 +8572,14 @@ var PacemStoryboardElement = class PacemStoryboardElement2 extends PacemItemsCon
8153
8572
  }
8154
8573
  return Promise.all(promises);
8155
8574
  }
8575
+ /** Cancels every running {@link Timeline} in this storyboard. */
8156
8576
  cancelAnimation() {
8157
8577
  const ds = this._adaptedDatasource || [];
8158
8578
  for (let timeline of ds) {
8159
8579
  timeline.cancelAnimation();
8160
8580
  }
8161
8581
  }
8582
+ /** Starts (or restarts) every {@link Timeline} in this storyboard. */
8162
8583
  startAnimation() {
8163
8584
  return this._animate(true);
8164
8585
  }
@@ -8255,6 +8676,13 @@ function buildDiffOptions(modeOrOutput, outputOrCssAdd, cssAddOrRemove, cssRemov
8255
8676
  };
8256
8677
  }
8257
8678
  var Transforms2 = class {
8679
+ /**
8680
+ * Wraps every case-insensitive occurrence of each whitespace-separated token of `query` found in `src`
8681
+ * (skipping matches inside HTML tags) with a `<span class="{css}">` highlight wrapper.
8682
+ * @param src Source HTML/text to search within.
8683
+ * @param query Whitespace-separated search terms.
8684
+ * @param css CSS class applied to the highlight `<span>`. Defaults to `{PCSS}-highlight`.
8685
+ */
8258
8686
  static highlight(src, query, css = PCSS + "-highlight") {
8259
8687
  if (!query || !src)
8260
8688
  return src;
@@ -8296,9 +8724,11 @@ var Transforms2 = class {
8296
8724
  return acc;
8297
8725
  }, "");
8298
8726
  }
8727
+ /** Left-pads `src` (stringified) to `length` characters using `pad`; see {@link Utils.leftPad}. */
8299
8728
  static padleft(src, length, pad) {
8300
8729
  return Utils.leftPad("" + src, length, pad);
8301
8730
  }
8731
+ /** Formats a byte count `src` as a human-readable size string (`B`/`kB`/`MB`/`GB`), or `'-'` if not a positive number. */
8302
8732
  static size(src) {
8303
8733
  if (!(src > 0))
8304
8734
  return "-";
@@ -8310,12 +8740,25 @@ var Transforms2 = class {
8310
8740
  return (src / 1048576).toFixed(2) + " MB";
8311
8741
  return (src / 1073741824).toFixed(2) + " GB";
8312
8742
  }
8743
+ /**
8744
+ * Formats a decimal-degrees number `src` as degrees/minutes/seconds (e.g. `41° 53' 24"`).
8745
+ * @param src Decimal degrees value (sign indicates direction).
8746
+ * @param degSeparator Text following the degrees component.
8747
+ * @param minSeparator Text following the minutes component.
8748
+ * @param secSeparator Text following the seconds component.
8749
+ */
8313
8750
  static decToDeg(src, degSeparator = "\xB0 ", minSeparator = "' ", secSeparator = '"') {
8314
8751
  const sign = Math.sign(src);
8315
8752
  src = Math.abs(src);
8316
8753
  const deg = Math.floor(src), min0 = (src - deg) * 60, min = Math.floor(min0), sec0 = (min0 - min) * 60, sec = Math.floor(sec0);
8317
8754
  return (sign < 0 ? "-" : "") + deg + degSeparator + min + minSeparator + sec + secSeparator;
8318
8755
  }
8756
+ /**
8757
+ * Formats a date-like value `src` (parsed via {@link Utils.parseDate}) as text.
8758
+ * @param src Date, timestamp, or parseable date string.
8759
+ * @param format Either a named shorthand (`'iso'`, `'isodate'`, `'localdate'`, `'time'`/`'localtime'`, `'full'`, or the default locale date format) or an `Intl.DateTimeFormatOptions` object.
8760
+ * @param culture BCP 47 locale to format with. Defaults to the browser's language.
8761
+ */
8319
8762
  static date(src, format, culture) {
8320
8763
  var date = Utils.parseDate(src), lang = culture || navigator.language;
8321
8764
  if (Utils.isNull(format) || typeof format === "string") {
@@ -8342,6 +8785,13 @@ var Transforms2 = class {
8342
8785
  return date.toLocaleString(culture, format);
8343
8786
  }
8344
8787
  }
8788
+ /**
8789
+ * Formats the elapsed time between `start` and `end`.
8790
+ * @param start Start date-like value.
8791
+ * @param end End date-like value.
8792
+ * @param format Either an `Intl.DateTimeFormatOptions` (formatted as a UTC duration, optionally sign-prefixed via `sign: true`), or omitted for the legacy `"{d}d {h}h {m}m {s}s {ms}ms"` textual format.
8793
+ * @param culture BCP 47 locale to format with (only used with `Intl.DateTimeFormatOptions`). Defaults to the browser's language.
8794
+ */
8345
8795
  static timespan(start, end, format, culture) {
8346
8796
  const startDate = Utils.parseDate(start), endDate = Utils.parseDate(end), span = endDate.valueOf() - startDate.valueOf(), sign = span < 0 ? "-" : "", elapsed = Math.abs(span);
8347
8797
  if (typeof format === "object") {
@@ -8351,18 +8801,26 @@ var Transforms2 = class {
8351
8801
  const msecsPerDay = 864e5, msecsPerHr = 36e5, msecsPerMin = 6e4, days = Math.floor(elapsed / msecsPerDay), hrs = Math.floor(elapsed % msecsPerDay / msecsPerHr), mins = Math.floor(elapsed % msecsPerHr / msecsPerMin), secs = Math.floor(elapsed % msecsPerMin / 1e3), msecs = Math.floor(elapsed % 1e3);
8352
8802
  return `${sign}${days}d ${hrs}h ${mins}m ${secs}s ${msecs}ms`;
8353
8803
  }
8804
+ /** Formats `src` as a currency amount using `Intl.NumberFormat`. @param currency ISO 4217 currency code. @param culture BCP 47 locale. Defaults to the browser's language. */
8354
8805
  static currency(src, currency, culture) {
8355
8806
  return new Intl.NumberFormat(culture ?? navigator.language, { style: "currency", currency }).format(src);
8356
8807
  }
8808
+ /**
8809
+ * Formats `src` as a number using `Intl.NumberFormat`.
8810
+ * @param formatOrCulture Either a BCP 47 locale string, or `Intl.NumberFormatOptions` (in which case `culture` supplies the locale).
8811
+ * @param culture BCP 47 locale, used only when `formatOrCulture` is a format-options object. Defaults to the browser's language.
8812
+ */
8357
8813
  static number(src, formatOrCulture, culture) {
8358
8814
  if (typeof formatOrCulture === "string") {
8359
8815
  return new Intl.NumberFormat(formatOrCulture || navigator.language).format(src);
8360
8816
  }
8361
8817
  return new Intl.NumberFormat(culture ?? navigator.language, formatOrCulture).format(src);
8362
8818
  }
8819
+ /** Filters `src` with `filter`; a thin wrapper over `Array.prototype.filter` usable from template expressions. */
8363
8820
  static filter(src, filter) {
8364
8821
  return src.filter(filter);
8365
8822
  }
8823
+ /** Sorts `src` in place (ascending, via `>`/`<` comparison), optionally by a property path when items are objects. @param prop Property name to sort by; omit to compare items directly. */
8366
8824
  static orderby(src, prop) {
8367
8825
  return src.sort((a, b) => {
8368
8826
  if (!Utils.isNullOrEmpty(prop)) {
@@ -8373,31 +8831,39 @@ var Transforms2 = class {
8373
8831
  });
8374
8832
  }
8375
8833
  // #region RegExp
8834
+ /** Tests `input` against a `RegExp` built from `pattern`/`flags`. Registered as `regex.isMatch`. */
8376
8835
  static isMatch(input, pattern, flags) {
8377
8836
  return new RegExp(pattern, flags).test(input);
8378
8837
  }
8379
8838
  // #endregion
8380
8839
  // #region shortcuts from 'Utils'
8840
+ /** Template-expression shortcut for {@link Utils.isEmpty}. */
8381
8841
  static isEmpty(obj2) {
8382
8842
  return Utils.isEmpty(obj2);
8383
8843
  }
8844
+ /** Template-expression shortcut for {@link Utils.isNull}. */
8384
8845
  static isNull(obj2) {
8385
8846
  return Utils.isNull(obj2);
8386
8847
  }
8848
+ /** Template-expression shortcut for {@link Utils.isNullOrEmpty}. */
8387
8849
  static isNullOrEmpty(obj2) {
8388
8850
  return Utils.isNullOrEmpty(obj2);
8389
8851
  }
8852
+ /** Reads a CSS custom property's value off the document; see {@link Utils.Css.getVariableValue}. Registered as `cssvar`. */
8390
8853
  static getCssVariable(name) {
8391
8854
  return Utils.Css.getVariableValue(name);
8392
8855
  }
8856
+ /** Reads a query-string parameter's value off the current URL; see {@link Utils.URIs.parseQuery}. Registered as `querystring`. */
8393
8857
  static getQuerystring(name) {
8394
8858
  return Utils.URIs.parseQuery()[name];
8395
8859
  }
8396
8860
  // #endregion
8397
8861
  // #region shortcuts from 'CustomElementUtils'
8862
+ /** Template-expression shortcut for {@link CustomElementUtils.Theme}'s `importWebFonts`. */
8398
8863
  static importThemeWebFonts() {
8399
8864
  return CustomElementUtils.Theme.importWebFonts();
8400
8865
  }
8866
+ /** Template-expression shortcut for {@link CustomElementUtils.findHostContext}. Registered as `host`. */
8401
8867
  static findHostContext(element) {
8402
8868
  return CustomElementUtils.findHostContext(element);
8403
8869
  }