@reticlehq/browser 2.0.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.
Files changed (191) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +17 -0
  3. package/dist/actions/actions-dom.d.ts +29 -0
  4. package/dist/actions/actions-dom.d.ts.map +1 -0
  5. package/dist/actions/actions-dom.js +153 -0
  6. package/dist/actions/actions-dom.js.map +1 -0
  7. package/dist/actions/actions.d.ts +92 -0
  8. package/dist/actions/actions.d.ts.map +1 -0
  9. package/dist/actions/actions.js +348 -0
  10. package/dist/actions/actions.js.map +1 -0
  11. package/dist/actions/scroll.d.ts +19 -0
  12. package/dist/actions/scroll.d.ts.map +1 -0
  13. package/dist/actions/scroll.js +44 -0
  14. package/dist/actions/scroll.js.map +1 -0
  15. package/dist/commands/commands.d.ts +5 -0
  16. package/dist/commands/commands.d.ts.map +1 -0
  17. package/dist/commands/commands.js +246 -0
  18. package/dist/commands/commands.js.map +1 -0
  19. package/dist/dom/a11y.d.ts +20 -0
  20. package/dist/dom/a11y.d.ts.map +1 -0
  21. package/dist/dom/a11y.js +263 -0
  22. package/dist/dom/a11y.js.map +1 -0
  23. package/dist/dom/auto-anchor.d.ts +66 -0
  24. package/dist/dom/auto-anchor.d.ts.map +1 -0
  25. package/dist/dom/auto-anchor.js +75 -0
  26. package/dist/dom/auto-anchor.js.map +1 -0
  27. package/dist/dom/dom-ignore.d.ts +7 -0
  28. package/dist/dom/dom-ignore.d.ts.map +1 -0
  29. package/dist/dom/dom-ignore.js +21 -0
  30. package/dist/dom/dom-ignore.js.map +1 -0
  31. package/dist/dom/query.d.ts +6 -0
  32. package/dist/dom/query.d.ts.map +1 -0
  33. package/dist/dom/query.js +236 -0
  34. package/dist/dom/query.js.map +1 -0
  35. package/dist/dom/refs.d.ts +15 -0
  36. package/dist/dom/refs.d.ts.map +1 -0
  37. package/dist/dom/refs.js +36 -0
  38. package/dist/dom/refs.js.map +1 -0
  39. package/dist/dom/snapshot.d.ts +22 -0
  40. package/dist/dom/snapshot.d.ts.map +1 -0
  41. package/dist/dom/snapshot.js +171 -0
  42. package/dist/dom/snapshot.js.map +1 -0
  43. package/dist/dom/theme.d.ts +26 -0
  44. package/dist/dom/theme.d.ts.map +1 -0
  45. package/dist/dom/theme.js +90 -0
  46. package/dist/dom/theme.js.map +1 -0
  47. package/dist/index.d.ts +25 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +32 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/observers/animation.d.ts +4 -0
  52. package/dist/observers/animation.d.ts.map +1 -0
  53. package/dist/observers/animation.js +35 -0
  54. package/dist/observers/animation.js.map +1 -0
  55. package/dist/observers/console.d.ts +4 -0
  56. package/dist/observers/console.d.ts.map +1 -0
  57. package/dist/observers/console.js +58 -0
  58. package/dist/observers/console.js.map +1 -0
  59. package/dist/observers/dom.d.ts +4 -0
  60. package/dist/observers/dom.d.ts.map +1 -0
  61. package/dist/observers/dom.js +96 -0
  62. package/dist/observers/dom.js.map +1 -0
  63. package/dist/observers/health.d.ts +8 -0
  64. package/dist/observers/health.d.ts.map +1 -0
  65. package/dist/observers/health.js +33 -0
  66. package/dist/observers/health.js.map +1 -0
  67. package/dist/observers/network.d.ts +11 -0
  68. package/dist/observers/network.d.ts.map +1 -0
  69. package/dist/observers/network.js +128 -0
  70. package/dist/observers/network.js.map +1 -0
  71. package/dist/observers/route.d.ts +4 -0
  72. package/dist/observers/route.d.ts.map +1 -0
  73. package/dist/observers/route.js +56 -0
  74. package/dist/observers/route.js.map +1 -0
  75. package/dist/observers/scroll.d.ts +4 -0
  76. package/dist/observers/scroll.d.ts.map +1 -0
  77. package/dist/observers/scroll.js +42 -0
  78. package/dist/observers/scroll.js.map +1 -0
  79. package/dist/observers/types.d.ts +6 -0
  80. package/dist/observers/types.d.ts.map +1 -0
  81. package/dist/observers/types.js +2 -0
  82. package/dist/observers/types.js.map +1 -0
  83. package/dist/presenter/overlay.d.ts +12 -0
  84. package/dist/presenter/overlay.d.ts.map +1 -0
  85. package/dist/presenter/overlay.js +31 -0
  86. package/dist/presenter/overlay.js.map +1 -0
  87. package/dist/presenter/presenter-config.d.ts +86 -0
  88. package/dist/presenter/presenter-config.d.ts.map +1 -0
  89. package/dist/presenter/presenter-config.js +51 -0
  90. package/dist/presenter/presenter-config.js.map +1 -0
  91. package/dist/presenter/presenter-controls.d.ts +74 -0
  92. package/dist/presenter/presenter-controls.d.ts.map +1 -0
  93. package/dist/presenter/presenter-controls.js +360 -0
  94. package/dist/presenter/presenter-controls.js.map +1 -0
  95. package/dist/presenter/presenter-effects.d.ts +14 -0
  96. package/dist/presenter/presenter-effects.d.ts.map +1 -0
  97. package/dist/presenter/presenter-effects.js +40 -0
  98. package/dist/presenter/presenter-effects.js.map +1 -0
  99. package/dist/presenter/presenter-glow.d.ts +43 -0
  100. package/dist/presenter/presenter-glow.d.ts.map +1 -0
  101. package/dist/presenter/presenter-glow.js +126 -0
  102. package/dist/presenter/presenter-glow.js.map +1 -0
  103. package/dist/presenter/presenter-log.d.ts +43 -0
  104. package/dist/presenter/presenter-log.d.ts.map +1 -0
  105. package/dist/presenter/presenter-log.js +118 -0
  106. package/dist/presenter/presenter-log.js.map +1 -0
  107. package/dist/presenter/presenter-run-state.d.ts +48 -0
  108. package/dist/presenter/presenter-run-state.d.ts.map +1 -0
  109. package/dist/presenter/presenter-run-state.js +37 -0
  110. package/dist/presenter/presenter-run-state.js.map +1 -0
  111. package/dist/presenter/presenter-styles.d.ts +7 -0
  112. package/dist/presenter/presenter-styles.d.ts.map +1 -0
  113. package/dist/presenter/presenter-styles.js +118 -0
  114. package/dist/presenter/presenter-styles.js.map +1 -0
  115. package/dist/presenter/presenter-tally.d.ts +20 -0
  116. package/dist/presenter/presenter-tally.d.ts.map +1 -0
  117. package/dist/presenter/presenter-tally.js +38 -0
  118. package/dist/presenter/presenter-tally.js.map +1 -0
  119. package/dist/presenter/presenter-verbs.d.ts +2 -0
  120. package/dist/presenter/presenter-verbs.d.ts.map +1 -0
  121. package/dist/presenter/presenter-verbs.js +29 -0
  122. package/dist/presenter/presenter-verbs.js.map +1 -0
  123. package/dist/presenter/presenter.d.ts +89 -0
  124. package/dist/presenter/presenter.d.ts.map +1 -0
  125. package/dist/presenter/presenter.js +428 -0
  126. package/dist/presenter/presenter.js.map +1 -0
  127. package/dist/recorder/recorder-styles.d.ts +12 -0
  128. package/dist/recorder/recorder-styles.d.ts.map +1 -0
  129. package/dist/recorder/recorder-styles.js +45 -0
  130. package/dist/recorder/recorder-styles.js.map +1 -0
  131. package/dist/recorder/recorder.d.ts +60 -0
  132. package/dist/recorder/recorder.d.ts.map +1 -0
  133. package/dist/recorder/recorder.js +436 -0
  134. package/dist/recorder/recorder.js.map +1 -0
  135. package/dist/registry/adapters.d.ts +31 -0
  136. package/dist/registry/adapters.d.ts.map +1 -0
  137. package/dist/registry/adapters.js +47 -0
  138. package/dist/registry/adapters.js.map +1 -0
  139. package/dist/registry/capabilities.d.ts +25 -0
  140. package/dist/registry/capabilities.d.ts.map +1 -0
  141. package/dist/registry/capabilities.js +48 -0
  142. package/dist/registry/capabilities.js.map +1 -0
  143. package/dist/registry/commit-and-signal.d.ts +9 -0
  144. package/dist/registry/commit-and-signal.d.ts.map +1 -0
  145. package/dist/registry/commit-and-signal.js +12 -0
  146. package/dist/registry/commit-and-signal.js.map +1 -0
  147. package/dist/registry/domains.d.ts +15 -0
  148. package/dist/registry/domains.d.ts.map +1 -0
  149. package/dist/registry/domains.js +19 -0
  150. package/dist/registry/domains.js.map +1 -0
  151. package/dist/registry/emitter.d.ts +28 -0
  152. package/dist/registry/emitter.d.ts.map +1 -0
  153. package/dist/registry/emitter.js +27 -0
  154. package/dist/registry/emitter.js.map +1 -0
  155. package/dist/registry/stores.d.ts +9 -0
  156. package/dist/registry/stores.d.ts.map +1 -0
  157. package/dist/registry/stores.js +30 -0
  158. package/dist/registry/stores.js.map +1 -0
  159. package/dist/reticle-presenter-helpers.d.ts +19 -0
  160. package/dist/reticle-presenter-helpers.d.ts.map +1 -0
  161. package/dist/reticle-presenter-helpers.js +81 -0
  162. package/dist/reticle-presenter-helpers.js.map +1 -0
  163. package/dist/reticle.d.ts +113 -0
  164. package/dist/reticle.d.ts.map +1 -0
  165. package/dist/reticle.js +379 -0
  166. package/dist/reticle.js.map +1 -0
  167. package/dist/review/annotator.d.ts +36 -0
  168. package/dist/review/annotator.d.ts.map +1 -0
  169. package/dist/review/annotator.js +321 -0
  170. package/dist/review/annotator.js.map +1 -0
  171. package/dist/review/mark-anchor.d.ts +23 -0
  172. package/dist/review/mark-anchor.d.ts.map +1 -0
  173. package/dist/review/mark-anchor.js +74 -0
  174. package/dist/review/mark-anchor.js.map +1 -0
  175. package/dist/security/serialization.d.ts +6 -0
  176. package/dist/security/serialization.d.ts.map +1 -0
  177. package/dist/security/serialization.js +103 -0
  178. package/dist/security/serialization.js.map +1 -0
  179. package/dist/timers/clock.d.ts +6 -0
  180. package/dist/timers/clock.d.ts.map +1 -0
  181. package/dist/timers/clock.js +80 -0
  182. package/dist/timers/clock.js.map +1 -0
  183. package/dist/timers/native-timers.d.ts +37 -0
  184. package/dist/timers/native-timers.d.ts.map +1 -0
  185. package/dist/timers/native-timers.js +79 -0
  186. package/dist/timers/native-timers.js.map +1 -0
  187. package/dist/transport/transport.d.ts +54 -0
  188. package/dist/transport/transport.d.ts.map +1 -0
  189. package/dist/transport/transport.js +182 -0
  190. package/dist/transport/transport.js.map +1 -0
  191. package/package.json +52 -0
@@ -0,0 +1,48 @@
1
+ /** Self-describing capability registry — the testable surface the app advertises. */
2
+ // Persist on a global so the registry survives HMR module re-evaluation (matches __reticleAdapters).
3
+ const globalStore = globalThis;
4
+ function empty() {
5
+ return { testids: [], signals: [], stores: [], flows: [] };
6
+ }
7
+ const capabilities = (globalStore.__reticleCapabilities ??= empty());
8
+ function mergeUnique(into, add) {
9
+ if (add === undefined)
10
+ return;
11
+ for (const v of add)
12
+ if (!into.includes(v))
13
+ into.push(v);
14
+ }
15
+ /** Called by the host app via reticle.describe(). Merges (idempotent), never replaces wholesale. */
16
+ export function registerCapabilities(input) {
17
+ mergeUnique(capabilities.testids, input.testids);
18
+ mergeUnique(capabilities.signals, input.signals);
19
+ mergeUnique(capabilities.stores, input.stores);
20
+ if (input.flows !== undefined) {
21
+ for (const flow of input.flows) {
22
+ const existing = capabilities.flows.find((f) => f.name === flow.name);
23
+ if (existing === undefined) {
24
+ capabilities.flows.push({ name: flow.name, steps: [...flow.steps] });
25
+ }
26
+ else {
27
+ existing.steps = [...flow.steps]; // last writer wins for a named flow
28
+ }
29
+ }
30
+ }
31
+ }
32
+ /** Snapshot copy of the registered capabilities (defensive — never hand out the live arrays). */
33
+ export function getCapabilities() {
34
+ return {
35
+ testids: [...capabilities.testids],
36
+ signals: [...capabilities.signals],
37
+ stores: [...capabilities.stores],
38
+ flows: capabilities.flows.map((f) => ({ name: f.name, steps: [...f.steps] })),
39
+ };
40
+ }
41
+ /** Whether the app has advertised any capabilities (used in the HELLO flag). */
42
+ export function hasCapabilities() {
43
+ return (capabilities.testids.length > 0 ||
44
+ capabilities.signals.length > 0 ||
45
+ capabilities.stores.length > 0 ||
46
+ capabilities.flows.length > 0);
47
+ }
48
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/registry/capabilities.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAsBrF,qGAAqG;AACrG,MAAM,WAAW,GAAG,UAAiE,CAAC;AAEtF,SAAS,KAAK;IACZ,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,YAAY,GAAiB,CAAC,WAAW,CAAC,qBAAqB,KAAK,KAAK,EAAE,CAAC,CAAC;AAEnF,SAAS,WAAW,CAAC,IAAc,EAAE,GAAkC;IACrE,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO;IAC9B,KAAK,MAAM,CAAC,IAAI,GAAG;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,oBAAoB,CAAC,KAAwB;IAC3D,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACjD,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACjD,WAAW,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/C,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;YACtE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACvE,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,oCAAoC;YACxE,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,OAAO,EAAE,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC;QAClC,OAAO,EAAE,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC;QAClC,MAAM,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC;QAChC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;KAC9E,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,eAAe;IAC7B,OAAO,CACL,YAAY,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;QAC/B,YAAY,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;QAC/B,YAAY,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAC9B,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAC9B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * P5b — pair a mutation with its signal so the two can't drift. The lighter alternative to a
3
+ * Zustand middleware: one call runs the mutation, then emits the signal exactly once, and returns
4
+ * the mutation's value. If `mutate` throws, the mutation never happened — so the signal is NOT
5
+ * emitted and the error propagates unchanged (no try/finally, which would wrongly emit on throw).
6
+ */
7
+ import type { ReticleEmitter } from './emitter.js';
8
+ export declare function commitAndSignal<T>(emitter: ReticleEmitter, mutate: () => T, name: string, data?: Record<string, unknown>): T;
9
+ //# sourceMappingURL=commit-and-signal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commit-and-signal.d.ts","sourceRoot":"","sources":["../../src/registry/commit-and-signal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,MAAM,CAAC,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,CAAC,CAIH"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * P5b — pair a mutation with its signal so the two can't drift. The lighter alternative to a
3
+ * Zustand middleware: one call runs the mutation, then emits the signal exactly once, and returns
4
+ * the mutation's value. If `mutate` throws, the mutation never happened — so the signal is NOT
5
+ * emitted and the error propagates unchanged (no try/finally, which would wrongly emit on throw).
6
+ */
7
+ export function commitAndSignal(emitter, mutate, name, data) {
8
+ const result = mutate(); // throws here? then signal below is never reached — by design.
9
+ emitter.signal(name, data);
10
+ return result;
11
+ }
12
+ //# sourceMappingURL=commit-and-signal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commit-and-signal.js","sourceRoot":"","sources":["../../src/registry/commit-and-signal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,UAAU,eAAe,CAC7B,OAAuB,EACvB,MAAe,EACf,IAAY,EACZ,IAA8B;IAE9B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,+DAA+D;IACxF,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC3B,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * P5c — self-registering domains. Instead of one hand-maintained flat-map of the whole testable
3
+ * surface, each app domain co-locates its `{ testids, signals, stores }` and calls
4
+ * `registerReticleDomain(...)`; the capability registry assembles itself from every domain. Thin
5
+ * adapter over `registerCapabilities`, so merge/dedupe (and HMR persistence) are reused, not
6
+ * reinvented — later calls accumulate as a union, empty domains are a no-op.
7
+ */
8
+ /** A co-located domain bundle (one `reticle.ts` per app domain). */
9
+ export interface ReticleDomain {
10
+ testids?: readonly string[];
11
+ signals?: readonly string[];
12
+ stores?: readonly string[];
13
+ }
14
+ export declare function registerReticleDomain(domain: ReticleDomain): void;
15
+ //# sourceMappingURL=domains.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../../src/registry/domains.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAMjE"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * P5c — self-registering domains. Instead of one hand-maintained flat-map of the whole testable
3
+ * surface, each app domain co-locates its `{ testids, signals, stores }` and calls
4
+ * `registerReticleDomain(...)`; the capability registry assembles itself from every domain. Thin
5
+ * adapter over `registerCapabilities`, so merge/dedupe (and HMR persistence) are reused, not
6
+ * reinvented — later calls accumulate as a union, empty domains are a no-op.
7
+ */
8
+ import { registerCapabilities } from './capabilities.js';
9
+ export function registerReticleDomain(domain) {
10
+ const input = {};
11
+ if (domain.testids !== undefined)
12
+ input.testids = [...domain.testids];
13
+ if (domain.signals !== undefined)
14
+ input.signals = [...domain.signals];
15
+ if (domain.stores !== undefined)
16
+ input.stores = [...domain.stores];
17
+ registerCapabilities(input);
18
+ }
19
+ //# sourceMappingURL=domains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.js","sourceRoot":"","sources":["../../src/registry/domains.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,oBAAoB,EAA0B,MAAM,mBAAmB,CAAC;AASjF,MAAM,UAAU,qBAAqB,CAAC,MAAqB;IACzD,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,KAAK,CAAC,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACtE,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,KAAK,CAAC,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACtE,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACnE,oBAAoB,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The injected-emitter pattern (P5a): host-app components depend on a tiny structural interface
3
+ * instead of importing the SDK directly. The real emitter proxies to the connected `reticle`
4
+ * singleton; when Reticle isn't connected (or isn't loaded) every call is a SAFE NO-OP — so nothing
5
+ * breaks in production or before `reticle.connect()`, and `@reticlehq/browser` stays out of the prod bundle.
6
+ */
7
+ /** Structural emitter the host app's components depend on. */
8
+ export interface ReticleEmitter {
9
+ signal(name: string, data?: Record<string, unknown>): void;
10
+ state(name: string, value: unknown): void;
11
+ }
12
+ /** The subset of the reticle singleton an emitter proxies to (lets tests inject a fake). */
13
+ export interface EmitterTarget {
14
+ signal(name: string, data?: Record<string, unknown>): void;
15
+ state(name: string, value: unknown): void;
16
+ /** Discriminator the emitter reads per call to decide forward-vs-no-op. */
17
+ readonly connected: boolean;
18
+ }
19
+ export interface CreateReticleEmitterOptions {
20
+ /** Override the proxy target (tests / advanced embedding). Defaults to the reticle singleton. */
21
+ target?: EmitterTarget;
22
+ }
23
+ /**
24
+ * Create an emitter. Reads `target.connected` on EVERY call (not at creation) so an emitter
25
+ * made at module load — before `reticle.connect()` — starts working the moment Reticle connects.
26
+ */
27
+ export declare function createReticleEmitter(options?: CreateReticleEmitterOptions): ReticleEmitter;
28
+ //# sourceMappingURL=emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/registry/emitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3D,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3C;AAED,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3D,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,2BAA2B;IAC1C,iGAAiG;IACjG,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,2BAAgC,GAAG,cAAc,CAY9F"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * The injected-emitter pattern (P5a): host-app components depend on a tiny structural interface
3
+ * instead of importing the SDK directly. The real emitter proxies to the connected `reticle`
4
+ * singleton; when Reticle isn't connected (or isn't loaded) every call is a SAFE NO-OP — so nothing
5
+ * breaks in production or before `reticle.connect()`, and `@reticlehq/browser` stays out of the prod bundle.
6
+ */
7
+ import { reticle } from '../index.js';
8
+ /**
9
+ * Create an emitter. Reads `target.connected` on EVERY call (not at creation) so an emitter
10
+ * made at module load — before `reticle.connect()` — starts working the moment Reticle connects.
11
+ */
12
+ export function createReticleEmitter(options = {}) {
13
+ const target = options.target ?? reticle;
14
+ return {
15
+ signal(name, data = {}) {
16
+ if (!target.connected)
17
+ return;
18
+ target.signal(name, data);
19
+ },
20
+ state(name, value) {
21
+ if (!target.connected)
22
+ return;
23
+ target.state(name, value);
24
+ },
25
+ };
26
+ }
27
+ //# sourceMappingURL=emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/registry/emitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAqBtC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAuC,EAAE;IAC5E,MAAM,MAAM,GAAkB,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC;IACxD,OAAO;QACL,MAAM,CAAC,IAAY,EAAE,OAAgC,EAAE;YACrD,IAAI,CAAC,MAAM,CAAC,SAAS;gBAAE,OAAO;YAC9B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,KAAK,CAAC,IAAY,EAAE,KAAc;YAChC,IAAI,CAAC,MAAM,CAAC,SAAS;gBAAE,OAAO;YAC9B,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ /** Store registry — lets the agent pull live framework/store state on demand. */
2
+ export type StoreGetter = () => unknown;
3
+ /** App calls this once per store: registerStore('workspace', () => useWorkspace.getState()). */
4
+ export declare function registerStore(name: string, getter: StoreGetter): void;
5
+ export declare function unregisterStore(name: string): void;
6
+ export declare function storeNames(): string[];
7
+ /** Read one store (by name) or all of them. Each getter is isolated: a throw becomes an error string. */
8
+ export declare function readStores(only?: string): Record<string, unknown>;
9
+ //# sourceMappingURL=stores.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../../src/registry/stores.ts"],"names":[],"mappings":"AAEA,iFAAiF;AACjF,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC;AAMxC,gGAAgG;AAChG,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAErE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,UAAU,IAAI,MAAM,EAAE,CAErC;AAED,yGAAyG;AACzG,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWjE"}
@@ -0,0 +1,30 @@
1
+ import { sanitizeForTransport } from '../security/serialization.js';
2
+ // Persist on a global so registrations survive HMR re-evaluation (see adapters.ts / feedback #7).
3
+ const globalStore = globalThis;
4
+ const stores = (globalStore.__reticleStores ??= new Map());
5
+ /** App calls this once per store: registerStore('workspace', () => useWorkspace.getState()). */
6
+ export function registerStore(name, getter) {
7
+ stores.set(name, getter);
8
+ }
9
+ export function unregisterStore(name) {
10
+ stores.delete(name);
11
+ }
12
+ export function storeNames() {
13
+ return [...stores.keys()];
14
+ }
15
+ /** Read one store (by name) or all of them. Each getter is isolated: a throw becomes an error string. */
16
+ export function readStores(only) {
17
+ const out = {};
18
+ for (const [name, getter] of stores) {
19
+ if (only !== undefined && name !== only)
20
+ continue;
21
+ try {
22
+ out[name] = sanitizeForTransport(getter());
23
+ }
24
+ catch (error) {
25
+ out[name] = { __error: error instanceof Error ? error.message : String(error) };
26
+ }
27
+ }
28
+ return out;
29
+ }
30
+ //# sourceMappingURL=stores.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stores.js","sourceRoot":"","sources":["../../src/registry/stores.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAKpE,kGAAkG;AAClG,MAAM,WAAW,GAAG,UAAuE,CAAC;AAC5F,MAAM,MAAM,GAA6B,CAAC,WAAW,CAAC,eAAe,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AAErF,gGAAgG;AAChG,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAAmB;IAC7D,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACpC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;YAAE,SAAS;QAClD,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAClF,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { PresenterMode } from '@reticlehq/core';
2
+ /** Coerce an unknown arg to a string, falling back to `fallback` (default empty) when it isn't one. */
3
+ export declare function str(value: unknown, fallback?: string): string;
4
+ /** A short human label for a ref ("button \"Save\"") for the presenter HUD. */
5
+ export declare function refLabel(refId: string): string;
6
+ /**
7
+ * Classify a browser command into the presenter intent the human watcher sees. Exhaustive
8
+ * over the ReticleCommand names that actually reach the browser. CLOCK/NARRATE are control/meta
9
+ * (neither a page read nor an act) -> IDLE so they don't paint a misleading chip. NARRATE never
10
+ * reaches #presentBefore anyway (it returns early in #handleCommand) and must not clear the mode.
11
+ */
12
+ export declare function modeForCommand(commandName: string): PresenterMode;
13
+ /**
14
+ * Human-legible status for a read command — now WITH the target (which testid/value/ref/store), so
15
+ * the watcher sees "Finding [testid=row-3700]" instead of a meaningless repeating "Finding an
16
+ * element". Falls back to the bare verb when no target is in the args.
17
+ */
18
+ export declare function presentStatus(commandName: string, args?: Record<string, unknown>): string;
19
+ //# sourceMappingURL=reticle-presenter-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reticle-presenter-helpers.d.ts","sourceRoot":"","sources":["../src/reticle-presenter-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhE,uGAAuG;AACvG,wBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAK,GAAG,MAAM,CAEzD;AAED,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK9C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAgBjE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,MAAM,CAyB7F"}
@@ -0,0 +1,81 @@
1
+ import { ReticleCommand, PresenterMode } from '@reticlehq/core';
2
+ import { refs } from './dom/refs.js';
3
+ import { describe } from './dom/a11y.js';
4
+ /** Coerce an unknown arg to a string, falling back to `fallback` (default empty) when it isn't one. */
5
+ export function str(value, fallback = '') {
6
+ return typeof value === 'string' ? value : fallback;
7
+ }
8
+ /** A short human label for a ref ("button \"Save\"") for the presenter HUD. */
9
+ export function refLabel(refId) {
10
+ const el = refs.resolve(refId);
11
+ if (!(el instanceof Element))
12
+ return refId;
13
+ const d = describe(el);
14
+ return d.name.length > 0 ? `${d.role} "${d.name}"` : `${d.role} (${refId})`;
15
+ }
16
+ /**
17
+ * Classify a browser command into the presenter intent the human watcher sees. Exhaustive
18
+ * over the ReticleCommand names that actually reach the browser. CLOCK/NARRATE are control/meta
19
+ * (neither a page read nor an act) -> IDLE so they don't paint a misleading chip. NARRATE never
20
+ * reaches #presentBefore anyway (it returns early in #handleCommand) and must not clear the mode.
21
+ */
22
+ export function modeForCommand(commandName) {
23
+ switch (commandName) {
24
+ case ReticleCommand.ACT:
25
+ case ReticleCommand.ACT_SEQUENCE:
26
+ return PresenterMode.ACTING;
27
+ case ReticleCommand.SNAPSHOT:
28
+ case ReticleCommand.QUERY:
29
+ case ReticleCommand.MATCH:
30
+ case ReticleCommand.INSPECT:
31
+ case ReticleCommand.ANIMATIONS:
32
+ case ReticleCommand.STATE_READ:
33
+ case ReticleCommand.CAPABILITIES:
34
+ return PresenterMode.READING;
35
+ default:
36
+ return PresenterMode.IDLE;
37
+ }
38
+ }
39
+ /**
40
+ * Human-legible status for a read command — now WITH the target (which testid/value/ref/store), so
41
+ * the watcher sees "Finding [testid=row-3700]" instead of a meaningless repeating "Finding an
42
+ * element". Falls back to the bare verb when no target is in the args.
43
+ */
44
+ export function presentStatus(commandName, args = {}) {
45
+ switch (commandName) {
46
+ case ReticleCommand.SNAPSHOT:
47
+ return 'Looking at the page';
48
+ case ReticleCommand.QUERY:
49
+ case ReticleCommand.MATCH: {
50
+ const q = commandName === ReticleCommand.MATCH ? (args['query'] ?? {}) : args;
51
+ const target = queryTarget(q);
52
+ return target !== undefined ? `Finding ${target}` : 'Finding an element';
53
+ }
54
+ case ReticleCommand.INSPECT: {
55
+ const ref = str(args['ref']);
56
+ return ref !== undefined ? `Inspecting ${refLabel(ref)}` : 'Inspecting an element';
57
+ }
58
+ case ReticleCommand.ANIMATIONS:
59
+ return 'Reading animations';
60
+ case ReticleCommand.STATE_READ: {
61
+ const store = str(args['store']);
62
+ return store !== undefined ? `Reading state: ${store}` : 'Reading state';
63
+ }
64
+ case ReticleCommand.CAPABILITIES:
65
+ return 'Reading capabilities';
66
+ default:
67
+ return commandName;
68
+ }
69
+ }
70
+ /** Compact "what we're looking for" from a query's args (testid/value/name/role/text/label). */
71
+ function queryTarget(q) {
72
+ const testid = str(q['testid']) ?? (str(q['by']) === 'testid' ? str(q['value']) : undefined);
73
+ if (testid !== undefined)
74
+ return `[testid=${testid}]`;
75
+ const name = str(q['name']);
76
+ const value = str(q['value']) ?? str(q['text']) ?? str(q['label']) ?? str(q['role']);
77
+ if (value !== undefined)
78
+ return name !== undefined ? `"${value}" (${name})` : `"${value}"`;
79
+ return name !== undefined ? `"${name}"` : undefined;
80
+ }
81
+ //# sourceMappingURL=reticle-presenter-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reticle-presenter-helpers.js","sourceRoot":"","sources":["../src/reticle-presenter-helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ import { RETICLE_URL_PARAM } from '@reticlehq/core';
2
+ import { type CapabilitiesInput } from './registry/capabilities.js';
3
+ export interface ReticleConnectOptions {
4
+ /** WS endpoint of the local bridge. Defaults to ws://localhost:<port><path>. */
5
+ url?: string;
6
+ /** Human-friendly session label so the agent can target the right tab. */
7
+ session?: string;
8
+ /**
9
+ * Stable project identity, normally stamped by the build plugin (e.g. "acme-web-9f3c1d"). Lets the
10
+ * agent scope to the right app even when its dev server boots on an unexpected port. Optional.
11
+ */
12
+ projectId?: string;
13
+ /** Browser/bridge pairing token. Required when either endpoint is non-localhost. */
14
+ token?: string;
15
+ /** Explicitly allow Reticle on a non-localhost page or bridge. Requires token. */
16
+ allowNonLocalhost?: boolean;
17
+ /**
18
+ * Escape hatch for the production backstop. Reticle is dev-only and refuses to connect when the
19
+ * build reports NODE_ENV=production (an SSR healthcheck or a prod bundle opened locally would
20
+ * otherwise activate). The real fix is to gate the import behind `import.meta.env.DEV` so it's
21
+ * tree-shaken out; this flag only exists for the rare intentional prod diagnostic.
22
+ */
23
+ allowInProduction?: boolean;
24
+ /** Show a small in-page status chip (connection + event count). */
25
+ overlay?: boolean;
26
+ /** Presenter mode: glow border, animated cursor, click/hover effects, narration HUD. */
27
+ present?: boolean;
28
+ /** Per-action pacing (ms) in presenter mode so a human can follow. Default 450. */
29
+ pace?: number;
30
+ /** Min ms each narration line stays visible before the next replaces it (presenter). Default 3000. */
31
+ narrationDwellMs?: number;
32
+ /**
33
+ * Border behavior in presenter mode: 'session' (default) persists the border for the whole
34
+ * session; 'busy' restores the fade-after-idle behavior.
35
+ */
36
+ border?: 'session' | 'busy';
37
+ /** Max accumulated activity-log rows before the oldest are pruned (presenter). Default 50. */
38
+ logMax?: number;
39
+ /**
40
+ * Mount the floating human-recorder toolbar (Record/Stop/Annotate).
41
+ * Default off — purely additive, dev-only.
42
+ */
43
+ recorder?: boolean;
44
+ /**
45
+ * Mount the "Flag a bug" annotator: the human clicks an element that looks wrong, types what's
46
+ * wrong, and Reticle emits a HUMAN_MARK the agent drains via reticle_review. Defaults to ON with the
47
+ * presenter (it's the human's side of the look→act→assert loop); pass `annotate: false` to suppress.
48
+ */
49
+ annotate?: boolean;
50
+ /** Live-control: overridable ended-border fade delay (native timer). Default 4000. */
51
+ endedFadeMs?: number;
52
+ /** Session auto-end after this much agent idle (presenter). Default 5min; agent-tunable via reticle_session. */
53
+ idleEndMs?: number;
54
+ }
55
+ /**
56
+ * Runtime backstop for the dev-only SDK: block connecting when the build reports production, unless
57
+ * explicitly overridden. Pure so it's testable; connect() reads NODE_ENV safely (process may be absent
58
+ * in a raw browser). This is defense-in-depth — the primary guard is the consumer gating the import
59
+ * behind `import.meta.env.DEV` so the SDK is dead-code-eliminated from prod bundles entirely.
60
+ */
61
+ export declare function shouldBlockProduction(nodeEnv: string | undefined, allowInProduction: boolean): boolean;
62
+ export declare function connectionPolicy(pageHostname: string, bridgeUrl: string, allowNonLocalhost: boolean, token: string | undefined): {
63
+ allowed: boolean;
64
+ reason?: string;
65
+ };
66
+ /**
67
+ * Resolve the session label. An absent label or the `auto` sentinel yields a fresh per-tab id (via
68
+ * the injected generator) so multi-tab / new-tab routes never collide; any other label is used
69
+ * verbatim so tabs can intentionally share a session. `gen` is injected to keep this clock-free.
70
+ */
71
+ export declare function resolveSessionLabel(option: string | undefined, gen: () => string): string;
72
+ export { RETICLE_URL_PARAM };
73
+ /**
74
+ * Extract Reticle identity overrides from a `location.search` string. Pure (takes the string, not the
75
+ * window) so it's testable without a DOM. Explicit connect() options still win over these.
76
+ */
77
+ export declare function reticleParamsFromSearch(search: string): {
78
+ session?: string;
79
+ projectId?: string;
80
+ };
81
+ /**
82
+ * Resolve the session + project identity for a connection: an explicit, non-`auto` option wins;
83
+ * otherwise a launcher-stamped URL param is used; otherwise undefined (caller generates a per-tab id).
84
+ * Crucially `auto` is treated like "unset" so an app that passes the auto sentinel still lets a pooled
85
+ * launcher correlate the lease via __reticle_session. Pure for testability.
86
+ */
87
+ export declare function resolveConnectIdentity(options: {
88
+ session?: string;
89
+ projectId?: string;
90
+ }, search: string): {
91
+ session: string | undefined;
92
+ projectId: string | undefined;
93
+ };
94
+ /**
95
+ * The browser-side orchestrator. Wires observers -> events -> bridge, and bridge
96
+ * commands -> handlers. Embedded in the host app (dev only).
97
+ */
98
+ export declare class Reticle {
99
+ #private;
100
+ connect(options?: ReticleConnectOptions): void;
101
+ /** Whether the in-page SDK is connected to the bridge (read by createReticleEmitter, P5a). */
102
+ get connected(): boolean;
103
+ /** Surface an arbitrary app-domain observation the DOM can't express (plan/03 §7). */
104
+ signal(name: string, data?: Record<string, unknown>): void;
105
+ /** Report a framework/store state change the agent can observe and assert on. */
106
+ state(name: string, value: unknown): void;
107
+ /** Advertise the app's testable surface so the agent learns it without reading source. */
108
+ describe(input: CapabilitiesInput): void;
109
+ /** Live-control: end the session programmatically from the host app (drives the panel to ended). */
110
+ endSession(): void;
111
+ disconnect(): void;
112
+ }
113
+ //# sourceMappingURL=reticle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reticle.d.ts","sourceRoot":"","sources":["../src/reticle.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,iBAAiB,EAWlB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,4BAA4B,CAAC;AAuBpC,MAAM,WAAW,qBAAqB;IACpC,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sGAAsG;IACtG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC5B,8FAA8F;IAC9F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gHAAgH;IAChH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,iBAAiB,EAAE,OAAO,GACzB,OAAO,CAET;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,OAAO,EAC1B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAiCvC;AAMD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,MAAM,GAAG,MAAM,CAEzF;AAGD,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAQhG;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EACjD,MAAM,EAAE,MAAM,GACb;IAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAShE;AAED;;;GAGG;AACH,qBAAa,OAAO;;IAiBlB,OAAO,CAAC,OAAO,GAAE,qBAA0B,GAAG,IAAI;IAoIlD,8FAA8F;IAC9F,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,sFAAsF;IACtF,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IAI9D,iFAAiF;IACjF,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAIzC,0FAA0F;IAC1F,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAIxC,oGAAoG;IACpG,UAAU,IAAI,IAAI;IAIlB,UAAU,IAAI,IAAI;CAsHnB"}