foldkit-primitives 0.7.0 → 0.9.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.
package/README.md CHANGED
@@ -154,7 +154,7 @@ reference: every Model shape, Message, argument, and failure rule.
154
154
  | [`device`](./device/README.md) | hardware | `Geolocation`, `mediaDevices`, `mediaStream`, `permissions`, fullscreen |
155
155
  | [`events`](./events/README.md) | raw window events | `Visibility`, `WindowSize`, `Idle`, `InputModality`, `keyboardEvents`, `pointerEvents`, `scrollEvents`, `activeElementEvents`, `matchHotkey` |
156
156
  | [`observers`](./observers/README.md) | element observers | `Resize`, `Intersection`, `Mutation`, `Bounds` |
157
- | [`dom`](./dom/README.md) | element Mounts and one-shot Commands | `Autofocus`, `InputMask`, `KeepInView`, `Measure`, `FocusScope`, `FollowTabStop`, `ScrollLock`, `HideOutside`, `copyText`, `readText`, `share`, `loadScript`, `keepScroll` |
157
+ | [`dom`](./dom/README.md) | element Mounts and one-shot Commands | `Autofocus`, `InputMask`, `KeepInView`, `Measure`, `FocusScope`, `FollowTabStop`, `ScrollLock`, `HideOutside`, `copyText`, `readText`, `share`, `loadScript`, `keepScroll`, `pointedLinks` |
158
158
 
159
159
  ## Rules every primitive keeps
160
160
 
@@ -67,6 +67,8 @@ export declare const Geolocation: Bundle.Bundle<"Geolocation", void, {
67
67
  } | null;
68
68
  readonly lastError: string | null;
69
69
  }, {
70
+ readonly _tag: "Denied";
71
+ } | {
70
72
  readonly _tag: "Failed";
71
73
  readonly message: string;
72
74
  } | {
@@ -74,8 +76,6 @@ export declare const Geolocation: Bundle.Bundle<"Geolocation", void, {
74
76
  readonly latitude: number;
75
77
  readonly longitude: number;
76
78
  readonly accuracy: number;
77
- } | {
78
- readonly _tag: "Denied";
79
79
  }, never, never, never, void, {}, {}>;
80
80
  //#endregion
81
81
  //#region src/device/media-devices.d.ts
@@ -139,8 +139,6 @@ export declare const mediaDevices: <const Name extends string>(config: {
139
139
  }[];
140
140
  readonly lastError: string | null;
141
141
  }, {
142
- readonly _tag: "Denied";
143
- } | {
144
142
  readonly _tag: "Failed";
145
143
  readonly message: string;
146
144
  } | {
@@ -155,6 +153,8 @@ export declare const mediaDevices: <const Name extends string>(config: {
155
153
  readonly kind: "audioinput" | "audiooutput" | "videoinput";
156
154
  readonly label: string;
157
155
  }[];
156
+ } | {
157
+ readonly _tag: "Denied";
158
158
  }, never, never, never, void, {}, {}>;
159
159
  //#endregion
160
160
  //#region src/device/media-stream.d.ts
@@ -1,6 +1,7 @@
1
1
  import { A as ScrollLock, C as targetOf, D as MoveStarted, E as MoveEnded, M as tabbableWithin, O as Moved, S as Targets, T as Move, _ as boxOf, a as TextEdited, b as TargetHovered, c as DRAG_THRESHOLD, d as DragFact, f as DragPlace, g as PointerDrag, h as DraggedOver, i as TextCommitted, j as FocusScope, k as HideOutside, l as DragCancelled, m as DragZone, n as EditableText, o as TextFact, p as DragStarted, r as TextCancelled, s as textOf, t as EditAsked, u as DragDropped, v as zoneOf, w as Fact, x as TargetPressed, y as TargetFact } from "../editable-text-BbsPOATY.mjs";
2
2
  import { Schema, Stream } from "effect";
3
3
  import * as Mount from "foldkit/mount";
4
+ import { Url } from "foldkit/url";
4
5
  import { Command } from "foldkit/command";
5
6
  //#region src/dom/autofocus.d.ts
6
7
  export declare const Focused: Schema.TaggedStruct<"Focused", {}>;
@@ -139,5 +140,15 @@ export interface KeepScrollOptions {
139
140
  */
140
141
  export declare const keepScroll: (options?: KeepScrollOptions) => Stream.Stream<never>;
141
142
  //#endregion
143
+ //#region src/dom/pointed-links.d.ts
144
+ /**
145
+ * The address of the link a reader points at or tabs to, on the page's own
146
+ * origin: where they may go next, for a `Data.preload` before they go. Each
147
+ * link once while they stay on it, since crossing its text sends one event
148
+ * per element inside it. Without a document the stream is empty. Lift with
149
+ * `Subscription.persistent`, mapping each address to a Message.
150
+ */
151
+ export declare const pointedLinks: () => Stream.Stream<Url>;
152
+ //#endregion
142
153
  export { DRAG_THRESHOLD, DragCancelled, DragDropped, DragFact, DragPlace, DragStarted, DragZone, DraggedOver, EditAsked, EditableText, Fact, FocusScope, HideOutside, Move, MoveEnded, MoveStarted, Moved, PointerDrag, ScrollLock, TargetFact, TargetHovered, TargetPressed, Targets, TextCancelled, TextCommitted, TextEdited, TextFact, boxOf, tabbableWithin, targetOf, textOf, zoneOf };
143
154
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/dom/autofocus.ts","../../src/dom/clipboard.ts","../../src/dom/input-mask.ts","../../src/dom/keep-in-view.ts","../../src/dom/script-loader.ts","../../src/dom/share.ts","../../src/dom/measure.ts","../../src/dom/follow-tab-stop.ts","../../src/dom/scroll.ts"],"mappings":";;;;;qBAUa,SAAO,OAAA;YACR,iBAAiB,QAAQ;qBAExB,WAAS,MAAA;;;;;qBCJT,4CAAgB;;;sBAAhB,OAAA;;;YAID,0BAA0B,iBAAiB;qBAE1C,gDAAoB;;;;;;;;YAIrB,8BAA8B,qBAAqB;;;;;;qBAUlD,WAAY,iBAAe,QAAQ;;;;;qBAsBnC,gBAAe,QAAQ;;;qBCvCvB,OAAK,OAAA;;;;YAIN,eAAe,MAAM;qBA2BpB,YACX,eACA;WACY;WAAyB;;qBAoC1B,WAAS,MAAA;;;;;;;;;qBCtET,YAAU,MAAA;;;;;;qBCDV,yCAAa;;;sBAAb,OAAA;;;YAID,uBAAuB,cAAc;;qBASpC,aAAc,gBAAc,QAAQ;;;qBCbpC,WAAS,OAAA;;;;;YAKV,mBAAmB,UAAU;qBAE5B,wCAAY;;;;sBAAZ,OAAA;;;YAKD,sBAAsB,aAAa;;qBAUlC,QAAS,MAAM,cAAY,QAAQ;;;;qBCVnC,WAAY;;;;;;;qBASZ,SAAO,MAAA;;;;;;qBCrBP,eAAa,MAAA;;;;UCuBhB,mBAAmB;WAClB;aAAyB;;;QAE5B;YACI;aACC,aAAa;;;iBAIT;;WAEN;;WAEA;;;;;WAKA;;;;;;;;qBAqHE,aAAc,UAAS,sBAAyB,OAAO"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/dom/autofocus.ts","../../src/dom/clipboard.ts","../../src/dom/input-mask.ts","../../src/dom/keep-in-view.ts","../../src/dom/script-loader.ts","../../src/dom/share.ts","../../src/dom/measure.ts","../../src/dom/follow-tab-stop.ts","../../src/dom/scroll.ts","../../src/dom/pointed-links.ts"],"mappings":";;;;;;qBAUa,SAAO,OAAA;YACR,iBAAiB,QAAQ;qBAExB,WAAS,MAAA;;;;;qBCJT,4CAAgB;;;sBAAhB,OAAA;;;YAID,0BAA0B,iBAAiB;qBAE1C,gDAAoB;;;;;;;;YAIrB,8BAA8B,qBAAqB;;;;;;qBAUlD,WAAY,iBAAe,QAAQ;;;;;qBAsBnC,gBAAe,QAAQ;;;qBCvCvB,OAAK,OAAA;;;;YAIN,eAAe,MAAM;qBA2BpB,YACX,eACA;WACY;WAAyB;;qBAoC1B,WAAS,MAAA;;;;;;;;;qBCtET,YAAU,MAAA;;;;;;qBCDV,yCAAa;;;sBAAb,OAAA;;;YAID,uBAAuB,cAAc;;qBASpC,aAAc,gBAAc,QAAQ;;;qBCbpC,WAAS,OAAA;;;;;YAKV,mBAAmB,UAAU;qBAE5B,wCAAY;;;;sBAAZ,OAAA;;;YAKD,sBAAsB,aAAa;;qBAUlC,QAAS,MAAM,cAAY,QAAQ;;;;qBCVnC,WAAY;;;;;;;qBASZ,SAAO,MAAA;;;;;;qBCrBP,eAAa,MAAA;;;;UCuBhB,mBAAmB;WAClB;aAAyB;;;QAE5B;YACI;aACC,aAAa;;;iBAIT;;WAEN;;WAEA;;;;;WAKA;;;;;;;;qBAqHE,aAAc,UAAS,sBAAyB,OAAO;;;;;;;;;;qBC9JvD,oBAAmB,OAAO,OAAO"}
@@ -2,6 +2,8 @@ import { C as MoveEnded, D as ScrollLock, E as HideOutside, O as FocusScope, S a
2
2
  import { Effect, Option, Queue, Schema, Stream } from "effect";
3
3
  import * as Mount from "foldkit/mount";
4
4
  import { defineMessageUnion } from "foldkit/message";
5
+ import * as Subscription from "foldkit/subscription";
6
+ import { fromString, toString } from "foldkit/url";
5
7
  //#region src/dom/autofocus.ts
6
8
  /**
7
9
  * Autofocus as a Mount: focuses the element on insert, then emits `Focused`.
@@ -511,6 +513,31 @@ const keepScroll = (options = {}) => {
511
513
  return Stream.callback(() => Effect.acquireRelease(Effect.sync(() => attach(storageKey, kept, patience)), (detach) => Effect.sync(detach)));
512
514
  };
513
515
  //#endregion
514
- export { Autofocus, ClipboardMessage, ClipboardReadMessage, DRAG_THRESHOLD, DragCancelled, DragDropped, DragPlace, DragStarted, DragZone, DraggedOver, EditAsked, EditableText, FocusScope, Focused, FollowTabStop, HideOutside, Input, InputMask, KeepInView, Measure, Move, MoveEnded, MoveStarted, Moved, PointerDrag, ScriptMessage, ScrollLock, ShareData, ShareMessage, TargetHovered, TargetPressed, Targets, TextCancelled, TextCommitted, TextEdited, applyMask, boxOf, copyText, keepScroll, loadScript, measured, readText, share, tabbableWithin, targetOf, textOf, zoneOf };
516
+ //#region src/dom/pointed-links.ts
517
+ /**
518
+ * The address of the link a reader points at or tabs to, on the page's own
519
+ * origin: where they may go next, for a `Data.preload` before they go. Each
520
+ * link once while they stay on it, since crossing its text sends one event
521
+ * per element inside it. Without a document the stream is empty. Lift with
522
+ * `Subscription.persistent`, mapping each address to a Message.
523
+ */
524
+ const pointedLinks = () => {
525
+ if (typeof document === "undefined") return Stream.empty;
526
+ const linkOf = (event) => {
527
+ const link = event.target instanceof Element ? event.target.closest("a[href]") : null;
528
+ return link instanceof HTMLAnchorElement && link.origin === window.location.origin ? fromString(link.href) : Option.none();
529
+ };
530
+ return Stream.merge(Subscription.fromEventFilterMap({
531
+ target: document,
532
+ type: "pointerover",
533
+ filterMapEvent: linkOf
534
+ }), Subscription.fromEventFilterMap({
535
+ target: document,
536
+ type: "focusin",
537
+ filterMapEvent: linkOf
538
+ })).pipe(Stream.changesWith((a, b) => toString(a) === toString(b)));
539
+ };
540
+ //#endregion
541
+ export { Autofocus, ClipboardMessage, ClipboardReadMessage, DRAG_THRESHOLD, DragCancelled, DragDropped, DragPlace, DragStarted, DragZone, DraggedOver, EditAsked, EditableText, FocusScope, Focused, FollowTabStop, HideOutside, Input, InputMask, KeepInView, Measure, Move, MoveEnded, MoveStarted, Moved, PointerDrag, ScriptMessage, ScrollLock, ShareData, ShareMessage, TargetHovered, TargetPressed, Targets, TextCancelled, TextCommitted, TextEdited, applyMask, boxOf, copyText, keepScroll, loadScript, measured, pointedLinks, readText, share, tabbableWithin, targetOf, textOf, zoneOf };
515
542
 
516
543
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["failMessage","failMessage"],"sources":["../../src/dom/autofocus.ts","../../src/dom/clipboard.ts","../../src/dom/input-mask.ts","../../src/dom/keep-in-view.ts","../../src/dom/script-loader.ts","../../src/dom/share.ts","../../src/dom/measure.ts","../../src/dom/scroll.ts"],"sourcesContent":["/**\n * Autofocus as a Mount: focuses the element on insert, then emits `Focused`.\n * The message means focus was requested — a non-focusable element or a\n * hidden tab may decline, and the browser does not report that. Plain\n * `focus()`, no scroll options: scroll behavior stays the application's\n * choice.\n */\nimport { Effect, Schema } from 'effect'\nimport * as Mount from 'foldkit/mount'\n\nexport const Focused = Schema.TaggedStruct('Focused', {})\nexport type Focused = typeof Focused.Type\n\nexport const Autofocus = Mount.define('Autofocus', {\n messages: [Focused],\n execute: ({ element }) =>\n Effect.sync(() => {\n const focusable = element as unknown as { readonly focus?: unknown }\n if (typeof focusable.focus === 'function') {\n ;(focusable.focus as () => void).call(element)\n }\n return Focused.make({})\n }),\n})\n","/**\n * The clipboard as Commands: run in `update` beside any bundle. A copy yields\n * `Copied` or `CopyFailed`, a read `Read` or `ReadFailed`. No Model involved:\n * the clipboard is not application state.\n */\nimport { Effect, Schema } from 'effect'\nimport type { Command } from 'foldkit/command'\nimport { defineMessageUnion } from 'foldkit/message'\n\nexport const ClipboardMessage = defineMessageUnion({\n Copied: {},\n CopyFailed: { message: Schema.String },\n})\nexport type ClipboardMessage = typeof ClipboardMessage.Type\n\nexport const ClipboardReadMessage = defineMessageUnion({\n Read: { text: Schema.String },\n ReadFailed: { message: Schema.String },\n})\nexport type ClipboardReadMessage = typeof ClipboardReadMessage.Type\n\nconst failMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error)\n\n/**\n * Copies text to the clipboard. Without a clipboard API (SSR, insecure\n * context, denied permission) the command yields `CopyFailed` instead of\n * throwing, so `update` handles both outcomes as Messages.\n */\nexport const copyText = (text: string): Command<ClipboardMessage, never, never> => ({\n name: 'Clipboard.copy',\n args: { text },\n effect:\n typeof navigator !== 'undefined' && typeof navigator.clipboard?.writeText === 'function'\n ? Effect.matchEffect(\n Effect.tryPromise({\n try: () => navigator.clipboard.writeText(text),\n catch: failMessage,\n }),\n {\n onFailure: message => Effect.succeed(ClipboardMessage.CopyFailed({ message })),\n onSuccess: () => Effect.succeed(ClipboardMessage.Copied()),\n },\n )\n : Effect.succeed(ClipboardMessage.CopyFailed({ message: 'clipboard is unavailable' })),\n})\n\n/**\n * Reads the clipboard's text. The browser may ask the user first; a refusal,\n * an insecure context or no clipboard API yields `ReadFailed`.\n */\nexport const readText = (): Command<ClipboardReadMessage, never, never> => ({\n name: 'Clipboard.read',\n effect:\n typeof navigator !== 'undefined' && typeof navigator.clipboard?.readText === 'function'\n ? Effect.matchEffect(\n Effect.tryPromise({ try: () => navigator.clipboard.readText(), catch: failMessage }),\n {\n onFailure: message => Effect.succeed(ClipboardReadMessage.ReadFailed({ message })),\n onSuccess: text => Effect.succeed(ClipboardReadMessage.Read({ text })),\n },\n )\n : Effect.succeed(ClipboardReadMessage.ReadFailed({ message: 'clipboard is unavailable' })),\n})\n","/**\n * An input mask as a Mount plus a pure mask function. The pattern language\n * is three placeholders — `#` digit, `A` letter, `*` either, all ASCII —\n * with every other character literal. Literals appear only once a later placeholder\n * consumes input, so partial values never dangle a separator. The Mount\n * rewrites the field, restores the caret approximately, and emits `Input`\n * with both the masked and raw values; the parent owns the state, like any\n * controlled input.\n */\nimport { Effect, Queue, Schema, Stream } from 'effect'\nimport * as Mount from 'foldkit/mount'\n\nexport const Input = Schema.TaggedStruct('Input', {\n value: Schema.String,\n raw: Schema.String,\n})\nexport type Input = typeof Input.Type\n\nconst isDigit = (char: string): boolean => char >= '0' && char <= '9'\nconst isLetter = (char: string): boolean =>\n (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z')\n\nconst matches = (placeholder: string, char: string): boolean =>\n placeholder === '#'\n ? isDigit(char)\n : placeholder === 'A'\n ? isLetter(char)\n : isDigit(char) || isLetter(char)\n\nconst isPlaceholder = (char: string): boolean => char === '#' || char === 'A' || char === '*'\n\n/** Whether any placeholder at or after `from` consumes any input at or after `at`. */\nconst fillable = (pattern: string, from: number, value: string, at: number): boolean => {\n for (let i = from; i < pattern.length; i++) {\n const placeholder = pattern[i]!\n if (!isPlaceholder(placeholder)) continue\n for (let j = at; j < value.length; j++) {\n if (matches(placeholder, value[j]!)) return true\n }\n }\n return false\n}\n\nexport const applyMask = (\n value: string,\n pattern: string,\n): { readonly masked: string; readonly raw: string } => {\n let masked = ''\n let raw = ''\n let at = 0\n for (let i = 0; i < pattern.length; i++) {\n const slot = pattern[i]!\n if (isPlaceholder(slot)) {\n while (at < value.length && !matches(slot, value[at]!)) at++\n if (at >= value.length) break\n masked += value[at]!\n raw += value[at]!\n at++\n } else if (fillable(pattern, i + 1, value, at)) {\n masked += slot\n } else {\n break\n }\n }\n return { masked, raw }\n}\n\ninterface MaskableField {\n value: string\n selectionStart: number | null\n addEventListener(type: string, listener: () => void): void\n removeEventListener(type: string, listener: () => void): void\n setSelectionRange?(start: number, end: number): void\n}\n\nconst asField = (element: Element): MaskableField | null => {\n const field = element as unknown as Partial<MaskableField>\n return typeof field.value === 'string' && typeof field.addEventListener === 'function'\n ? (field as MaskableField)\n : null\n}\n\nexport const InputMask = Mount.defineStream('InputMask', {\n messages: [Input],\n args: { pattern: Schema.String },\n execute: ({ element, pattern }) =>\n Stream.callback<typeof Input.Type>(queue =>\n Effect.gen(function* () {\n const field = asField(element)\n if (field === null) return\n const onInput = () => {\n const { masked, raw } = applyMask(field.value, pattern)\n if (masked !== field.value) {\n const caret = field.selectionStart ?? masked.length\n field.value = masked\n const at = Math.min(caret, masked.length)\n try {\n field.setSelectionRange?.(at, at)\n } catch {\n // Select-all style inputs reject ranges; the value still stands.\n }\n }\n Queue.offerUnsafe(queue, Input.make({ value: masked, raw }))\n }\n yield* Effect.acquireRelease(\n Effect.sync(() => {\n field.addEventListener('input', onInput)\n return field\n }),\n current => Effect.sync(() => current.removeEventListener('input', onInput)),\n )\n }),\n ),\n})\n","/**\n * Keeps what is marked in view as a Mount: whenever an element in the mounted\n * one's subtree newly matches `selector`, such as the row just selected in a\n * list, it is scrolled into view the least amount that shows it (`nearest`).\n * The element keeps its identity and its focus: nothing is redrawn to move it.\n *\n * It watches with a `MutationObserver` for as long as it is mounted, which is as\n * long as the list or canvas that can change what is marked.\n */\nimport { Effect, Schema, Stream } from 'effect'\nimport * as Mount from 'foldkit/mount'\n\nexport const KeepInView = Mount.defineStream('KeepInView', {\n messages: [Schema.Never],\n args: {\n /** What is marked, as a selector within the element: `[aria-selected=\"true\"]`. */\n selector: Schema.String,\n },\n execute: ({ element, selector }) =>\n Stream.callback<never>(() =>\n Effect.acquireRelease(\n Effect.sync(() => {\n let marked = element.querySelector(selector)\n const observer = new MutationObserver(() => {\n const now = element.querySelector(selector)\n // Only a change of what is marked scrolls: the author's own scrolling stays.\n // A DOM with no layout (jsdom, in a test) has no scrollIntoView and nothing to scroll.\n if (now !== null && now !== marked && typeof now.scrollIntoView === 'function')\n now.scrollIntoView({ block: 'nearest', inline: 'nearest' })\n marked = now\n })\n observer.observe(element, { subtree: true, childList: true, attributes: true })\n return observer\n }),\n observer => Effect.sync(() => observer.disconnect()),\n ),\n ),\n})\n","/**\n * Script loading as a Command: appends a `src` script to the head unless one\n * is already there. Idempotent by URL — concurrent placements collapse onto\n * the first tag instead of fetching twice. Yields `Loaded` on success and\n * `LoadFailed` otherwise (network error, no document), so `update` handles\n * both outcomes as Messages.\n */\nimport { Effect, Schema } from 'effect'\nimport type { Command } from 'foldkit/command'\nimport { defineMessageUnion } from 'foldkit/message'\n\nexport const ScriptMessage = defineMessageUnion({\n Loaded: {},\n LoadFailed: { message: Schema.String },\n})\nexport type ScriptMessage = typeof ScriptMessage.Type\n\nconst failMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error)\n\n// Tags still fetching, by URL: concurrent loads share one tag and its fate.\nconst inflight = new Map<string, Promise<void>>()\n\n/** Loads a script by URL, once per URL. */\nexport const loadScript = (src: string): Command<ScriptMessage, never, never> => ({\n name: 'Script.load',\n args: { src },\n effect: Effect.matchEffect(\n Effect.tryPromise({\n try: () => {\n if (typeof document === 'undefined') {\n return Promise.reject(new Error('script loading is unavailable'))\n }\n // Concurrent loads share one tag and its fate, instead of racing\n // past the presence check and fetching twice: the in-flight entry\n // is checked before presence, in the same synchronous block that\n // appends, so a second load cannot slip between them.\n const running = inflight.get(src)\n if (running !== undefined) return running\n // getAttribute, not .src: the property resolves to an absolute URL\n // and would never equal the given string.\n const present = Array.from(document.getElementsByTagName('script')).some(\n element => element.getAttribute('src') === src,\n )\n if (present) return Promise.resolve()\n const completion = new Promise<void>((resolve, reject) => {\n const element = document.createElement('script')\n element.src = src\n element.async = true\n element.onload = () => resolve()\n element.onerror = () => {\n // A dead tag must not satisfy later presence checks.\n element.remove()\n reject(new Error(`failed to load script: ${src}`))\n }\n document.head.appendChild(element)\n })\n const tracked = completion.then(\n () => {\n inflight.delete(src)\n },\n (error: unknown) => {\n inflight.delete(src)\n throw error\n },\n )\n inflight.set(src, tracked)\n return tracked\n },\n catch: (error: unknown) => error,\n }),\n {\n onFailure: error => Effect.succeed(ScriptMessage.LoadFailed({ message: failMessage(error) })),\n onSuccess: () => Effect.succeed(ScriptMessage.Loaded()),\n },\n ),\n})\n","/**\n * Web Share as a Command: runs in `update` beside any bundle, yields\n * `Shared` on success. Dismissal is its own outcome, not a failure — the\n * application tells a cancelled sheet apart from a broken one. Without a\n * share API (desktop, insecure context) it yields `ShareFailed` instead of\n * throwing, so `update` handles every outcome as a Message.\n */\nimport { Effect, Schema } from 'effect'\nimport type { Command } from 'foldkit/command'\nimport { defineMessageUnion } from 'foldkit/message'\n\nexport const ShareData = Schema.Struct({\n title: Schema.optional(Schema.String),\n text: Schema.optional(Schema.String),\n url: Schema.optional(Schema.String),\n})\nexport type ShareData = typeof ShareData.Type\n\nexport const ShareMessage = defineMessageUnion({\n Shared: {},\n Dismissed: {},\n ShareFailed: { message: Schema.String },\n})\nexport type ShareMessage = typeof ShareMessage.Type\n\nconst failMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error)\n\nconst isDismissal = (error: unknown): boolean =>\n typeof (error as { readonly name?: unknown } | null)?.name === 'string' &&\n (error as { readonly name: string }).name === 'AbortError'\n\n/** Shares data through the platform sheet. */\nexport const share = (data: ShareData): Command<ShareMessage, never, never> => ({\n name: 'Share.share',\n args: { data },\n effect:\n typeof navigator !== 'undefined' && typeof navigator.share === 'function'\n ? Effect.matchEffect(\n Effect.tryPromise({\n // Omit absent fields: the platform type rejects explicit\n // undefined under exactOptionalPropertyTypes.\n try: () =>\n navigator.share({\n ...(data.title !== undefined ? { title: data.title } : {}),\n ...(data.text !== undefined ? { text: data.text } : {}),\n ...(data.url !== undefined ? { url: data.url } : {}),\n }),\n catch: (error: unknown) => error,\n }),\n {\n onFailure: error =>\n Effect.succeed(\n isDismissal(error)\n ? ShareMessage.Dismissed()\n : ShareMessage.ShareFailed({ message: failMessage(error) }),\n ),\n onSuccess: () => Effect.succeed(ShareMessage.Shared()),\n },\n )\n : Effect.succeed(ShareMessage.ShareFailed({ message: 'share is unavailable' })),\n})\n","/**\n * Measures marked elements as a Mount, for a view to draw something over them,\n * such as an editor's selection outline, with no Message and no Model: where\n * an element is, is presentation, known to the DOM and to no transition.\n *\n * For each named target, the first element in the mounted one's subtree that\n * matches its selector is measured relative to the mounted element's scroll\n * box, which is what an absolutely placed child of it is laid out in. The\n * mounted element gets `--fk-<name>-x`, `-y`, `-w` and `-h` in pixels, and\n * `--fk-<name>-display`: `block` while a target is found, `none` while none is.\n *\n * It measures again when the subtree changes (a selection moves), in the\n * frame the change is drawn in; and, at most once a frame, when the mounted\n * element scrolls, the window resizes, the mounted element or a measured one\n * changes size, an image or a font inside loads, and on every frame of a\n * transition or an animation inside. What moves a target by any other way,\n * such as a stylesheet added that shifts it without resizing it, is seen at\n * the next of these.\n */\nimport { Effect, Schema, Stream } from 'effect'\nimport * as Mount from 'foldkit/mount'\n\n/** The custom properties `Measure` writes for a target named `name`. */\nexport const measured = (name: string) =>\n ({\n x: `--fk-${name}-x`,\n y: `--fk-${name}-y`,\n w: `--fk-${name}-w`,\n h: `--fk-${name}-h`,\n display: `--fk-${name}-display`,\n }) as const\n\nexport const Measure = Mount.defineStream('Measure', {\n messages: [Schema.Never],\n args: {\n /** Each target by name, as a selector within the element: `{ selected: '[aria-selected=\"true\"]' }`. */\n targets: Schema.Record(Schema.String, Schema.String),\n },\n execute: ({ element, targets }) =>\n Stream.callback<never>(() =>\n Effect.acquireRelease(\n Effect.sync(() => {\n const container = element as HTMLElement\n const names = Object.keys(targets)\n let watched: ReadonlyArray<Element> = []\n let frame: number | undefined\n // Whether a transition or an animation may be moving something, until one frame finds none.\n let animating = false\n\n const measure = () => {\n if (frame !== undefined) cancelAnimationFrame(frame)\n frame = undefined\n const box = container.getBoundingClientRect()\n const found: Array<Element> = []\n for (const name of names) {\n const property = measured(name)\n const target = container.querySelector(targets[name]!)\n if (target === null) {\n container.style.setProperty(property.display, 'none')\n continue\n }\n found.push(target)\n const rect = target.getBoundingClientRect()\n // Relative to the scroll box: where the content is, not where the viewport shows it.\n const x = rect.left - box.left - container.clientLeft + container.scrollLeft\n const y = rect.top - box.top - container.clientTop + container.scrollTop\n container.style.setProperty(property.x, `${x}px`)\n container.style.setProperty(property.y, `${y}px`)\n container.style.setProperty(property.w, `${rect.width}px`)\n container.style.setProperty(property.h, `${rect.height}px`)\n container.style.setProperty(property.display, 'block')\n }\n // A measured element that changes size, as an image loading does, is measured again.\n if (found.length !== watched.length || found.some((each, at) => each !== watched[at])) {\n for (const each of watched) sizes.unobserve(each)\n for (const each of found) sizes.observe(each)\n watched = found\n }\n if (animating) {\n // Asked each frame rather than counted: an element removed mid-transition ends none.\n animating = container\n .getAnimations({ subtree: true })\n .some(animation => animation.playState === 'running')\n if (animating) soon()\n }\n }\n const soon = () => {\n if (frame === undefined) frame = requestAnimationFrame(measure)\n }\n const moving = () => {\n animating = true\n soon()\n }\n\n // A change is measured as its records arrive, before the frame it is drawn in is\n // painted, so a box never shows one frame on the element it has left.\n const changes = new MutationObserver(measure)\n // Made, and the fonts listened to, before anything observes: where one is\n // missing (jsdom has neither a ResizeObserver nor `document.fonts`), the Mount\n // fails with nothing attached to call `measure`.\n const sizes = new ResizeObserver(soon)\n document.fonts.addEventListener('loadingdone', soon)\n // Its own properties change the container's style too, but writing the same\n // values again records nothing, so a measure that changed nothing rests.\n changes.observe(container, { subtree: true, childList: true, attributes: true })\n sizes.observe(container)\n container.addEventListener('scroll', soon, { passive: true })\n window.addEventListener('resize', soon)\n // `load` does not bubble, so it is caught on the way down.\n container.addEventListener('load', soon, { capture: true })\n container.addEventListener('transitionrun', moving)\n container.addEventListener('animationstart', moving)\n measure()\n return () => {\n if (frame !== undefined) cancelAnimationFrame(frame)\n changes.disconnect()\n sizes.disconnect()\n container.removeEventListener('scroll', soon)\n window.removeEventListener('resize', soon)\n container.removeEventListener('load', soon, { capture: true })\n document.fonts.removeEventListener('loadingdone', soon)\n container.removeEventListener('transitionrun', moving)\n container.removeEventListener('animationstart', moving)\n }\n }),\n stop => Effect.sync(stop),\n ),\n ),\n})\n","/**\n * Where the window is scrolled, across an application's own navigations, as\n * a stream. Left to itself, a browser keeps the scroll of the entry it\n * leaves when a link pushes a new one, and on Back restores the old offset\n * before the application has drawn the entry it returns to, so the offset is\n * clamped to a page still loading. Here a pushed entry starts at the top,\n * and Back, Forward or a reload return where that entry was, once the page\n * is tall enough to hold it.\n *\n * Three rules, each found the slow way:\n *\n * 1. The offset is taken when the reader acts. The next screen is drawn\n * before a Navigate Command pushes the address, so by the time the URL\n * changes the window is already clamped to the new, shorter page. The\n * scroll is recorded at the reader's click or key (capture phase), and at\n * the start of Back and Forward, which begin in the browser before\n * anything is drawn.\n * 2. A restore holds its place while the next screen settles. A restore made\n * when the entry changes is undone by the loading state drawn right after\n * it, so the target is held on each frame for a moment, until the reader\n * scrolls, touches or types, or another navigation starts.\n * 3. Entries are keyed by the Navigation API's entry key, which a reload and\n * a full navigation keep; offsets rest in `sessionStorage`, so Back into\n * another document restores too. Where the browser has no Navigation API\n * the stream attaches nothing and leaves the browser's own behaviour\n * alone.\n *\n * Lift with `Subscription.persistent`; the stream sends no Messages. Only\n * the window scrolls: a nested container is the route graph's to know, when\n * `Site.transition` arrives.\n */\nimport { Effect, Option, Stream } from 'effect'\n\n/** The part of the Navigation API used here: TypeScript's DOM library does not declare it yet. */\ninterface Navigation extends EventTarget {\n readonly currentEntry: { readonly key: string } | null\n}\ndeclare global {\n interface Window {\n readonly navigation?: Navigation\n }\n}\n\nexport interface KeepScrollOptions {\n /** The `sessionStorage` key holding entry offsets. Default `'foldkit:scroll'`. */\n readonly storageKey?: string | undefined\n /** Entries remembered at most: the oldest are forgotten first. Default 50. */\n readonly kept?: number | undefined\n /**\n * How long a restore holds its place while the next screen settles, in\n * milliseconds. Default 2000.\n */\n readonly patience?: number | undefined\n}\n\nconst navigationTypeOf = (event: Event): Option.Option<unknown> =>\n 'navigationType' in event ? Option.some(event.navigationType) : Option.none()\n\nconst readSaved = (storageKey: string): Map<string, number> => {\n try {\n const stored: unknown = JSON.parse(sessionStorage.getItem(storageKey) ?? '[]')\n return new Map(\n Array.isArray(stored)\n ? stored.filter(\n (pair): pair is [string, number] =>\n Array.isArray(pair) && typeof pair[0] === 'string' && typeof pair[1] === 'number',\n )\n : [],\n )\n } catch {\n // Storage blocked, or something else wrote the key: nothing is remembered.\n return new Map()\n }\n}\n\n/** Starts keeping the scroll; the release undoes everything it installed. */\nconst attach = (storageKey: string, kept: number, patience: number): (() => void) => {\n const navigation = window.navigation\n if (navigation === undefined) return () => {}\n const restoration = window.history.scrollRestoration\n window.history.scrollRestoration = 'manual'\n const saved = readSaved(storageKey)\n const detaches: Array<() => void> = []\n const on = (target: EventTarget, type: string, listener: EventListener, capture?: boolean) => {\n target.addEventListener(type, listener, capture)\n detaches.push(() => target.removeEventListener(type, listener, capture))\n }\n const keyOf = () =>\n Option.fromNullOr(navigation.currentEntry).pipe(Option.map(entry => entry.key))\n /** Where the current entry was left, if it has been. */\n const savedHere = () => Option.flatMap(keyOf(), key => Option.fromUndefinedOr(saved.get(key)))\n const remember = () => {\n const key = keyOf()\n if (Option.isNone(key)) return\n // Moved to the end, so it is the last to be forgotten.\n saved.delete(key.value)\n saved.set(key.value, window.scrollY)\n for (const old of saved.keys()) {\n if (saved.size <= kept) break\n saved.delete(old)\n }\n }\n\n let settling = new AbortController()\n /**\n * Holds the window at `top` while the next screen settles, whenever the page\n * can hold it, until the reader scrolls, touches or types, or another\n * navigation starts.\n */\n const settle = (top: number) => {\n settling.abort()\n settling = new AbortController()\n const { signal } = settling\n for (const input of ['wheel', 'touchstart', 'keydown', 'pointerdown'])\n window.addEventListener(input, () => settling.abort(), { passive: true, signal })\n const until = performance.now() + patience\n const step = () => {\n if (signal.aborted) return\n const room = document.documentElement.scrollHeight - window.innerHeight\n if (room >= top && Math.round(window.scrollY) !== top)\n window.scrollTo({ top, behavior: 'instant' })\n if (performance.now() < until) requestAnimationFrame(step)\n else settling.abort()\n }\n step()\n }\n\n // Remembered where the reader acts, before the application does: by the time\n // it pushes an address it has drawn the next screen, and the window is\n // already clamped to it. Back and Forward start in the browser, before\n // anything is drawn, so they are remembered as they begin.\n const acted = () => remember()\n for (const input of ['click', 'keydown']) on(window, input, acted, true)\n const traversing = (event: Event) => {\n if (Option.contains(navigationTypeOf(event), 'traverse')) remember()\n }\n on(navigation, 'navigate', traversing)\n const changed = (event: Event) => {\n const type = navigationTypeOf(event)\n if (Option.contains(type, 'push')) settle(0)\n else if (Option.contains(type, 'traverse')) settle(Option.getOrElse(savedHere(), () => 0))\n // A replace is the same entry, narrowed or selected in place: it stays where it is.\n }\n on(navigation, 'currententrychange', changed)\n const hidden = () => {\n remember()\n try {\n sessionStorage.setItem(storageKey, JSON.stringify([...saved]))\n } catch {\n // Storage blocked: the next document starts at the top.\n }\n }\n on(window, 'pagehide', hidden)\n // A reload, or Back into this document from another: where this entry was.\n const here = savedHere()\n if (Option.isSome(here)) settle(here.value)\n return () => {\n settling.abort()\n for (const detach of detaches) detach()\n window.history.scrollRestoration = restoration\n }\n}\n\n/**\n * Keeps the window's scroll across same-document navigations: a pushed entry\n * starts at the top, and Back, Forward or a reload return where that entry\n * was. Without a window the stream is empty instead of throwing. Lift with\n * `Subscription.persistent`; the stream sends no Messages.\n */\nexport const keepScroll = (options: KeepScrollOptions = {}): Stream.Stream<never> => {\n if (typeof window === 'undefined') return Stream.empty\n const storageKey = options.storageKey ?? 'foldkit:scroll'\n const kept = options.kept ?? 50\n const patience = options.patience ?? 2000\n return Stream.callback<never>(() =>\n Effect.acquireRelease(\n Effect.sync(() => attach(storageKey, kept, patience)),\n detach => Effect.sync(detach),\n ),\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["failMessage","failMessage","urlToString"],"sources":["../../src/dom/autofocus.ts","../../src/dom/clipboard.ts","../../src/dom/input-mask.ts","../../src/dom/keep-in-view.ts","../../src/dom/script-loader.ts","../../src/dom/share.ts","../../src/dom/measure.ts","../../src/dom/scroll.ts","../../src/dom/pointed-links.ts"],"sourcesContent":["/**\n * Autofocus as a Mount: focuses the element on insert, then emits `Focused`.\n * The message means focus was requested — a non-focusable element or a\n * hidden tab may decline, and the browser does not report that. Plain\n * `focus()`, no scroll options: scroll behavior stays the application's\n * choice.\n */\nimport { Effect, Schema } from 'effect'\nimport * as Mount from 'foldkit/mount'\n\nexport const Focused = Schema.TaggedStruct('Focused', {})\nexport type Focused = typeof Focused.Type\n\nexport const Autofocus = Mount.define('Autofocus', {\n messages: [Focused],\n execute: ({ element }) =>\n Effect.sync(() => {\n const focusable = element as unknown as { readonly focus?: unknown }\n if (typeof focusable.focus === 'function') {\n ;(focusable.focus as () => void).call(element)\n }\n return Focused.make({})\n }),\n})\n","/**\n * The clipboard as Commands: run in `update` beside any bundle. A copy yields\n * `Copied` or `CopyFailed`, a read `Read` or `ReadFailed`. No Model involved:\n * the clipboard is not application state.\n */\nimport { Effect, Schema } from 'effect'\nimport type { Command } from 'foldkit/command'\nimport { defineMessageUnion } from 'foldkit/message'\n\nexport const ClipboardMessage = defineMessageUnion({\n Copied: {},\n CopyFailed: { message: Schema.String },\n})\nexport type ClipboardMessage = typeof ClipboardMessage.Type\n\nexport const ClipboardReadMessage = defineMessageUnion({\n Read: { text: Schema.String },\n ReadFailed: { message: Schema.String },\n})\nexport type ClipboardReadMessage = typeof ClipboardReadMessage.Type\n\nconst failMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error)\n\n/**\n * Copies text to the clipboard. Without a clipboard API (SSR, insecure\n * context, denied permission) the command yields `CopyFailed` instead of\n * throwing, so `update` handles both outcomes as Messages.\n */\nexport const copyText = (text: string): Command<ClipboardMessage, never, never> => ({\n name: 'Clipboard.copy',\n args: { text },\n effect:\n typeof navigator !== 'undefined' && typeof navigator.clipboard?.writeText === 'function'\n ? Effect.matchEffect(\n Effect.tryPromise({\n try: () => navigator.clipboard.writeText(text),\n catch: failMessage,\n }),\n {\n onFailure: message => Effect.succeed(ClipboardMessage.CopyFailed({ message })),\n onSuccess: () => Effect.succeed(ClipboardMessage.Copied()),\n },\n )\n : Effect.succeed(ClipboardMessage.CopyFailed({ message: 'clipboard is unavailable' })),\n})\n\n/**\n * Reads the clipboard's text. The browser may ask the user first; a refusal,\n * an insecure context or no clipboard API yields `ReadFailed`.\n */\nexport const readText = (): Command<ClipboardReadMessage, never, never> => ({\n name: 'Clipboard.read',\n effect:\n typeof navigator !== 'undefined' && typeof navigator.clipboard?.readText === 'function'\n ? Effect.matchEffect(\n Effect.tryPromise({ try: () => navigator.clipboard.readText(), catch: failMessage }),\n {\n onFailure: message => Effect.succeed(ClipboardReadMessage.ReadFailed({ message })),\n onSuccess: text => Effect.succeed(ClipboardReadMessage.Read({ text })),\n },\n )\n : Effect.succeed(ClipboardReadMessage.ReadFailed({ message: 'clipboard is unavailable' })),\n})\n","/**\n * An input mask as a Mount plus a pure mask function. The pattern language\n * is three placeholders — `#` digit, `A` letter, `*` either, all ASCII —\n * with every other character literal. Literals appear only once a later placeholder\n * consumes input, so partial values never dangle a separator. The Mount\n * rewrites the field, restores the caret approximately, and emits `Input`\n * with both the masked and raw values; the parent owns the state, like any\n * controlled input.\n */\nimport { Effect, Queue, Schema, Stream } from 'effect'\nimport * as Mount from 'foldkit/mount'\n\nexport const Input = Schema.TaggedStruct('Input', {\n value: Schema.String,\n raw: Schema.String,\n})\nexport type Input = typeof Input.Type\n\nconst isDigit = (char: string): boolean => char >= '0' && char <= '9'\nconst isLetter = (char: string): boolean =>\n (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z')\n\nconst matches = (placeholder: string, char: string): boolean =>\n placeholder === '#'\n ? isDigit(char)\n : placeholder === 'A'\n ? isLetter(char)\n : isDigit(char) || isLetter(char)\n\nconst isPlaceholder = (char: string): boolean => char === '#' || char === 'A' || char === '*'\n\n/** Whether any placeholder at or after `from` consumes any input at or after `at`. */\nconst fillable = (pattern: string, from: number, value: string, at: number): boolean => {\n for (let i = from; i < pattern.length; i++) {\n const placeholder = pattern[i]!\n if (!isPlaceholder(placeholder)) continue\n for (let j = at; j < value.length; j++) {\n if (matches(placeholder, value[j]!)) return true\n }\n }\n return false\n}\n\nexport const applyMask = (\n value: string,\n pattern: string,\n): { readonly masked: string; readonly raw: string } => {\n let masked = ''\n let raw = ''\n let at = 0\n for (let i = 0; i < pattern.length; i++) {\n const slot = pattern[i]!\n if (isPlaceholder(slot)) {\n while (at < value.length && !matches(slot, value[at]!)) at++\n if (at >= value.length) break\n masked += value[at]!\n raw += value[at]!\n at++\n } else if (fillable(pattern, i + 1, value, at)) {\n masked += slot\n } else {\n break\n }\n }\n return { masked, raw }\n}\n\ninterface MaskableField {\n value: string\n selectionStart: number | null\n addEventListener(type: string, listener: () => void): void\n removeEventListener(type: string, listener: () => void): void\n setSelectionRange?(start: number, end: number): void\n}\n\nconst asField = (element: Element): MaskableField | null => {\n const field = element as unknown as Partial<MaskableField>\n return typeof field.value === 'string' && typeof field.addEventListener === 'function'\n ? (field as MaskableField)\n : null\n}\n\nexport const InputMask = Mount.defineStream('InputMask', {\n messages: [Input],\n args: { pattern: Schema.String },\n execute: ({ element, pattern }) =>\n Stream.callback<typeof Input.Type>(queue =>\n Effect.gen(function* () {\n const field = asField(element)\n if (field === null) return\n const onInput = () => {\n const { masked, raw } = applyMask(field.value, pattern)\n if (masked !== field.value) {\n const caret = field.selectionStart ?? masked.length\n field.value = masked\n const at = Math.min(caret, masked.length)\n try {\n field.setSelectionRange?.(at, at)\n } catch {\n // Select-all style inputs reject ranges; the value still stands.\n }\n }\n Queue.offerUnsafe(queue, Input.make({ value: masked, raw }))\n }\n yield* Effect.acquireRelease(\n Effect.sync(() => {\n field.addEventListener('input', onInput)\n return field\n }),\n current => Effect.sync(() => current.removeEventListener('input', onInput)),\n )\n }),\n ),\n})\n","/**\n * Keeps what is marked in view as a Mount: whenever an element in the mounted\n * one's subtree newly matches `selector`, such as the row just selected in a\n * list, it is scrolled into view the least amount that shows it (`nearest`).\n * The element keeps its identity and its focus: nothing is redrawn to move it.\n *\n * It watches with a `MutationObserver` for as long as it is mounted, which is as\n * long as the list or canvas that can change what is marked.\n */\nimport { Effect, Schema, Stream } from 'effect'\nimport * as Mount from 'foldkit/mount'\n\nexport const KeepInView = Mount.defineStream('KeepInView', {\n messages: [Schema.Never],\n args: {\n /** What is marked, as a selector within the element: `[aria-selected=\"true\"]`. */\n selector: Schema.String,\n },\n execute: ({ element, selector }) =>\n Stream.callback<never>(() =>\n Effect.acquireRelease(\n Effect.sync(() => {\n let marked = element.querySelector(selector)\n const observer = new MutationObserver(() => {\n const now = element.querySelector(selector)\n // Only a change of what is marked scrolls: the author's own scrolling stays.\n // A DOM with no layout (jsdom, in a test) has no scrollIntoView and nothing to scroll.\n if (now !== null && now !== marked && typeof now.scrollIntoView === 'function')\n now.scrollIntoView({ block: 'nearest', inline: 'nearest' })\n marked = now\n })\n observer.observe(element, { subtree: true, childList: true, attributes: true })\n return observer\n }),\n observer => Effect.sync(() => observer.disconnect()),\n ),\n ),\n})\n","/**\n * Script loading as a Command: appends a `src` script to the head unless one\n * is already there. Idempotent by URL — concurrent placements collapse onto\n * the first tag instead of fetching twice. Yields `Loaded` on success and\n * `LoadFailed` otherwise (network error, no document), so `update` handles\n * both outcomes as Messages.\n */\nimport { Effect, Schema } from 'effect'\nimport type { Command } from 'foldkit/command'\nimport { defineMessageUnion } from 'foldkit/message'\n\nexport const ScriptMessage = defineMessageUnion({\n Loaded: {},\n LoadFailed: { message: Schema.String },\n})\nexport type ScriptMessage = typeof ScriptMessage.Type\n\nconst failMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error)\n\n// Tags still fetching, by URL: concurrent loads share one tag and its fate.\nconst inflight = new Map<string, Promise<void>>()\n\n/** Loads a script by URL, once per URL. */\nexport const loadScript = (src: string): Command<ScriptMessage, never, never> => ({\n name: 'Script.load',\n args: { src },\n effect: Effect.matchEffect(\n Effect.tryPromise({\n try: () => {\n if (typeof document === 'undefined') {\n return Promise.reject(new Error('script loading is unavailable'))\n }\n // Concurrent loads share one tag and its fate, instead of racing\n // past the presence check and fetching twice: the in-flight entry\n // is checked before presence, in the same synchronous block that\n // appends, so a second load cannot slip between them.\n const running = inflight.get(src)\n if (running !== undefined) return running\n // getAttribute, not .src: the property resolves to an absolute URL\n // and would never equal the given string.\n const present = Array.from(document.getElementsByTagName('script')).some(\n element => element.getAttribute('src') === src,\n )\n if (present) return Promise.resolve()\n const completion = new Promise<void>((resolve, reject) => {\n const element = document.createElement('script')\n element.src = src\n element.async = true\n element.onload = () => resolve()\n element.onerror = () => {\n // A dead tag must not satisfy later presence checks.\n element.remove()\n reject(new Error(`failed to load script: ${src}`))\n }\n document.head.appendChild(element)\n })\n const tracked = completion.then(\n () => {\n inflight.delete(src)\n },\n (error: unknown) => {\n inflight.delete(src)\n throw error\n },\n )\n inflight.set(src, tracked)\n return tracked\n },\n catch: (error: unknown) => error,\n }),\n {\n onFailure: error => Effect.succeed(ScriptMessage.LoadFailed({ message: failMessage(error) })),\n onSuccess: () => Effect.succeed(ScriptMessage.Loaded()),\n },\n ),\n})\n","/**\n * Web Share as a Command: runs in `update` beside any bundle, yields\n * `Shared` on success. Dismissal is its own outcome, not a failure — the\n * application tells a cancelled sheet apart from a broken one. Without a\n * share API (desktop, insecure context) it yields `ShareFailed` instead of\n * throwing, so `update` handles every outcome as a Message.\n */\nimport { Effect, Schema } from 'effect'\nimport type { Command } from 'foldkit/command'\nimport { defineMessageUnion } from 'foldkit/message'\n\nexport const ShareData = Schema.Struct({\n title: Schema.optional(Schema.String),\n text: Schema.optional(Schema.String),\n url: Schema.optional(Schema.String),\n})\nexport type ShareData = typeof ShareData.Type\n\nexport const ShareMessage = defineMessageUnion({\n Shared: {},\n Dismissed: {},\n ShareFailed: { message: Schema.String },\n})\nexport type ShareMessage = typeof ShareMessage.Type\n\nconst failMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error)\n\nconst isDismissal = (error: unknown): boolean =>\n typeof (error as { readonly name?: unknown } | null)?.name === 'string' &&\n (error as { readonly name: string }).name === 'AbortError'\n\n/** Shares data through the platform sheet. */\nexport const share = (data: ShareData): Command<ShareMessage, never, never> => ({\n name: 'Share.share',\n args: { data },\n effect:\n typeof navigator !== 'undefined' && typeof navigator.share === 'function'\n ? Effect.matchEffect(\n Effect.tryPromise({\n // Omit absent fields: the platform type rejects explicit\n // undefined under exactOptionalPropertyTypes.\n try: () =>\n navigator.share({\n ...(data.title !== undefined ? { title: data.title } : {}),\n ...(data.text !== undefined ? { text: data.text } : {}),\n ...(data.url !== undefined ? { url: data.url } : {}),\n }),\n catch: (error: unknown) => error,\n }),\n {\n onFailure: error =>\n Effect.succeed(\n isDismissal(error)\n ? ShareMessage.Dismissed()\n : ShareMessage.ShareFailed({ message: failMessage(error) }),\n ),\n onSuccess: () => Effect.succeed(ShareMessage.Shared()),\n },\n )\n : Effect.succeed(ShareMessage.ShareFailed({ message: 'share is unavailable' })),\n})\n","/**\n * Measures marked elements as a Mount, for a view to draw something over them,\n * such as an editor's selection outline, with no Message and no Model: where\n * an element is, is presentation, known to the DOM and to no transition.\n *\n * For each named target, the first element in the mounted one's subtree that\n * matches its selector is measured relative to the mounted element's scroll\n * box, which is what an absolutely placed child of it is laid out in. The\n * mounted element gets `--fk-<name>-x`, `-y`, `-w` and `-h` in pixels, and\n * `--fk-<name>-display`: `block` while a target is found, `none` while none is.\n *\n * It measures again when the subtree changes (a selection moves), in the\n * frame the change is drawn in; and, at most once a frame, when the mounted\n * element scrolls, the window resizes, the mounted element or a measured one\n * changes size, an image or a font inside loads, and on every frame of a\n * transition or an animation inside. What moves a target by any other way,\n * such as a stylesheet added that shifts it without resizing it, is seen at\n * the next of these.\n */\nimport { Effect, Schema, Stream } from 'effect'\nimport * as Mount from 'foldkit/mount'\n\n/** The custom properties `Measure` writes for a target named `name`. */\nexport const measured = (name: string) =>\n ({\n x: `--fk-${name}-x`,\n y: `--fk-${name}-y`,\n w: `--fk-${name}-w`,\n h: `--fk-${name}-h`,\n display: `--fk-${name}-display`,\n }) as const\n\nexport const Measure = Mount.defineStream('Measure', {\n messages: [Schema.Never],\n args: {\n /** Each target by name, as a selector within the element: `{ selected: '[aria-selected=\"true\"]' }`. */\n targets: Schema.Record(Schema.String, Schema.String),\n },\n execute: ({ element, targets }) =>\n Stream.callback<never>(() =>\n Effect.acquireRelease(\n Effect.sync(() => {\n const container = element as HTMLElement\n const names = Object.keys(targets)\n let watched: ReadonlyArray<Element> = []\n let frame: number | undefined\n // Whether a transition or an animation may be moving something, until one frame finds none.\n let animating = false\n\n const measure = () => {\n if (frame !== undefined) cancelAnimationFrame(frame)\n frame = undefined\n const box = container.getBoundingClientRect()\n const found: Array<Element> = []\n for (const name of names) {\n const property = measured(name)\n const target = container.querySelector(targets[name]!)\n if (target === null) {\n container.style.setProperty(property.display, 'none')\n continue\n }\n found.push(target)\n const rect = target.getBoundingClientRect()\n // Relative to the scroll box: where the content is, not where the viewport shows it.\n const x = rect.left - box.left - container.clientLeft + container.scrollLeft\n const y = rect.top - box.top - container.clientTop + container.scrollTop\n container.style.setProperty(property.x, `${x}px`)\n container.style.setProperty(property.y, `${y}px`)\n container.style.setProperty(property.w, `${rect.width}px`)\n container.style.setProperty(property.h, `${rect.height}px`)\n container.style.setProperty(property.display, 'block')\n }\n // A measured element that changes size, as an image loading does, is measured again.\n if (found.length !== watched.length || found.some((each, at) => each !== watched[at])) {\n for (const each of watched) sizes.unobserve(each)\n for (const each of found) sizes.observe(each)\n watched = found\n }\n if (animating) {\n // Asked each frame rather than counted: an element removed mid-transition ends none.\n animating = container\n .getAnimations({ subtree: true })\n .some(animation => animation.playState === 'running')\n if (animating) soon()\n }\n }\n const soon = () => {\n if (frame === undefined) frame = requestAnimationFrame(measure)\n }\n const moving = () => {\n animating = true\n soon()\n }\n\n // A change is measured as its records arrive, before the frame it is drawn in is\n // painted, so a box never shows one frame on the element it has left.\n const changes = new MutationObserver(measure)\n // Made, and the fonts listened to, before anything observes: where one is\n // missing (jsdom has neither a ResizeObserver nor `document.fonts`), the Mount\n // fails with nothing attached to call `measure`.\n const sizes = new ResizeObserver(soon)\n document.fonts.addEventListener('loadingdone', soon)\n // Its own properties change the container's style too, but writing the same\n // values again records nothing, so a measure that changed nothing rests.\n changes.observe(container, { subtree: true, childList: true, attributes: true })\n sizes.observe(container)\n container.addEventListener('scroll', soon, { passive: true })\n window.addEventListener('resize', soon)\n // `load` does not bubble, so it is caught on the way down.\n container.addEventListener('load', soon, { capture: true })\n container.addEventListener('transitionrun', moving)\n container.addEventListener('animationstart', moving)\n measure()\n return () => {\n if (frame !== undefined) cancelAnimationFrame(frame)\n changes.disconnect()\n sizes.disconnect()\n container.removeEventListener('scroll', soon)\n window.removeEventListener('resize', soon)\n container.removeEventListener('load', soon, { capture: true })\n document.fonts.removeEventListener('loadingdone', soon)\n container.removeEventListener('transitionrun', moving)\n container.removeEventListener('animationstart', moving)\n }\n }),\n stop => Effect.sync(stop),\n ),\n ),\n})\n","/**\n * Where the window is scrolled, across an application's own navigations, as\n * a stream. Left to itself, a browser keeps the scroll of the entry it\n * leaves when a link pushes a new one, and on Back restores the old offset\n * before the application has drawn the entry it returns to, so the offset is\n * clamped to a page still loading. Here a pushed entry starts at the top,\n * and Back, Forward or a reload return where that entry was, once the page\n * is tall enough to hold it.\n *\n * Three rules, each found the slow way:\n *\n * 1. The offset is taken when the reader acts. The next screen is drawn\n * before a Navigate Command pushes the address, so by the time the URL\n * changes the window is already clamped to the new, shorter page. The\n * scroll is recorded at the reader's click or key (capture phase), and at\n * the start of Back and Forward, which begin in the browser before\n * anything is drawn.\n * 2. A restore holds its place while the next screen settles. A restore made\n * when the entry changes is undone by the loading state drawn right after\n * it, so the target is held on each frame for a moment, until the reader\n * scrolls, touches or types, or another navigation starts.\n * 3. Entries are keyed by the Navigation API's entry key, which a reload and\n * a full navigation keep; offsets rest in `sessionStorage`, so Back into\n * another document restores too. Where the browser has no Navigation API\n * the stream attaches nothing and leaves the browser's own behaviour\n * alone.\n *\n * Lift with `Subscription.persistent`; the stream sends no Messages. Only\n * the window scrolls: a nested container is the route graph's to know, when\n * `Site.transition` arrives.\n */\nimport { Effect, Option, Stream } from 'effect'\n\n/** The part of the Navigation API used here: TypeScript's DOM library does not declare it yet. */\ninterface Navigation extends EventTarget {\n readonly currentEntry: { readonly key: string } | null\n}\ndeclare global {\n interface Window {\n readonly navigation?: Navigation\n }\n}\n\nexport interface KeepScrollOptions {\n /** The `sessionStorage` key holding entry offsets. Default `'foldkit:scroll'`. */\n readonly storageKey?: string | undefined\n /** Entries remembered at most: the oldest are forgotten first. Default 50. */\n readonly kept?: number | undefined\n /**\n * How long a restore holds its place while the next screen settles, in\n * milliseconds. Default 2000.\n */\n readonly patience?: number | undefined\n}\n\nconst navigationTypeOf = (event: Event): Option.Option<unknown> =>\n 'navigationType' in event ? Option.some(event.navigationType) : Option.none()\n\nconst readSaved = (storageKey: string): Map<string, number> => {\n try {\n const stored: unknown = JSON.parse(sessionStorage.getItem(storageKey) ?? '[]')\n return new Map(\n Array.isArray(stored)\n ? stored.filter(\n (pair): pair is [string, number] =>\n Array.isArray(pair) && typeof pair[0] === 'string' && typeof pair[1] === 'number',\n )\n : [],\n )\n } catch {\n // Storage blocked, or something else wrote the key: nothing is remembered.\n return new Map()\n }\n}\n\n/** Starts keeping the scroll; the release undoes everything it installed. */\nconst attach = (storageKey: string, kept: number, patience: number): (() => void) => {\n const navigation = window.navigation\n if (navigation === undefined) return () => {}\n const restoration = window.history.scrollRestoration\n window.history.scrollRestoration = 'manual'\n const saved = readSaved(storageKey)\n const detaches: Array<() => void> = []\n const on = (target: EventTarget, type: string, listener: EventListener, capture?: boolean) => {\n target.addEventListener(type, listener, capture)\n detaches.push(() => target.removeEventListener(type, listener, capture))\n }\n const keyOf = () =>\n Option.fromNullOr(navigation.currentEntry).pipe(Option.map(entry => entry.key))\n /** Where the current entry was left, if it has been. */\n const savedHere = () => Option.flatMap(keyOf(), key => Option.fromUndefinedOr(saved.get(key)))\n const remember = () => {\n const key = keyOf()\n if (Option.isNone(key)) return\n // Moved to the end, so it is the last to be forgotten.\n saved.delete(key.value)\n saved.set(key.value, window.scrollY)\n for (const old of saved.keys()) {\n if (saved.size <= kept) break\n saved.delete(old)\n }\n }\n\n let settling = new AbortController()\n /**\n * Holds the window at `top` while the next screen settles, whenever the page\n * can hold it, until the reader scrolls, touches or types, or another\n * navigation starts.\n */\n const settle = (top: number) => {\n settling.abort()\n settling = new AbortController()\n const { signal } = settling\n for (const input of ['wheel', 'touchstart', 'keydown', 'pointerdown'])\n window.addEventListener(input, () => settling.abort(), { passive: true, signal })\n const until = performance.now() + patience\n const step = () => {\n if (signal.aborted) return\n const room = document.documentElement.scrollHeight - window.innerHeight\n if (room >= top && Math.round(window.scrollY) !== top)\n window.scrollTo({ top, behavior: 'instant' })\n if (performance.now() < until) requestAnimationFrame(step)\n else settling.abort()\n }\n step()\n }\n\n // Remembered where the reader acts, before the application does: by the time\n // it pushes an address it has drawn the next screen, and the window is\n // already clamped to it. Back and Forward start in the browser, before\n // anything is drawn, so they are remembered as they begin.\n const acted = () => remember()\n for (const input of ['click', 'keydown']) on(window, input, acted, true)\n const traversing = (event: Event) => {\n if (Option.contains(navigationTypeOf(event), 'traverse')) remember()\n }\n on(navigation, 'navigate', traversing)\n const changed = (event: Event) => {\n const type = navigationTypeOf(event)\n if (Option.contains(type, 'push')) settle(0)\n else if (Option.contains(type, 'traverse')) settle(Option.getOrElse(savedHere(), () => 0))\n // A replace is the same entry, narrowed or selected in place: it stays where it is.\n }\n on(navigation, 'currententrychange', changed)\n const hidden = () => {\n remember()\n try {\n sessionStorage.setItem(storageKey, JSON.stringify([...saved]))\n } catch {\n // Storage blocked: the next document starts at the top.\n }\n }\n on(window, 'pagehide', hidden)\n // A reload, or Back into this document from another: where this entry was.\n const here = savedHere()\n if (Option.isSome(here)) settle(here.value)\n return () => {\n settling.abort()\n for (const detach of detaches) detach()\n window.history.scrollRestoration = restoration\n }\n}\n\n/**\n * Keeps the window's scroll across same-document navigations: a pushed entry\n * starts at the top, and Back, Forward or a reload return where that entry\n * was. Without a window the stream is empty instead of throwing. Lift with\n * `Subscription.persistent`; the stream sends no Messages.\n */\nexport const keepScroll = (options: KeepScrollOptions = {}): Stream.Stream<never> => {\n if (typeof window === 'undefined') return Stream.empty\n const storageKey = options.storageKey ?? 'foldkit:scroll'\n const kept = options.kept ?? 50\n const patience = options.patience ?? 2000\n return Stream.callback<never>(() =>\n Effect.acquireRelease(\n Effect.sync(() => attach(storageKey, kept, patience)),\n detach => Effect.sync(detach),\n ),\n )\n}\n","import { Option, Stream } from 'effect'\nimport * as Subscription from 'foldkit/subscription'\nimport { fromString, toString as urlToString, type Url } from 'foldkit/url'\n\n/**\n * The address of the link a reader points at or tabs to, on the page's own\n * origin: where they may go next, for a `Data.preload` before they go. Each\n * link once while they stay on it, since crossing its text sends one event\n * per element inside it. Without a document the stream is empty. Lift with\n * `Subscription.persistent`, mapping each address to a Message.\n */\nexport const pointedLinks = (): Stream.Stream<Url> => {\n if (typeof document === 'undefined') return Stream.empty\n const linkOf = (event: Event): Option.Option<Url> => {\n const link = event.target instanceof Element ? event.target.closest('a[href]') : null\n return link instanceof HTMLAnchorElement && link.origin === window.location.origin\n ? fromString(link.href)\n : Option.none()\n }\n return Stream.merge(\n Subscription.fromEventFilterMap({\n target: document,\n type: 'pointerover',\n filterMapEvent: linkOf,\n }),\n Subscription.fromEventFilterMap({ target: document, type: 'focusin', filterMapEvent: linkOf }),\n ).pipe(Stream.changesWith((a, b) => urlToString(a) === urlToString(b)))\n}\n"],"mappings":";;;;;;;;;;;;;;AAUA,MAAa,UAAU,OAAO,aAAa,WAAW,CAAC,CAAC;AAGxD,MAAa,YAAY,MAAM,OAAO,aAAa;CACjD,UAAU,CAAC,OAAO;CAClB,UAAU,EAAE,cACV,OAAO,WAAW;EAChB,MAAM,YAAY;EAClB,IAAI,OAAO,UAAU,UAAU,YAC5B,UAAW,MAAqB,KAAK,OAAO;EAE/C,OAAO,QAAQ,KAAK,CAAC,CAAC;CACxB,CAAC;AACL,CAAC;;;;;;;;ACdD,MAAa,mBAAmB,mBAAmB;CACjD,QAAQ,CAAC;CACT,YAAY,EAAE,SAAS,OAAO,OAAO;AACvC,CAAC;AAGD,MAAa,uBAAuB,mBAAmB;CACrD,MAAM,EAAE,MAAM,OAAO,OAAO;CAC5B,YAAY,EAAE,SAAS,OAAO,OAAO;AACvC,CAAC;AAGD,MAAMA,iBAAe,UACnB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;;;;;;AAOvD,MAAa,YAAY,UAA2D;CAClF,MAAM;CACN,MAAM,EAAE,KAAK;CACb,QACE,OAAO,cAAc,eAAe,OAAO,UAAU,WAAW,cAAc,aAC1E,OAAO,YACL,OAAO,WAAW;EAChB,WAAW,UAAU,UAAU,UAAU,IAAI;EAC7C,OAAOA;CACT,CAAC,GACD;EACE,YAAW,YAAW,OAAO,QAAQ,iBAAiB,WAAW,EAAE,QAAQ,CAAC,CAAC;EAC7E,iBAAiB,OAAO,QAAQ,iBAAiB,OAAO,CAAC;CAC3D,CACF,IACA,OAAO,QAAQ,iBAAiB,WAAW,EAAE,SAAS,2BAA2B,CAAC,CAAC;AAC3F;;;;;AAMA,MAAa,kBAA+D;CAC1E,MAAM;CACN,QACE,OAAO,cAAc,eAAe,OAAO,UAAU,WAAW,aAAa,aACzE,OAAO,YACL,OAAO,WAAW;EAAE,WAAW,UAAU,UAAU,SAAS;EAAG,OAAOA;CAAY,CAAC,GACnF;EACE,YAAW,YAAW,OAAO,QAAQ,qBAAqB,WAAW,EAAE,QAAQ,CAAC,CAAC;EACjF,YAAW,SAAQ,OAAO,QAAQ,qBAAqB,KAAK,EAAE,KAAK,CAAC,CAAC;CACvE,CACF,IACA,OAAO,QAAQ,qBAAqB,WAAW,EAAE,SAAS,2BAA2B,CAAC,CAAC;AAC/F;;;;;;;;;;;;ACnDA,MAAa,QAAQ,OAAO,aAAa,SAAS;CAChD,OAAO,OAAO;CACd,KAAK,OAAO;AACd,CAAC;AAGD,MAAM,WAAW,SAA0B,QAAQ,OAAO,QAAQ;AAClE,MAAM,YAAY,SACf,QAAQ,OAAO,QAAQ,OAAS,QAAQ,OAAO,QAAQ;AAE1D,MAAM,WAAW,aAAqB,SACpC,gBAAgB,MACZ,QAAQ,IAAI,IACZ,gBAAgB,MACd,SAAS,IAAI,IACb,QAAQ,IAAI,KAAK,SAAS,IAAI;AAEtC,MAAM,iBAAiB,SAA0B,SAAS,OAAO,SAAS,OAAO,SAAS;;AAG1F,MAAM,YAAY,SAAiB,MAAc,OAAe,OAAwB;CACtF,KAAK,IAAI,IAAI,MAAM,IAAI,QAAQ,QAAQ,KAAK;EAC1C,MAAM,cAAc,QAAQ;EAC5B,IAAI,CAAC,cAAc,WAAW,GAAG;EACjC,KAAK,IAAI,IAAI,IAAI,IAAI,MAAM,QAAQ,KACjC,IAAI,QAAQ,aAAa,MAAM,EAAG,GAAG,OAAO;CAEhD;CACA,OAAO;AACT;AAEA,MAAa,aACX,OACA,YACsD;CACtD,IAAI,SAAS;CACb,IAAI,MAAM;CACV,IAAI,KAAK;CACT,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,OAAO,QAAQ;EACrB,IAAI,cAAc,IAAI,GAAG;GACvB,OAAO,KAAK,MAAM,UAAU,CAAC,QAAQ,MAAM,MAAM,GAAI,GAAG;GACxD,IAAI,MAAM,MAAM,QAAQ;GACxB,UAAU,MAAM;GAChB,OAAO,MAAM;GACb;EACF,OAAO,IAAI,SAAS,SAAS,IAAI,GAAG,OAAO,EAAE,GAC3C,UAAU;OAEV;CAEJ;CACA,OAAO;EAAE;EAAQ;CAAI;AACvB;AAUA,MAAM,WAAW,YAA2C;CAC1D,MAAM,QAAQ;CACd,OAAO,OAAO,MAAM,UAAU,YAAY,OAAO,MAAM,qBAAqB,aACvE,QACD;AACN;AAEA,MAAa,YAAY,MAAM,aAAa,aAAa;CACvD,UAAU,CAAC,KAAK;CAChB,MAAM,EAAE,SAAS,OAAO,OAAO;CAC/B,UAAU,EAAE,SAAS,cACnB,OAAO,UAA4B,UACjC,OAAO,IAAI,aAAa;EACtB,MAAM,QAAQ,QAAQ,OAAO;EAC7B,IAAI,UAAU,MAAM;EACpB,MAAM,gBAAgB;GACpB,MAAM,EAAE,QAAQ,QAAQ,UAAU,MAAM,OAAO,OAAO;GACtD,IAAI,WAAW,MAAM,OAAO;IAC1B,MAAM,QAAQ,MAAM,kBAAkB,OAAO;IAC7C,MAAM,QAAQ;IACd,MAAM,KAAK,KAAK,IAAI,OAAO,OAAO,MAAM;IACxC,IAAI;KACF,MAAM,oBAAoB,IAAI,EAAE;IAClC,QAAQ,CAER;GACF;GACA,MAAM,YAAY,OAAO,MAAM,KAAK;IAAE,OAAO;IAAQ;GAAI,CAAC,CAAC;EAC7D;EACA,OAAO,OAAO,eACZ,OAAO,WAAW;GAChB,MAAM,iBAAiB,SAAS,OAAO;GACvC,OAAO;EACT,CAAC,IACD,YAAW,OAAO,WAAW,QAAQ,oBAAoB,SAAS,OAAO,CAAC,CAC5E;CACF,CAAC,CACH;AACJ,CAAC;;;;;;;;;;;;ACrGD,MAAa,aAAa,MAAM,aAAa,cAAc;CACzD,UAAU,CAAC,OAAO,KAAK;CACvB,MAAM;;AAEJ,UAAU,OAAO,OACnB;CACA,UAAU,EAAE,SAAS,eACnB,OAAO,eACL,OAAO,eACL,OAAO,WAAW;EAChB,IAAI,SAAS,QAAQ,cAAc,QAAQ;EAC3C,MAAM,WAAW,IAAI,uBAAuB;GAC1C,MAAM,MAAM,QAAQ,cAAc,QAAQ;GAG1C,IAAI,QAAQ,QAAQ,QAAQ,UAAU,OAAO,IAAI,mBAAmB,YAClE,IAAI,eAAe;IAAE,OAAO;IAAW,QAAQ;GAAU,CAAC;GAC5D,SAAS;EACX,CAAC;EACD,SAAS,QAAQ,SAAS;GAAE,SAAS;GAAM,WAAW;GAAM,YAAY;EAAK,CAAC;EAC9E,OAAO;CACT,CAAC,IACD,aAAY,OAAO,WAAW,SAAS,WAAW,CAAC,CACrD,CACF;AACJ,CAAC;;;;;;;;;;AC1BD,MAAa,gBAAgB,mBAAmB;CAC9C,QAAQ,CAAC;CACT,YAAY,EAAE,SAAS,OAAO,OAAO;AACvC,CAAC;AAGD,MAAMC,iBAAe,UACnB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAGvD,MAAM,2BAAW,IAAI,IAA2B;;AAGhD,MAAa,cAAc,SAAuD;CAChF,MAAM;CACN,MAAM,EAAE,IAAI;CACZ,QAAQ,OAAO,YACb,OAAO,WAAW;EAChB,WAAW;GACT,IAAI,OAAO,aAAa,aACtB,OAAO,QAAQ,uBAAO,IAAI,MAAM,+BAA+B,CAAC;GAMlE,MAAM,UAAU,SAAS,IAAI,GAAG;GAChC,IAAI,YAAY,KAAA,GAAW,OAAO;GAMlC,IAHgB,MAAM,KAAK,SAAS,qBAAqB,QAAQ,CAAC,CAAC,CAAC,MAClE,YAAW,QAAQ,aAAa,KAAK,MAAM,GAEnC,GAAG,OAAO,QAAQ,QAAQ;GAapC,MAAM,UAAU,IAZO,SAAe,SAAS,WAAW;IACxD,MAAM,UAAU,SAAS,cAAc,QAAQ;IAC/C,QAAQ,MAAM;IACd,QAAQ,QAAQ;IAChB,QAAQ,eAAe,QAAQ;IAC/B,QAAQ,gBAAgB;KAEtB,QAAQ,OAAO;KACf,uBAAO,IAAI,MAAM,0BAA0B,KAAK,CAAC;IACnD;IACA,SAAS,KAAK,YAAY,OAAO;GACnC,CACyB,CAAC,CAAC,WACnB;IACJ,SAAS,OAAO,GAAG;GACrB,IACC,UAAmB;IAClB,SAAS,OAAO,GAAG;IACnB,MAAM;GACR,CACF;GACA,SAAS,IAAI,KAAK,OAAO;GACzB,OAAO;EACT;EACA,QAAQ,UAAmB;CAC7B,CAAC,GACD;EACE,YAAW,UAAS,OAAO,QAAQ,cAAc,WAAW,EAAE,SAASA,cAAY,KAAK,EAAE,CAAC,CAAC;EAC5F,iBAAiB,OAAO,QAAQ,cAAc,OAAO,CAAC;CACxD,CACF;AACF;;;;;;;;;;ACjEA,MAAa,YAAY,OAAO,OAAO;CACrC,OAAO,OAAO,SAAS,OAAO,MAAM;CACpC,MAAM,OAAO,SAAS,OAAO,MAAM;CACnC,KAAK,OAAO,SAAS,OAAO,MAAM;AACpC,CAAC;AAGD,MAAa,eAAe,mBAAmB;CAC7C,QAAQ,CAAC;CACT,WAAW,CAAC;CACZ,aAAa,EAAE,SAAS,OAAO,OAAO;AACxC,CAAC;AAGD,MAAM,eAAe,UACnB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAEvD,MAAM,eAAe,UACnB,OAAQ,OAA8C,SAAS,YAC9D,MAAoC,SAAS;;AAGhD,MAAa,SAAS,UAA0D;CAC9E,MAAM;CACN,MAAM,EAAE,KAAK;CACb,QACE,OAAO,cAAc,eAAe,OAAO,UAAU,UAAU,aAC3D,OAAO,YACL,OAAO,WAAW;EAGhB,WACE,UAAU,MAAM;GACd,GAAI,KAAK,UAAU,KAAA,IAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;GACxD,GAAI,KAAK,SAAS,KAAA,IAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;GACrD,GAAI,KAAK,QAAQ,KAAA,IAAY,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;EACpD,CAAC;EACH,QAAQ,UAAmB;CAC7B,CAAC,GACD;EACE,YAAW,UACT,OAAO,QACL,YAAY,KAAK,IACb,aAAa,UAAU,IACvB,aAAa,YAAY,EAAE,SAAS,YAAY,KAAK,EAAE,CAAC,CAC9D;EACF,iBAAiB,OAAO,QAAQ,aAAa,OAAO,CAAC;CACvD,CACF,IACA,OAAO,QAAQ,aAAa,YAAY,EAAE,SAAS,uBAAuB,CAAC,CAAC;AACpF;;;;;;;;;;;;;;;;;;;;;;;ACtCA,MAAa,YAAY,UACtB;CACC,GAAG,QAAQ,KAAK;CAChB,GAAG,QAAQ,KAAK;CAChB,GAAG,QAAQ,KAAK;CAChB,GAAG,QAAQ,KAAK;CAChB,SAAS,QAAQ,KAAK;AACxB;AAEF,MAAa,UAAU,MAAM,aAAa,WAAW;CACnD,UAAU,CAAC,OAAO,KAAK;CACvB,MAAM;;AAEJ,SAAS,OAAO,OAAO,OAAO,QAAQ,OAAO,MAAM,EACrD;CACA,UAAU,EAAE,SAAS,cACnB,OAAO,eACL,OAAO,eACL,OAAO,WAAW;EAChB,MAAM,YAAY;EAClB,MAAM,QAAQ,OAAO,KAAK,OAAO;EACjC,IAAI,UAAkC,CAAC;EACvC,IAAI;EAEJ,IAAI,YAAY;EAEhB,MAAM,gBAAgB;GACpB,IAAI,UAAU,KAAA,GAAW,qBAAqB,KAAK;GACnD,QAAQ,KAAA;GACR,MAAM,MAAM,UAAU,sBAAsB;GAC5C,MAAM,QAAwB,CAAC;GAC/B,KAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,WAAW,SAAS,IAAI;IAC9B,MAAM,SAAS,UAAU,cAAc,QAAQ,KAAM;IACrD,IAAI,WAAW,MAAM;KACnB,UAAU,MAAM,YAAY,SAAS,SAAS,MAAM;KACpD;IACF;IACA,MAAM,KAAK,MAAM;IACjB,MAAM,OAAO,OAAO,sBAAsB;IAE1C,MAAM,IAAI,KAAK,OAAO,IAAI,OAAO,UAAU,aAAa,UAAU;IAClE,MAAM,IAAI,KAAK,MAAM,IAAI,MAAM,UAAU,YAAY,UAAU;IAC/D,UAAU,MAAM,YAAY,SAAS,GAAG,GAAG,EAAE,GAAG;IAChD,UAAU,MAAM,YAAY,SAAS,GAAG,GAAG,EAAE,GAAG;IAChD,UAAU,MAAM,YAAY,SAAS,GAAG,GAAG,KAAK,MAAM,GAAG;IACzD,UAAU,MAAM,YAAY,SAAS,GAAG,GAAG,KAAK,OAAO,GAAG;IAC1D,UAAU,MAAM,YAAY,SAAS,SAAS,OAAO;GACvD;GAEA,IAAI,MAAM,WAAW,QAAQ,UAAU,MAAM,MAAM,MAAM,OAAO,SAAS,QAAQ,GAAG,GAAG;IACrF,KAAK,MAAM,QAAQ,SAAS,MAAM,UAAU,IAAI;IAChD,KAAK,MAAM,QAAQ,OAAO,MAAM,QAAQ,IAAI;IAC5C,UAAU;GACZ;GACA,IAAI,WAAW;IAEb,YAAY,UACT,cAAc,EAAE,SAAS,KAAK,CAAC,CAAC,CAChC,MAAK,cAAa,UAAU,cAAc,SAAS;IACtD,IAAI,WAAW,KAAK;GACtB;EACF;EACA,MAAM,aAAa;GACjB,IAAI,UAAU,KAAA,GAAW,QAAQ,sBAAsB,OAAO;EAChE;EACA,MAAM,eAAe;GACnB,YAAY;GACZ,KAAK;EACP;EAIA,MAAM,UAAU,IAAI,iBAAiB,OAAO;EAI5C,MAAM,QAAQ,IAAI,eAAe,IAAI;EACrC,SAAS,MAAM,iBAAiB,eAAe,IAAI;EAGnD,QAAQ,QAAQ,WAAW;GAAE,SAAS;GAAM,WAAW;GAAM,YAAY;EAAK,CAAC;EAC/E,MAAM,QAAQ,SAAS;EACvB,UAAU,iBAAiB,UAAU,MAAM,EAAE,SAAS,KAAK,CAAC;EAC5D,OAAO,iBAAiB,UAAU,IAAI;EAEtC,UAAU,iBAAiB,QAAQ,MAAM,EAAE,SAAS,KAAK,CAAC;EAC1D,UAAU,iBAAiB,iBAAiB,MAAM;EAClD,UAAU,iBAAiB,kBAAkB,MAAM;EACnD,QAAQ;EACR,aAAa;GACX,IAAI,UAAU,KAAA,GAAW,qBAAqB,KAAK;GACnD,QAAQ,WAAW;GACnB,MAAM,WAAW;GACjB,UAAU,oBAAoB,UAAU,IAAI;GAC5C,OAAO,oBAAoB,UAAU,IAAI;GACzC,UAAU,oBAAoB,QAAQ,MAAM,EAAE,SAAS,KAAK,CAAC;GAC7D,SAAS,MAAM,oBAAoB,eAAe,IAAI;GACtD,UAAU,oBAAoB,iBAAiB,MAAM;GACrD,UAAU,oBAAoB,kBAAkB,MAAM;EACxD;CACF,CAAC,IACD,SAAQ,OAAO,KAAK,IAAI,CAC1B,CACF;AACJ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzED,MAAM,oBAAoB,UACxB,oBAAoB,QAAQ,OAAO,KAAK,MAAM,cAAc,IAAI,OAAO,KAAK;AAE9E,MAAM,aAAa,eAA4C;CAC7D,IAAI;EACF,MAAM,SAAkB,KAAK,MAAM,eAAe,QAAQ,UAAU,KAAK,IAAI;EAC7E,OAAO,IAAI,IACT,MAAM,QAAQ,MAAM,IAChB,OAAO,QACJ,SACC,MAAM,QAAQ,IAAI,KAAK,OAAO,KAAK,OAAO,YAAY,OAAO,KAAK,OAAO,QAC7E,IACA,CAAC,CACP;CACF,QAAQ;EAEN,uBAAO,IAAI,IAAI;CACjB;AACF;;AAGA,MAAM,UAAU,YAAoB,MAAc,aAAmC;CACnF,MAAM,aAAa,OAAO;CAC1B,IAAI,eAAe,KAAA,GAAW,aAAa,CAAC;CAC5C,MAAM,cAAc,OAAO,QAAQ;CACnC,OAAO,QAAQ,oBAAoB;CACnC,MAAM,QAAQ,UAAU,UAAU;CAClC,MAAM,WAA8B,CAAC;CACrC,MAAM,MAAM,QAAqB,MAAc,UAAyB,YAAsB;EAC5F,OAAO,iBAAiB,MAAM,UAAU,OAAO;EAC/C,SAAS,WAAW,OAAO,oBAAoB,MAAM,UAAU,OAAO,CAAC;CACzE;CACA,MAAM,cACJ,OAAO,WAAW,WAAW,YAAY,CAAC,CAAC,KAAK,OAAO,KAAI,UAAS,MAAM,GAAG,CAAC;;CAEhF,MAAM,kBAAkB,OAAO,QAAQ,MAAM,IAAG,QAAO,OAAO,gBAAgB,MAAM,IAAI,GAAG,CAAC,CAAC;CAC7F,MAAM,iBAAiB;EACrB,MAAM,MAAM,MAAM;EAClB,IAAI,OAAO,OAAO,GAAG,GAAG;EAExB,MAAM,OAAO,IAAI,KAAK;EACtB,MAAM,IAAI,IAAI,OAAO,OAAO,OAAO;EACnC,KAAK,MAAM,OAAO,MAAM,KAAK,GAAG;GAC9B,IAAI,MAAM,QAAQ,MAAM;GACxB,MAAM,OAAO,GAAG;EAClB;CACF;CAEA,IAAI,WAAW,IAAI,gBAAgB;;;;;;CAMnC,MAAM,UAAU,QAAgB;EAC9B,SAAS,MAAM;EACf,WAAW,IAAI,gBAAgB;EAC/B,MAAM,EAAE,WAAW;EACnB,KAAK,MAAM,SAAS;GAAC;GAAS;GAAc;GAAW;EAAa,GAClE,OAAO,iBAAiB,aAAa,SAAS,MAAM,GAAG;GAAE,SAAS;GAAM;EAAO,CAAC;EAClF,MAAM,QAAQ,YAAY,IAAI,IAAI;EAClC,MAAM,aAAa;GACjB,IAAI,OAAO,SAAS;GAEpB,IADa,SAAS,gBAAgB,eAAe,OAAO,eAChD,OAAO,KAAK,MAAM,OAAO,OAAO,MAAM,KAChD,OAAO,SAAS;IAAE;IAAK,UAAU;GAAU,CAAC;GAC9C,IAAI,YAAY,IAAI,IAAI,OAAO,sBAAsB,IAAI;QACpD,SAAS,MAAM;EACtB;EACA,KAAK;CACP;CAMA,MAAM,cAAc,SAAS;CAC7B,KAAK,MAAM,SAAS,CAAC,SAAS,SAAS,GAAG,GAAG,QAAQ,OAAO,OAAO,IAAI;CACvE,MAAM,cAAc,UAAiB;EACnC,IAAI,OAAO,SAAS,iBAAiB,KAAK,GAAG,UAAU,GAAG,SAAS;CACrE;CACA,GAAG,YAAY,YAAY,UAAU;CACrC,MAAM,WAAW,UAAiB;EAChC,MAAM,OAAO,iBAAiB,KAAK;EACnC,IAAI,OAAO,SAAS,MAAM,MAAM,GAAG,OAAO,CAAC;OACtC,IAAI,OAAO,SAAS,MAAM,UAAU,GAAG,OAAO,OAAO,UAAU,UAAU,SAAS,CAAC,CAAC;CAE3F;CACA,GAAG,YAAY,sBAAsB,OAAO;CAC5C,MAAM,eAAe;EACnB,SAAS;EACT,IAAI;GACF,eAAe,QAAQ,YAAY,KAAK,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC;EAC/D,QAAQ,CAER;CACF;CACA,GAAG,QAAQ,YAAY,MAAM;CAE7B,MAAM,OAAO,UAAU;CACvB,IAAI,OAAO,OAAO,IAAI,GAAG,OAAO,KAAK,KAAK;CAC1C,aAAa;EACX,SAAS,MAAM;EACf,KAAK,MAAM,UAAU,UAAU,OAAO;EACtC,OAAO,QAAQ,oBAAoB;CACrC;AACF;;;;;;;AAQA,MAAa,cAAc,UAA6B,CAAC,MAA4B;CACnF,IAAI,OAAO,WAAW,aAAa,OAAO,OAAO;CACjD,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,WAAW,QAAQ,YAAY;CACrC,OAAO,OAAO,eACZ,OAAO,eACL,OAAO,WAAW,OAAO,YAAY,MAAM,QAAQ,CAAC,IACpD,WAAU,OAAO,KAAK,MAAM,CAC9B,CACF;AACF;;;;;;;;;;ACzKA,MAAa,qBAAyC;CACpD,IAAI,OAAO,aAAa,aAAa,OAAO,OAAO;CACnD,MAAM,UAAU,UAAqC;EACnD,MAAM,OAAO,MAAM,kBAAkB,UAAU,MAAM,OAAO,QAAQ,SAAS,IAAI;EACjF,OAAO,gBAAgB,qBAAqB,KAAK,WAAW,OAAO,SAAS,SACxE,WAAW,KAAK,IAAI,IACpB,OAAO,KAAK;CAClB;CACA,OAAO,OAAO,MACZ,aAAa,mBAAmB;EAC9B,QAAQ;EACR,MAAM;EACN,gBAAgB;CAClB,CAAC,GACD,aAAa,mBAAmB;EAAE,QAAQ;EAAU,MAAM;EAAW,gBAAgB;CAAO,CAAC,CAC/F,CAAC,CAAC,KAAK,OAAO,aAAa,GAAG,MAAMC,SAAY,CAAC,MAAMA,SAAY,CAAC,CAAC,CAAC;AACxE"}
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Coordinates, FullscreenMessage, Geolocation, GeolocationMessage, GeolocationModel, LiveStream, LiveStreamService, MediaDevice, MediaDevicesHandle, MediaDevicesMessage, MediaDevicesModel, MediaStreamConstraints, MediaStreamHandle, MediaStreamMessage, MediaStreamModel, MediaTrackHandle, PermissionState, PermissionStatusHandle, PermissionsHandle, PermissionsMessage, PermissionsModel, Watch, WatchService, enterFullscreen, exitFullscreen, fullscreenChanges, mediaDevices, mediaStream, permissions } from "./device/index.mjs";
2
2
  import { A as ScrollLock, C as targetOf, D as MoveStarted, E as MoveEnded, M as tabbableWithin, O as Moved, S as Targets, T as Move, _ as boxOf, a as TextEdited, b as TargetHovered, c as DRAG_THRESHOLD, d as DragFact, f as DragPlace, g as PointerDrag, h as DraggedOver, i as TextCommitted, j as FocusScope, k as HideOutside, l as DragCancelled, m as DragZone, n as EditableText, o as TextFact, p as DragStarted, r as TextCancelled, s as textOf, t as EditAsked, u as DragDropped, v as zoneOf, w as Fact, x as TargetPressed, y as TargetFact } from "./editable-text-BbsPOATY.mjs";
3
- import { Autofocus, ClipboardMessage, ClipboardReadMessage, Focused, FollowTabStop, Input, InputMask, KeepInView, KeepScrollOptions, Measure, ScriptMessage, ShareData, ShareMessage, applyMask, copyText, keepScroll, loadScript, measured, readText, share } from "./dom/index.mjs";
3
+ import { Autofocus, ClipboardMessage, ClipboardReadMessage, Focused, FollowTabStop, Input, InputMask, KeepInView, KeepScrollOptions, Measure, ScriptMessage, ShareData, ShareMessage, applyMask, copyText, keepScroll, loadScript, measured, pointedLinks, readText, share } from "./dom/index.mjs";
4
4
  import { a as modalityOfKey, i as Modality, n as InputModalityMessage, r as InputModalityModel, t as InputModality } from "./input-modality-DGOhAknO.mjs";
5
5
  import { ActiveElementMessage, Idle, IdleMessage, IdleModel, KeyPress, KeyboardMessage, PointerMessage, ScrollMessage, Visibility, VisibilityMessage, VisibilityModel, WindowSize, WindowSizeMessage, WindowSizeModel, activeElementEvents, keyboardEvents, matchHotkey, pointerEvents, scrollEvents } from "./events/index.mjs";
6
6
  import { Breakpoints, BreakpointsMessage, BreakpointsModel, MediaQuery, MediaQueryMessage, MediaQueryModel, Platform, PlatformHints, PrefersDark, PrefersReducedMotion, breakpointFor, isBrowser, isServer, platformFromUA } from "./media/index.mjs";
@@ -9,4 +9,4 @@ import { Acquired, AcquiredSource, BroadcastChannelHandle, BroadcastMessage, Con
9
9
  import { Bounds, Intersection, IntersectionChanged, Measured, Mutated, Mutation, Resize, Resized } from "./observers/index.mjs";
10
10
  import { History, HistoryModel, Locale, LocaleMessage, LocaleModel, MasonryPlacement, MeasureRow, Pagination, PaginationMessage, PaginationModel, RowMeasured, SelectionSet, SelectionSetMessage, SelectionSetModel, Viewport, ViewportScrolled, Virtual, VirtualLayout, VirtualMessage, VirtualModel, VirtualWindow, canRedo, canUndo, distanceToEnd, history, isAtEnd, isSelected, masonry, offset, offsetFor, pageCount, range, stickyHeader, totalHeight, visibleRange, windowFor } from "./state/index.mjs";
11
11
  import { Interval, IntervalMessage, IntervalModel, Throttle, ThrottleMessage, ThrottleModel, Throttled, Timer, TimerMessage, TimerModel, debounce, formatRelativeTime, ticks } from "./time/index.mjs";
12
- export { Acquired, AcquiredSource, ActiveElementMessage, Autofocus, Bounds, Breakpoints, BreakpointsMessage, BreakpointsModel, BroadcastChannelHandle, BroadcastMessage, ClipboardMessage, ClipboardReadMessage, Conversation, ConversationHandler, Coordinates, DRAG_THRESHOLD, DragCancelled, DragDropped, DragFact, DragPlace, DragStarted, DragZone, DraggedOver, EditAsked, EditableText, Fact, FocusScope, Focused, FollowTabStop, FullscreenMessage, Geolocation, GeolocationMessage, GeolocationModel, HideOutside, History, HistoryModel, Idle, IdleMessage, IdleModel, Input, InputMask, InputModality, InputModalityMessage, InputModalityModel, Intersection, IntersectionChanged, Interval, IntervalMessage, IntervalModel, KeepInView, KeepScrollOptions, KeyPress, KeyboardMessage, LiveStream, LiveStreamService, Locale, LocaleMessage, LocaleModel, MasonryPlacement, Measure, MeasureRow, Measured, MediaDevice, MediaDevicesHandle, MediaDevicesMessage, MediaDevicesModel, MediaQuery, MediaQueryMessage, MediaQueryModel, MediaStreamConstraints, MediaStreamHandle, MediaStreamMessage, MediaStreamModel, MediaTrackHandle, Modality, motion_d_exports as Motion, Move, MoveEnded, MoveStarted, Moved, Mutated, Mutation, Online, OnlineMessage, OnlineModel, Pagination, PaginationMessage, PaginationModel, PermissionState, PermissionStatusHandle, PermissionsHandle, PermissionsMessage, PermissionsModel, Platform, PlatformHints, PointerDrag, PointerMessage, PrefersDark, PrefersReducedMotion, Presence, PresenceMessage, PresenceModel, Resize, Resized, RowMeasured, ScriptMessage, ScrollLock, ScrollMessage, SelectionSet, SelectionSetMessage, SelectionSetModel, ShareData, ShareMessage, SharedHost, SharedHostConnection, SharedHostOptions, Socket, SocketHandle, SocketService, SocketView, Source, SourceHandle, SourceService, Spring, SpringMessage, SpringModel, SseMessage, SseModel, SseView, StartHost, TargetFact, TargetHovered, TargetPressed, Targets, TextCancelled, TextCommitted, TextEdited, TextFact, Throttle, ThrottleMessage, ThrottleModel, Throttled, Timer, TimerMessage, TimerModel, Tween, TweenMessage, TweenModel, Viewport, ViewportScrolled, Virtual, VirtualLayout, VirtualMessage, VirtualModel, VirtualWindow, Visibility, VisibilityMessage, VisibilityModel, Watch, WatchService, WebSocketMessage, WebSocketModel, WindowSize, WindowSizeMessage, WindowSizeModel, activeElementEvents, applyMask, boxOf, breakpointFor, broadcastMessages, canRedo, canUndo, copyText, debounce, distanceToEnd, enterFullscreen, exitFullscreen, formatRelativeTime, fullscreenChanges, history, isAtEnd, isBrowser, isLive, isOpen, isSelected, isServer, isVisible, keepScroll, keyboardEvents, loadScript, masonry, matchHotkey, measured, mediaDevices, mediaStream, modalityOfKey, offset, offsetFor, pageCount, permissions, platformFromUA, pointerEvents, postBroadcast, range, readText, scrollEvents, share, sse, stickyHeader, tabbableWithin, targetOf, textOf, ticks, totalHeight, viewOf, viewOfSse, visibleRange, websocket, windowFor, zoneOf };
12
+ export { Acquired, AcquiredSource, ActiveElementMessage, Autofocus, Bounds, Breakpoints, BreakpointsMessage, BreakpointsModel, BroadcastChannelHandle, BroadcastMessage, ClipboardMessage, ClipboardReadMessage, Conversation, ConversationHandler, Coordinates, DRAG_THRESHOLD, DragCancelled, DragDropped, DragFact, DragPlace, DragStarted, DragZone, DraggedOver, EditAsked, EditableText, Fact, FocusScope, Focused, FollowTabStop, FullscreenMessage, Geolocation, GeolocationMessage, GeolocationModel, HideOutside, History, HistoryModel, Idle, IdleMessage, IdleModel, Input, InputMask, InputModality, InputModalityMessage, InputModalityModel, Intersection, IntersectionChanged, Interval, IntervalMessage, IntervalModel, KeepInView, KeepScrollOptions, KeyPress, KeyboardMessage, LiveStream, LiveStreamService, Locale, LocaleMessage, LocaleModel, MasonryPlacement, Measure, MeasureRow, Measured, MediaDevice, MediaDevicesHandle, MediaDevicesMessage, MediaDevicesModel, MediaQuery, MediaQueryMessage, MediaQueryModel, MediaStreamConstraints, MediaStreamHandle, MediaStreamMessage, MediaStreamModel, MediaTrackHandle, Modality, motion_d_exports as Motion, Move, MoveEnded, MoveStarted, Moved, Mutated, Mutation, Online, OnlineMessage, OnlineModel, Pagination, PaginationMessage, PaginationModel, PermissionState, PermissionStatusHandle, PermissionsHandle, PermissionsMessage, PermissionsModel, Platform, PlatformHints, PointerDrag, PointerMessage, PrefersDark, PrefersReducedMotion, Presence, PresenceMessage, PresenceModel, Resize, Resized, RowMeasured, ScriptMessage, ScrollLock, ScrollMessage, SelectionSet, SelectionSetMessage, SelectionSetModel, ShareData, ShareMessage, SharedHost, SharedHostConnection, SharedHostOptions, Socket, SocketHandle, SocketService, SocketView, Source, SourceHandle, SourceService, Spring, SpringMessage, SpringModel, SseMessage, SseModel, SseView, StartHost, TargetFact, TargetHovered, TargetPressed, Targets, TextCancelled, TextCommitted, TextEdited, TextFact, Throttle, ThrottleMessage, ThrottleModel, Throttled, Timer, TimerMessage, TimerModel, Tween, TweenMessage, TweenModel, Viewport, ViewportScrolled, Virtual, VirtualLayout, VirtualMessage, VirtualModel, VirtualWindow, Visibility, VisibilityMessage, VisibilityModel, Watch, WatchService, WebSocketMessage, WebSocketModel, WindowSize, WindowSizeMessage, WindowSizeModel, activeElementEvents, applyMask, boxOf, breakpointFor, broadcastMessages, canRedo, canUndo, copyText, debounce, distanceToEnd, enterFullscreen, exitFullscreen, formatRelativeTime, fullscreenChanges, history, isAtEnd, isBrowser, isLive, isOpen, isSelected, isServer, isVisible, keepScroll, keyboardEvents, loadScript, masonry, matchHotkey, measured, mediaDevices, mediaStream, modalityOfKey, offset, offsetFor, pageCount, permissions, platformFromUA, pointedLinks, pointerEvents, postBroadcast, range, readText, scrollEvents, share, sse, stickyHeader, tabbableWithin, targetOf, textOf, ticks, totalHeight, viewOf, viewOfSse, visibleRange, websocket, windowFor, zoneOf };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { C as MoveEnded, D as ScrollLock, E as HideOutside, O as FocusScope, S as Move, T as Moved, _ as zoneOf, a as TextCommitted, b as Targets, c as DRAG_THRESHOLD, d as DragPlace, f as DragStarted, g as boxOf, h as PointerDrag, i as TextCancelled, k as tabbableWithin, l as DragCancelled, m as DraggedOver, n as EditAsked, o as TextEdited, p as DragZone, r as EditableText, s as textOf, t as FollowTabStop, u as DragDropped, v as TargetHovered, w as MoveStarted, x as targetOf, y as TargetPressed } from "./follow-tab-stop-BDxyoUPQ.mjs";
2
- import { Autofocus, ClipboardMessage, ClipboardReadMessage, Focused, Input, InputMask, KeepInView, Measure, ScriptMessage, ShareData, ShareMessage, applyMask, copyText, keepScroll, loadScript, measured, readText, share } from "./dom/index.mjs";
2
+ import { Autofocus, ClipboardMessage, ClipboardReadMessage, Focused, Input, InputMask, KeepInView, Measure, ScriptMessage, ShareData, ShareMessage, applyMask, copyText, keepScroll, loadScript, measured, pointedLinks, readText, share } from "./dom/index.mjs";
3
3
  import { Coordinates, FullscreenMessage, Geolocation, GeolocationMessage, GeolocationModel, LiveStream, MediaDevice, MediaDevicesMessage, MediaDevicesModel, MediaStreamMessage, MediaStreamModel, PermissionState, PermissionsMessage, PermissionsModel, Watch, enterFullscreen, exitFullscreen, fullscreenChanges, mediaDevices, mediaStream, permissions } from "./device/index.mjs";
4
4
  import { a as modalityOfKey, i as Modality, n as InputModalityMessage, r as InputModalityModel, t as InputModality } from "./input-modality-m6v7__Xs.mjs";
5
5
  import { ActiveElementMessage, Idle, IdleMessage, IdleModel, KeyboardMessage, PointerMessage, ScrollMessage, Visibility, VisibilityMessage, VisibilityModel, WindowSize, WindowSizeMessage, WindowSizeModel, activeElementEvents, keyboardEvents, matchHotkey, pointerEvents, scrollEvents } from "./events/index.mjs";
@@ -9,4 +9,4 @@ import { BroadcastMessage, Online, OnlineMessage, OnlineModel, SharedHost, Socke
9
9
  import { Bounds, Intersection, IntersectionChanged, Measured, Mutated, Mutation, Resize, Resized } from "./observers/index.mjs";
10
10
  import { History, HistoryModel, Locale, LocaleMessage, LocaleModel, MeasureRow, Pagination, PaginationMessage, PaginationModel, RowMeasured, SelectionSet, SelectionSetMessage, SelectionSetModel, Viewport, ViewportScrolled, Virtual, VirtualMessage, VirtualModel, canRedo, canUndo, distanceToEnd, history, isAtEnd, isSelected, masonry, offset, offsetFor, pageCount, range, stickyHeader, totalHeight, visibleRange, windowFor } from "./state/index.mjs";
11
11
  import { Interval, IntervalMessage, IntervalModel, Throttle, ThrottleMessage, ThrottleModel, Throttled, Timer, TimerMessage, TimerModel, debounce, formatRelativeTime, ticks } from "./time/index.mjs";
12
- export { ActiveElementMessage, Autofocus, Bounds, Breakpoints, BreakpointsMessage, BreakpointsModel, BroadcastMessage, ClipboardMessage, ClipboardReadMessage, Coordinates, DRAG_THRESHOLD, DragCancelled, DragDropped, DragPlace, DragStarted, DragZone, DraggedOver, EditAsked, EditableText, FocusScope, Focused, FollowTabStop, FullscreenMessage, Geolocation, GeolocationMessage, GeolocationModel, HideOutside, History, HistoryModel, Idle, IdleMessage, IdleModel, Input, InputMask, InputModality, InputModalityMessage, InputModalityModel, Intersection, IntersectionChanged, Interval, IntervalMessage, IntervalModel, KeepInView, KeyboardMessage, LiveStream, Locale, LocaleMessage, LocaleModel, Measure, MeasureRow, Measured, MediaDevice, MediaDevicesMessage, MediaDevicesModel, MediaQuery, MediaQueryMessage, MediaQueryModel, MediaStreamMessage, MediaStreamModel, Modality, motion_exports as Motion, Move, MoveEnded, MoveStarted, Moved, Mutated, Mutation, Online, OnlineMessage, OnlineModel, Pagination, PaginationMessage, PaginationModel, PermissionState, PermissionsMessage, PermissionsModel, Platform, PointerDrag, PointerMessage, PrefersDark, PrefersReducedMotion, Presence, PresenceMessage, PresenceModel, Resize, Resized, RowMeasured, ScriptMessage, ScrollLock, ScrollMessage, SelectionSet, SelectionSetMessage, SelectionSetModel, ShareData, ShareMessage, SharedHost, Socket, SocketView, Source, Spring, SpringMessage, SpringModel, SseMessage, SseModel, SseView, TargetHovered, TargetPressed, Targets, TextCancelled, TextCommitted, TextEdited, Throttle, ThrottleMessage, ThrottleModel, Throttled, Timer, TimerMessage, TimerModel, Tween, TweenMessage, TweenModel, Viewport, ViewportScrolled, Virtual, VirtualMessage, VirtualModel, Visibility, VisibilityMessage, VisibilityModel, Watch, WebSocketMessage, WebSocketModel, WindowSize, WindowSizeMessage, WindowSizeModel, activeElementEvents, applyMask, boxOf, breakpointFor, broadcastMessages, canRedo, canUndo, copyText, debounce, distanceToEnd, enterFullscreen, exitFullscreen, formatRelativeTime, fullscreenChanges, history, isAtEnd, isBrowser, isLive, isOpen, isSelected, isServer, isVisible, keepScroll, keyboardEvents, loadScript, masonry, matchHotkey, measured, mediaDevices, mediaStream, modalityOfKey, offset, offsetFor, pageCount, permissions, platformFromUA, pointerEvents, postBroadcast, range, readText, scrollEvents, share, sse, stickyHeader, tabbableWithin, targetOf, textOf, ticks, totalHeight, viewOf, viewOfSse, visibleRange, websocket, windowFor, zoneOf };
12
+ export { ActiveElementMessage, Autofocus, Bounds, Breakpoints, BreakpointsMessage, BreakpointsModel, BroadcastMessage, ClipboardMessage, ClipboardReadMessage, Coordinates, DRAG_THRESHOLD, DragCancelled, DragDropped, DragPlace, DragStarted, DragZone, DraggedOver, EditAsked, EditableText, FocusScope, Focused, FollowTabStop, FullscreenMessage, Geolocation, GeolocationMessage, GeolocationModel, HideOutside, History, HistoryModel, Idle, IdleMessage, IdleModel, Input, InputMask, InputModality, InputModalityMessage, InputModalityModel, Intersection, IntersectionChanged, Interval, IntervalMessage, IntervalModel, KeepInView, KeyboardMessage, LiveStream, Locale, LocaleMessage, LocaleModel, Measure, MeasureRow, Measured, MediaDevice, MediaDevicesMessage, MediaDevicesModel, MediaQuery, MediaQueryMessage, MediaQueryModel, MediaStreamMessage, MediaStreamModel, Modality, motion_exports as Motion, Move, MoveEnded, MoveStarted, Moved, Mutated, Mutation, Online, OnlineMessage, OnlineModel, Pagination, PaginationMessage, PaginationModel, PermissionState, PermissionsMessage, PermissionsModel, Platform, PointerDrag, PointerMessage, PrefersDark, PrefersReducedMotion, Presence, PresenceMessage, PresenceModel, Resize, Resized, RowMeasured, ScriptMessage, ScrollLock, ScrollMessage, SelectionSet, SelectionSetMessage, SelectionSetModel, ShareData, ShareMessage, SharedHost, Socket, SocketView, Source, Spring, SpringMessage, SpringModel, SseMessage, SseModel, SseView, TargetHovered, TargetPressed, Targets, TextCancelled, TextCommitted, TextEdited, Throttle, ThrottleMessage, ThrottleModel, Throttled, Timer, TimerMessage, TimerModel, Tween, TweenMessage, TweenModel, Viewport, ViewportScrolled, Virtual, VirtualMessage, VirtualModel, Visibility, VisibilityMessage, VisibilityModel, Watch, WebSocketMessage, WebSocketModel, WindowSize, WindowSizeMessage, WindowSizeModel, activeElementEvents, applyMask, boxOf, breakpointFor, broadcastMessages, canRedo, canUndo, copyText, debounce, distanceToEnd, enterFullscreen, exitFullscreen, formatRelativeTime, fullscreenChanges, history, isAtEnd, isBrowser, isLive, isOpen, isSelected, isServer, isVisible, keepScroll, keyboardEvents, loadScript, masonry, matchHotkey, measured, mediaDevices, mediaStream, modalityOfKey, offset, offsetFor, pageCount, permissions, platformFromUA, pointedLinks, pointerEvents, postBroadcast, range, readText, scrollEvents, share, sse, stickyHeader, tabbableWithin, targetOf, textOf, ticks, totalHeight, viewOf, viewOfSse, visibleRange, websocket, windowFor, zoneOf };
@@ -1,9 +1,9 @@
1
1
  import { A as ScrollLock, C as targetOf, D as MoveStarted, E as MoveEnded, M as tabbableWithin, O as Moved, S as Targets, T as Move, _ as boxOf, a as TextEdited, b as TargetHovered, c as DRAG_THRESHOLD, d as DragFact, f as DragPlace, g as PointerDrag, h as DraggedOver, i as TextCommitted, j as FocusScope, k as HideOutside, l as DragCancelled, m as DragZone, n as EditableText, o as TextFact, p as DragStarted, r as TextCancelled, s as textOf, t as EditAsked, u as DragDropped, v as zoneOf, w as Fact$1, x as TargetPressed, y as TargetFact } from "../editable-text-BbsPOATY.mjs";
2
2
  import { a as modalityOfKey, i as Modality, r as InputModalityModel, t as InputModality } from "../input-modality-DGOhAknO.mjs";
3
- import { Schema } from "effect";
3
+ import { Option, Schema } from "effect";
4
4
  import * as Mount from "foldkit/mount";
5
5
  import { Bundle, Declared } from "foldkit-bundle";
6
- import { Behavior, Behaviors, SlotItem } from "foldkit-mixins";
6
+ import { Behavior, Behaviors, NamedBehavior, SlotItem } from "foldkit-mixins";
7
7
  import { Attribute, Html, HtmlBuilder, KeyboardModifiers } from "foldkit/html";
8
8
  declare namespace dismiss_layer_d_exports {
9
9
  export { BehaviorOptions$14 as BehaviorOptions, Dismiss, LAYER_ATTRIBUTE, Layer$1 as Layer, Message$9 as Message, Model$9 as Model, TRIGGER_ATTRIBUTE, behavior$14 as behavior, bundle$9 as bundle, layersOnPath, toDismiss };
@@ -434,7 +434,7 @@ declare const bundle$5: Bundle.Bundle<"ListNavigation", {
434
434
  readonly _tag: "Focused";
435
435
  readonly id: string;
436
436
  }, never, never, never, void, {}, {}>;
437
- interface BehaviorOptions$8<Input, Slots> {
437
+ interface BehaviorOptions$8<Input, Slots, ParentMessage> {
438
438
  readonly container: keyof Slots & string;
439
439
  /** The slot rendered once per item; must carry the item's id (see `Behaviors.Collection`). */
440
440
  readonly item: keyof Slots & string;
@@ -442,6 +442,17 @@ interface BehaviorOptions$8<Input, Slots> {
442
442
  /** The text an item is matched by when typing. */
443
443
  readonly text: (input: Input, index: number) => string;
444
444
  readonly direction?: (input: Input) => Direction;
445
+ /**
446
+ * Whether a printable key moves the pointer. Off when the container is a
447
+ * text field: letters belong to the field, and arrows still navigate.
448
+ * Defaults to on.
449
+ */
450
+ readonly typeahead?: boolean;
451
+ /**
452
+ * Enter on the current enabled item. One handler with the arrows: a second
453
+ * key handler on the same slot would be a second owner of `keydown`.
454
+ */
455
+ readonly commit?: (input: Input, id: string) => ParentMessage;
445
456
  }
446
457
  /**
447
458
  * The key's outcome, before it is turned into an attribute: navigation to an
@@ -466,7 +477,7 @@ declare const keyOutcome: (items: Behaviors.Collection.Items<unknown>, texts: Re
466
477
  * `OnFocus` as under `RovingTabindex`. Under `virtual` nothing takes DOM focus
467
478
  * and the container carries `aria-activedescendant`.
468
479
  */
469
- declare const behavior$8: <Field extends string>(declared: Declared<typeof bundle$5, Field>, args: Args$5) => <Slots>(slots: Slots) => <Input extends { readonly [K in Field]: Model$5; }, ParentMessage>(options: BehaviorOptions$8<Input, Slots>) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
480
+ declare const behavior$8: <Field extends string>(declared: Declared<typeof bundle$5, Field>, args: Args$5) => <Slots>(slots: Slots) => <Input extends { readonly [K in Field]: Model$5; }, ParentMessage>(options: BehaviorOptions$8<Input, Slots, ParentMessage>) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
470
481
  declare namespace long_press_d_exports {
471
482
  export { Args$4 as Args, BehaviorOptions$7 as BehaviorOptions, LongPressed, Message$4 as Message, Model$4 as Model, behavior$7 as behavior, bundle$4 as bundle };
472
483
  }
@@ -577,6 +588,50 @@ interface BehaviorOptions$6<Slots, ParentMessage> {
577
588
  readonly toMessage: (fact: Fact$1) => ParentMessage;
578
589
  }
579
590
  declare const behavior$6: <Slots>(slots: Slots) => <Input, ParentMessage>(options: BehaviorOptions$6<Slots, ParentMessage>) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
591
+ declare namespace overlay_d_exports {
592
+ export { DismissPolicy, FocusPolicy, Policy, behaviors, modal, nonModal };
593
+ }
594
+ interface DismissPolicy {
595
+ /** Dismiss on a press outside. Default `true`. */
596
+ readonly outside: boolean;
597
+ /** Dismiss on Escape when topmost. Default `true`. */
598
+ readonly escape: boolean;
599
+ }
600
+ interface FocusPolicy {
601
+ /** Keep Tab, Shift+Tab, and stray focus inside. Default `true`. */
602
+ readonly contain: boolean;
603
+ /** Give focus back to what had it on unmount. Default `true`. */
604
+ readonly restore: boolean;
605
+ /** A selector inside the layer to focus first. */
606
+ readonly initialFocus?: string;
607
+ }
608
+ interface Policy {
609
+ readonly dismiss: DismissPolicy;
610
+ readonly focus: FocusPolicy;
611
+ /** Lock the document's scroll while mounted. */
612
+ readonly scroll: {
613
+ readonly lock: boolean;
614
+ };
615
+ /** Mark everything outside inert while mounted. */
616
+ readonly inert: boolean;
617
+ }
618
+ /** A modal overlay: dismissed by Escape and outside press, focused, locked, inert. */
619
+ declare const modal: Policy;
620
+ /** A modeless overlay: dismissed by Escape and outside press, focus restored, page usable. */
621
+ declare const nonModal: Policy;
622
+ /**
623
+ * The policy as behaviors, to spread into the view's pipe alongside the
624
+ * widget's own. Conditional pieces are included or left out when the list
625
+ * is built — a static policy per composition — so no slot carries a mount
626
+ * its policy never uses.
627
+ */
628
+ declare const behaviors: <Slots>(slots: Slots) => <Input, ParentMessage, StackField extends string>(options: {
629
+ readonly stack: Declared<typeof bundle$9, StackField>;
630
+ readonly layer: keyof Slots & string;
631
+ readonly trigger?: keyof Slots & string;
632
+ readonly id: (input: Input) => string;
633
+ readonly policy: Policy;
634
+ }) => ReadonlyArray<NamedBehavior<Slots, Input, ParentMessage>>;
580
635
  declare namespace press_d_exports {
581
636
  export { Args$3 as Args, BehaviorOptions$5 as BehaviorOptions, Fact, Message$3 as Message, Model$3 as Model, PointerType, Pressed, behavior$5 as behavior, bundle$3 as bundle, events };
582
637
  }
@@ -834,6 +889,91 @@ interface BehaviorOptions$2<Slots, ParentMessage> {
834
889
  readonly toMessage: (fact: DragFact) => ParentMessage;
835
890
  }
836
891
  declare const behavior$2: <Slots>(slots: Slots) => <Input, ParentMessage>(options: BehaviorOptions$2<Slots, ParentMessage>) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
892
+ declare namespace placing_d_exports {
893
+ export { AnchorRect, KeepWithin, OriginRect, PanelRect, PlaceAt, PlaceAtPoint, Placed, PlacedAt, Viewport, ViewportPoint, keepWithin, placeAt, placeAtPoint, placeAtTrigger, placeFor, placedAbove, placedSide, placedTop, shiftIntoViewport };
894
+ }
895
+ interface PanelRect {
896
+ readonly top: number;
897
+ readonly right: number;
898
+ readonly bottom: number;
899
+ readonly height: number;
900
+ }
901
+ interface Viewport {
902
+ readonly width: number;
903
+ readonly height: number;
904
+ }
905
+ interface Placed {
906
+ /** Pixels to move left; `0` when the panel fits. */
907
+ readonly dx: number;
908
+ /** Whether the panel stands above its trigger instead of below. */
909
+ readonly flip: boolean;
910
+ }
911
+ /** Where the panel goes so it fits: left by the overflow, above when the
912
+ * bottom clears the window and the room overhead fits the panel. */
913
+ declare const placeFor: (rect: PanelRect, viewport: Viewport, margin?: number) => Placed;
914
+ /** Pixels to move a box up so its bottom sits `margin` inside the viewport.
915
+ * `0` when it already fits, or when its top is already at the margin. */
916
+ declare const shiftIntoViewport: (rect: {
917
+ readonly top: number;
918
+ readonly bottom: number;
919
+ }, viewportHeight: number, margin?: number) => number;
920
+ /** Attribute `keepWithin` sets to `placedAbove` when the panel flips. */
921
+ declare const placedSide = "data-fk-placed";
922
+ /** Value of `placedSide` while the panel stands above its anchor. */
923
+ declare const placedAbove = "above";
924
+ interface AnchorRect {
925
+ readonly left: number;
926
+ readonly top: number;
927
+ readonly bottom: number;
928
+ readonly width: number;
929
+ readonly height: number;
930
+ }
931
+ interface OriginRect {
932
+ readonly left: number;
933
+ readonly top: number;
934
+ }
935
+ interface PlacedAt {
936
+ readonly left: number;
937
+ readonly top: number;
938
+ }
939
+ /** Custom property `PlaceAt` writes. A panel reads it as `top` so a viewport
940
+ * flip, which sets the `top` property, still wins. */
941
+ declare const placedTop = "--fk-placed-top";
942
+ /** Where a popup sits under its trigger's left edge, in the offset parent's
943
+ * coordinates. A zero-size trigger (an inert document) stays at the origin. */
944
+ declare const placeAt: (trigger: AnchorRect, origin: OriginRect, gap?: number) => PlacedAt;
945
+ interface ViewportPoint {
946
+ readonly x: number;
947
+ readonly y: number;
948
+ }
949
+ /** Where a popup's top-left sits on a viewport point, in the offset parent's
950
+ * coordinates. A context menu uses it: the right-click event carries the
951
+ * point, and `OnContextMenu` does not. */
952
+ declare const placeAtPoint: (point: ViewportPoint, origin: OriginRect) => PlacedAt;
953
+ declare const KeepWithin: Mount.MountDefinitionNoArgs<"KeepWithin", never>;
954
+ declare const PlaceAt: Mount.MountDefinitionWithArgs<"PlaceAt", {
955
+ /** Element id of the trigger the popup opens under. */
956
+ triggerId: Schema.String;
957
+ /** Pixels between the trigger's bottom and the popup. */
958
+ gap: Schema.Number;
959
+ }, never>;
960
+ declare const PlaceAtPoint: Mount.MountDefinitionWithArgs<"PlaceAtPoint", {
961
+ /** Viewport x of the popup's top-left. */
962
+ x: Schema.Number;
963
+ /** Viewport y of the popup's top-left. */
964
+ y: Schema.Number;
965
+ }, never>;
966
+ declare const placeAtTrigger: <Slots>(slots: Slots) => <Input, ParentMessage>(options: {
967
+ readonly panel: keyof Slots & string;
968
+ /** The trigger this open belongs to. Read at insert, so key the panel by it. */
969
+ readonly triggerId: (input: Input) => string;
970
+ readonly gap?: number;
971
+ /** A viewport point wins over the trigger. None places under `triggerId`. */
972
+ readonly at?: (input: Input) => Option.Option<ViewportPoint>;
973
+ }) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
974
+ declare const keepWithin: <Slots>(slots: Slots) => <Input, ParentMessage>(options: {
975
+ readonly panel: keyof Slots & string;
976
+ }) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
837
977
  declare namespace tree_navigation_d_exports {
838
978
  export { Action, Args$1 as Args, BehaviorOptions$1 as BehaviorOptions, Message$1 as Message, Model$1 as Model, Row, Shown, behavior$1 as behavior, bundle$1 as bundle, isOpen, move, shown, tabStop };
839
979
  }
@@ -1015,5 +1155,5 @@ interface BehaviorOptions<Input, Slots> {
1015
1155
  */
1016
1156
  declare const behavior: <Field extends string>(declared: Declared<typeof bundle, Field>) => <Slots>(slots: Slots) => <Input extends { readonly [K in Field]: Model; }, ParentMessage>(options: BehaviorOptions<Input, Slots>) => Behavior.NamedBehavior<Slots, Input, ParentMessage>;
1017
1157
  //#endregion
1018
- export { dismiss_layer_d_exports as DismissLayer, editable_text_d_exports as EditableText, focus_scope_d_exports as FocusScope, focus_visible_d_exports as FocusVisible, grid_navigation_d_exports as GridNavigation, layers_d_exports as Layers, list_navigation_d_exports as ListNavigation, live_announce_d_exports as LiveAnnounce, long_press_d_exports as LongPress, move_d_exports as Move, pointer_drag_d_exports as PointerDrag, press_d_exports as Press, roving_tabindex_d_exports as RovingTabindex, selection_d_exports as Selection, targets_d_exports as Targets, tree_navigation_d_exports as TreeNavigation, typeahead_d_exports as Typeahead };
1158
+ export { dismiss_layer_d_exports as DismissLayer, editable_text_d_exports as EditableText, focus_scope_d_exports as FocusScope, focus_visible_d_exports as FocusVisible, grid_navigation_d_exports as GridNavigation, layers_d_exports as Layers, list_navigation_d_exports as ListNavigation, live_announce_d_exports as LiveAnnounce, long_press_d_exports as LongPress, move_d_exports as Move, overlay_d_exports as Overlay, placing_d_exports as Placing, pointer_drag_d_exports as PointerDrag, press_d_exports as Press, roving_tabindex_d_exports as RovingTabindex, selection_d_exports as Selection, targets_d_exports as Targets, tree_navigation_d_exports as TreeNavigation, typeahead_d_exports as Typeahead };
1019
1159
  //# sourceMappingURL=index.d.mts.map