@launchsecure/launch-kit 0.0.25 → 0.0.26

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 (126) hide show
  1. package/README.md +50 -0
  2. package/dist/beacon/beacon.mjs +1016 -0
  3. package/dist/beacon/beacon.mjs.map +1 -0
  4. package/dist/beacon/beacon.umd.js +87 -0
  5. package/dist/beacon/beacon.umd.js.map +1 -0
  6. package/dist/beacon/index-DAIDnjfR.mjs +513 -0
  7. package/dist/beacon/index-DAIDnjfR.mjs.map +1 -0
  8. package/dist/beacon/types/capture/element.d.ts +3 -0
  9. package/dist/beacon/types/capture/element.d.ts.map +1 -0
  10. package/dist/beacon/types/capture/framework.d.ts +3 -0
  11. package/dist/beacon/types/capture/framework.d.ts.map +1 -0
  12. package/dist/beacon/types/capture/metadata.d.ts +3 -0
  13. package/dist/beacon/types/capture/metadata.d.ts.map +1 -0
  14. package/dist/beacon/types/capture/overlay.d.ts +7 -0
  15. package/dist/beacon/types/capture/overlay.d.ts.map +1 -0
  16. package/dist/beacon/types/capture/picker.d.ts +12 -0
  17. package/dist/beacon/types/capture/picker.d.ts.map +1 -0
  18. package/dist/beacon/types/capture/screenshot.d.ts +7 -0
  19. package/dist/beacon/types/capture/screenshot.d.ts.map +1 -0
  20. package/dist/beacon/types/capture/selector.d.ts +2 -0
  21. package/dist/beacon/types/capture/selector.d.ts.map +1 -0
  22. package/dist/beacon/types/element.d.ts +50 -0
  23. package/dist/beacon/types/element.d.ts.map +1 -0
  24. package/dist/beacon/types/index.d.ts +4 -0
  25. package/dist/beacon/types/index.d.ts.map +1 -0
  26. package/dist/beacon/types/transport/submit.d.ts +3 -0
  27. package/dist/beacon/types/transport/submit.d.ts.map +1 -0
  28. package/dist/beacon/types/types.d.ts +88 -0
  29. package/dist/beacon/types/types.d.ts.map +1 -0
  30. package/dist/beacon/types/ui/button.d.ts +2 -0
  31. package/dist/beacon/types/ui/button.d.ts.map +1 -0
  32. package/dist/beacon/types/ui/drawer.d.ts +31 -0
  33. package/dist/beacon/types/ui/drawer.d.ts.map +1 -0
  34. package/dist/beacon/types/ui/icons.d.ts +9 -0
  35. package/dist/beacon/types/ui/icons.d.ts.map +1 -0
  36. package/dist/beacon/types/ui/pick-mode-overlay.d.ts +25 -0
  37. package/dist/beacon/types/ui/pick-mode-overlay.d.ts.map +1 -0
  38. package/dist/beacon/types/ui/pin-popover.d.ts +14 -0
  39. package/dist/beacon/types/ui/pin-popover.d.ts.map +1 -0
  40. package/dist/chart-client/assets/{index-C8ANseEa.js → index-Bk1hawjD.js} +63 -58
  41. package/dist/chart-client/assets/index-DpaGa3bY.css +1 -0
  42. package/dist/chart-client/index.html +2 -2
  43. package/dist/client/assets/index-Bfel4OQ5.css +32 -0
  44. package/dist/client/assets/{index-Ds9UP_cj.js → index-eC-WuUWB.js} +58 -58
  45. package/dist/client/index.html +2 -2
  46. package/dist/council-client/assets/{index-Dc41S-R2.js → index-Cs_MVXHf.js} +14 -14
  47. package/dist/council-client/assets/index-P5kMsT5a.css +1 -0
  48. package/dist/council-client/index.html +2 -2
  49. package/dist/deck-client/assets/{_baseUniq-2gclQXo7.js → _baseUniq-C2xT_eYu.js} +1 -1
  50. package/dist/deck-client/assets/{arc-DcMY5Wm0.js → arc-CmVL9pGd.js} +1 -1
  51. package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-B8iirmmJ.js → architectureDiagram-Q4EWVU46-BSFgdjve.js} +1 -1
  52. package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-B4JBLjmJ.js → blockDiagram-DXYQGD6D-DuLzscvP.js} +1 -1
  53. package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-CojrJAk8.js → c4Diagram-AHTNJAMY-CfCJB8eY.js} +1 -1
  54. package/dist/deck-client/assets/channel-B4aNO8ZB.js +1 -0
  55. package/dist/deck-client/assets/{chunk-4BX2VUAB-Bmb_BMDo.js → chunk-4BX2VUAB-DxmLYTWZ.js} +1 -1
  56. package/dist/deck-client/assets/{chunk-4TB4RGXK-CumBy8qe.js → chunk-4TB4RGXK-CCnf7GFE.js} +1 -1
  57. package/dist/deck-client/assets/{chunk-55IACEB6-Ka8Hb1wD.js → chunk-55IACEB6-Db9DApcj.js} +1 -1
  58. package/dist/deck-client/assets/{chunk-EDXVE4YY-B3sIPiQo.js → chunk-EDXVE4YY-DmYDq8ZI.js} +1 -1
  59. package/dist/deck-client/assets/{chunk-FMBD7UC4-C1tYkaqu.js → chunk-FMBD7UC4-BGhUlF20.js} +1 -1
  60. package/dist/deck-client/assets/{chunk-OYMX7WX6-D7Wacbky.js → chunk-OYMX7WX6-CpEnicQZ.js} +1 -1
  61. package/dist/deck-client/assets/{chunk-QZHKN3VN-ChXI0vO3.js → chunk-QZHKN3VN-Doa7LKwf.js} +1 -1
  62. package/dist/deck-client/assets/{chunk-YZCP3GAM-BXhiqf8u.js → chunk-YZCP3GAM-CpkIlH6V.js} +1 -1
  63. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-BHTI0yWz.js +1 -0
  64. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-BHTI0yWz.js +1 -0
  65. package/dist/deck-client/assets/clone-HduFm7qU.js +1 -0
  66. package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-Bqp3p68D.js → cose-bilkent-S5V4N54A-Bkh8Bfcb.js} +1 -1
  67. package/dist/deck-client/assets/{dagre-KV5264BT-BS-rtyhZ.js → dagre-KV5264BT-Bp0XpTgH.js} +1 -1
  68. package/dist/deck-client/assets/{diagram-5BDNPKRD-BIrj9YGI.js → diagram-5BDNPKRD-ZHiyGYPQ.js} +1 -1
  69. package/dist/deck-client/assets/{diagram-G4DWMVQ6-noHWPIg4.js → diagram-G4DWMVQ6-BW-Q8_H5.js} +1 -1
  70. package/dist/deck-client/assets/{diagram-MMDJMWI5-C2qHxvqV.js → diagram-MMDJMWI5-6I3LTafu.js} +1 -1
  71. package/dist/deck-client/assets/{diagram-TYMM5635-BytnGQr-.js → diagram-TYMM5635-CyM5YK28.js} +1 -1
  72. package/dist/deck-client/assets/{erDiagram-SMLLAGMA-BfK5m2YQ.js → erDiagram-SMLLAGMA-CjNxVJHk.js} +1 -1
  73. package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-Cq925G1Z.js → flowDiagram-DWJPFMVM-BDQHuAJR.js} +1 -1
  74. package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-DhhHPAmj.js → ganttDiagram-T4ZO3ILL-B7MnkpbP.js} +1 -1
  75. package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-B3Lc0h9q.js → gitGraphDiagram-UUTBAWPF-C9dZAcYD.js} +1 -1
  76. package/dist/deck-client/assets/{graph-RTawgVWm.js → graph-CjdBnzUy.js} +1 -1
  77. package/dist/deck-client/assets/{index-BfIfJXmS.js → index-DeIVPW63.js} +68 -68
  78. package/dist/deck-client/assets/index-LKZDAS9S.css +1 -0
  79. package/dist/deck-client/assets/{infoDiagram-42DDH7IO-BlR584kX.js → infoDiagram-42DDH7IO-C7d3iRC3.js} +1 -1
  80. package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-DygKoNGY.js → ishikawaDiagram-UXIWVN3A-BcYGKj09.js} +1 -1
  81. package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-BnaiYp9N.js → journeyDiagram-VCZTEJTY-DqFlRrOL.js} +1 -1
  82. package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-BQBUBzJC.js → kanban-definition-6JOO6SKY-BJhPp1NR.js} +1 -1
  83. package/dist/deck-client/assets/{layout-DeZ8HI1T.js → layout-DIeS6GvK.js} +1 -1
  84. package/dist/deck-client/assets/{linear-C6roLi_9.js → linear-He_yJy5H.js} +1 -1
  85. package/dist/deck-client/assets/{min-CbUksbuI.js → min-DQ6Kx06t.js} +1 -1
  86. package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-iNxV62yN.js → mindmap-definition-QFDTVHPH-sQ62L8T2.js} +1 -1
  87. package/dist/deck-client/assets/{pieDiagram-DEJITSTG-DHVA0jaG.js → pieDiagram-DEJITSTG-BqCWmU2K.js} +1 -1
  88. package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-DBeKKLUQ.js → quadrantDiagram-34T5L4WZ-rQ1TJOoe.js} +1 -1
  89. package/dist/deck-client/assets/{requirementDiagram-MS252O5E-CBwITx7p.js → requirementDiagram-MS252O5E-BO2MPBOM.js} +1 -1
  90. package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-BtE-1YTU.js → sankeyDiagram-XADWPNL6-BgsHEVex.js} +1 -1
  91. package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-DN96yPP2.js → sequenceDiagram-FGHM5R23-B3j1yMLU.js} +1 -1
  92. package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-VUkKC2uJ.js → stateDiagram-FHFEXIEX-C8jFlZou.js} +1 -1
  93. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-BoqepHW0.js +1 -0
  94. package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-oUeZhRns.js → timeline-definition-GMOUNBTQ-tM-qo4Zk.js} +1 -1
  95. package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-D87fK90n.js → vennDiagram-DHZGUBPP-B0-6kOEu.js} +1 -1
  96. package/dist/deck-client/assets/wardley-RL74JXVD-HpBk07P-.js +162 -0
  97. package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-Ca_i0QRA.js → wardleyDiagram-NUSXRM2D-BkA1NLDE.js} +1 -1
  98. package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-CUOJVIvq.js → xychartDiagram-5P7HB3ND-CEKGSuI-.js} +1 -1
  99. package/dist/deck-client/index.html +2 -2
  100. package/dist/server/chart-serve.js +990 -116
  101. package/dist/server/cli.js +28413 -6982
  102. package/dist/server/council-entry.js +0 -0
  103. package/dist/server/deck-mcp-entry.js +332 -3
  104. package/dist/server/deck-serve.js +288 -0
  105. package/dist/server/fb-wizard.js +0 -0
  106. package/dist/server/graph/queries/classify.scm +8 -0
  107. package/dist/server/graph/queries/exports.scm +7 -0
  108. package/dist/server/graph-mcp-entry.js +1639 -197
  109. package/dist/server/recall-entry.js +1112 -0
  110. package/package.json +47 -21
  111. package/dist/chart-client/assets/index--120d9P9.css +0 -1
  112. package/dist/client/assets/index-Bf8zdL3x.css +0 -32
  113. package/dist/council-client/assets/index-CofZh7pS.css +0 -1
  114. package/dist/deck-client/assets/channel-ERh5jKXV.js +0 -1
  115. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-CMi1Gaev.js +0 -1
  116. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-CMi1Gaev.js +0 -1
  117. package/dist/deck-client/assets/clone-DfWhlD4X.js +0 -1
  118. package/dist/deck-client/assets/index-765AIQ9z.css +0 -1
  119. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-CA0IjulK.js +0 -1
  120. package/dist/deck-client/assets/wardley-RL74JXVD-DYbYcpDp.js +0 -162
  121. package/dist/server/deck-server/deck-mcp-entry.js +0 -1789
  122. package/dist/server/deck-server/deck-serve.js +0 -1275
  123. package/dist/server/server/chart-serve.js +0 -4643
  124. package/dist/server/server/cli.js +0 -13360
  125. package/dist/server/server/fb-wizard.js +0 -136
  126. package/dist/server/server/graph-mcp-entry.js +0 -6776
@@ -0,0 +1 @@
1
+ {"version":3,"file":"beacon.mjs","sources":["../../src/beacon-client/ui/icons.ts","../../src/beacon-client/ui/button.ts","../../src/beacon-client/ui/drawer.ts","../../src/beacon-client/ui/pin-popover.ts","../../src/beacon-client/ui/pick-mode-overlay.ts","../../src/beacon-client/capture/picker.ts","../../src/beacon-client/capture/selector.ts","../../src/beacon-client/capture/framework.ts","../../src/beacon-client/capture/element.ts","../../src/beacon-client/capture/metadata.ts","../../src/beacon-client/capture/screenshot.ts","../../src/beacon-client/capture/overlay.ts","../../src/beacon-client/transport/submit.ts","../../src/beacon-client/element.ts","../../src/beacon-client/index.ts"],"sourcesContent":["// Inline SVGs to avoid an icon library dep. Returns innerHTML strings (caller assigns).\n\nexport const ICONS = {\n feedback: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>`,\n pin: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 17v5\"/><path d=\"M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z\"/></svg>`,\n close: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>`,\n trash: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 6h18\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\"/><path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>`,\n send: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m22 2-7 20-4-9-9-4Z\"/><path d=\"M22 2 11 13\"/></svg>`,\n check: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polyline points=\"20 6 9 17 4 12\"/></svg>`,\n} as const;\n","// Default floating trigger button. Rendered into the Shadow DOM unless a slot=\"trigger\"\n// child is provided by the consumer.\n\nimport { ICONS } from './icons';\n\nexport function createTriggerButton(label = 'Feedback'): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'beacon-default-trigger';\n btn.setAttribute('aria-label', label);\n btn.innerHTML = `${ICONS.feedback}<span>${label}</span>`;\n return btn;\n}\n","// The form drawer: description textarea + severity picker + pin list + actions.\n// Built imperatively (no JSX). The element class is the controller; this module\n// handles markup + small DOM helpers.\n\nimport { ICONS } from './icons';\nimport type { Pin, Severity } from '../types';\n\nconst DEFAULT_SEVERITIES: Severity[] = ['bug', 'idea', 'ux', 'a11y'];\n\nexport interface DrawerCallbacks {\n onClose: () => void;\n onAnnotate: () => void;\n onSubmit: () => void;\n onPinNoteChange: (pinNumber: number, note: string) => void;\n onPinDelete: (pinNumber: number) => void;\n onDescriptionChange: (value: string) => void;\n onSeverityChange: (sev: Severity) => void;\n}\n\nexport class DrawerView {\n readonly root: HTMLDivElement;\n readonly bodyEl: HTMLDivElement;\n private severities: Severity[];\n private callbacks: DrawerCallbacks;\n private state = {\n description: '',\n severity: 'bug' as Severity,\n pins: [] as Pin[],\n annotatedScreenshot: undefined as string | undefined,\n submitting: false,\n status: '' as string,\n statusKind: '' as '' | 'error' | 'success',\n };\n\n constructor(severities: Severity[], callbacks: DrawerCallbacks) {\n this.severities = severities.length > 0 ? severities : DEFAULT_SEVERITIES;\n this.callbacks = callbacks;\n this.root = document.createElement('div');\n this.root.className = 'beacon-drawer';\n this.root.innerHTML = `\n <div class=\"beacon-drawer-header\">\n <div class=\"beacon-drawer-title\">Send feedback</div>\n <button type=\"button\" class=\"beacon-icon-btn\" data-action=\"close\" aria-label=\"Close\">${ICONS.close}</button>\n </div>\n <div class=\"beacon-drawer-body\"></div>\n `;\n this.bodyEl = this.root.querySelector('.beacon-drawer-body') as HTMLDivElement;\n this.root.querySelector('[data-action=\"close\"]')!.addEventListener('click', () => this.callbacks.onClose());\n this.render();\n }\n\n open() {\n this.root.classList.remove('minimized');\n this.root.classList.add('open');\n }\n\n close() {\n this.root.classList.remove('open');\n }\n\n minimize() {\n this.root.classList.add('minimized');\n this.root.classList.remove('open');\n }\n\n setPins(pins: Pin[], annotatedScreenshot?: string) {\n this.state.pins = pins;\n if (annotatedScreenshot !== undefined) this.state.annotatedScreenshot = annotatedScreenshot;\n this.render();\n }\n\n getAnnotatedScreenshot(): string | undefined {\n return this.state.annotatedScreenshot;\n }\n\n setAnnotatedScreenshot(value: string | undefined) {\n this.state.annotatedScreenshot = value;\n this.render();\n }\n\n setSubmitting(submitting: boolean) {\n this.state.submitting = submitting;\n this.render();\n }\n\n setStatus(status: string, kind: '' | 'error' | 'success' = '') {\n this.state.status = status;\n this.state.statusKind = kind;\n this.render();\n }\n\n reset() {\n this.state = {\n description: '',\n severity: 'bug',\n pins: [],\n annotatedScreenshot: undefined,\n submitting: false,\n status: '',\n statusKind: '',\n };\n this.render();\n }\n\n getDescription() { return this.state.description; }\n getSeverity() { return this.state.severity; }\n\n private render() {\n const canSubmit = this.state.description.trim().length > 0 && !this.state.submitting;\n\n this.bodyEl.innerHTML = `\n <div class=\"beacon-field\">\n <label class=\"beacon-label\" for=\"beacon-desc\">What's the issue?</label>\n <textarea id=\"beacon-desc\" class=\"beacon-textarea\" placeholder=\"Describe what you saw, what you expected, anything that helps reproduce…\">${escapeHtml(this.state.description)}</textarea>\n </div>\n\n <div class=\"beacon-field\">\n <span class=\"beacon-label\">Severity</span>\n <div class=\"beacon-severity\" role=\"radiogroup\">\n ${this.severities.map((sev) => `\n <label class=\"beacon-severity-opt ${sev === this.state.severity ? 'selected' : ''}\" data-sev=\"${sev}\">\n <input type=\"radio\" name=\"beacon-severity\" value=\"${sev}\" ${sev === this.state.severity ? 'checked' : ''}>\n ${sev}\n </label>\n `).join('')}\n </div>\n </div>\n\n ${this.state.annotatedScreenshot ? `\n <div class=\"beacon-field\">\n <span class=\"beacon-label\">Annotated screenshot</span>\n <img src=\"${this.state.annotatedScreenshot}\" class=\"beacon-thumb\" alt=\"Annotated screenshot preview\">\n </div>\n ` : ''}\n\n ${this.state.pins.length > 0 ? `\n <div class=\"beacon-field\">\n <span class=\"beacon-label\">Pins (${this.state.pins.length})</span>\n <div class=\"beacon-pin-list\">\n ${this.state.pins.map((p) => `\n <div class=\"beacon-pin-item\" data-pin=\"${p.number}\">\n <span class=\"beacon-pin-num\">${p.number}</span>\n <div class=\"beacon-pin-meta\">\n <div class=\"beacon-pin-selector\" title=\"${escapeHtml(p.selector)}\">${escapeHtml(p.selector)}</div>\n <input type=\"text\" class=\"beacon-pin-note-input\" placeholder=\"Add a note (optional)\" value=\"${escapeHtml(p.note ?? '')}\">\n </div>\n <button type=\"button\" class=\"beacon-icon-btn\" data-pin-delete=\"${p.number}\" aria-label=\"Remove pin ${p.number}\">${ICONS.trash}</button>\n </div>\n `).join('')}\n </div>\n </div>\n ` : ''}\n\n <div class=\"beacon-actions\">\n <button type=\"button\" class=\"beacon-btn secondary\" data-action=\"annotate\" ${this.state.submitting ? 'disabled' : ''}>\n ${ICONS.pin} ${this.state.pins.length > 0 ? 'Add another pin' : 'Annotate elements'}\n </button>\n <span style=\"flex:1\"></span>\n <button type=\"button\" class=\"beacon-btn primary\" data-action=\"submit\" ${canSubmit ? '' : 'disabled'}>\n ${ICONS.send} ${this.state.submitting ? 'Sending…' : 'Send'}\n </button>\n </div>\n\n ${this.state.status ? `<div class=\"beacon-status ${this.state.statusKind}\">${escapeHtml(this.state.status)}</div>` : ''}\n `;\n\n // Wire events.\n const desc = this.bodyEl.querySelector('#beacon-desc') as HTMLTextAreaElement;\n desc.addEventListener('input', () => {\n this.state.description = desc.value;\n this.callbacks.onDescriptionChange(desc.value);\n // Re-render only the submit button's disabled state — full re-render kills focus, so skip it here.\n const submitBtn = this.bodyEl.querySelector('[data-action=\"submit\"]') as HTMLButtonElement | null;\n if (submitBtn) {\n submitBtn.disabled = !(desc.value.trim().length > 0) || this.state.submitting;\n }\n });\n\n this.bodyEl.querySelectorAll<HTMLInputElement>('input[name=\"beacon-severity\"]').forEach((input) => {\n input.addEventListener('change', () => {\n if (input.checked) {\n this.state.severity = input.value as Severity;\n this.callbacks.onSeverityChange(this.state.severity);\n this.render();\n }\n });\n });\n\n this.bodyEl.querySelector('[data-action=\"annotate\"]')?.addEventListener('click', () => this.callbacks.onAnnotate());\n this.bodyEl.querySelector('[data-action=\"submit\"]')?.addEventListener('click', () => this.callbacks.onSubmit());\n\n this.bodyEl.querySelectorAll<HTMLButtonElement>('[data-pin-delete]').forEach((btn) => {\n btn.addEventListener('click', () => {\n const num = Number(btn.getAttribute('data-pin-delete'));\n this.callbacks.onPinDelete(num);\n });\n });\n\n this.bodyEl.querySelectorAll<HTMLInputElement>('.beacon-pin-note-input').forEach((input) => {\n const item = input.closest('[data-pin]');\n const num = Number(item?.getAttribute('data-pin') ?? 0);\n input.addEventListener('input', () => this.callbacks.onPinNoteChange(num, input.value));\n });\n }\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n","// Small contextual popover that opens next to a picked element so the user can\n// optionally type a note. The cross icon discards this pin and lets the user keep\n// picking; Save attaches the (optional) note. Escape ends annotation entirely.\n\nimport { ICONS } from './icons';\n\nexport type PinPopoverCancel = 'pin' | 'all' | false;\n\nexport interface PinPopoverResult {\n note?: string;\n // 'pin' = discard this pin, keep picking. 'all' = end annotation. false = save.\n cancelled: PinPopoverCancel;\n}\n\nexport function showPinPopover(opts: {\n shadowRoot: ShadowRoot;\n anchor: { x: number; y: number }; // viewport coords\n pinNumber: number;\n}): Promise<PinPopoverResult> {\n return new Promise((resolve) => {\n const popover = document.createElement('div');\n // Mount on body (not shadow root) so we escape transformed-ancestor stacking\n // contexts. beacon-no-capture keeps it out of the screenshot. theme-auto follows\n // OS preference; if a future caller needs explicit theme, add an opts.theme.\n popover.className = 'beacon-pin-popover open beacon-no-capture beacon-theme-auto';\n popover.innerHTML = `\n <div class=\"beacon-pin-popover-header\">\n <div style=\"display:flex;align-items:center;gap:6px;font-weight:600;font-size:13px;\">\n <span class=\"beacon-pin-num\">${opts.pinNumber}</span>\n <span>Note for this pin</span>\n </div>\n <button type=\"button\" class=\"beacon-icon-btn\" data-action=\"cancel\" aria-label=\"Discard this pin\">${ICONS.close}</button>\n </div>\n <textarea class=\"beacon-textarea\" rows=\"2\" placeholder=\"Optional — describe what's wrong here…\" style=\"min-height:48px;\"></textarea>\n <div class=\"beacon-pin-popover-actions\">\n <button type=\"button\" class=\"beacon-btn primary\" data-action=\"save\">${ICONS.check} Save</button>\n </div>\n `;\n\n // Position below the picked point, clamped to viewport.\n const POPOVER_W = 240;\n const POPOVER_H = 160;\n const left = Math.min(Math.max(8, opts.anchor.x), window.innerWidth - POPOVER_W - 8);\n const top = Math.min(Math.max(8, opts.anchor.y + 12), window.innerHeight - POPOVER_H - 8);\n popover.style.left = `${left}px`;\n popover.style.top = `${top}px`;\n\n document.body.appendChild(popover);\n\n const textarea = popover.querySelector('textarea')!;\n textarea.focus();\n\n function close(result: PinPopoverResult) {\n document.removeEventListener('keydown', handleGlobalKey, true);\n popover.remove();\n resolve(result);\n }\n\n // Document-level Escape handler so it works regardless of focus location\n // (textarea, popover background, anywhere on the page). Escape ends the whole\n // annotation session — use the cross icon to drop just this pin.\n function handleGlobalKey(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n close({ cancelled: 'all' });\n }\n }\n document.addEventListener('keydown', handleGlobalKey, true);\n\n popover.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n const action = target.closest('[data-action]')?.getAttribute('data-action');\n if (action === 'cancel') close({ cancelled: 'pin' });\n if (action === 'save') {\n const note = textarea.value.trim();\n close({ ...(note ? { note } : {}), cancelled: false });\n }\n });\n\n // Cmd/Ctrl+Enter inside the textarea = save (Enter alone inserts newlines).\n textarea.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n const note = textarea.value.trim();\n close({ ...(note ? { note } : {}), cancelled: false });\n }\n });\n });\n}\n","// Visual overlay shown during pin-mode. Three layers:\n// 1. Subtle dotted viewport border + soft inset glow → \"you're in pin mode\"\n// 2. Top-center hint pill → \"press Esc to finish\"\n// 3. Numbered markers → over each already-pinned\n// element so the user can\n// see what they pinned\n//\n// Mounted on document.body (NOT the beacon Shadow DOM) because position:fixed\n// children of transformed/filtered/contained ancestors get anchored to that\n// ancestor instead of the viewport — and many host pages put a transform on\n// sticky headers, which is exactly where the slotted trigger lives.\n//\n// Each element carries the `beacon-no-capture` class so the screenshot filter\n// in capture/screenshot.ts skips them. All use pointer-events: none so they\n// don't block elementsFromPoint during picking.\n\nconst NO_CAPTURE_CLASS = 'beacon-no-capture';\nconst DEFAULT_ACCENT = '#0ea5e9';\nconst DEFAULT_HINT = 'Click any element to pin it · Press Esc to finish';\n\nexport interface PinAnchor {\n target: Element;\n /** Selector to re-query if `target` is detached from DOM (React re-render, conditional unmount). */\n selector?: string;\n /** Last-known viewport rect from pin time. Used as a faded \"anchor lost\" marker if both\n * the live ref and the selector lookup fail. */\n fallbackRect?: { x: number; y: number; w: number; h: number };\n}\n\nexport interface PickModeOverlay {\n addPin(pinNumber: number, anchor: PinAnchor): void;\n /** Swap the hint pill into a loading state (with spinner). Pass undefined to restore the default hint. */\n setLoading(message?: string): void;\n destroy(): void;\n}\n\nexport interface PickModeOverlayOptions {\n /** Accent color for border, hint pill, markers, and outlines. Defaults to sky-blue. */\n accent?: string;\n}\n\n/** Append a hex alpha suffix only when the color is a 7-char hex. Other formats\n * (`rgb(...)`, named colors) pass through unchanged — the alpha effect is lost\n * but the value stays valid. */\nfunction withAlpha(color: string, alphaHex: string): string {\n return /^#[0-9a-fA-F]{6}$/.test(color) ? `${color}${alphaHex}` : color;\n}\n\nexport function createPickModeOverlay(opts: PickModeOverlayOptions = {}): PickModeOverlay {\n const ACCENT = opts.accent ?? DEFAULT_ACCENT;\n const ACCENT_BORDER = withAlpha(ACCENT, 'b3'); // ~70% alpha for dashed viewport border\n const ACCENT_GLOW = withAlpha(ACCENT, '2e'); // ~18% alpha for inset glow\n // One-time keyframes for the loading spinner. Kept in <head> with the\n // beacon-no-capture class — <style> tags don't render so they don't affect\n // the screenshot, but we mark them anyway for filter consistency.\n const styleTag = document.createElement('style');\n styleTag.className = NO_CAPTURE_CLASS;\n styleTag.textContent = '@keyframes beacon-spin { to { transform: rotate(360deg); } }';\n document.head.appendChild(styleTag);\n\n const frame = document.createElement('div');\n frame.className = NO_CAPTURE_CLASS;\n frame.setAttribute('aria-hidden', 'true');\n frame.style.cssText = [\n 'position: fixed',\n 'inset: 0',\n 'pointer-events: none',\n 'z-index: 2147483646',\n `border: 2px dashed ${ACCENT_BORDER}`,\n 'border-radius: 4px',\n `box-shadow: inset 0 0 56px ${ACCENT_GLOW}`,\n 'box-sizing: border-box',\n ].join('; ');\n\n const hint = document.createElement('div');\n hint.className = NO_CAPTURE_CLASS;\n hint.setAttribute('role', 'status');\n hint.style.cssText = [\n 'position: fixed',\n 'top: 16px',\n 'left: 50%',\n 'transform: translateX(-50%)',\n `background: ${ACCENT}`,\n 'color: #fff',\n 'padding: 6px 14px',\n 'border-radius: 999px',\n 'font: 500 12px/1.4 system-ui, -apple-system, sans-serif',\n 'letter-spacing: 0.01em',\n 'box-shadow: 0 4px 12px #0000004d',\n 'pointer-events: none',\n 'white-space: nowrap',\n 'z-index: 2147483646',\n ].join('; ');\n hint.textContent = DEFAULT_HINT;\n\n const SPINNER_HTML = `<span style=\"\n display: inline-block;\n width: 12px;\n height: 12px;\n border: 2px solid #fff;\n border-top-color: transparent;\n border-radius: 50%;\n animation: beacon-spin 800ms linear infinite;\n vertical-align: middle;\n margin-right: 8px;\n \"></span>`;\n\n function escapeHtml(s: string): string {\n return s.replace(/[<>&]/g, (c) => ({ '<': '&lt;', '>': '&gt;', '&': '&amp;' }[c] as string));\n }\n\n document.body.appendChild(frame);\n document.body.appendChild(hint);\n\n const tracked = new Map<number, { anchor: PinAnchor; marker: HTMLDivElement; outline: HTMLDivElement }>();\n\n function makeMarker(num: number): HTMLDivElement {\n const m = document.createElement('div');\n m.className = NO_CAPTURE_CLASS;\n m.setAttribute('aria-hidden', 'true');\n m.style.cssText = [\n 'position: fixed',\n 'width: 24px',\n 'height: 24px',\n 'border-radius: 999px',\n `background: ${ACCENT}`,\n 'color: #fff',\n 'display: flex',\n 'align-items: center',\n 'justify-content: center',\n 'font: 700 12px/1 system-ui, -apple-system, sans-serif',\n 'border: 2px solid #fff',\n 'box-shadow: 0 2px 8px #00000066',\n 'pointer-events: none',\n 'z-index: 2147483646',\n ].join('; ');\n m.textContent = String(num);\n document.body.appendChild(m);\n return m;\n }\n\n function makeOutline(): HTMLDivElement {\n const o = document.createElement('div');\n o.className = NO_CAPTURE_CLASS;\n o.setAttribute('aria-hidden', 'true');\n o.style.cssText = [\n 'position: fixed',\n 'pointer-events: none',\n `border: 2px solid ${ACCENT}`,\n 'border-radius: 2px',\n 'box-sizing: border-box',\n // Slightly below marker z so the marker visually \"sits on\" the outline corner.\n 'z-index: 2147483645',\n ].join('; ');\n document.body.appendChild(o);\n return o;\n }\n\n function placeAt(\n entry: { marker: HTMLDivElement; outline: HTMLDivElement },\n rect: { x: number; y: number; w: number; h: number },\n isStale: boolean,\n ) {\n const opacity = isStale ? '0.5' : '1';\n\n entry.outline.style.display = 'block';\n entry.outline.style.opacity = opacity;\n entry.outline.style.left = `${rect.x}px`;\n entry.outline.style.top = `${rect.y}px`;\n entry.outline.style.width = `${rect.w}px`;\n entry.outline.style.height = `${rect.h}px`;\n\n entry.marker.style.display = 'flex';\n entry.marker.style.opacity = opacity;\n entry.marker.style.left = `${rect.x + rect.w - 12}px`;\n entry.marker.style.top = `${Math.max(2, rect.y - 12)}px`;\n }\n\n function hide(entry: { marker: HTMLDivElement; outline: HTMLDivElement }) {\n entry.marker.style.display = 'none';\n entry.outline.style.display = 'none';\n }\n\n function reposition() {\n tracked.forEach((entry) => {\n // Tier 1: live element ref still in DOM\n let liveTarget: Element | null = entry.anchor.target;\n if (!document.contains(liveTarget)) liveTarget = null;\n\n // Tier 2: re-query by selector (handles React re-renders that swap the node)\n if (!liveTarget && entry.anchor.selector) {\n liveTarget = document.querySelector(entry.anchor.selector);\n if (liveTarget) entry.anchor.target = liveTarget; // refresh for next reposition\n }\n\n if (liveTarget) {\n const r = liveTarget.getBoundingClientRect();\n if (r.width > 0 || r.height > 0) {\n placeAt(entry, { x: r.left, y: r.top, w: r.width, h: r.height }, false);\n return;\n }\n }\n\n // Tier 3: fallback to the rect captured at pin time. Honest \"anchor lost\"\n // signal — half opacity so the user can see this isn't tracking anymore.\n const fr = entry.anchor.fallbackRect;\n if (fr && (fr.w > 0 || fr.h > 0)) {\n placeAt(entry, fr, true);\n return;\n }\n\n hide(entry);\n });\n }\n\n let raf: number | null = null;\n function schedule() {\n if (raf !== null) return;\n raf = requestAnimationFrame(() => {\n raf = null;\n reposition();\n });\n }\n\n window.addEventListener('scroll', schedule, true);\n window.addEventListener('resize', schedule);\n\n return {\n addPin(num, anchor) {\n const marker = makeMarker(num);\n const outline = makeOutline();\n tracked.set(num, { anchor, marker, outline });\n reposition();\n },\n setLoading(message) {\n if (message) {\n hint.innerHTML = SPINNER_HTML + escapeHtml(message);\n } else {\n hint.textContent = DEFAULT_HINT;\n }\n },\n destroy() {\n window.removeEventListener('scroll', schedule, true);\n window.removeEventListener('resize', schedule);\n if (raf !== null) cancelAnimationFrame(raf);\n frame.remove();\n hint.remove();\n styleTag.remove();\n tracked.forEach(({ marker, outline }) => {\n marker.remove();\n outline.remove();\n });\n tracked.clear();\n },\n };\n}\n","// Hover/click element picker. Draws an outline overlay over the hovered element\n// and resolves with the clicked element. Skips the widget's own elements via\n// composedPath check against the provided shadow root.\n\nexport interface PickerOptions {\n shadowRoot: ShadowRoot;\n onHover?: (el: Element | null) => void;\n /** Outline color for the hovered-element highlight. Defaults to sky-blue. */\n accent?: string;\n}\n\nconst DEFAULT_ACCENT = '#0ea5e9';\n\n/** Append hex alpha suffix only for 7-char hex; other color formats pass through unchanged. */\nfunction withAlpha(color: string, alphaHex: string): string {\n return /^#[0-9a-fA-F]{6}$/.test(color) ? `${color}${alphaHex}` : color;\n}\n\nexport interface PickerHandle {\n cancel: () => void;\n promise: Promise<Element | null>; // resolves with picked element, or null on Escape\n}\n\nexport function startPicker(opts: PickerOptions): PickerHandle {\n const { shadowRoot, onHover } = opts;\n const accent = opts.accent ?? DEFAULT_ACCENT;\n const accentFill = withAlpha(accent, '14'); // ~8% alpha hover-fill tint\n\n // Outline overlay — appended to body, position: fixed, pointer-events: none.\n const outline = document.createElement('div');\n outline.style.cssText = [\n 'position: fixed',\n 'pointer-events: none',\n 'z-index: 2147483646',\n `border: 2px solid ${accent}`,\n `background: ${accentFill}`,\n 'transition: all 60ms ease-out',\n 'box-sizing: border-box',\n 'border-radius: 2px',\n ].join('; ');\n document.body.appendChild(outline);\n\n const tooltip = document.createElement('div');\n tooltip.style.cssText = [\n 'position: fixed',\n 'pointer-events: none',\n 'z-index: 2147483647',\n 'background: #0f172a',\n 'color: #fff',\n 'font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace',\n 'padding: 3px 6px',\n 'border-radius: 3px',\n 'max-width: 280px',\n 'overflow: hidden',\n 'text-overflow: ellipsis',\n 'white-space: nowrap',\n ].join('; ');\n document.body.appendChild(tooltip);\n\n const previousCursor = document.body.style.cursor;\n document.body.style.cursor = 'crosshair';\n\n let resolved = false;\n let resolvePromise: (v: Element | null) => void = () => {};\n const promise = new Promise<Element | null>((res) => { resolvePromise = res; });\n\n function isWidgetElement(el: EventTarget | null): boolean {\n if (!el || !(el instanceof Node)) return false;\n // composedPath gives us shadow boundaries.\n let node: Node | null = el;\n while (node) {\n if (node === shadowRoot || node === shadowRoot.host) return true;\n node = node.parentNode ?? (node as ShadowRoot).host ?? null;\n }\n return false;\n }\n\n function findTarget(x: number, y: number): Element | null {\n // Hide overlay so it doesn't appear in elementsFromPoint, then use elementsFromPoint\n // and pick the first non-widget element.\n outline.style.display = 'none';\n tooltip.style.display = 'none';\n const candidates = document.elementsFromPoint(x, y);\n outline.style.display = 'block';\n tooltip.style.display = 'block';\n for (const c of candidates) {\n if (!isWidgetElement(c)) return c;\n }\n return null;\n }\n\n function positionOutline(el: Element) {\n const rect = el.getBoundingClientRect();\n outline.style.left = `${rect.left}px`;\n outline.style.top = `${rect.top}px`;\n outline.style.width = `${rect.width}px`;\n outline.style.height = `${rect.height}px`;\n\n const tag = el.tagName.toLowerCase();\n const cls = el.classList.length > 0 ? '.' + Array.from(el.classList).slice(0, 2).join('.') : '';\n tooltip.textContent = tag + cls;\n // Place tooltip just above the element, or below if it would clip the top.\n const above = rect.top - 22;\n tooltip.style.left = `${rect.left}px`;\n tooltip.style.top = `${above >= 0 ? above : rect.bottom + 4}px`;\n }\n\n function handleMove(e: MouseEvent) {\n const el = findTarget(e.clientX, e.clientY);\n if (el) {\n positionOutline(el);\n onHover?.(el);\n } else {\n outline.style.display = 'none';\n tooltip.style.display = 'none';\n onHover?.(null);\n }\n }\n\n // Listen on pointerdown (NOT click) so we intercept the press BEFORE the host\n // page reacts. Radix Select / Popover / Dialog open on pointerdown — by the\n // time `click` fires, the page state has changed (dropdown open, focus moved,\n // layout shifted) and elementsFromPoint at click coords returns the wrong thing.\n // pointerdown + capture phase + preventDefault + stopPropagation gives us the\n // element under the cursor exactly as the user saw it, before any host handlers run.\n function handlePointerDown(e: PointerEvent) {\n if (e.button !== 0) return; // ignore right/middle clicks\n e.preventDefault();\n e.stopPropagation();\n const el = findTarget(e.clientX, e.clientY);\n if (el) finish(el);\n }\n\n // Also swallow the trailing click/mouseup so a host-page handler doesn't fire\n // anyway. We've already finished by this point but keep listeners briefly.\n function swallow(e: Event) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n function handleKey(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault();\n finish(null);\n }\n }\n\n function finish(el: Element | null) {\n if (resolved) return;\n resolved = true;\n document.removeEventListener('mousemove', handleMove, true);\n document.removeEventListener('pointerdown', handlePointerDown, true);\n document.removeEventListener('click', swallow, true);\n document.removeEventListener('mouseup', swallow, true);\n document.removeEventListener('keydown', handleKey, true);\n outline.remove();\n tooltip.remove();\n document.body.style.cursor = previousCursor;\n resolvePromise(el);\n }\n\n document.addEventListener('mousemove', handleMove, true);\n document.addEventListener('pointerdown', handlePointerDown, true);\n document.addEventListener('click', swallow, true);\n document.addEventListener('mouseup', swallow, true);\n document.addEventListener('keydown', handleKey, true);\n\n return {\n cancel: () => finish(null),\n promise,\n };\n}\n","// Build a unique-ish CSS selector path for an element by walking up the parent chain.\n// Strategy per ancestor: id (if unique) → tag.classes (if unique among siblings) → tag:nth-of-type(n).\n// Stops at <body> or after a depth limit.\n\nconst MAX_DEPTH = 8;\n\nfunction isUniqueId(id: string, root: Document | ShadowRoot = document): boolean {\n if (!id) return false;\n try {\n return root.querySelectorAll(`#${CSS.escape(id)}`).length === 1;\n } catch {\n return false;\n }\n}\n\nfunction tagWithClasses(el: Element): string {\n const tag = el.tagName.toLowerCase();\n const classes = Array.from(el.classList)\n // Drop classes that look like generated atomic / hashed names (heuristic — keep stable-looking ones).\n .filter((c) => c.length > 0 && c.length < 40)\n .slice(0, 3)\n .map((c) => `.${CSS.escape(c)}`)\n .join('');\n return tag + classes;\n}\n\nfunction nthOfTypeIndex(el: Element): number {\n const parent = el.parentElement;\n if (!parent) return 1;\n const sameTag = Array.from(parent.children).filter((c) => c.tagName === el.tagName);\n return sameTag.indexOf(el) + 1;\n}\n\nexport function buildSelector(target: Element): string {\n if (!target || target.nodeType !== Node.ELEMENT_NODE) return '';\n\n // Fast path: unique id on the target itself.\n if (target.id && isUniqueId(target.id)) {\n return `#${CSS.escape(target.id)}`;\n }\n\n const parts: string[] = [];\n let el: Element | null = target;\n let depth = 0;\n\n while (el && el.tagName.toLowerCase() !== 'body' && depth < MAX_DEPTH) {\n const current: Element = el;\n\n if (current.id && isUniqueId(current.id)) {\n parts.unshift(`#${CSS.escape(current.id)}`);\n break;\n }\n\n const base = tagWithClasses(current);\n const parent: HTMLElement | null = current.parentElement;\n\n // If this base matches multiple siblings, disambiguate with :nth-of-type.\n let part = base;\n if (parent) {\n try {\n const currentClasses = Array.from(current.classList).join(' ');\n const siblings: Element[] = Array.from(parent.children).filter(\n (c: Element) => c.tagName === current.tagName && Array.from(c.classList).join(' ') === currentClasses,\n );\n if (siblings.length > 1) {\n part = `${current.tagName.toLowerCase()}:nth-of-type(${nthOfTypeIndex(current)})`;\n }\n } catch {\n // ignore — fall back to base\n }\n }\n\n parts.unshift(part);\n el = parent;\n depth++;\n }\n\n return parts.join(' > ');\n}\n","// Best-effort framework component name detection.\n// Production builds usually minify component names — return null quietly when unavailable.\n\nimport type { Pin } from '../types';\n\ntype FW = NonNullable<Pin['framework']>;\n\nfunction detectReact(el: Element): FW | null {\n // React stores fiber refs on properties like __reactFiber$<hash> / __reactInternalInstance$<hash>.\n const keys = Object.keys(el).filter((k) => k.startsWith('__reactFiber$') || k.startsWith('__reactInternalInstance$'));\n if (keys.length === 0) return null;\n\n let fiber: unknown = (el as unknown as Record<string, unknown>)[keys[0]!];\n // Walk up the fiber chain to find the nearest function/class component (skip host elements).\n for (let i = 0; i < 10 && fiber; i++) {\n const f = fiber as { type?: unknown; return?: unknown };\n const type = f.type;\n if (typeof type === 'function') {\n const name = (type as { displayName?: string; name?: string }).displayName ?? (type as { name?: string }).name;\n if (name && name !== '_default') return { lib: 'react', name };\n }\n if (typeof type === 'object' && type !== null) {\n const name = (type as { displayName?: string; name?: string }).displayName ?? (type as { name?: string }).name;\n if (name) return { lib: 'react', name };\n }\n fiber = f.return;\n }\n return { lib: 'react' };\n}\n\nfunction detectVue(el: Element): FW | null {\n const anyEl = el as unknown as Record<string, unknown>;\n const vueParent = anyEl.__vueParentComponent as { type?: { name?: string; __name?: string } } | undefined;\n if (vueParent) {\n const name = vueParent.type?.name ?? vueParent.type?.__name;\n return { lib: 'vue', ...(name ? { name } : {}) };\n }\n if (anyEl.__vue__) return { lib: 'vue' };\n return null;\n}\n\nfunction detectAngular(el: Element): FW | null {\n // Angular dev mode exposes window.ng.getComponent(el).\n const ng = (window as unknown as { ng?: { getComponent?: (el: Element) => unknown } }).ng;\n if (!ng?.getComponent) return null;\n try {\n const cmp = ng.getComponent(el);\n if (!cmp) return null;\n const ctor = (cmp as { constructor?: { name?: string } }).constructor;\n return { lib: 'angular', ...(ctor?.name ? { name: ctor.name } : {}) };\n } catch {\n return null;\n }\n}\n\nfunction detectSvelte(el: Element): FW | null {\n // Svelte exposes very little at runtime. Look for $$ properties on the host.\n const anyEl = el as unknown as Record<string, unknown>;\n if ('__svelte_meta' in anyEl) return { lib: 'svelte' };\n return null;\n}\n\nexport function detectFramework(el: Element): Pin['framework'] | undefined {\n const result = detectReact(el) ?? detectVue(el) ?? detectAngular(el) ?? detectSvelte(el);\n return result ?? undefined;\n}\n","// Capture per-pin element data: outerHTML (truncated), selector, computed styles, bounding rect, framework hint.\n\nimport type { RawPinCapture } from '../types';\nimport { buildSelector } from './selector';\nimport { detectFramework } from './framework';\n\n// Limits matched to the /api/feedback zod schema. The route caps each list / string\n// length defensively — exceed any of these and the entire payload 400s with no\n// useful detail surfaced in the beacon UI, so we mirror the caps here.\nconst OUTER_HTML_LIMIT = 5000; // schema: outerHTML max 8000\nconst PARENT_OUTER_HTML_LIMIT = 1000; // schema: parentOuterHTML max 2000\nconst SELECTOR_LIMIT = 1000; // schema: selector max 1000\nconst ID_LIMIT = 200; // schema: id max 200\nconst CLASSLIST_MAX_ENTRIES = 50; // schema: classList array max 50\nconst CLASS_NAME_LIMIT = 200; // schema: each class max 200\nconst STYLE_VALUE_LIMIT = 500; // schema: computedStyles value max 500\n\n// A focused, useful subset of computed style properties. Dumping all 400+ resolved\n// properties is noise; this list covers layout, typography, color, and key visual hints.\nconst USEFUL_STYLE_PROPS = [\n 'display', 'position', 'top', 'right', 'bottom', 'left',\n 'width', 'height', 'min-width', 'min-height', 'max-width', 'max-height',\n 'margin', 'padding',\n 'font-family', 'font-size', 'font-weight', 'line-height', 'text-align',\n 'color', 'background-color', 'background-image',\n 'border', 'border-radius',\n 'opacity', 'visibility', 'overflow',\n 'z-index', 'transform', 'transition',\n 'flex', 'flex-direction', 'justify-content', 'align-items', 'gap',\n 'grid-template-columns', 'grid-template-rows',\n] as const;\n\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, max) + `\\n\\n/* … truncated, original was ${s.length} chars */`;\n}\n\nfunction pickStyles(el: Element): Record<string, string> {\n const computed = getComputedStyle(el);\n const out: Record<string, string> = {};\n for (const prop of USEFUL_STYLE_PROPS) {\n const value = computed.getPropertyValue(prop);\n if (value && value !== 'normal' && value !== 'none' && value !== 'auto' && value !== '0px') {\n out[prop] = value.trim().slice(0, STYLE_VALUE_LIMIT);\n }\n }\n return out;\n}\n\nfunction capClassList(el: Element): string[] {\n const all = Array.from(el.classList);\n // First slice to the entry cap, then truncate each class name. Order matters:\n // truncating first and then slicing would still produce >50 entries.\n return all\n .slice(0, CLASSLIST_MAX_ENTRIES)\n .map((c) => (c.length > CLASS_NAME_LIMIT ? c.slice(0, CLASS_NAME_LIMIT) : c));\n}\n\nexport function capturePin(el: Element): RawPinCapture {\n const rect = el.getBoundingClientRect();\n const rawSelector = buildSelector(el);\n const rawId = el.id || null;\n return {\n selector: rawSelector.length > SELECTOR_LIMIT ? rawSelector.slice(0, SELECTOR_LIMIT) : rawSelector,\n tagName: el.tagName.toLowerCase(),\n id: rawId && rawId.length > ID_LIMIT ? rawId.slice(0, ID_LIMIT) : rawId,\n classList: capClassList(el),\n outerHTML: truncate(el.outerHTML, OUTER_HTML_LIMIT),\n ...(el.parentElement\n ? { parentOuterHTML: truncate(el.parentElement.outerHTML, PARENT_OUTER_HTML_LIMIT) }\n : {}),\n computedStyles: pickStyles(el),\n boundingRect: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n w: Math.round(rect.width),\n h: Math.round(rect.height),\n },\n ...(detectFramework(el) ? { framework: detectFramework(el)! } : {}),\n };\n}\n","// Capture browser / viewport / locale metadata. Pure read-only — no instrumentation.\n\nimport type { Metadata } from '../types';\n\ninterface UADataLike {\n brands: Array<{ brand: string; version: string }>;\n mobile: boolean;\n platform: string;\n}\n\nfunction getUaData(): Metadata['uaData'] {\n const nav = navigator as Navigator & { userAgentData?: UADataLike };\n if (!nav.userAgentData) return undefined;\n // Pick the first non-\"Not.A/Brand\" brand for legibility.\n const brand = nav.userAgentData.brands.find((b) => !/Not[.\\-]?A.?Brand/i.test(b.brand))?.brand\n ?? nav.userAgentData.brands[0]?.brand\n ?? 'unknown';\n return {\n brand,\n mobile: nav.userAgentData.mobile,\n platform: nav.userAgentData.platform,\n };\n}\n\nfunction getTheme(): Metadata['theme'] {\n if (window.matchMedia('(prefers-color-scheme: dark)').matches) return 'dark';\n if (window.matchMedia('(prefers-color-scheme: light)').matches) return 'light';\n return undefined;\n}\n\nexport function captureMetadata(): Metadata {\n return {\n url: window.location.href,\n ...(document.referrer ? { referrer: document.referrer } : {}),\n userAgent: navigator.userAgent,\n ...(getUaData() ? { uaData: getUaData()! } : {}),\n viewport: {\n w: window.innerWidth,\n h: window.innerHeight,\n dpr: window.devicePixelRatio || 1,\n },\n screen: {\n w: window.screen.width,\n h: window.screen.height,\n },\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n locale: navigator.language,\n ...(getTheme() ? { theme: getTheme()! } : {}),\n capturedAt: new Date().toISOString(),\n };\n}\n","// Lazy-loaded screenshot capture via html-to-image.\n// Captures the viewport (document.documentElement) as a JPEG data URL.\n//\n// Cross-origin images that don't return CORS headers (e.g., GitHub avatar redirects\n// from github.com → avatars.githubusercontent.com) cause html-to-image to taint\n// the canvas → toJpeg throws SecurityError. Filter alone wasn't reliable because\n// html-to-image fetches some images outside the filter's reach. Belt-and-suspenders:\n// physically swap cross-origin <img>.src to a transparent pixel before capture,\n// restore after. The user sees a brief blank where the avatar was during capture\n// (~hundreds of ms); the page never sees a screenshot failure.\n\nlet htmlToImage: typeof import('html-to-image') | null = null;\n\nasync function load() {\n if (!htmlToImage) {\n htmlToImage = await import('html-to-image');\n }\n return htmlToImage;\n}\n\nexport interface ScreenshotOptions {\n quality?: number; // 0..1, default 0.7\n pixelRatio?: number; // default min(devicePixelRatio, 2) — capping to keep file size sane\n excludeShadowRoot?: ShadowRoot; // skip our own widget elements\n}\n\nconst TRANSPARENT_PIXEL =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkAAIAAAoAAv/lxKUAAAAASUVORK5CYII=';\n\nfunction isUrlSafeForCanvas(rawUrl: string, crossOriginAttr?: string | null): boolean {\n if (!rawUrl) return true;\n if (rawUrl.startsWith('data:') || rawUrl.startsWith('blob:')) return true;\n if (rawUrl.startsWith('/') || rawUrl.startsWith('#')) return true;\n try {\n const u = new URL(rawUrl, window.location.href);\n if (u.origin === window.location.origin) return true;\n } catch {\n return false;\n }\n return crossOriginAttr === 'anonymous' || crossOriginAttr === 'use-credentials';\n}\n\n/**\n * Replace cross-origin image sources with a transparent pixel for the duration of\n * the capture so html-to-image can't even attempt to fetch them. Returns a restore\n * function that puts the originals back.\n *\n * Covers two element types:\n * - HTML <img> (uses .src)\n * - SVG <image> (uses href / xlink:href) — used by AstronautAvatar for GitHub avatars\n */\nfunction neutralizeCrossOriginImages(): () => void {\n const stashedImg: Array<{ el: HTMLImageElement; src: string }> = [];\n const stashedSvg: Array<{ el: SVGImageElement; href: string | null; xlink: string | null }> = [];\n\n document.querySelectorAll('img').forEach((img) => {\n if (!isUrlSafeForCanvas(img.src, img.crossOrigin)) {\n stashedImg.push({ el: img, src: img.src });\n img.src = TRANSPARENT_PIXEL;\n }\n });\n\n document.querySelectorAll('image').forEach((img) => {\n const svgImg = img as unknown as SVGImageElement;\n const href = svgImg.getAttribute('href');\n const xlink = svgImg.getAttributeNS('http://www.w3.org/1999/xlink', 'href');\n const url = href || xlink || '';\n if (url && !isUrlSafeForCanvas(url)) {\n stashedSvg.push({ el: svgImg, href, xlink });\n if (href !== null) svgImg.setAttribute('href', TRANSPARENT_PIXEL);\n if (xlink !== null) svgImg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', TRANSPARENT_PIXEL);\n }\n });\n\n return () => {\n for (const { el, src } of stashedImg) {\n el.src = src;\n }\n for (const { el, href, xlink } of stashedSvg) {\n if (href !== null) el.setAttribute('href', href);\n if (xlink !== null) el.setAttributeNS('http://www.w3.org/1999/xlink', 'href', xlink);\n }\n };\n}\n\nexport async function captureScreenshot(opts: ScreenshotOptions = {}): Promise<string> {\n const { quality = 0.7, pixelRatio = Math.min(window.devicePixelRatio || 1, 2), excludeShadowRoot } = opts;\n const lib = await load();\n\n // Skip:\n // - the widget's host element (drawer / floating trigger)\n // - any element marked .beacon-no-capture (overlays mounted to document.body\n // because shadow-DOM children get trapped inside transformed ancestors)\n const filter = excludeShadowRoot\n ? (node: Node) => {\n let cur: Node | null = node;\n while (cur) {\n if (cur === excludeShadowRoot.host) return false;\n if (cur instanceof Element && cur.classList.contains('beacon-no-capture')) return false;\n cur = cur.parentNode;\n }\n return true;\n }\n : undefined;\n\n const restore = neutralizeCrossOriginImages();\n\n try {\n return await lib.toJpeg(document.documentElement, {\n quality,\n pixelRatio,\n cacheBust: true,\n ...(filter ? { filter } : {}),\n imagePlaceholder: TRANSPARENT_PIXEL,\n // Cap dimensions to viewport so we don't accidentally capture full document height.\n width: window.innerWidth,\n height: window.innerHeight,\n style: {\n // Avoid scrolling artifacts.\n transform: 'none',\n },\n });\n } finally {\n restore();\n }\n}\n","// Draw the captured pins onto a screenshot. Takes the viewport screenshot data\n// URL and the pin list, returns a new data URL with two things baked per pin:\n//\n// 1. An outline rectangle around the pinned element (so triagers can tell\n// WHICH element was pinned without clicking into the pin data).\n// 2. A numbered circle at the outline's top-right corner.\n//\n// Rect freshness: pin.boundingRect is captured at pin time. If the user scrolls\n// between pinning and screenshot capture, that rect is in stale viewport coords.\n// We recompute via the same fallback chain the live overlay uses:\n// live element ref → selector lookup → captured rect\n// This keeps outlines and markers correctly anchored to what was pinned.\n\nimport type { Pin } from '../types';\n\nconst MARKER_RADIUS = 14;\nconst MARKER_STROKE = '#ffffff';\nconst MARKER_TEXT = '#ffffff';\nconst OUTLINE_WIDTH = 3;\nconst DEFAULT_ACCENT = '#0ea5e9';\n\nexport async function drawMarkers(\n screenshotDataUrl: string,\n pins: Pin[],\n viewportSize: { w: number; h: number; dpr: number },\n pinElements?: WeakMap<Pin, Element>,\n accent: string = DEFAULT_ACCENT,\n): Promise<string> {\n const MARKER_FILL = accent;\n const OUTLINE_COLOR = accent;\n const img = await loadImage(screenshotDataUrl);\n\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('Could not get 2D canvas context');\n\n ctx.drawImage(img, 0, 0);\n\n // Map viewport coords → screenshot pixel coords using the ratio between image\n // size and the captured viewport dimensions.\n const scaleX = canvas.width / viewportSize.w;\n const scaleY = canvas.height / viewportSize.h;\n\n for (const pin of pins) {\n const rect = getFreshRect(pin, pinElements);\n if (!rect) continue;\n\n const x = rect.x * scaleX;\n const y = rect.y * scaleY;\n const w = rect.w * scaleX;\n const h = rect.h * scaleY;\n\n // ── Outline rectangle ──\n ctx.lineWidth = OUTLINE_WIDTH;\n ctx.strokeStyle = OUTLINE_COLOR;\n ctx.strokeRect(x, y, w, h);\n\n // ── Numbered marker at top-right corner (matches the live overlay placement\n // so what users saw during pin mode looks like what triagers see later). ──\n const cx = x + w;\n const cy = y;\n\n // Filled circle.\n ctx.beginPath();\n ctx.fillStyle = MARKER_FILL;\n ctx.arc(cx, cy, MARKER_RADIUS, 0, Math.PI * 2);\n ctx.fill();\n\n // White outer stroke for contrast.\n ctx.lineWidth = 3;\n ctx.strokeStyle = MARKER_STROKE;\n ctx.stroke();\n\n // Number text.\n ctx.fillStyle = MARKER_TEXT;\n ctx.font = 'bold 16px system-ui, -apple-system, sans-serif';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(String(pin.number), cx, cy + 1);\n }\n\n return canvas.toDataURL('image/jpeg', 0.85);\n}\n\n/**\n * Three-tier fallback for \"where is this pinned element NOW\":\n * 1. Live element ref via WeakMap (most accurate — handles scroll, layout shift)\n * 2. Selector re-query (handles React re-render swapping the node identity)\n * 3. Original captured rect (last resort — may be stale relative to current viewport)\n */\nfunction getFreshRect(\n pin: Pin,\n pinElements?: WeakMap<Pin, Element>,\n): { x: number; y: number; w: number; h: number } | null {\n const target = pinElements?.get(pin);\n if (target && document.contains(target)) {\n const r = target.getBoundingClientRect();\n if (r.width > 0 || r.height > 0) {\n return { x: r.left, y: r.top, w: r.width, h: r.height };\n }\n }\n\n if (pin.selector) {\n try {\n const found = document.querySelector(pin.selector);\n if (found) {\n const r = found.getBoundingClientRect();\n if (r.width > 0 || r.height > 0) {\n return { x: r.left, y: r.top, w: r.width, h: r.height };\n }\n }\n } catch {\n // Invalid selector — fall through to captured rect.\n }\n }\n\n return pin.boundingRect;\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = (err) => reject(err);\n img.src = src;\n });\n}\n","// POST the feedback payload to the configured endpoint.\n\nimport type { FeedbackPayload, SubmitResponse } from '../types';\n\nexport async function submitFeedback(\n endpoint: string,\n payload: FeedbackPayload,\n headers?: Record<string, string>,\n): Promise<SubmitResponse> {\n const res = await fetch(endpoint, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...(headers ?? {}),\n },\n body: JSON.stringify(payload),\n });\n\n let body: unknown = null;\n const contentType = res.headers.get('Content-Type') ?? '';\n if (contentType.includes('application/json')) {\n try {\n body = await res.json();\n } catch {\n body = null;\n }\n } else {\n try {\n body = await res.text();\n } catch {\n body = null;\n }\n }\n\n return {\n ok: res.ok,\n status: res.status,\n body,\n };\n}\n","// <launch-kit-beacon> custom element. Orchestrates the capture pipeline + UI.\n\nimport stylesCss from './styles.css?inline';\n\nimport type { BeaconConfig, FeedbackPayload, Pin, RawPinCapture, Severity } from './types';\nimport { createTriggerButton } from './ui/button';\nimport { DrawerView } from './ui/drawer';\nimport { showPinPopover } from './ui/pin-popover';\nimport { createPickModeOverlay } from './ui/pick-mode-overlay';\nimport { startPicker } from './capture/picker';\nimport { capturePin } from './capture/element';\nimport { captureMetadata } from './capture/metadata';\nimport { captureScreenshot } from './capture/screenshot';\nimport { drawMarkers } from './capture/overlay';\nimport { submitFeedback } from './transport/submit';\n\nconst ATTRS = ['endpoint', 'position', 'theme', 'severities'] as const;\n\n// Inject the beacon stylesheet into <head> once, idempotently. Needed because the\n// drawer + pin popover are appended to document.body to escape transformed-ancestor\n// stacking contexts (sticky headers, etc.) — they're outside the shadow root, so the\n// shadow-scoped <style> doesn't reach them.\nconst GLOBAL_STYLE_ID = 'launch-kit-beacon-portal-styles';\nfunction ensureGlobalStyles(stylesText: string): void {\n if (document.getElementById(GLOBAL_STYLE_ID)) return;\n const tag = document.createElement('style');\n tag.id = GLOBAL_STYLE_ID;\n tag.textContent = stylesText;\n document.head.appendChild(tag);\n}\n\n// CSS custom properties consumers can override. The drawer's stylesheet uses\n// var(--beacon-*); after the body-mount refactor we copy the host's resolved\n// values onto the body-mounted drawer/popover (CSS inheritance no longer reaches\n// across the body boundary).\nconst CUSTOMIZABLE_VARS = [\n '--beacon-accent',\n '--beacon-bg',\n '--beacon-fg',\n '--beacon-muted',\n '--beacon-border',\n '--beacon-radius',\n '--beacon-shadow',\n '--beacon-z-index',\n '--beacon-bug',\n '--beacon-idea',\n '--beacon-ux',\n '--beacon-a11y',\n] as const;\n\nconst DEFAULT_ACCENT = '#0ea5e9';\n\nexport class LaunchKitBeacon extends HTMLElement {\n static get observedAttributes() { return ATTRS as unknown as string[]; }\n\n private shadow!: ShadowRoot;\n private trigger?: HTMLElement;\n private drawer?: DrawerView;\n private slotEl?: HTMLSlotElement;\n\n private _config: BeaconConfig | null = null;\n private pins: Pin[] = [];\n // Tracks the live DOM element each pin came from so re-entering annotate mode\n // can restore visual markers for previously pinned items. Off-payload by design.\n private pinElements = new WeakMap<Pin, Element>();\n private description = '';\n private severity: Severity = 'bug';\n // While drawer is open, block clicks on the host page so users can't accidentally\n // navigate away mid-feedback (and lose their pins). Same approach as a modal.\n private documentClickBlocker?: (e: MouseEvent) => void;\n // Set when submit succeeds so the close() warn skips during the 1.5s delay before\n // auto-close — without this, users who click the X during that window would see\n // \"Discard your feedback?\" right after they just sent it.\n private submitSucceeded = false;\n\n /** Public — wrappers can set `widget.config = {...}` for dynamic endpoint/headers/context. */\n set config(value: BeaconConfig) {\n this._config = value;\n }\n get config(): BeaconConfig | null {\n if (this._config) return this._config;\n const endpoint = this.getAttribute('endpoint');\n return endpoint ? { endpoint } : null;\n }\n\n connectedCallback() {\n if (!this.shadow) {\n this.shadow = this.attachShadow({ mode: 'open' });\n const style = document.createElement('style');\n style.textContent = stylesCss;\n this.shadow.appendChild(style);\n\n // Slot for custom trigger override.\n this.slotEl = document.createElement('slot');\n this.slotEl.name = 'trigger';\n this.shadow.appendChild(this.slotEl);\n\n // Default trigger (shown unless slot is filled or position=\"hidden\").\n this.trigger = createTriggerButton();\n this.shadow.appendChild(this.trigger);\n this.trigger.addEventListener('click', () => this.open());\n\n // If consumer provided a slot=\"trigger\" child, hook clicks on it.\n this.slotEl.addEventListener('slotchange', () => {\n const assigned = this.slotEl!.assignedElements();\n if (assigned.length > 0) {\n // Hide the default; wire all assigned elements to open the drawer.\n if (this.trigger) (this.trigger as HTMLElement).style.display = 'none';\n assigned.forEach((el) => el.addEventListener('click', () => this.open()));\n }\n });\n\n this.drawer = new DrawerView(this.parseSeverities(), {\n onClose: () => this.close(),\n onAnnotate: () => this.startAnnotate(),\n onSubmit: () => this.handleSubmit(),\n onPinNoteChange: (n, note) => this.updatePinNote(n, note),\n onPinDelete: (n) => this.deletePin(n),\n onDescriptionChange: (v) => { this.description = v; },\n onSeverityChange: (s) => { this.severity = s; },\n });\n // Mount the drawer at document.body so it escapes any transformed ancestor\n // (sticky headers, blurred toolbars) that would otherwise trap it in a sub-\n // stacking-context and put it underneath other floating UI like a Command\n // Center / PDA shell. The trigger stays in shadow DOM (slotted from the\n // header is fine; that's where the user expects to see it).\n ensureGlobalStyles(stylesCss);\n this.drawer.root.classList.add('beacon-no-capture');\n this.drawer.root.classList.add(`beacon-theme-${this.getAttribute('theme') ?? 'auto'}`);\n document.body.appendChild(this.drawer.root);\n }\n\n // Default attributes if not set.\n if (!this.hasAttribute('position')) this.setAttribute('position', 'bottom-right');\n if (!this.hasAttribute('theme')) this.setAttribute('theme', 'auto');\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (name === 'severities' && this.drawer) {\n // Re-create drawer with new severities. Keep current state.\n // Cheapest path: instruct drawer to refresh — but our drawer captures severities at construction.\n // Acceptable simplification: log a warning if attribute changes mid-life.\n // Production wrappers should set severities at construction via initial attribute.\n console.warn('[launch-kit-beacon] severities attribute changed after mount; not yet hot-reloaded.');\n }\n if (name === 'theme' && this.drawer && oldValue !== newValue) {\n this.drawer.root.classList.remove(`beacon-theme-${oldValue ?? 'auto'}`);\n this.drawer.root.classList.add(`beacon-theme-${newValue ?? 'auto'}`);\n }\n }\n\n // ── Public API ──────────────────────────────────────────\n\n open() {\n if (!this.drawer) return;\n // Edge-aware positioning when consumer is using a slotted trigger\n // (typical pattern when position=\"hidden\" — e.g., the trigger lives in a header).\n // Otherwise fall back to CSS-driven default position (bottom-right / bottom-left).\n if (this.getAttribute('position') === 'hidden') {\n const triggerEl = this.slotEl?.assignedElements()[0] as HTMLElement | undefined;\n if (triggerEl) {\n positionDrawerRelativeTo(this.drawer.root, triggerEl);\n }\n }\n this.submitSucceeded = false;\n this.syncCustomProperties();\n this.installClickBlocker();\n this.drawer.open();\n }\n\n close() {\n if (!this.drawer) return;\n if (!this.submitSucceeded && this.hasUnsavedData()) {\n // eslint-disable-next-line no-alert\n const ok = window.confirm('You have unsaved feedback. Close and discard it?');\n if (!ok) return;\n }\n this.forceClose();\n }\n\n disconnectedCallback() {\n // Custom element being removed from DOM (e.g., HMR or framework teardown).\n // Make sure we don't leak the document-level click listener.\n this.uninstallClickBlocker();\n // Drawer is mounted at body level — pull it out so we don't leave orphans\n // behind on HMR or framework teardown.\n if (this.drawer && this.drawer.root.parentNode) {\n this.drawer.root.parentNode.removeChild(this.drawer.root);\n }\n }\n\n async openWithPicker() {\n this.open();\n // Defer to next tick so the drawer is in DOM before we minimize it.\n setTimeout(() => this.startAnnotate(), 0);\n }\n\n // ── Annotate flow ──────────────────────────────────────────\n\n private async startAnnotate() {\n if (!this.drawer) return;\n this.drawer.minimize();\n\n const accent = this.getAccentColor();\n const overlay = createPickModeOverlay({ accent });\n\n // Restore markers for pins from prior annotate sessions. Use the WeakMap'd\n // element ref if it's still in the DOM; the overlay's reposition logic also\n // falls back to selector and captured rect if this ref is stale.\n for (const pin of this.pins) {\n const target = this.pinElements.get(pin);\n if (target) {\n overlay.addPin(pin.number, {\n target,\n selector: pin.selector,\n fallbackRect: pin.boundingRect,\n });\n }\n }\n\n try {\n let next = true;\n while (next) {\n const handle = startPicker({ shadowRoot: this.shadow, accent });\n const el = await handle.promise;\n if (!el) break; // user pressed Escape\n\n const rect = el.getBoundingClientRect();\n const popoverResult = await showPinPopover({\n shadowRoot: this.shadow,\n anchor: { x: rect.left, y: rect.bottom },\n pinNumber: this.pins.length + 1,\n });\n // 'all' (Escape) ends annotation; 'pin' (cross icon) drops this one and\n // re-enters pick mode for the next element. false falls through to capture.\n if (popoverResult.cancelled === 'all') break;\n if (popoverResult.cancelled === 'pin') continue;\n\n const raw = capturePin(el);\n const pin: Pin = {\n number: this.pins.length + 1,\n ...raw,\n ...(popoverResult.note ? { note: popoverResult.note } : {}),\n };\n this.pins.push(pin);\n this.pinElements.set(pin, el);\n overlay.addPin(pin.number, {\n target: el,\n selector: raw.selector,\n fallbackRect: raw.boundingRect,\n });\n\n // Loop continues — user picks another element OR presses Escape to finish.\n }\n\n // Capture final screenshot + draw markers + reopen drawer with preview.\n if (this.pins.length > 0) {\n // Swap the hint pill into a spinner BEFORE the capture so the user has\n // visible feedback during the 500ms-2s html-to-image walks the DOM.\n // Yield one frame so the swap actually paints before the main thread\n // gets busy with capture work.\n overlay.setLoading('Capturing screenshot…');\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n\n try {\n const meta = captureMetadata();\n const raw = await captureScreenshot({ excludeShadowRoot: this.shadow });\n const annotated = await drawMarkers(raw, this.pins, meta.viewport, this.pinElements, accent);\n this.drawer.setPins(this.pins, annotated);\n } catch (err) {\n // Don't drop the report — pins still post. But surface the failure so users\n // know why their preview is missing instead of guessing.\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[launch-kit-beacon] screenshot capture failed:', err);\n this.drawer.setPins(this.pins);\n this.drawer.setStatus(`Screenshot capture failed: ${msg}`, 'error');\n }\n }\n } finally {\n overlay.destroy();\n }\n\n this.drawer.open();\n }\n\n private updatePinNote(num: number, note: string) {\n const pin = this.pins.find((p) => p.number === num);\n if (!pin) return;\n if (note.trim()) {\n pin.note = note;\n } else {\n delete pin.note;\n }\n // Don't re-render — the input is already up to date; rerender would lose focus.\n }\n\n private deletePin(num: number) {\n this.pins = this.pins.filter((p) => p.number !== num);\n // Renumber.\n this.pins.forEach((p, i) => { p.number = i + 1; });\n // Invalidate the cached annotated screenshot — it bakes the deleted pin's\n // marker into the JPEG. handleSubmit will recapture if needed.\n this.drawer?.setAnnotatedScreenshot(undefined);\n this.drawer?.setPins(this.pins);\n }\n\n // ── Submit flow ──────────────────────────────────────────\n\n private async handleSubmit() {\n if (!this.drawer) return;\n const cfg = this.config;\n if (!cfg?.endpoint) {\n this.drawer.setStatus('Missing endpoint configuration', 'error');\n return;\n }\n\n const description = this.drawer.getDescription().trim();\n const severity = this.drawer.getSeverity();\n if (!description) {\n this.drawer.setStatus('Description is required', 'error');\n return;\n }\n\n // Show the loading state IMMEDIATELY after validation, before any expensive\n // async work. Without this, the user clicks Save and sees nothing change for\n // 500ms-2s while captureScreenshot walks the DOM. Yield one frame so the\n // disabled state actually paints before the main thread gets busy.\n this.drawer.setSubmitting(true);\n\n // Reuse the screenshot already produced at end of annotate. Only recapture\n // if missing — invalidated by deletePin or never produced (e.g., user typed\n // a description and clicked Save without annotating).\n let screenshotDataUrl = this.drawer.getAnnotatedScreenshot();\n const needsCapture = !screenshotDataUrl && this.pins.length > 0;\n\n this.drawer.setStatus(needsCapture ? 'Capturing screenshot…' : 'Sending…');\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n\n const meta = captureMetadata();\n\n if (needsCapture) {\n try {\n const raw = await captureScreenshot({ excludeShadowRoot: this.shadow });\n screenshotDataUrl = await drawMarkers(raw, this.pins, meta.viewport, this.pinElements, this.getAccentColor());\n } catch (err) {\n console.error('[launch-kit-beacon] screenshot capture failed at submit:', err);\n }\n }\n\n const payload: FeedbackPayload = {\n description,\n severity,\n ...(screenshotDataUrl ? { screenshot: { dataUrl: screenshotDataUrl, mime: 'image/jpeg' } } : {}),\n metadata: meta,\n pins: this.pins,\n ...(this.resolveContext() ? { context: this.resolveContext() } : {}),\n };\n\n // Pre-submit hook (cancellable).\n const beforeEvent = new CustomEvent('beacon-before-submit', {\n detail: { payload },\n cancelable: true,\n bubbles: true,\n composed: true,\n });\n const proceed = this.dispatchEvent(beforeEvent);\n if (!proceed) {\n this.drawer.setSubmitting(false);\n this.drawer.setStatus('Submission cancelled', 'error');\n return;\n }\n\n this.drawer.setStatus('Sending…');\n\n try {\n const headers = this.resolveHeaders();\n const response = await submitFeedback(cfg.endpoint, payload, headers);\n this.drawer.setSubmitting(false);\n\n if (response.ok) {\n this.submitSucceeded = true;\n this.drawer.setStatus('Sent — thanks!', 'success');\n this.dispatchEvent(new CustomEvent('beacon-after-submit', {\n detail: { response },\n bubbles: true,\n composed: true,\n }));\n // Reset state and close after a moment. forceClose skips the \"discard?\"\n // warn (because submitSucceeded is true) and tears down the click blocker.\n setTimeout(() => {\n this.forceClose();\n }, 1500);\n } else {\n this.drawer.setStatus(`Failed: ${response.status}`, 'error');\n }\n } catch (err) {\n this.drawer.setSubmitting(false);\n const msg = err instanceof Error ? err.message : 'Network error';\n this.drawer.setStatus(`Failed: ${msg}`, 'error');\n }\n }\n\n // ── Helpers ──────────────────────────────────────────\n\n /**\n * Resolved accent color — reads --beacon-accent from the host's computed style\n * (which picks up any inline `style=\"--beacon-accent: …\"` or stylesheet override\n * targeting the host). Falls back to the default sky-blue if unset.\n */\n private getAccentColor(): string {\n if (typeof window === 'undefined') return DEFAULT_ACCENT;\n const v = getComputedStyle(this).getPropertyValue('--beacon-accent').trim();\n return v || DEFAULT_ACCENT;\n }\n\n /**\n * Mirror every customizable --beacon-* var from the host onto the body-mounted\n * drawer. CSS inheritance stops at the body boundary, so we copy the host's\n * resolved values forward. Called on open() so changes mid-session are picked up.\n */\n private syncCustomProperties(): void {\n if (!this.drawer) return;\n const cs = getComputedStyle(this);\n for (const name of CUSTOMIZABLE_VARS) {\n const val = cs.getPropertyValue(name).trim();\n if (val) this.drawer.root.style.setProperty(name, val);\n }\n }\n\n private hasUnsavedData(): boolean {\n if (this.pins.length > 0) return true;\n const desc = this.drawer?.getDescription() ?? '';\n return desc.trim().length > 0;\n }\n\n private resetState(): void {\n this.pins = [];\n this.description = '';\n this.severity = 'bug';\n this.pinElements = new WeakMap();\n this.drawer?.reset();\n }\n\n private forceClose(): void {\n this.uninstallClickBlocker();\n this.resetState();\n this.submitSucceeded = false;\n this.drawer?.close();\n }\n\n private installClickBlocker(): void {\n if (this.documentClickBlocker) return;\n this.documentClickBlocker = (e: MouseEvent) => {\n const path = e.composedPath();\n // Allow:\n // 1. Clicks inside the shadow root or on the slotted trigger — both go\n // through the host element on their composed path.\n // 2. Clicks on body-mounted beacon UI — drawer, popover, and any future\n // body-mounted UI carry the `beacon-no-capture` class, so we allowlist\n // anything whose path crosses such an element.\n // Pick-mode border/hint/markers are pointer-events:none and never appear in\n // an event path, so they don't need to be allowlisted explicitly.\n if (path.includes(this.shadow.host)) return;\n for (const node of path) {\n if (node instanceof Element && node.classList.contains('beacon-no-capture')) return;\n }\n e.preventDefault();\n e.stopPropagation();\n };\n document.addEventListener('click', this.documentClickBlocker, true);\n }\n\n private uninstallClickBlocker(): void {\n if (!this.documentClickBlocker) return;\n document.removeEventListener('click', this.documentClickBlocker, true);\n this.documentClickBlocker = undefined;\n }\n\n private resolveHeaders(): Record<string, string> | undefined {\n const h = this.config?.headers;\n if (!h) return undefined;\n return typeof h === 'function' ? h() : h;\n }\n\n private resolveContext(): Record<string, unknown> | undefined {\n const c = this.config?.context;\n if (!c) return undefined;\n return typeof c === 'function' ? c() : c;\n }\n\n private parseSeverities(): Severity[] {\n const attr = this.getAttribute('severities');\n if (!attr) return ['bug', 'idea', 'ux', 'a11y'];\n return attr.split(',').map((s) => s.trim()).filter(Boolean) as Severity[];\n }\n}\n\nexport function defineBeacon(tagName = 'launch-kit-beacon'): void {\n if (typeof window === 'undefined') return;\n if (!customElements.get(tagName)) {\n customElements.define(tagName, LaunchKitBeacon);\n }\n}\n\n// ── Helpers ──────────────────────────────────────────\n\nconst DRAWER_WIDTH = 380;\nconst VIEWPORT_MARGIN = 8;\nconst ESTIMATED_DRAWER_HEIGHT = 520;\n\n/**\n * Position the drawer relative to a trigger element, edge-aware.\n *\n * Default placement: directly below the trigger, with the drawer's right edge\n * aligned to the trigger's right edge. Falls back to opening above the trigger\n * if there isn't enough space below. Always clamps within the viewport so the\n * drawer never overflows off-screen.\n */\nfunction positionDrawerRelativeTo(drawer: HTMLElement, trigger: HTMLElement): void {\n const rect = trigger.getBoundingClientRect();\n const viewportW = window.innerWidth;\n const viewportH = window.innerHeight;\n\n // ── Horizontal: align drawer's right edge to trigger's right edge ─────────\n // Compute desired right offset; clamp so drawer never overflows past either edge.\n let rightOffset = Math.max(VIEWPORT_MARGIN, viewportW - rect.right);\n // If aligning right would push the drawer's left edge past the viewport, shift it.\n const leftEdgeIfApplied = viewportW - rightOffset - DRAWER_WIDTH;\n if (leftEdgeIfApplied < VIEWPORT_MARGIN) {\n rightOffset = Math.max(VIEWPORT_MARGIN, viewportW - DRAWER_WIDTH - VIEWPORT_MARGIN);\n }\n\n // ── Vertical: prefer below trigger, fall back to above ────────────────────\n const spaceBelow = viewportH - rect.bottom - VIEWPORT_MARGIN;\n const spaceAbove = rect.top - VIEWPORT_MARGIN;\n\n // Set ALL four anchors explicitly. Use 'auto' (not '') to override CSS defaults\n // (the drawer's CSS has `bottom: 20px` for the floating-trigger case — empty\n // string falls back to that; 'auto' is the only way to truly clear it).\n drawer.style.left = 'auto';\n drawer.style.right = `${rightOffset}px`;\n\n if (spaceBelow >= ESTIMATED_DRAWER_HEIGHT || spaceBelow >= spaceAbove) {\n drawer.style.top = `${rect.bottom + VIEWPORT_MARGIN}px`;\n drawer.style.bottom = 'auto';\n } else {\n drawer.style.top = 'auto';\n drawer.style.bottom = `${viewportH - rect.top + VIEWPORT_MARGIN}px`;\n }\n}\n","// Entry point for the launch-kit beacon Web Component.\n// Importing this module auto-registers the <launch-kit-beacon> custom element.\n// Exposed via the @launchsecure/launch-kit/beacon subpath export.\n\nimport { defineBeacon, LaunchKitBeacon } from './element';\n\nexport { LaunchKitBeacon, defineBeacon };\nexport type {\n BeaconConfig,\n FeedbackPayload,\n Pin,\n Metadata,\n Severity,\n HeaderProvider,\n ContextProvider,\n SubmitResponse,\n} from './types';\n\n// Auto-register on import. Consumers who want to control the tag name can call\n// defineBeacon('my-tag') themselves before any <launch-kit-beacon> elements are parsed.\ndefineBeacon();\n"],"names":["ICONS","createTriggerButton","label","btn","DEFAULT_SEVERITIES","DrawerView","severities","callbacks","pins","annotatedScreenshot","value","submitting","status","kind","canSubmit","escapeHtml","sev","p","desc","submitBtn","input","_a","_b","num","item","s","showPinPopover","opts","resolve","popover","POPOVER_W","POPOVER_H","left","top","textarea","close","result","handleGlobalKey","e","action","note","NO_CAPTURE_CLASS","DEFAULT_ACCENT","DEFAULT_HINT","withAlpha","color","alphaHex","createPickModeOverlay","ACCENT","ACCENT_BORDER","ACCENT_GLOW","styleTag","frame","hint","SPINNER_HTML","c","tracked","makeMarker","m","makeOutline","o","placeAt","entry","rect","isStale","opacity","hide","reposition","liveTarget","r","fr","raf","schedule","anchor","marker","outline","message","startPicker","shadowRoot","onHover","accent","accentFill","tooltip","previousCursor","resolved","resolvePromise","promise","res","isWidgetElement","el","node","findTarget","x","y","candidates","positionOutline","tag","cls","above","handleMove","handlePointerDown","swallow","handleKey","finish","MAX_DEPTH","isUniqueId","id","root","tagWithClasses","classes","nthOfTypeIndex","parent","buildSelector","target","parts","depth","current","base","part","currentClasses","detectReact","keys","k","fiber","i","f","type","name","detectVue","anyEl","vueParent","detectAngular","ng","cmp","ctor","detectSvelte","detectFramework","OUTER_HTML_LIMIT","PARENT_OUTER_HTML_LIMIT","SELECTOR_LIMIT","ID_LIMIT","CLASSLIST_MAX_ENTRIES","CLASS_NAME_LIMIT","STYLE_VALUE_LIMIT","USEFUL_STYLE_PROPS","truncate","max","pickStyles","computed","out","prop","capClassList","capturePin","rawSelector","rawId","getUaData","nav","b","getTheme","captureMetadata","htmlToImage","load","TRANSPARENT_PIXEL","isUrlSafeForCanvas","rawUrl","crossOriginAttr","neutralizeCrossOriginImages","stashedImg","stashedSvg","img","svgImg","href","xlink","url","src","captureScreenshot","quality","pixelRatio","excludeShadowRoot","lib","filter","cur","restore","MARKER_RADIUS","MARKER_STROKE","MARKER_TEXT","OUTLINE_WIDTH","drawMarkers","screenshotDataUrl","viewportSize","pinElements","MARKER_FILL","OUTLINE_COLOR","loadImage","canvas","ctx","scaleX","scaleY","pin","getFreshRect","w","h","cx","cy","found","reject","err","submitFeedback","endpoint","payload","headers","body","ATTRS","GLOBAL_STYLE_ID","ensureGlobalStyles","stylesText","CUSTOMIZABLE_VARS","LaunchKitBeacon","style","stylesCss","assigned","n","v","oldValue","newValue","triggerEl","positionDrawerRelativeTo","overlay","next","popoverResult","raw","meta","annotated","msg","cfg","description","severity","needsCapture","beforeEvent","response","cs","val","path","attr","defineBeacon","tagName","DRAWER_WIDTH","VIEWPORT_MARGIN","ESTIMATED_DRAWER_HEIGHT","drawer","trigger","viewportW","viewportH","rightOffset","spaceBelow","spaceAbove"],"mappings":"srNAEaA,IAAQ;AAAA,EACnB,UAAU;AAAA,EACV,KAAK;AAAA,EACL,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AACT;ACJO,SAASC,EAAoBC,IAAQ,YAA+B;AACzE,QAAMC,IAAM,SAAS,cAAc,QAAQ;AAC3C,SAAAA,EAAI,OAAO,UACXA,EAAI,YAAY,0BAChBA,EAAI,aAAa,cAAcD,CAAK,GACpCC,EAAI,YAAY,GAAGH,EAAM,QAAQ,SAASE,CAAK,WACxCC;AACT;ACLA,MAAMC,IAAiC,CAAC,OAAO,QAAQ,MAAM,MAAM;AAY5D,MAAMC,EAAW;AAAA,EAetB,YAAYC,GAAwBC,GAA4B;AAVhE,SAAQ,QAAQ;AAAA,MACd,aAAa;AAAA,MACb,UAAU;AAAA,MACV,MAAM,CAAA;AAAA,MACN,qBAAqB;AAAA,MACrB,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,YAAY;AAAA,IAAA,GAIZ,KAAK,aAAaD,EAAW,SAAS,IAAIA,IAAaF,GACvD,KAAK,YAAYG,GACjB,KAAK,OAAO,SAAS,cAAc,KAAK,GACxC,KAAK,KAAK,YAAY,iBACtB,KAAK,KAAK,YAAY;AAAA;AAAA;AAAA,+FAGqEP,EAAM,KAAK;AAAA;AAAA;AAAA,OAItG,KAAK,SAAS,KAAK,KAAK,cAAc,qBAAqB,GAC3D,KAAK,KAAK,cAAc,uBAAuB,EAAG,iBAAiB,SAAS,MAAM,KAAK,UAAU,SAAS,GAC1G,KAAK,OAAA;AAAA,EACP;AAAA,EAEA,OAAO;AACL,SAAK,KAAK,UAAU,OAAO,WAAW,GACtC,KAAK,KAAK,UAAU,IAAI,MAAM;AAAA,EAChC;AAAA,EAEA,QAAQ;AACN,SAAK,KAAK,UAAU,OAAO,MAAM;AAAA,EACnC;AAAA,EAEA,WAAW;AACT,SAAK,KAAK,UAAU,IAAI,WAAW,GACnC,KAAK,KAAK,UAAU,OAAO,MAAM;AAAA,EACnC;AAAA,EAEA,QAAQQ,GAAaC,GAA8B;AACjD,SAAK,MAAM,OAAOD,GACdC,MAAwB,WAAW,KAAK,MAAM,sBAAsBA,IACxE,KAAK,OAAA;AAAA,EACP;AAAA,EAEA,yBAA6C;AAC3C,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,uBAAuBC,GAA2B;AAChD,SAAK,MAAM,sBAAsBA,GACjC,KAAK,OAAA;AAAA,EACP;AAAA,EAEA,cAAcC,GAAqB;AACjC,SAAK,MAAM,aAAaA,GACxB,KAAK,OAAA;AAAA,EACP;AAAA,EAEA,UAAUC,GAAgBC,IAAiC,IAAI;AAC7D,SAAK,MAAM,SAASD,GACpB,KAAK,MAAM,aAAaC,GACxB,KAAK,OAAA;AAAA,EACP;AAAA,EAEA,QAAQ;AACN,SAAK,QAAQ;AAAA,MACX,aAAa;AAAA,MACb,UAAU;AAAA,MACV,MAAM,CAAA;AAAA,MACN,qBAAqB;AAAA,MACrB,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,YAAY;AAAA,IAAA,GAEd,KAAK,OAAA;AAAA,EACP;AAAA,EAEA,iBAAiB;AAAE,WAAO,KAAK,MAAM;AAAA,EAAa;AAAA,EAClD,cAAc;AAAE,WAAO,KAAK,MAAM;AAAA,EAAU;AAAA,EAEpC,SAAS;;AACf,UAAMC,IAAY,KAAK,MAAM,YAAY,OAAO,SAAS,KAAK,CAAC,KAAK,MAAM;AAE1E,SAAK,OAAO,YAAY;AAAA;AAAA;AAAA,oJAGwHC,EAAW,KAAK,MAAM,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAM1K,KAAK,WAAW,IAAI,CAACC,MAAQ;AAAA,gDACOA,MAAQ,KAAK,MAAM,WAAW,aAAa,EAAE,eAAeA,CAAG;AAAA,kEAC7CA,CAAG,KAAKA,MAAQ,KAAK,MAAM,WAAW,YAAY,EAAE;AAAA,gBACtGA,CAAG;AAAA;AAAA,WAER,EAAE,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,QAIb,KAAK,MAAM,sBAAsB;AAAA;AAAA;AAAA,sBAGnB,KAAK,MAAM,mBAAmB;AAAA;AAAA,UAE1C,EAAE;AAAA;AAAA,QAEJ,KAAK,MAAM,KAAK,SAAS,IAAI;AAAA;AAAA,6CAEQ,KAAK,MAAM,KAAK,MAAM;AAAA;AAAA,cAErD,KAAK,MAAM,KAAK,IAAI,CAACC,MAAM;AAAA,uDACcA,EAAE,MAAM;AAAA,+CAChBA,EAAE,MAAM;AAAA;AAAA,4DAEKF,EAAWE,EAAE,QAAQ,CAAC,KAAKF,EAAWE,EAAE,QAAQ,CAAC;AAAA,gHACGF,EAAWE,EAAE,QAAQ,EAAE,CAAC;AAAA;AAAA,iFAEvDA,EAAE,MAAM,4BAA4BA,EAAE,MAAM,KAAKjB,EAAM,KAAK;AAAA;AAAA,aAEhI,EAAE,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA,UAGb,EAAE;AAAA;AAAA;AAAA,oFAGwE,KAAK,MAAM,aAAa,aAAa,EAAE;AAAA,YAC/GA,EAAM,GAAG,IAAI,KAAK,MAAM,KAAK,SAAS,IAAI,oBAAoB,mBAAmB;AAAA;AAAA;AAAA,gFAGbc,IAAY,KAAK,UAAU;AAAA,YAC/Fd,EAAM,IAAI,IAAI,KAAK,MAAM,aAAa,aAAa,MAAM;AAAA;AAAA;AAAA;AAAA,QAI7D,KAAK,MAAM,SAAS,6BAA6B,KAAK,MAAM,UAAU,KAAKe,EAAW,KAAK,MAAM,MAAM,CAAC,WAAW,EAAE;AAAA;AAIzH,UAAMG,IAAO,KAAK,OAAO,cAAc,cAAc;AACrD,IAAAA,EAAK,iBAAiB,SAAS,MAAM;AACnC,WAAK,MAAM,cAAcA,EAAK,OAC9B,KAAK,UAAU,oBAAoBA,EAAK,KAAK;AAE7C,YAAMC,IAAY,KAAK,OAAO,cAAc,wBAAwB;AACpE,MAAIA,MACFA,EAAU,WAAW,EAAED,EAAK,MAAM,OAAO,SAAS,MAAM,KAAK,MAAM;AAAA,IAEvE,CAAC,GAED,KAAK,OAAO,iBAAmC,+BAA+B,EAAE,QAAQ,CAACE,MAAU;AACjG,MAAAA,EAAM,iBAAiB,UAAU,MAAM;AACrC,QAAIA,EAAM,YACR,KAAK,MAAM,WAAWA,EAAM,OAC5B,KAAK,UAAU,iBAAiB,KAAK,MAAM,QAAQ,GACnD,KAAK,OAAA;AAAA,MAET,CAAC;AAAA,IACH,CAAC,IAEDC,IAAA,KAAK,OAAO,cAAc,0BAA0B,MAApD,QAAAA,EAAuD,iBAAiB,SAAS,MAAM,KAAK,UAAU,gBACtGC,IAAA,KAAK,OAAO,cAAc,wBAAwB,MAAlD,QAAAA,EAAqD,iBAAiB,SAAS,MAAM,KAAK,UAAU,aAEpG,KAAK,OAAO,iBAAoC,mBAAmB,EAAE,QAAQ,CAACnB,MAAQ;AACpF,MAAAA,EAAI,iBAAiB,SAAS,MAAM;AAClC,cAAMoB,IAAM,OAAOpB,EAAI,aAAa,iBAAiB,CAAC;AACtD,aAAK,UAAU,YAAYoB,CAAG;AAAA,MAChC,CAAC;AAAA,IACH,CAAC,GAED,KAAK,OAAO,iBAAmC,wBAAwB,EAAE,QAAQ,CAACH,MAAU;AAC1F,YAAMI,IAAOJ,EAAM,QAAQ,YAAY,GACjCG,IAAM,QAAOC,KAAA,gBAAAA,EAAM,aAAa,gBAAe,CAAC;AACtD,MAAAJ,EAAM,iBAAiB,SAAS,MAAM,KAAK,UAAU,gBAAgBG,GAAKH,EAAM,KAAK,CAAC;AAAA,IACxF,CAAC;AAAA,EACH;AACF;AAEA,SAASL,EAAWU,GAAmB;AACrC,SAAOA,EACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,OAAO;AAC1B;ACvMO,SAASC,EAAeC,GAID;AAC5B,SAAO,IAAI,QAAQ,CAACC,MAAY;AAC9B,UAAMC,IAAU,SAAS,cAAc,KAAK;AAI5C,IAAAA,EAAQ,YAAY,+DACpBA,EAAQ,YAAY;AAAA;AAAA;AAAA,yCAGiBF,EAAK,SAAS;AAAA;AAAA;AAAA,2GAGoD3B,EAAM,KAAK;AAAA;AAAA;AAAA;AAAA,8EAIxCA,EAAM,KAAK;AAAA;AAAA;AAKrF,UAAM8B,IAAY,KACZC,IAAY,KACZC,IAAO,KAAK,IAAI,KAAK,IAAI,GAAGL,EAAK,OAAO,CAAC,GAAG,OAAO,aAAaG,IAAY,CAAC,GAC7EG,IAAM,KAAK,IAAI,KAAK,IAAI,GAAGN,EAAK,OAAO,IAAI,EAAE,GAAG,OAAO,cAAcI,IAAY,CAAC;AACxF,IAAAF,EAAQ,MAAM,OAAO,GAAGG,CAAI,MAC5BH,EAAQ,MAAM,MAAM,GAAGI,CAAG,MAE1B,SAAS,KAAK,YAAYJ,CAAO;AAEjC,UAAMK,IAAWL,EAAQ,cAAc,UAAU;AACjD,IAAAK,EAAS,MAAA;AAET,aAASC,EAAMC,GAA0B;AACvC,eAAS,oBAAoB,WAAWC,GAAiB,EAAI,GAC7DR,EAAQ,OAAA,GACRD,EAAQQ,CAAM;AAAA,IAChB;AAKA,aAASC,EAAgBC,GAAkB;AACzC,MAAIA,EAAE,QAAQ,aACZA,EAAE,eAAA,GACFA,EAAE,gBAAA,GACFH,EAAM,EAAE,WAAW,OAAO;AAAA,IAE9B;AACA,aAAS,iBAAiB,WAAWE,GAAiB,EAAI,GAE1DR,EAAQ,iBAAiB,SAAS,CAACS,MAAM;;AAEvC,YAAMC,KAASlB,IADAiB,EAAE,OACK,QAAQ,eAAe,MAA9B,gBAAAjB,EAAiC,aAAa;AAE7D,UADIkB,MAAW,YAAUJ,EAAM,EAAE,WAAW,OAAO,GAC/CI,MAAW,QAAQ;AACrB,cAAMC,IAAON,EAAS,MAAM,KAAA;AAC5B,QAAAC,EAAM,EAAE,GAAIK,IAAO,EAAE,MAAAA,EAAA,IAAS,IAAK,WAAW,IAAO;AAAA,MACvD;AAAA,IACF,CAAC,GAGDN,EAAS,iBAAiB,WAAW,CAACI,MAAM;AAC1C,UAAIA,EAAE,QAAQ,YAAYA,EAAE,WAAWA,EAAE,UAAU;AACjD,QAAAA,EAAE,eAAA;AACF,cAAME,IAAON,EAAS,MAAM,KAAA;AAC5B,QAAAC,EAAM,EAAE,GAAIK,IAAO,EAAE,MAAAA,EAAA,IAAS,IAAK,WAAW,IAAO;AAAA,MACvD;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;ACzEA,MAAMC,IAAmB,qBACnBC,IAAiB,WACjBC,IAAe;AA0BrB,SAASC,EAAUC,GAAeC,GAA0B;AAC1D,SAAO,oBAAoB,KAAKD,CAAK,IAAI,GAAGA,CAAK,GAAGC,CAAQ,KAAKD;AACnE;AAEO,SAASE,EAAsBpB,IAA+B,IAAqB;AACxF,QAAMqB,IAASrB,EAAK,UAAUe,GACxBO,IAAgBL,EAAUI,GAAQ,IAAI,GACtCE,IAAcN,EAAUI,GAAQ,IAAI,GAIpCG,IAAW,SAAS,cAAc,OAAO;AAC/C,EAAAA,EAAS,YAAYV,GACrBU,EAAS,cAAc,gEACvB,SAAS,KAAK,YAAYA,CAAQ;AAElC,QAAMC,IAAQ,SAAS,cAAc,KAAK;AAC1C,EAAAA,EAAM,YAAYX,GAClBW,EAAM,aAAa,eAAe,MAAM,GACxCA,EAAM,MAAM,UAAU;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,sBAAsBH,CAAa;AAAA,IACnC;AAAA,IACA,8BAA8BC,CAAW;AAAA,IACzC;AAAA,EAAA,EACA,KAAK,IAAI;AAEX,QAAMG,IAAO,SAAS,cAAc,KAAK;AACzC,EAAAA,EAAK,YAAYZ,GACjBY,EAAK,aAAa,QAAQ,QAAQ,GAClCA,EAAK,MAAM,UAAU;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAeL,CAAM;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,IAAI,GACXK,EAAK,cAAcV;AAEnB,QAAMW,IAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYrB,WAASvC,EAAWU,GAAmB;AACrC,WAAOA,EAAE,QAAQ,UAAU,CAAC8B,OAAO,EAAE,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAA,GAAUA,CAAC,CAAY;AAAA,EAC7F;AAEA,WAAS,KAAK,YAAYH,CAAK,GAC/B,SAAS,KAAK,YAAYC,CAAI;AAE9B,QAAMG,wBAAc,IAAA;AAEpB,WAASC,EAAWlC,GAA6B;AAC/C,UAAMmC,IAAI,SAAS,cAAc,KAAK;AACtC,WAAAA,EAAE,YAAYjB,GACdiB,EAAE,aAAa,eAAe,MAAM,GACpCA,EAAE,MAAM,UAAU;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAeV,CAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,EACA,KAAK,IAAI,GACXU,EAAE,cAAc,OAAOnC,CAAG,GAC1B,SAAS,KAAK,YAAYmC,CAAC,GACpBA;AAAA,EACT;AAEA,WAASC,IAA8B;AACrC,UAAMC,IAAI,SAAS,cAAc,KAAK;AACtC,WAAAA,EAAE,YAAYnB,GACdmB,EAAE,aAAa,eAAe,MAAM,GACpCA,EAAE,MAAM,UAAU;AAAA,MAChB;AAAA,MACA;AAAA,MACA,qBAAqBZ,CAAM;AAAA,MAC3B;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,IAAA,EACA,KAAK,IAAI,GACX,SAAS,KAAK,YAAYY,CAAC,GACpBA;AAAA,EACT;AAEA,WAASC,EACPC,GACAC,GACAC,GACA;AACA,UAAMC,IAAUD,IAAU,QAAQ;AAElC,IAAAF,EAAM,QAAQ,MAAM,UAAU,SAC9BA,EAAM,QAAQ,MAAM,UAAUG,GAC9BH,EAAM,QAAQ,MAAM,OAAO,GAAGC,EAAK,CAAC,MACpCD,EAAM,QAAQ,MAAM,MAAM,GAAGC,EAAK,CAAC,MACnCD,EAAM,QAAQ,MAAM,QAAQ,GAAGC,EAAK,CAAC,MACrCD,EAAM,QAAQ,MAAM,SAAS,GAAGC,EAAK,CAAC,MAEtCD,EAAM,OAAO,MAAM,UAAU,QAC7BA,EAAM,OAAO,MAAM,UAAUG,GAC7BH,EAAM,OAAO,MAAM,OAAO,GAAGC,EAAK,IAAIA,EAAK,IAAI,EAAE,MACjDD,EAAM,OAAO,MAAM,MAAM,GAAG,KAAK,IAAI,GAAGC,EAAK,IAAI,EAAE,CAAC;AAAA,EACtD;AAEA,WAASG,EAAKJ,GAA4D;AACxE,IAAAA,EAAM,OAAO,MAAM,UAAU,QAC7BA,EAAM,QAAQ,MAAM,UAAU;AAAA,EAChC;AAEA,WAASK,IAAa;AACpB,IAAAX,EAAQ,QAAQ,CAACM,MAAU;AAEzB,UAAIM,IAA6BN,EAAM,OAAO;AAS9C,UARK,SAAS,SAASM,CAAU,MAAGA,IAAa,OAG7C,CAACA,KAAcN,EAAM,OAAO,aAC9BM,IAAa,SAAS,cAAcN,EAAM,OAAO,QAAQ,GACrDM,MAAYN,EAAM,OAAO,SAASM,KAGpCA,GAAY;AACd,cAAMC,IAAID,EAAW,sBAAA;AACrB,YAAIC,EAAE,QAAQ,KAAKA,EAAE,SAAS,GAAG;AAC/B,UAAAR,EAAQC,GAAO,EAAE,GAAGO,EAAE,MAAM,GAAGA,EAAE,KAAK,GAAGA,EAAE,OAAO,GAAGA,EAAE,OAAA,GAAU,EAAK;AACtE;AAAA,QACF;AAAA,MACF;AAIA,YAAMC,IAAKR,EAAM,OAAO;AACxB,UAAIQ,MAAOA,EAAG,IAAI,KAAKA,EAAG,IAAI,IAAI;AAChC,QAAAT,EAAQC,GAAOQ,GAAI,EAAI;AACvB;AAAA,MACF;AAEA,MAAAJ,EAAKJ,CAAK;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,MAAIS,IAAqB;AACzB,WAASC,IAAW;AAClB,IAAID,MAAQ,SACZA,IAAM,sBAAsB,MAAM;AAChC,MAAAA,IAAM,MACNJ,EAAA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,gBAAO,iBAAiB,UAAUK,GAAU,EAAI,GAChD,OAAO,iBAAiB,UAAUA,CAAQ,GAEnC;AAAA,IACL,OAAOjD,GAAKkD,GAAQ;AAClB,YAAMC,IAASjB,EAAWlC,CAAG,GACvBoD,IAAUhB,EAAA;AAChB,MAAAH,EAAQ,IAAIjC,GAAK,EAAE,QAAAkD,GAAQ,QAAAC,GAAQ,SAAAC,GAAS,GAC5CR,EAAA;AAAA,IACF;AAAA,IACA,WAAWS,GAAS;AAClB,MAAIA,IACFvB,EAAK,YAAYC,IAAevC,EAAW6D,CAAO,IAElDvB,EAAK,cAAcV;AAAA,IAEvB;AAAA,IACA,UAAU;AACR,aAAO,oBAAoB,UAAU6B,GAAU,EAAI,GACnD,OAAO,oBAAoB,UAAUA,CAAQ,GACzCD,MAAQ,QAAM,qBAAqBA,CAAG,GAC1CnB,EAAM,OAAA,GACNC,EAAK,OAAA,GACLF,EAAS,OAAA,GACTK,EAAQ,QAAQ,CAAC,EAAE,QAAAkB,GAAQ,SAAAC,QAAc;AACvC,QAAAD,EAAO,OAAA,GACPC,EAAQ,OAAA;AAAA,MACV,CAAC,GACDnB,EAAQ,MAAA;AAAA,IACV;AAAA,EAAA;AAEJ;ACpPA,MAAMd,KAAiB;AAGvB,SAASE,GAAUC,GAAeC,GAA0B;AAC1D,SAAO,oBAAoB,KAAKD,CAAK,IAAI,GAAGA,CAAK,GAAGC,CAAQ,KAAKD;AACnE;AAOO,SAASgC,GAAYlD,GAAmC;AAC7D,QAAM,EAAE,YAAAmD,GAAY,SAAAC,EAAA,IAAYpD,GAC1BqD,IAASrD,EAAK,UAAUe,IACxBuC,IAAarC,GAAUoC,GAAQ,IAAI,GAGnCL,IAAU,SAAS,cAAc,KAAK;AAC5C,EAAAA,EAAQ,MAAM,UAAU;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqBK,CAAM;AAAA,IAC3B,eAAeC,CAAU;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,IAAI,GACX,SAAS,KAAK,YAAYN,CAAO;AAEjC,QAAMO,IAAU,SAAS,cAAc,KAAK;AAC5C,EAAAA,EAAQ,MAAM,UAAU;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,IAAI,GACX,SAAS,KAAK,YAAYA,CAAO;AAEjC,QAAMC,IAAiB,SAAS,KAAK,MAAM;AAC3C,WAAS,KAAK,MAAM,SAAS;AAE7B,MAAIC,IAAW,IACXC,IAA8C,MAAM;AAAA,EAAC;AACzD,QAAMC,IAAU,IAAI,QAAwB,CAACC,MAAQ;AAAE,IAAAF,IAAiBE;AAAA,EAAK,CAAC;AAE9E,WAASC,EAAgBC,GAAiC;AACxD,QAAI,CAACA,KAAM,EAAEA,aAAc,MAAO,QAAO;AAEzC,QAAIC,IAAoBD;AACxB,WAAOC,KAAM;AACX,UAAIA,MAASZ,KAAcY,MAASZ,EAAW,KAAM,QAAO;AAC5D,MAAAY,IAAOA,EAAK,cAAeA,EAAoB,QAAQ;AAAA,IACzD;AACA,WAAO;AAAA,EACT;AAEA,WAASC,EAAWC,GAAWC,GAA2B;AAGxD,IAAAlB,EAAQ,MAAM,UAAU,QACxBO,EAAQ,MAAM,UAAU;AACxB,UAAMY,IAAa,SAAS,kBAAkBF,GAAGC,CAAC;AAClD,IAAAlB,EAAQ,MAAM,UAAU,SACxBO,EAAQ,MAAM,UAAU;AACxB,eAAW3B,KAAKuC;AACd,UAAI,CAACN,EAAgBjC,CAAC,EAAG,QAAOA;AAElC,WAAO;AAAA,EACT;AAEA,WAASwC,EAAgBN,GAAa;AACpC,UAAM1B,IAAO0B,EAAG,sBAAA;AAChB,IAAAd,EAAQ,MAAM,OAAO,GAAGZ,EAAK,IAAI,MACjCY,EAAQ,MAAM,MAAM,GAAGZ,EAAK,GAAG,MAC/BY,EAAQ,MAAM,QAAQ,GAAGZ,EAAK,KAAK,MACnCY,EAAQ,MAAM,SAAS,GAAGZ,EAAK,MAAM;AAErC,UAAMiC,IAAMP,EAAG,QAAQ,YAAA,GACjBQ,IAAMR,EAAG,UAAU,SAAS,IAAI,MAAM,MAAM,KAAKA,EAAG,SAAS,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI;AAC7F,IAAAP,EAAQ,cAAcc,IAAMC;AAE5B,UAAMC,IAAQnC,EAAK,MAAM;AACzB,IAAAmB,EAAQ,MAAM,OAAO,GAAGnB,EAAK,IAAI,MACjCmB,EAAQ,MAAM,MAAM,GAAGgB,KAAS,IAAIA,IAAQnC,EAAK,SAAS,CAAC;AAAA,EAC7D;AAEA,WAASoC,EAAW7D,GAAe;AACjC,UAAMmD,IAAKE,EAAWrD,EAAE,SAASA,EAAE,OAAO;AAC1C,IAAImD,KACFM,EAAgBN,CAAE,GAClBV,KAAA,QAAAA,EAAUU,OAEVd,EAAQ,MAAM,UAAU,QACxBO,EAAQ,MAAM,UAAU,QACxBH,KAAA,QAAAA,EAAU;AAAA,EAEd;AAQA,WAASqB,EAAkB9D,GAAiB;AAC1C,QAAIA,EAAE,WAAW,EAAG;AACpB,IAAAA,EAAE,eAAA,GACFA,EAAE,gBAAA;AACF,UAAMmD,IAAKE,EAAWrD,EAAE,SAASA,EAAE,OAAO;AAC1C,IAAImD,OAAWA,CAAE;AAAA,EACnB;AAIA,WAASY,EAAQ/D,GAAU;AACzB,IAAAA,EAAE,eAAA,GACFA,EAAE,gBAAA;AAAA,EACJ;AAEA,WAASgE,EAAUhE,GAAkB;AACnC,IAAIA,EAAE,QAAQ,aACZA,EAAE,eAAA,GACFiE,EAAO,IAAI;AAAA,EAEf;AAEA,WAASA,EAAOd,GAAoB;AAClC,IAAIL,MACJA,IAAW,IACX,SAAS,oBAAoB,aAAae,GAAY,EAAI,GAC1D,SAAS,oBAAoB,eAAeC,GAAmB,EAAI,GACnE,SAAS,oBAAoB,SAASC,GAAS,EAAI,GACnD,SAAS,oBAAoB,WAAWA,GAAS,EAAI,GACrD,SAAS,oBAAoB,WAAWC,GAAW,EAAI,GACvD3B,EAAQ,OAAA,GACRO,EAAQ,OAAA,GACR,SAAS,KAAK,MAAM,SAASC,GAC7BE,EAAeI,CAAE;AAAA,EACnB;AAEA,kBAAS,iBAAiB,aAAaU,GAAY,EAAI,GACvD,SAAS,iBAAiB,eAAeC,GAAmB,EAAI,GAChE,SAAS,iBAAiB,SAASC,GAAS,EAAI,GAChD,SAAS,iBAAiB,WAAWA,GAAS,EAAI,GAClD,SAAS,iBAAiB,WAAWC,GAAW,EAAI,GAE7C;AAAA,IACL,QAAQ,MAAMC,EAAO,IAAI;AAAA,IACzB,SAAAjB;AAAA,EAAA;AAEJ;ACvKA,MAAMkB,KAAY;AAElB,SAASC,EAAWC,GAAYC,IAA8B,UAAmB;AAC/E,MAAI,CAACD,EAAI,QAAO;AAChB,MAAI;AACF,WAAOC,EAAK,iBAAiB,IAAI,IAAI,OAAOD,CAAE,CAAC,EAAE,EAAE,WAAW;AAAA,EAChE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASE,GAAenB,GAAqB;AAC3C,QAAMO,IAAMP,EAAG,QAAQ,YAAA,GACjBoB,IAAU,MAAM,KAAKpB,EAAG,SAAS,EAEpC,OAAO,CAAClC,MAAMA,EAAE,SAAS,KAAKA,EAAE,SAAS,EAAE,EAC3C,MAAM,GAAG,CAAC,EACV,IAAI,CAACA,MAAM,IAAI,IAAI,OAAOA,CAAC,CAAC,EAAE,EAC9B,KAAK,EAAE;AACV,SAAOyC,IAAMa;AACf;AAEA,SAASC,GAAerB,GAAqB;AAC3C,QAAMsB,IAAStB,EAAG;AAClB,SAAKsB,IACW,MAAM,KAAKA,EAAO,QAAQ,EAAE,OAAO,CAACxD,MAAMA,EAAE,YAAYkC,EAAG,OAAO,EACnE,QAAQA,CAAE,IAAI,IAFT;AAGtB;AAEO,SAASuB,GAAcC,GAAyB;AACrD,MAAI,CAACA,KAAUA,EAAO,aAAa,KAAK,aAAc,QAAO;AAG7D,MAAIA,EAAO,MAAMR,EAAWQ,EAAO,EAAE;AACnC,WAAO,IAAI,IAAI,OAAOA,EAAO,EAAE,CAAC;AAGlC,QAAMC,IAAkB,CAAA;AACxB,MAAIzB,IAAqBwB,GACrBE,IAAQ;AAEZ,SAAO1B,KAAMA,EAAG,QAAQ,kBAAkB,UAAU0B,IAAQX,MAAW;AACrE,UAAMY,IAAmB3B;AAEzB,QAAI2B,EAAQ,MAAMX,EAAWW,EAAQ,EAAE,GAAG;AACxC,MAAAF,EAAM,QAAQ,IAAI,IAAI,OAAOE,EAAQ,EAAE,CAAC,EAAE;AAC1C;AAAA,IACF;AAEA,UAAMC,IAAOT,GAAeQ,CAAO,GAC7BL,IAA6BK,EAAQ;AAG3C,QAAIE,IAAOD;AACX,QAAIN;AACF,UAAI;AACF,cAAMQ,IAAiB,MAAM,KAAKH,EAAQ,SAAS,EAAE,KAAK,GAAG;AAI7D,QAH4B,MAAM,KAAKL,EAAO,QAAQ,EAAE;AAAA,UACtD,CAACxD,MAAeA,EAAE,YAAY6D,EAAQ,WAAW,MAAM,KAAK7D,EAAE,SAAS,EAAE,KAAK,GAAG,MAAMgE;AAAA,QAAA,EAE5E,SAAS,MACpBD,IAAO,GAAGF,EAAQ,QAAQ,aAAa,gBAAgBN,GAAeM,CAAO,CAAC;AAAA,MAElF,QAAQ;AAAA,MAER;AAGF,IAAAF,EAAM,QAAQI,CAAI,GAClB7B,IAAKsB,GACLI;AAAA,EACF;AAEA,SAAOD,EAAM,KAAK,KAAK;AACzB;ACvEA,SAASM,GAAY/B,GAAwB;AAE3C,QAAMgC,IAAO,OAAO,KAAKhC,CAAE,EAAE,OAAO,CAACiC,MAAMA,EAAE,WAAW,eAAe,KAAKA,EAAE,WAAW,0BAA0B,CAAC;AACpH,MAAID,EAAK,WAAW,EAAG,QAAO;AAE9B,MAAIE,IAAkBlC,EAA0CgC,EAAK,CAAC,CAAE;AAExE,WAASG,IAAI,GAAGA,IAAI,MAAMD,GAAOC,KAAK;AACpC,UAAMC,IAAIF,GACJG,IAAOD,EAAE;AACf,QAAI,OAAOC,KAAS,YAAY;AAC9B,YAAMC,IAAQD,EAAiD,eAAgBA,EAA2B;AAC1G,UAAIC,KAAQA,MAAS,mBAAmB,EAAE,KAAK,SAAS,MAAAA,EAAA;AAAA,IAC1D;AACA,QAAI,OAAOD,KAAS,YAAYA,MAAS,MAAM;AAC7C,YAAMC,IAAQD,EAAiD,eAAgBA,EAA2B;AAC1G,UAAIC,EAAM,QAAO,EAAE,KAAK,SAAS,MAAAA,EAAA;AAAA,IACnC;AACA,IAAAJ,IAAQE,EAAE;AAAA,EACZ;AACA,SAAO,EAAE,KAAK,QAAA;AAChB;AAEA,SAASG,GAAUvC,GAAwB;;AACzC,QAAMwC,IAAQxC,GACRyC,IAAYD,EAAM;AACxB,MAAIC,GAAW;AACb,UAAMH,MAAO1G,IAAA6G,EAAU,SAAV,gBAAA7G,EAAgB,WAAQC,IAAA4G,EAAU,SAAV,gBAAA5G,EAAgB;AACrD,WAAO,EAAE,KAAK,OAAO,GAAIyG,IAAO,EAAE,MAAAA,EAAA,IAAS,GAAC;AAAA,EAC9C;AACA,SAAIE,EAAM,UAAgB,EAAE,KAAK,MAAA,IAC1B;AACT;AAEA,SAASE,GAAc1C,GAAwB;AAE7C,QAAM2C,IAAM,OAA2E;AACvF,MAAI,EAACA,KAAA,QAAAA,EAAI,cAAc,QAAO;AAC9B,MAAI;AACF,UAAMC,IAAMD,EAAG,aAAa3C,CAAE;AAC9B,QAAI,CAAC4C,EAAK,QAAO;AACjB,UAAMC,IAAQD,EAA4C;AAC1D,WAAO,EAAE,KAAK,WAAW,GAAIC,KAAA,QAAAA,EAAM,OAAO,EAAE,MAAMA,EAAK,KAAA,IAAS,GAAC;AAAA,EACnE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,GAAa9C,GAAwB;AAG5C,SAAI,mBADUA,IACuB,EAAE,KAAK,SAAA,IACrC;AACT;AAEO,SAAS+C,EAAgB/C,GAA2C;AAEzE,SADe+B,GAAY/B,CAAE,KAAKuC,GAAUvC,CAAE,KAAK0C,GAAc1C,CAAE,KAAK8C,GAAa9C,CAAE,KACtE;AACnB;ACxDA,MAAMgD,KAAmB,KACnBC,KAA0B,KAC1BC,IAAiB,KACjBC,IAAW,KACXC,KAAwB,IACxBC,IAAmB,KACnBC,KAAoB,KAIpBC,KAAqB;AAAA,EACzB;AAAA,EAAW;AAAA,EAAY;AAAA,EAAO;AAAA,EAAS;AAAA,EAAU;AAAA,EACjD;AAAA,EAAS;AAAA,EAAU;AAAA,EAAa;AAAA,EAAc;AAAA,EAAa;AAAA,EAC3D;AAAA,EAAU;AAAA,EACV;AAAA,EAAe;AAAA,EAAa;AAAA,EAAe;AAAA,EAAe;AAAA,EAC1D;AAAA,EAAS;AAAA,EAAoB;AAAA,EAC7B;AAAA,EAAU;AAAA,EACV;AAAA,EAAW;AAAA,EAAc;AAAA,EACzB;AAAA,EAAW;AAAA,EAAa;AAAA,EACxB;AAAA,EAAQ;AAAA,EAAkB;AAAA,EAAmB;AAAA,EAAe;AAAA,EAC5D;AAAA,EAAyB;AAC3B;AAEA,SAASC,EAASxH,GAAWyH,GAAqB;AAChD,SAAIzH,EAAE,UAAUyH,IAAYzH,IACrBA,EAAE,MAAM,GAAGyH,CAAG,IAAI;AAAA;AAAA,+BAAoCzH,EAAE,MAAM;AACvE;AAEA,SAAS0H,GAAW1D,GAAqC;AACvD,QAAM2D,IAAW,iBAAiB3D,CAAE,GAC9B4D,IAA8B,CAAA;AACpC,aAAWC,KAAQN,IAAoB;AACrC,UAAMtI,IAAQ0I,EAAS,iBAAiBE,CAAI;AAC5C,IAAI5I,KAASA,MAAU,YAAYA,MAAU,UAAUA,MAAU,UAAUA,MAAU,UACnF2I,EAAIC,CAAI,IAAI5I,EAAM,OAAO,MAAM,GAAGqI,EAAiB;AAAA,EAEvD;AACA,SAAOM;AACT;AAEA,SAASE,GAAa9D,GAAuB;AAI3C,SAHY,MAAM,KAAKA,EAAG,SAAS,EAIhC,MAAM,GAAGoD,EAAqB,EAC9B,IAAI,CAACtF,MAAOA,EAAE,SAASuF,IAAmBvF,EAAE,MAAM,GAAGuF,CAAgB,IAAIvF,CAAE;AAChF;AAEO,SAASiG,GAAW/D,GAA4B;AACrD,QAAM1B,IAAO0B,EAAG,sBAAA,GACVgE,IAAczC,GAAcvB,CAAE,GAC9BiE,IAAQjE,EAAG,MAAM;AACvB,SAAO;AAAA,IACL,UAAUgE,EAAY,SAASd,IAAiBc,EAAY,MAAM,GAAGd,CAAc,IAAIc;AAAA,IACvF,SAAShE,EAAG,QAAQ,YAAA;AAAA,IACpB,IAAIiE,KAASA,EAAM,SAASd,IAAWc,EAAM,MAAM,GAAGd,CAAQ,IAAIc;AAAA,IAClE,WAAWH,GAAa9D,CAAE;AAAA,IAC1B,WAAWwD,EAASxD,EAAG,WAAWgD,EAAgB;AAAA,IAClD,GAAIhD,EAAG,gBACH,EAAE,iBAAiBwD,EAASxD,EAAG,cAAc,WAAWiD,EAAuB,EAAA,IAC/E,CAAA;AAAA,IACJ,gBAAgBS,GAAW1D,CAAE;AAAA,IAC7B,cAAc;AAAA,MACZ,GAAG,KAAK,MAAM1B,EAAK,CAAC;AAAA,MACpB,GAAG,KAAK,MAAMA,EAAK,CAAC;AAAA,MACpB,GAAG,KAAK,MAAMA,EAAK,KAAK;AAAA,MACxB,GAAG,KAAK,MAAMA,EAAK,MAAM;AAAA,IAAA;AAAA,IAE3B,GAAIyE,EAAgB/C,CAAE,IAAI,EAAE,WAAW+C,EAAgB/C,CAAE,MAAO,CAAA;AAAA,EAAC;AAErE;ACtEA,SAASkE,IAAgC;;AACvC,QAAMC,IAAM;AACZ,SAAKA,EAAI,gBAKF;AAAA,IACL,SAJYvI,IAAAuI,EAAI,cAAc,OAAO,KAAK,CAACC,MAAM,CAAC,qBAAqB,KAAKA,EAAE,KAAK,CAAC,MAAxE,gBAAAxI,EAA2E,YACpFC,IAAAsI,EAAI,cAAc,OAAO,CAAC,MAA1B,gBAAAtI,EAA6B,UAC7B;AAAA,IAGH,QAAQsI,EAAI,cAAc;AAAA,IAC1B,UAAUA,EAAI,cAAc;AAAA,EAAA,IARN;AAU1B;AAEA,SAASE,IAA8B;AACrC,MAAI,OAAO,WAAW,8BAA8B,EAAE,QAAS,QAAO;AACtE,MAAI,OAAO,WAAW,+BAA+B,EAAE,QAAS,QAAO;AAEzE;AAEO,SAASC,IAA4B;AAC1C,SAAO;AAAA,IACL,KAAK,OAAO,SAAS;AAAA,IACrB,GAAI,SAAS,WAAW,EAAE,UAAU,SAAS,SAAA,IAAa,CAAA;AAAA,IAC1D,WAAW,UAAU;AAAA,IACrB,GAAIJ,MAAc,EAAE,QAAQA,EAAA,EAAU,IAAO,CAAA;AAAA,IAC7C,UAAU;AAAA,MACR,GAAG,OAAO;AAAA,MACV,GAAG,OAAO;AAAA,MACV,KAAK,OAAO,oBAAoB;AAAA,IAAA;AAAA,IAElC,QAAQ;AAAA,MACN,GAAG,OAAO,OAAO;AAAA,MACjB,GAAG,OAAO,OAAO;AAAA,IAAA;AAAA,IAEnB,UAAU,KAAK,iBAAiB,kBAAkB;AAAA,IAClD,QAAQ,UAAU;AAAA,IAClB,GAAIG,MAAa,EAAE,OAAOA,EAAA,EAAS,IAAO,CAAA;AAAA,IAC1C,aAAY,oBAAI,KAAA,GAAO,YAAA;AAAA,EAAY;AAEvC;ACvCA,IAAIE,IAAqD;AAEzD,eAAeC,KAAO;AACpB,SAAKD,MACHA,IAAc,MAAM,OAAO,sBAAe,IAErCA;AACT;AAQA,MAAME,IACJ;AAEF,SAASC,EAAmBC,GAAgBC,GAA0C;AAGpF,MAFI,CAACD,KACDA,EAAO,WAAW,OAAO,KAAKA,EAAO,WAAW,OAAO,KACvDA,EAAO,WAAW,GAAG,KAAKA,EAAO,WAAW,GAAG,EAAG,QAAO;AAC7D,MAAI;AAEF,QADU,IAAI,IAAIA,GAAQ,OAAO,SAAS,IAAI,EACxC,WAAW,OAAO,SAAS,OAAQ,QAAO;AAAA,EAClD,QAAQ;AACN,WAAO;AAAA,EACT;AACA,SAAOC,MAAoB,eAAeA,MAAoB;AAChE;AAWA,SAASC,KAA0C;AACjD,QAAMC,IAA2D,CAAA,GAC3DC,IAAwF,CAAA;AAE9F,kBAAS,iBAAiB,KAAK,EAAE,QAAQ,CAACC,MAAQ;AAChD,IAAKN,EAAmBM,EAAI,KAAKA,EAAI,WAAW,MAC9CF,EAAW,KAAK,EAAE,IAAIE,GAAK,KAAKA,EAAI,KAAK,GACzCA,EAAI,MAAMP;AAAA,EAEd,CAAC,GAED,SAAS,iBAAiB,OAAO,EAAE,QAAQ,CAACO,MAAQ;AAClD,UAAMC,IAASD,GACTE,IAAOD,EAAO,aAAa,MAAM,GACjCE,IAAQF,EAAO,eAAe,gCAAgC,MAAM,GACpEG,IAAMF,KAAQC,KAAS;AAC7B,IAAIC,KAAO,CAACV,EAAmBU,CAAG,MAChCL,EAAW,KAAK,EAAE,IAAIE,GAAQ,MAAAC,GAAM,OAAAC,GAAO,GACvCD,MAAS,QAAMD,EAAO,aAAa,QAAQR,CAAiB,GAC5DU,MAAU,QAAMF,EAAO,eAAe,gCAAgC,QAAQR,CAAiB;AAAA,EAEvG,CAAC,GAEM,MAAM;AACX,eAAW,EAAE,IAAAzE,GAAI,KAAAqF,EAAA,KAASP;AACxB,MAAA9E,EAAG,MAAMqF;AAEX,eAAW,EAAE,IAAArF,GAAI,MAAAkF,GAAM,OAAAC,EAAA,KAAWJ;AAChC,MAAIG,MAAS,QAAMlF,EAAG,aAAa,QAAQkF,CAAI,GAC3CC,MAAU,QAAMnF,EAAG,eAAe,gCAAgC,QAAQmF,CAAK;AAAA,EAEvF;AACF;AAEA,eAAsBG,EAAkBpJ,IAA0B,IAAqB;AACrF,QAAM,EAAE,SAAAqJ,IAAU,KAAK,YAAAC,IAAa,KAAK,IAAI,OAAO,oBAAoB,GAAG,CAAC,GAAG,mBAAAC,EAAA,IAAsBvJ,GAC/FwJ,IAAM,MAAMlB,GAAA,GAMZmB,IAASF,IACX,CAACxF,MAAe;AACd,QAAI2F,IAAmB3F;AACvB,WAAO2F,KAAK;AAEV,UADIA,MAAQH,EAAkB,QAC1BG,aAAe,WAAWA,EAAI,UAAU,SAAS,mBAAmB,EAAG,QAAO;AAClF,MAAAA,IAAMA,EAAI;AAAA,IACZ;AACA,WAAO;AAAA,EACT,IACA,QAEEC,IAAUhB,GAAA;AAEhB,MAAI;AACF,WAAO,MAAMa,EAAI,OAAO,SAAS,iBAAiB;AAAA,MAChD,SAAAH;AAAA,MACA,YAAAC;AAAA,MACA,WAAW;AAAA,MACX,GAAIG,IAAS,EAAE,QAAAA,EAAA,IAAW,CAAA;AAAA,MAC1B,kBAAkBlB;AAAA;AAAA,MAElB,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO;AAAA,MACf,OAAO;AAAA;AAAA,QAEL,WAAW;AAAA,MAAA;AAAA,IACb,CACD;AAAA,EACH,UAAA;AACE,IAAAoB,EAAA;AAAA,EACF;AACF;AC9GA,MAAMC,KAAgB,IAChBC,KAAgB,WAChBC,KAAc,WACdC,KAAgB,GAChBhJ,KAAiB;AAEvB,eAAsBiJ,EACpBC,GACApL,GACAqL,GACAC,GACA9G,IAAiBtC,IACA;AACjB,QAAMqJ,IAAc/G,GACdgH,IAAgBhH,GAChByF,IAAM,MAAMwB,GAAUL,CAAiB,GAEvCM,IAAS,SAAS,cAAc,QAAQ;AAC9C,EAAAA,EAAO,QAAQzB,EAAI,cACnByB,EAAO,SAASzB,EAAI;AACpB,QAAM0B,IAAMD,EAAO,WAAW,IAAI;AAClC,MAAI,CAACC,EAAK,OAAM,IAAI,MAAM,iCAAiC;AAE3D,EAAAA,EAAI,UAAU1B,GAAK,GAAG,CAAC;AAIvB,QAAM2B,IAASF,EAAO,QAAQL,EAAa,GACrCQ,IAASH,EAAO,SAASL,EAAa;AAE5C,aAAWS,KAAO9L,GAAM;AACtB,UAAMuD,IAAOwI,GAAaD,GAAKR,CAAW;AAC1C,QAAI,CAAC/H,EAAM;AAEX,UAAM,IAAIA,EAAK,IAAIqI,GACbvG,IAAI9B,EAAK,IAAIsI,GACbG,IAAIzI,EAAK,IAAIqI,GACbK,IAAI1I,EAAK,IAAIsI;AAGnB,IAAAF,EAAI,YAAYT,IAChBS,EAAI,cAAcH,GAClBG,EAAI,WAAW,GAAGtG,GAAG2G,GAAGC,CAAC;AAIzB,UAAMC,IAAK,IAAIF,GACTG,IAAK9G;AAGX,IAAAsG,EAAI,UAAA,GACJA,EAAI,YAAYJ,GAChBI,EAAI,IAAIO,GAAIC,GAAIpB,IAAe,GAAG,KAAK,KAAK,CAAC,GAC7CY,EAAI,KAAA,GAGJA,EAAI,YAAY,GAChBA,EAAI,cAAcX,IAClBW,EAAI,OAAA,GAGJA,EAAI,YAAYV,IAChBU,EAAI,OAAO,kDACXA,EAAI,YAAY,UAChBA,EAAI,eAAe,UACnBA,EAAI,SAAS,OAAOG,EAAI,MAAM,GAAGI,GAAIC,IAAK,CAAC;AAAA,EAC7C;AAEA,SAAOT,EAAO,UAAU,cAAc,IAAI;AAC5C;AAQA,SAASK,GACPD,GACAR,GACuD;AACvD,QAAM7E,IAAS6E,KAAA,gBAAAA,EAAa,IAAIQ;AAChC,MAAIrF,KAAU,SAAS,SAASA,CAAM,GAAG;AACvC,UAAM5C,IAAI4C,EAAO,sBAAA;AACjB,QAAI5C,EAAE,QAAQ,KAAKA,EAAE,SAAS;AAC5B,aAAO,EAAE,GAAGA,EAAE,MAAM,GAAGA,EAAE,KAAK,GAAGA,EAAE,OAAO,GAAGA,EAAE,OAAA;AAAA,EAEnD;AAEA,MAAIiI,EAAI;AACN,QAAI;AACF,YAAMM,IAAQ,SAAS,cAAcN,EAAI,QAAQ;AACjD,UAAIM,GAAO;AACT,cAAMvI,IAAIuI,EAAM,sBAAA;AAChB,YAAIvI,EAAE,QAAQ,KAAKA,EAAE,SAAS;AAC5B,iBAAO,EAAE,GAAGA,EAAE,MAAM,GAAGA,EAAE,KAAK,GAAGA,EAAE,OAAO,GAAGA,EAAE,OAAA;AAAA,MAEnD;AAAA,IACF,QAAQ;AAAA,IAER;AAGF,SAAOiI,EAAI;AACb;AAEA,SAASL,GAAUnB,GAAwC;AACzD,SAAO,IAAI,QAAQ,CAAClJ,GAASiL,MAAW;AACtC,UAAMpC,IAAM,IAAI,MAAA;AAChB,IAAAA,EAAI,SAAS,MAAM7I,EAAQ6I,CAAG,GAC9BA,EAAI,UAAU,CAACqC,MAAQD,EAAOC,CAAG,GACjCrC,EAAI,MAAMK;AAAA,EACZ,CAAC;AACH;AC5HA,eAAsBiC,GACpBC,GACAC,GACAC,GACyB;AACzB,QAAM3H,IAAM,MAAM,MAAMyH,GAAU;AAAA,IAChC,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,GAAIE,KAAW,CAAA;AAAA,IAAC;AAAA,IAElB,MAAM,KAAK,UAAUD,CAAO;AAAA,EAAA,CAC7B;AAED,MAAIE,IAAgB;AAEpB,OADoB5H,EAAI,QAAQ,IAAI,cAAc,KAAK,IACvC,SAAS,kBAAkB;AACzC,QAAI;AACF,MAAA4H,IAAO,MAAM5H,EAAI,KAAA;AAAA,IACnB,QAAQ;AACN,MAAA4H,IAAO;AAAA,IACT;AAAA;AAEA,QAAI;AACF,MAAAA,IAAO,MAAM5H,EAAI,KAAA;AAAA,IACnB,QAAQ;AACN,MAAA4H,IAAO;AAAA,IACT;AAGF,SAAO;AAAA,IACL,IAAI5H,EAAI;AAAA,IACR,QAAQA,EAAI;AAAA,IACZ,MAAA4H;AAAA,EAAA;AAEJ;ACxBA,MAAMC,KAAQ,CAAC,YAAY,YAAY,SAAS,YAAY,GAMtDC,IAAkB;AACxB,SAASC,GAAmBC,GAA0B;AACpD,MAAI,SAAS,eAAeF,CAAe,EAAG;AAC9C,QAAMrH,IAAM,SAAS,cAAc,OAAO;AAC1C,EAAAA,EAAI,KAAKqH,GACTrH,EAAI,cAAcuH,GAClB,SAAS,KAAK,YAAYvH,CAAG;AAC/B;AAMA,MAAMwH,KAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEM9K,IAAiB;AAEhB,MAAM+K,WAAwB,YAAY;AAAA,EAA1C,cAAA;AAAA,UAAA,GAAA,SAAA,GAQL,KAAQ,UAA+B,MACvC,KAAQ,OAAc,CAAA,GAGtB,KAAQ,kCAAkB,QAAA,GAC1B,KAAQ,cAAc,IACtB,KAAQ,WAAqB,OAO7B,KAAQ,kBAAkB;AAAA,EAAA;AAAA,EApB1B,WAAW,qBAAqB;AAAE,WAAOL;AAAA,EAA8B;AAAA;AAAA,EAuBvE,IAAI,OAAO1M,GAAqB;AAC9B,SAAK,UAAUA;AAAA,EACjB;AAAA,EACA,IAAI,SAA8B;AAChC,QAAI,KAAK,QAAS,QAAO,KAAK;AAC9B,UAAMsM,IAAW,KAAK,aAAa,UAAU;AAC7C,WAAOA,IAAW,EAAE,UAAAA,EAAA,IAAa;AAAA,EACnC;AAAA,EAEA,oBAAoB;AAClB,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS,KAAK,aAAa,EAAE,MAAM,QAAQ;AAChD,YAAMU,IAAQ,SAAS,cAAc,OAAO;AAC5C,MAAAA,EAAM,cAAcC,GACpB,KAAK,OAAO,YAAYD,CAAK,GAG7B,KAAK,SAAS,SAAS,cAAc,MAAM,GAC3C,KAAK,OAAO,OAAO,WACnB,KAAK,OAAO,YAAY,KAAK,MAAM,GAGnC,KAAK,UAAUzN,EAAA,GACf,KAAK,OAAO,YAAY,KAAK,OAAO,GACpC,KAAK,QAAQ,iBAAiB,SAAS,MAAM,KAAK,MAAM,GAGxD,KAAK,OAAO,iBAAiB,cAAc,MAAM;AAC/C,cAAM2N,IAAW,KAAK,OAAQ,iBAAA;AAC9B,QAAIA,EAAS,SAAS,MAEhB,KAAK,YAAU,KAAK,QAAwB,MAAM,UAAU,SAChEA,EAAS,QAAQ,CAACnI,MAAOA,EAAG,iBAAiB,SAAS,MAAM,KAAK,KAAA,CAAM,CAAC;AAAA,MAE5E,CAAC,GAED,KAAK,SAAS,IAAIpF,EAAW,KAAK,mBAAmB;AAAA,QACnD,SAAmB,MAAM,KAAK,MAAA;AAAA,QAC9B,YAAmB,MAAM,KAAK,cAAA;AAAA,QAC9B,UAAmB,MAAM,KAAK,aAAA;AAAA,QAC9B,iBAAmB,CAACwN,GAAGrL,MAAS,KAAK,cAAcqL,GAAGrL,CAAI;AAAA,QAC1D,aAAmB,CAACqL,MAAM,KAAK,UAAUA,CAAC;AAAA,QAC1C,qBAAqB,CAACC,MAAM;AAAE,eAAK,cAAcA;AAAA,QAAG;AAAA,QACpD,kBAAmB,CAACrM,MAAM;AAAE,eAAK,WAAWA;AAAA,QAAG;AAAA,MAAA,CAChD,GAMD6L,GAAmBK,CAAS,GAC5B,KAAK,OAAO,KAAK,UAAU,IAAI,mBAAmB,GAClD,KAAK,OAAO,KAAK,UAAU,IAAI,gBAAgB,KAAK,aAAa,OAAO,KAAK,MAAM,EAAE,GACrF,SAAS,KAAK,YAAY,KAAK,OAAO,IAAI;AAAA,IAC5C;AAGA,IAAK,KAAK,aAAa,UAAU,KAAG,KAAK,aAAa,YAAY,cAAc,GAC3E,KAAK,aAAa,OAAO,KAAG,KAAK,aAAa,SAAS,MAAM;AAAA,EACpE;AAAA,EAEA,yBAAyB5F,GAAcgG,GAAyBC,GAAyB;AACvF,IAAIjG,MAAS,gBAAgB,KAAK,UAKhC,QAAQ,KAAK,qFAAqF,GAEhGA,MAAS,WAAW,KAAK,UAAUgG,MAAaC,MAClD,KAAK,OAAO,KAAK,UAAU,OAAO,gBAAgBD,KAAY,MAAM,EAAE,GACtE,KAAK,OAAO,KAAK,UAAU,IAAI,gBAAgBC,KAAY,MAAM,EAAE;AAAA,EAEvE;AAAA;AAAA,EAIA,OAAO;;AACL,QAAK,KAAK,QAIV;AAAA,UAAI,KAAK,aAAa,UAAU,MAAM,UAAU;AAC9C,cAAMC,KAAY5M,IAAA,KAAK,WAAL,gBAAAA,EAAa,mBAAmB;AAClD,QAAI4M,KACFC,GAAyB,KAAK,OAAO,MAAMD,CAAS;AAAA,MAExD;AACA,WAAK,kBAAkB,IACvB,KAAK,qBAAA,GACL,KAAK,oBAAA,GACL,KAAK,OAAO,KAAA;AAAA;AAAA,EACd;AAAA,EAEA,QAAQ;AACN,IAAK,KAAK,WACN,CAAC,KAAK,mBAAmB,KAAK,oBAG5B,CADO,OAAO,QAAQ,kDAAkD,KAG9E,KAAK,WAAA;AAAA,EACP;AAAA,EAEA,uBAAuB;AAGrB,SAAK,sBAAA,GAGD,KAAK,UAAU,KAAK,OAAO,KAAK,cAClC,KAAK,OAAO,KAAK,WAAW,YAAY,KAAK,OAAO,IAAI;AAAA,EAE5D;AAAA,EAEA,MAAM,iBAAiB;AACrB,SAAK,KAAA,GAEL,WAAW,MAAM,KAAK,cAAA,GAAiB,CAAC;AAAA,EAC1C;AAAA;AAAA,EAIA,MAAc,gBAAgB;AAC5B,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,OAAO,SAAA;AAEZ,UAAMjJ,IAAS,KAAK,eAAA,GACdmJ,IAAUpL,EAAsB,EAAE,QAAAiC,GAAQ;AAKhD,eAAWsH,KAAO,KAAK,MAAM;AAC3B,YAAMrF,IAAS,KAAK,YAAY,IAAIqF,CAAG;AACvC,MAAIrF,KACFkH,EAAQ,OAAO7B,EAAI,QAAQ;AAAA,QACzB,QAAArF;AAAA,QACA,UAAUqF,EAAI;AAAA,QACd,cAAcA,EAAI;AAAA,MAAA,CACnB;AAAA,IAEL;AAEA,QAAI;AACF,UAAI8B,IAAO;AACX,aAAOA,KAAM;AAEX,cAAM3I,IAAK,MADIZ,GAAY,EAAE,YAAY,KAAK,QAAQ,QAAAG,GAAQ,EACtC;AACxB,YAAI,CAACS,EAAI;AAET,cAAM1B,IAAO0B,EAAG,sBAAA,GACV4I,IAAgB,MAAM3M,EAAe;AAAA,UACzC,YAAY,KAAK;AAAA,UACjB,QAAQ,EAAE,GAAGqC,EAAK,MAAM,GAAGA,EAAK,OAAA;AAAA,UAChC,WAAW,KAAK,KAAK,SAAS;AAAA,QAAA,CAC/B;AAGD,YAAIsK,EAAc,cAAc,MAAO;AACvC,YAAIA,EAAc,cAAc,MAAO;AAEvC,cAAMC,IAAM9E,GAAW/D,CAAE,GACnB6G,IAAW;AAAA,UACf,QAAQ,KAAK,KAAK,SAAS;AAAA,UAC3B,GAAGgC;AAAA,UACH,GAAID,EAAc,OAAO,EAAE,MAAMA,EAAc,KAAA,IAAS,CAAA;AAAA,QAAC;AAE3D,aAAK,KAAK,KAAK/B,CAAG,GAClB,KAAK,YAAY,IAAIA,GAAK7G,CAAE,GAC5B0I,EAAQ,OAAO7B,EAAI,QAAQ;AAAA,UACzB,QAAQ7G;AAAA,UACR,UAAU6I,EAAI;AAAA,UACd,cAAcA,EAAI;AAAA,QAAA,CACnB;AAAA,MAGH;AAGA,UAAI,KAAK,KAAK,SAAS,GAAG;AAKxB,QAAAH,EAAQ,WAAW,uBAAuB,GAC1C,MAAM,IAAI,QAAc,CAAC9J,MAAM,sBAAsB,MAAMA,EAAA,CAAG,CAAC;AAE/D,YAAI;AACF,gBAAMkK,IAAOxE,EAAA,GACPuE,IAAM,MAAMvD,EAAkB,EAAE,mBAAmB,KAAK,QAAQ,GAChEyD,IAAY,MAAM7C,EAAY2C,GAAK,KAAK,MAAMC,EAAK,UAAU,KAAK,aAAavJ,CAAM;AAC3F,eAAK,OAAO,QAAQ,KAAK,MAAMwJ,CAAS;AAAA,QAC1C,SAAS1B,GAAK;AAGZ,gBAAM2B,IAAM3B,aAAe,QAAQA,EAAI,UAAU,OAAOA,CAAG;AAC3D,kBAAQ,MAAM,kDAAkDA,CAAG,GACnE,KAAK,OAAO,QAAQ,KAAK,IAAI,GAC7B,KAAK,OAAO,UAAU,8BAA8B2B,CAAG,IAAI,OAAO;AAAA,QACpE;AAAA,MACF;AAAA,IACF,UAAA;AACE,MAAAN,EAAQ,QAAA;AAAA,IACV;AAEA,SAAK,OAAO,KAAA;AAAA,EACd;AAAA,EAEQ,cAAc5M,GAAaiB,GAAc;AAC/C,UAAM8J,IAAM,KAAK,KAAK,KAAK,CAACrL,MAAMA,EAAE,WAAWM,CAAG;AAClD,IAAK+K,MACD9J,EAAK,SACP8J,EAAI,OAAO9J,IAEX,OAAO8J,EAAI;AAAA,EAGf;AAAA,EAEQ,UAAU/K,GAAa;;AAC7B,SAAK,OAAO,KAAK,KAAK,OAAO,CAACN,MAAMA,EAAE,WAAWM,CAAG,GAEpD,KAAK,KAAK,QAAQ,CAACN,GAAG2G,MAAM;AAAE,MAAA3G,EAAE,SAAS2G,IAAI;AAAA,IAAG,CAAC,IAGjDvG,IAAA,KAAK,WAAL,QAAAA,EAAa,uBAAuB,UACpCC,IAAA,KAAK,WAAL,QAAAA,EAAa,QAAQ,KAAK;AAAA,EAC5B;AAAA;AAAA,EAIA,MAAc,eAAe;AAC3B,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAMoN,IAAM,KAAK;AACjB,QAAI,EAACA,KAAA,QAAAA,EAAK,WAAU;AAClB,WAAK,OAAO,UAAU,kCAAkC,OAAO;AAC/D;AAAA,IACF;AAEA,UAAMC,IAAc,KAAK,OAAO,eAAA,EAAiB,KAAA,GAC3CC,IAAW,KAAK,OAAO,YAAA;AAC7B,QAAI,CAACD,GAAa;AAChB,WAAK,OAAO,UAAU,2BAA2B,OAAO;AACxD;AAAA,IACF;AAMA,SAAK,OAAO,cAAc,EAAI;AAK9B,QAAI/C,IAAoB,KAAK,OAAO,uBAAA;AACpC,UAAMiD,IAAe,CAACjD,KAAqB,KAAK,KAAK,SAAS;AAE9D,SAAK,OAAO,UAAUiD,IAAe,0BAA0B,UAAU,GACzE,MAAM,IAAI,QAAc,CAACxK,MAAM,sBAAsB,MAAMA,EAAA,CAAG,CAAC;AAE/D,UAAMkK,IAAOxE,EAAA;AAEb,QAAI8E;AACF,UAAI;AACF,cAAMP,IAAM,MAAMvD,EAAkB,EAAE,mBAAmB,KAAK,QAAQ;AACtE,QAAAa,IAAoB,MAAMD,EAAY2C,GAAK,KAAK,MAAMC,EAAK,UAAU,KAAK,aAAa,KAAK,eAAA,CAAgB;AAAA,MAC9G,SAASzB,GAAK;AACZ,gBAAQ,MAAM,4DAA4DA,CAAG;AAAA,MAC/E;AAGF,UAAMG,IAA2B;AAAA,MAC/B,aAAA0B;AAAA,MACA,UAAAC;AAAA,MACA,GAAIhD,IAAoB,EAAE,YAAY,EAAE,SAASA,GAAmB,MAAM,aAAA,EAAa,IAAM,CAAA;AAAA,MAC7F,UAAU2C;AAAA,MACV,MAAM,KAAK;AAAA,MACX,GAAI,KAAK,mBAAmB,EAAE,SAAS,KAAK,eAAA,MAAqB,CAAA;AAAA,IAAC,GAI9DO,IAAc,IAAI,YAAY,wBAAwB;AAAA,MAC1D,QAAQ,EAAE,SAAA7B,EAAA;AAAA,MACV,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,UAAU;AAAA,IAAA,CACX;AAED,QAAI,CADY,KAAK,cAAc6B,CAAW,GAChC;AACZ,WAAK,OAAO,cAAc,EAAK,GAC/B,KAAK,OAAO,UAAU,wBAAwB,OAAO;AACrD;AAAA,IACF;AAEA,SAAK,OAAO,UAAU,UAAU;AAEhC,QAAI;AACF,YAAM5B,IAAU,KAAK,eAAA,GACf6B,IAAW,MAAMhC,GAAe2B,EAAI,UAAUzB,GAASC,CAAO;AACpE,WAAK,OAAO,cAAc,EAAK,GAE3B6B,EAAS,MACX,KAAK,kBAAkB,IACvB,KAAK,OAAO,UAAU,kBAAkB,SAAS,GACjD,KAAK,cAAc,IAAI,YAAY,uBAAuB;AAAA,QACxD,QAAQ,EAAE,UAAAA,EAAA;AAAA,QACV,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX,CAAC,GAGF,WAAW,MAAM;AACf,aAAK,WAAA;AAAA,MACP,GAAG,IAAI,KAEP,KAAK,OAAO,UAAU,WAAWA,EAAS,MAAM,IAAI,OAAO;AAAA,IAE/D,SAASjC,GAAK;AACZ,WAAK,OAAO,cAAc,EAAK;AAC/B,YAAM2B,IAAM3B,aAAe,QAAQA,EAAI,UAAU;AACjD,WAAK,OAAO,UAAU,WAAW2B,CAAG,IAAI,OAAO;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,iBAAyB;AAC/B,WAAI,OAAO,SAAW,MAAoB/L,IAChC,iBAAiB,IAAI,EAAE,iBAAiB,iBAAiB,EAAE,KAAA,KACzDA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,uBAA6B;AACnC,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAMsM,IAAK,iBAAiB,IAAI;AAChC,eAAWjH,KAAQyF,IAAmB;AACpC,YAAMyB,IAAMD,EAAG,iBAAiBjH,CAAI,EAAE,KAAA;AACtC,MAAIkH,KAAK,KAAK,OAAO,KAAK,MAAM,YAAYlH,GAAMkH,CAAG;AAAA,IACvD;AAAA,EACF;AAAA,EAEQ,iBAA0B;;AAChC,WAAI,KAAK,KAAK,SAAS,IAAU,QACpB5N,IAAA,KAAK,WAAL,gBAAAA,EAAa,qBAAoB,IAClC,OAAO,SAAS;AAAA,EAC9B;AAAA,EAEQ,aAAmB;;AACzB,SAAK,OAAO,CAAA,GACZ,KAAK,cAAc,IACnB,KAAK,WAAW,OAChB,KAAK,kCAAkB,QAAA,IACvBA,IAAA,KAAK,WAAL,QAAAA,EAAa;AAAA,EACf;AAAA,EAEQ,aAAmB;;AACzB,SAAK,sBAAA,GACL,KAAK,WAAA,GACL,KAAK,kBAAkB,KACvBA,IAAA,KAAK,WAAL,QAAAA,EAAa;AAAA,EACf;AAAA,EAEQ,sBAA4B;AAClC,IAAI,KAAK,yBACT,KAAK,uBAAuB,CAAC,MAAkB;AAC7C,YAAM6N,IAAO,EAAE,aAAA;AASf,UAAI,CAAAA,EAAK,SAAS,KAAK,OAAO,IAAI,GAClC;AAAA,mBAAWxJ,KAAQwJ;AACjB,cAAIxJ,aAAgB,WAAWA,EAAK,UAAU,SAAS,mBAAmB,EAAG;AAE/E,UAAE,eAAA,GACF,EAAE,gBAAA;AAAA;AAAA,IACJ,GACA,SAAS,iBAAiB,SAAS,KAAK,sBAAsB,EAAI;AAAA,EACpE;AAAA,EAEQ,wBAA8B;AACpC,IAAK,KAAK,yBACV,SAAS,oBAAoB,SAAS,KAAK,sBAAsB,EAAI,GACrE,KAAK,uBAAuB;AAAA,EAC9B;AAAA,EAEQ,iBAAqD;;AAC3D,UAAM+G,KAAIpL,IAAA,KAAK,WAAL,gBAAAA,EAAa;AACvB,QAAKoL;AACL,aAAO,OAAOA,KAAM,aAAaA,EAAA,IAAMA;AAAA,EACzC;AAAA,EAEQ,iBAAsD;;AAC5D,UAAMlJ,KAAIlC,IAAA,KAAK,WAAL,gBAAAA,EAAa;AACvB,QAAKkC;AACL,aAAO,OAAOA,KAAM,aAAaA,EAAA,IAAMA;AAAA,EACzC;AAAA,EAEQ,kBAA8B;AACpC,UAAM4L,IAAO,KAAK,aAAa,YAAY;AAC3C,WAAKA,IACEA,EAAK,MAAM,GAAG,EAAE,IAAI,CAAC1N,MAAMA,EAAE,KAAA,CAAM,EAAE,OAAO,OAAO,IADxC,CAAC,OAAO,QAAQ,MAAM,MAAM;AAAA,EAEhD;AACF;AAEO,SAAS2N,GAAaC,IAAU,qBAA2B;AAChE,EAAI,OAAO,SAAW,OACjB,eAAe,IAAIA,CAAO,KAC7B,eAAe,OAAOA,GAAS5B,EAAe;AAElD;AAIA,MAAM6B,IAAe,KACfC,IAAkB,GAClBC,KAA0B;AAUhC,SAAStB,GAAyBuB,GAAqBC,GAA4B;AACjF,QAAM3L,IAAO2L,EAAQ,sBAAA,GACfC,IAAY,OAAO,YACnBC,IAAY,OAAO;AAIzB,MAAIC,IAAc,KAAK,IAAIN,GAAiBI,IAAY5L,EAAK,KAAK;AAGlE,EAD0B4L,IAAYE,IAAcP,IAC5BC,MACtBM,IAAc,KAAK,IAAIN,GAAiBI,IAAYL,IAAeC,CAAe;AAIpF,QAAMO,IAAaF,IAAY7L,EAAK,SAASwL,GACvCQ,IAAahM,EAAK,MAAMwL;AAK9B,EAAAE,EAAO,MAAM,OAAO,QACpBA,EAAO,MAAM,QAAQ,GAAGI,CAAW,MAE/BC,KAAcN,MAA2BM,KAAcC,KACzDN,EAAO,MAAM,MAAM,GAAG1L,EAAK,SAASwL,CAAe,MACnDE,EAAO,MAAM,SAAS,WAEtBA,EAAO,MAAM,MAAM,QACnBA,EAAO,MAAM,SAAS,GAAGG,IAAY7L,EAAK,MAAMwL,CAAe;AAEnE;ACjhBAH,GAAA;"}
@@ -0,0 +1,87 @@
1
+ (function(C,L){typeof exports=="object"&&typeof module<"u"?L(exports):typeof define=="function"&&define.amd?define(["exports"],L):(C=typeof globalThis<"u"?globalThis:C||self,L(C.LaunchKitBeacon={}))})(this,function(C){"use strict";const L='.beacon-drawer,.beacon-pin-popover{--beacon-accent: #0ea5e9;--beacon-bg: #ffffff;--beacon-fg: #0f172a;--beacon-muted: #64748b;--beacon-border: #e2e8f0;--beacon-radius: 10px;--beacon-shadow: 0 10px 30px rgba(0, 0, 0, .15), 0 2px 6px rgba(0, 0, 0, .08);--beacon-z-index: 2147483647;--beacon-bug: #ef4444;--beacon-idea: #22c55e;--beacon-ux: #a855f7;--beacon-a11y: #06b6d4}.beacon-drawer.beacon-theme-dark,.beacon-pin-popover.beacon-theme-dark{--beacon-bg: #0f172a;--beacon-fg: #f1f5f9;--beacon-muted: #94a3b8;--beacon-border: #334155}@media (prefers-color-scheme: dark){.beacon-drawer.beacon-theme-auto,.beacon-pin-popover.beacon-theme-auto{--beacon-bg: #0f172a;--beacon-fg: #f1f5f9;--beacon-muted: #94a3b8;--beacon-border: #334155}}:host{--beacon-accent: #0ea5e9;--beacon-bg: #ffffff;--beacon-fg: #0f172a;--beacon-muted: #64748b;--beacon-border: #e2e8f0;--beacon-radius: 10px;--beacon-z-index: 2147483645;--beacon-shadow: 0 10px 30px rgba(0, 0, 0, .15), 0 2px 6px rgba(0, 0, 0, .08);--beacon-bug: #ef4444;--beacon-idea: #22c55e;--beacon-ux: #a855f7;--beacon-a11y: #06b6d4;position:fixed;z-index:var(--beacon-z-index);font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:14px;color:var(--beacon-fg);line-height:1.5}:host([theme="dark"]){--beacon-bg: #0f172a;--beacon-fg: #f1f5f9;--beacon-muted: #94a3b8;--beacon-border: #334155}@media (prefers-color-scheme: dark){:host([theme="auto"]){--beacon-bg: #0f172a;--beacon-fg: #f1f5f9;--beacon-muted: #94a3b8;--beacon-border: #334155}}:host([position="bottom-right"]){right:20px;bottom:20px;left:auto;top:auto}:host([position="bottom-left"]){left:20px;bottom:20px;right:auto;top:auto}:host([position="hidden"]){position:static;display:contents}:host([position="hidden"]) .beacon-default-trigger{display:none}.beacon-default-trigger{display:inline-flex;align-items:center;gap:6px;background:var(--beacon-accent);color:#fff;border:0;border-radius:999px;padding:10px 16px;font:inherit;font-weight:500;cursor:pointer;box-shadow:var(--beacon-shadow);transition:transform .15s ease,box-shadow .15s ease}.beacon-default-trigger:hover{transform:translateY(-1px);box-shadow:0 14px 36px #0003}.beacon-default-trigger svg{width:18px;height:18px}.beacon-drawer{position:fixed;right:20px;bottom:20px;width:380px;max-width:calc(100vw - 24px);max-height:calc(100vh - 24px);background:var(--beacon-bg);color:var(--beacon-fg);border:1px solid var(--beacon-border);border-radius:var(--beacon-radius);box-shadow:var(--beacon-shadow);display:none;flex-direction:column;overflow:hidden;z-index:var(--beacon-z-index)}:host([position="bottom-left"]) .beacon-drawer{left:20px;right:auto}.beacon-drawer.open{display:flex}.beacon-drawer.minimized{display:none}.beacon-drawer-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--beacon-border)}.beacon-drawer-title{font-weight:600}.beacon-icon-btn{background:transparent;border:0;color:var(--beacon-muted);cursor:pointer;padding:4px;border-radius:4px;display:inline-flex}.beacon-icon-btn:hover{background:var(--beacon-border);color:var(--beacon-fg)}.beacon-icon-btn svg{width:16px;height:16px}.beacon-drawer-body{padding:16px;overflow-y:auto;display:flex;flex-direction:column;gap:14px}.beacon-field{display:flex;flex-direction:column;gap:6px}.beacon-label{font-size:12px;color:var(--beacon-muted);font-weight:500}.beacon-textarea{width:100%;min-height:80px;padding:8px 10px;background:var(--beacon-bg);color:var(--beacon-fg);border:1px solid var(--beacon-border);border-radius:6px;font:inherit;resize:vertical;box-sizing:border-box}.beacon-textarea:focus{outline:2px solid var(--beacon-accent);outline-offset:-1px;border-color:var(--beacon-accent)}.beacon-severity{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}.beacon-severity-opt{position:relative;display:flex;align-items:center;justify-content:center;padding:6px 4px;background:transparent;border:1px solid var(--beacon-border);border-radius:6px;cursor:pointer;font-size:12px;font-weight:500;color:var(--beacon-fg);text-transform:capitalize}.beacon-severity-opt input{position:absolute;opacity:0;pointer-events:none}.beacon-severity-opt:hover{background:var(--beacon-border)}.beacon-severity-opt.selected[data-sev=bug]{border-color:var(--beacon-bug);color:var(--beacon-bug)}.beacon-severity-opt.selected[data-sev=idea]{border-color:var(--beacon-idea);color:var(--beacon-idea)}.beacon-severity-opt.selected[data-sev=ux]{border-color:var(--beacon-ux);color:var(--beacon-ux)}.beacon-severity-opt.selected[data-sev=a11y]{border-color:var(--beacon-a11y);color:var(--beacon-a11y)}.beacon-actions{display:flex;gap:8px;align-items:center}.beacon-btn{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:6px;border:0;cursor:pointer;font:inherit;font-weight:500;font-size:13px;transition:opacity .15s ease}.beacon-btn[disabled]{opacity:.5;cursor:not-allowed}.beacon-btn svg{width:14px;height:14px}.beacon-btn.primary{background:var(--beacon-accent);color:#fff}.beacon-btn.secondary{background:transparent;color:var(--beacon-fg);border:1px solid var(--beacon-border)}.beacon-btn.secondary:hover{background:var(--beacon-border)}.beacon-pin-list{display:flex;flex-direction:column;gap:6px;max-height:200px;overflow-y:auto}.beacon-pin-item{display:flex;align-items:flex-start;gap:8px;padding:8px;background:var(--beacon-border);border-radius:6px}.beacon-pin-num{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background:var(--beacon-accent);color:#fff;font-size:11px;font-weight:600;flex-shrink:0}.beacon-pin-meta{flex:1;min-width:0}.beacon-pin-selector{font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--beacon-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.beacon-pin-note{margin-top:4px;font-size:12px;color:var(--beacon-fg)}.beacon-pin-note-input{margin-top:4px;width:100%;padding:4px 6px;background:var(--beacon-bg);color:var(--beacon-fg);border:1px solid var(--beacon-border);border-radius:4px;font:inherit;font-size:12px;box-sizing:border-box}.beacon-thumb{width:100%;border:1px solid var(--beacon-border);border-radius:6px;display:block}.beacon-status{font-size:12px;color:var(--beacon-muted);text-align:center;padding:4px}.beacon-status.error{color:var(--beacon-bug)}.beacon-status.success{color:var(--beacon-idea)}.beacon-pin-popover{position:fixed;z-index:2147483647;width:240px;background:var(--beacon-bg);color:var(--beacon-fg);border:1px solid var(--beacon-border);border-radius:6px;box-shadow:var(--beacon-shadow);padding:10px;display:none;flex-direction:column;gap:8px}.beacon-pin-popover.open{display:flex}.beacon-pin-popover-header{display:flex;align-items:center;justify-content:space-between;gap:6px}.beacon-pin-popover-actions{display:flex;gap:6px;justify-content:flex-end}',A={feedback:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',pin:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 17v5"/><path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"/></svg>',close:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>',trash:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>',send:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>',check:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>'};function Re(e="Feedback"){const t=document.createElement("button");return t.type="button",t.className="beacon-default-trigger",t.setAttribute("aria-label",e),t.innerHTML=`${A.feedback}<span>${e}</span>`,t}const Te=["bug","idea","ux","a11y"];class $e{constructor(t,n){this.state={description:"",severity:"bug",pins:[],annotatedScreenshot:void 0,submitting:!1,status:"",statusKind:""},this.severities=t.length>0?t:Te,this.callbacks=n,this.root=document.createElement("div"),this.root.className="beacon-drawer",this.root.innerHTML=`
2
+ <div class="beacon-drawer-header">
3
+ <div class="beacon-drawer-title">Send feedback</div>
4
+ <button type="button" class="beacon-icon-btn" data-action="close" aria-label="Close">${A.close}</button>
5
+ </div>
6
+ <div class="beacon-drawer-body"></div>
7
+ `,this.bodyEl=this.root.querySelector(".beacon-drawer-body"),this.root.querySelector('[data-action="close"]').addEventListener("click",()=>this.callbacks.onClose()),this.render()}open(){this.root.classList.remove("minimized"),this.root.classList.add("open")}close(){this.root.classList.remove("open")}minimize(){this.root.classList.add("minimized"),this.root.classList.remove("open")}setPins(t,n){this.state.pins=t,n!==void 0&&(this.state.annotatedScreenshot=n),this.render()}getAnnotatedScreenshot(){return this.state.annotatedScreenshot}setAnnotatedScreenshot(t){this.state.annotatedScreenshot=t,this.render()}setSubmitting(t){this.state.submitting=t,this.render()}setStatus(t,n=""){this.state.status=t,this.state.statusKind=n,this.render()}reset(){this.state={description:"",severity:"bug",pins:[],annotatedScreenshot:void 0,submitting:!1,status:"",statusKind:""},this.render()}getDescription(){return this.state.description}getSeverity(){return this.state.severity}render(){var o,i;const t=this.state.description.trim().length>0&&!this.state.submitting;this.bodyEl.innerHTML=`
8
+ <div class="beacon-field">
9
+ <label class="beacon-label" for="beacon-desc">What's the issue?</label>
10
+ <textarea id="beacon-desc" class="beacon-textarea" placeholder="Describe what you saw, what you expected, anything that helps reproduce…">${$(this.state.description)}</textarea>
11
+ </div>
12
+
13
+ <div class="beacon-field">
14
+ <span class="beacon-label">Severity</span>
15
+ <div class="beacon-severity" role="radiogroup">
16
+ ${this.severities.map(r=>`
17
+ <label class="beacon-severity-opt ${r===this.state.severity?"selected":""}" data-sev="${r}">
18
+ <input type="radio" name="beacon-severity" value="${r}" ${r===this.state.severity?"checked":""}>
19
+ ${r}
20
+ </label>
21
+ `).join("")}
22
+ </div>
23
+ </div>
24
+
25
+ ${this.state.annotatedScreenshot?`
26
+ <div class="beacon-field">
27
+ <span class="beacon-label">Annotated screenshot</span>
28
+ <img src="${this.state.annotatedScreenshot}" class="beacon-thumb" alt="Annotated screenshot preview">
29
+ </div>
30
+ `:""}
31
+
32
+ ${this.state.pins.length>0?`
33
+ <div class="beacon-field">
34
+ <span class="beacon-label">Pins (${this.state.pins.length})</span>
35
+ <div class="beacon-pin-list">
36
+ ${this.state.pins.map(r=>`
37
+ <div class="beacon-pin-item" data-pin="${r.number}">
38
+ <span class="beacon-pin-num">${r.number}</span>
39
+ <div class="beacon-pin-meta">
40
+ <div class="beacon-pin-selector" title="${$(r.selector)}">${$(r.selector)}</div>
41
+ <input type="text" class="beacon-pin-note-input" placeholder="Add a note (optional)" value="${$(r.note??"")}">
42
+ </div>
43
+ <button type="button" class="beacon-icon-btn" data-pin-delete="${r.number}" aria-label="Remove pin ${r.number}">${A.trash}</button>
44
+ </div>
45
+ `).join("")}
46
+ </div>
47
+ </div>
48
+ `:""}
49
+
50
+ <div class="beacon-actions">
51
+ <button type="button" class="beacon-btn secondary" data-action="annotate" ${this.state.submitting?"disabled":""}>
52
+ ${A.pin} ${this.state.pins.length>0?"Add another pin":"Annotate elements"}
53
+ </button>
54
+ <span style="flex:1"></span>
55
+ <button type="button" class="beacon-btn primary" data-action="submit" ${t?"":"disabled"}>
56
+ ${A.send} ${this.state.submitting?"Sending…":"Send"}
57
+ </button>
58
+ </div>
59
+
60
+ ${this.state.status?`<div class="beacon-status ${this.state.statusKind}">${$(this.state.status)}</div>`:""}
61
+ `;const n=this.bodyEl.querySelector("#beacon-desc");n.addEventListener("input",()=>{this.state.description=n.value,this.callbacks.onDescriptionChange(n.value);const r=this.bodyEl.querySelector('[data-action="submit"]');r&&(r.disabled=!(n.value.trim().length>0)||this.state.submitting)}),this.bodyEl.querySelectorAll('input[name="beacon-severity"]').forEach(r=>{r.addEventListener("change",()=>{r.checked&&(this.state.severity=r.value,this.callbacks.onSeverityChange(this.state.severity),this.render())})}),(o=this.bodyEl.querySelector('[data-action="annotate"]'))==null||o.addEventListener("click",()=>this.callbacks.onAnnotate()),(i=this.bodyEl.querySelector('[data-action="submit"]'))==null||i.addEventListener("click",()=>this.callbacks.onSubmit()),this.bodyEl.querySelectorAll("[data-pin-delete]").forEach(r=>{r.addEventListener("click",()=>{const a=Number(r.getAttribute("data-pin-delete"));this.callbacks.onPinDelete(a)})}),this.bodyEl.querySelectorAll(".beacon-pin-note-input").forEach(r=>{const a=r.closest("[data-pin]"),s=Number((a==null?void 0:a.getAttribute("data-pin"))??0);r.addEventListener("input",()=>this.callbacks.onPinNoteChange(s,r.value))})}}function $(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function Pe(e){return new Promise(t=>{const n=document.createElement("div");n.className="beacon-pin-popover open beacon-no-capture beacon-theme-auto",n.innerHTML=`
62
+ <div class="beacon-pin-popover-header">
63
+ <div style="display:flex;align-items:center;gap:6px;font-weight:600;font-size:13px;">
64
+ <span class="beacon-pin-num">${e.pinNumber}</span>
65
+ <span>Note for this pin</span>
66
+ </div>
67
+ <button type="button" class="beacon-icon-btn" data-action="cancel" aria-label="Discard this pin">${A.close}</button>
68
+ </div>
69
+ <textarea class="beacon-textarea" rows="2" placeholder="Optional — describe what's wrong here…" style="min-height:48px;"></textarea>
70
+ <div class="beacon-pin-popover-actions">
71
+ <button type="button" class="beacon-btn primary" data-action="save">${A.check} Save</button>
72
+ </div>
73
+ `;const o=240,i=160,r=Math.min(Math.max(8,e.anchor.x),window.innerWidth-o-8),a=Math.min(Math.max(8,e.anchor.y+12),window.innerHeight-i-8);n.style.left=`${r}px`,n.style.top=`${a}px`,document.body.appendChild(n);const s=n.querySelector("textarea");s.focus();function c(u){document.removeEventListener("keydown",d,!0),n.remove(),t(u)}function d(u){u.key==="Escape"&&(u.preventDefault(),u.stopPropagation(),c({cancelled:"all"}))}document.addEventListener("keydown",d,!0),n.addEventListener("click",u=>{var w;const y=(w=u.target.closest("[data-action]"))==null?void 0:w.getAttribute("data-action");if(y==="cancel"&&c({cancelled:"pin"}),y==="save"){const v=s.value.trim();c({...v?{note:v}:{},cancelled:!1})}}),s.addEventListener("keydown",u=>{if(u.key==="Enter"&&(u.metaKey||u.ctrlKey)){u.preventDefault();const b=s.value.trim();c({...b?{note:b}:{},cancelled:!1})}})})}const P="beacon-no-capture",Me="#0ea5e9",V="Click any element to pin it · Press Esc to finish";function q(e,t){return/^#[0-9a-fA-F]{6}$/.test(e)?`${e}${t}`:e}function Ie(e={}){const t=e.accent??Me,n=q(t,"b3"),o=q(t,"2e"),i=document.createElement("style");i.className=P,i.textContent="@keyframes beacon-spin { to { transform: rotate(360deg); } }",document.head.appendChild(i);const r=document.createElement("div");r.className=P,r.setAttribute("aria-hidden","true"),r.style.cssText=["position: fixed","inset: 0","pointer-events: none","z-index: 2147483646",`border: 2px dashed ${n}`,"border-radius: 4px",`box-shadow: inset 0 0 56px ${o}`,"box-sizing: border-box"].join("; ");const a=document.createElement("div");a.className=P,a.setAttribute("role","status"),a.style.cssText=["position: fixed","top: 16px","left: 50%","transform: translateX(-50%)",`background: ${t}`,"color: #fff","padding: 6px 14px","border-radius: 999px","font: 500 12px/1.4 system-ui, -apple-system, sans-serif","letter-spacing: 0.01em","box-shadow: 0 4px 12px #0000004d","pointer-events: none","white-space: nowrap","z-index: 2147483646"].join("; "),a.textContent=V;const s=`<span style="
74
+ display: inline-block;
75
+ width: 12px;
76
+ height: 12px;
77
+ border: 2px solid #fff;
78
+ border-top-color: transparent;
79
+ border-radius: 50%;
80
+ animation: beacon-spin 800ms linear infinite;
81
+ vertical-align: middle;
82
+ margin-right: 8px;
83
+ "></span>`;function c(l){return l.replace(/[<>&]/g,f=>({"<":"&lt;",">":"&gt;","&":"&amp;"})[f])}document.body.appendChild(r),document.body.appendChild(a);const d=new Map;function u(l){const f=document.createElement("div");return f.className=P,f.setAttribute("aria-hidden","true"),f.style.cssText=["position: fixed","width: 24px","height: 24px","border-radius: 999px",`background: ${t}`,"color: #fff","display: flex","align-items: center","justify-content: center","font: 700 12px/1 system-ui, -apple-system, sans-serif","border: 2px solid #fff","box-shadow: 0 2px 8px #00000066","pointer-events: none","z-index: 2147483646"].join("; "),f.textContent=String(l),document.body.appendChild(f),f}function b(){const l=document.createElement("div");return l.className=P,l.setAttribute("aria-hidden","true"),l.style.cssText=["position: fixed","pointer-events: none",`border: 2px solid ${t}`,"border-radius: 2px","box-sizing: border-box","z-index: 2147483645"].join("; "),document.body.appendChild(l),l}function y(l,f,h){const p=h?"0.5":"1";l.outline.style.display="block",l.outline.style.opacity=p,l.outline.style.left=`${f.x}px`,l.outline.style.top=`${f.y}px`,l.outline.style.width=`${f.w}px`,l.outline.style.height=`${f.h}px`,l.marker.style.display="flex",l.marker.style.opacity=p,l.marker.style.left=`${f.x+f.w-12}px`,l.marker.style.top=`${Math.max(2,f.y-12)}px`}function w(l){l.marker.style.display="none",l.outline.style.display="none"}function v(){d.forEach(l=>{let f=l.anchor.target;if(document.contains(f)||(f=null),!f&&l.anchor.selector&&(f=document.querySelector(l.anchor.selector),f&&(l.anchor.target=f)),f){const p=f.getBoundingClientRect();if(p.width>0||p.height>0){y(l,{x:p.left,y:p.top,w:p.width,h:p.height},!1);return}}const h=l.anchor.fallbackRect;if(h&&(h.w>0||h.h>0)){y(l,h,!0);return}w(l)})}let E=null;function x(){E===null&&(E=requestAnimationFrame(()=>{E=null,v()}))}return window.addEventListener("scroll",x,!0),window.addEventListener("resize",x),{addPin(l,f){const h=u(l),p=b();d.set(l,{anchor:f,marker:h,outline:p}),v()},setLoading(l){l?a.innerHTML=s+c(l):a.textContent=V},destroy(){window.removeEventListener("scroll",x,!0),window.removeEventListener("resize",x),E!==null&&cancelAnimationFrame(E),r.remove(),a.remove(),i.remove(),d.forEach(({marker:l,outline:f})=>{l.remove(),f.remove()}),d.clear()}}}const _e="#0ea5e9";function De(e,t){return/^#[0-9a-fA-F]{6}$/.test(e)?`${e}${t}`:e}function Fe(e){const{shadowRoot:t,onHover:n}=e,o=e.accent??_e,i=De(o,"14"),r=document.createElement("div");r.style.cssText=["position: fixed","pointer-events: none","z-index: 2147483646",`border: 2px solid ${o}`,`background: ${i}`,"transition: all 60ms ease-out","box-sizing: border-box","border-radius: 2px"].join("; "),document.body.appendChild(r);const a=document.createElement("div");a.style.cssText=["position: fixed","pointer-events: none","z-index: 2147483647","background: #0f172a","color: #fff","font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace","padding: 3px 6px","border-radius: 3px","max-width: 280px","overflow: hidden","text-overflow: ellipsis","white-space: nowrap"].join("; "),document.body.appendChild(a);const s=document.body.style.cursor;document.body.style.cursor="crosshair";let c=!1,d=()=>{};const u=new Promise(h=>{d=h});function b(h){if(!h||!(h instanceof Node))return!1;let p=h;for(;p;){if(p===t||p===t.host)return!0;p=p.parentNode??p.host??null}return!1}function y(h,p){r.style.display="none",a.style.display="none";const N=document.elementsFromPoint(h,p);r.style.display="block",a.style.display="block";for(const O of N)if(!b(O))return O;return null}function w(h){const p=h.getBoundingClientRect();r.style.left=`${p.left}px`,r.style.top=`${p.top}px`,r.style.width=`${p.width}px`,r.style.height=`${p.height}px`;const N=h.tagName.toLowerCase(),O=h.classList.length>0?"."+Array.from(h.classList).slice(0,2).join("."):"";a.textContent=N+O;const Le=p.top-22;a.style.left=`${p.left}px`,a.style.top=`${Le>=0?Le:p.bottom+4}px`}function v(h){const p=y(h.clientX,h.clientY);p?(w(p),n==null||n(p)):(r.style.display="none",a.style.display="none",n==null||n(null))}function E(h){if(h.button!==0)return;h.preventDefault(),h.stopPropagation();const p=y(h.clientX,h.clientY);p&&f(p)}function x(h){h.preventDefault(),h.stopPropagation()}function l(h){h.key==="Escape"&&(h.preventDefault(),f(null))}function f(h){c||(c=!0,document.removeEventListener("mousemove",v,!0),document.removeEventListener("pointerdown",E,!0),document.removeEventListener("click",x,!0),document.removeEventListener("mouseup",x,!0),document.removeEventListener("keydown",l,!0),r.remove(),a.remove(),document.body.style.cursor=s,d(h))}return document.addEventListener("mousemove",v,!0),document.addEventListener("pointerdown",E,!0),document.addEventListener("click",x,!0),document.addEventListener("mouseup",x,!0),document.addEventListener("keydown",l,!0),{cancel:()=>f(null),promise:u}}const Oe=8;function K(e,t=document){if(!e)return!1;try{return t.querySelectorAll(`#${CSS.escape(e)}`).length===1}catch{return!1}}function Be(e){const t=e.tagName.toLowerCase(),n=Array.from(e.classList).filter(o=>o.length>0&&o.length<40).slice(0,3).map(o=>`.${CSS.escape(o)}`).join("");return t+n}function He(e){const t=e.parentElement;return t?Array.from(t.children).filter(o=>o.tagName===e.tagName).indexOf(e)+1:1}function ze(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return"";if(e.id&&K(e.id))return`#${CSS.escape(e.id)}`;const t=[];let n=e,o=0;for(;n&&n.tagName.toLowerCase()!=="body"&&o<Oe;){const i=n;if(i.id&&K(i.id)){t.unshift(`#${CSS.escape(i.id)}`);break}const r=Be(i),a=i.parentElement;let s=r;if(a)try{const c=Array.from(i.classList).join(" ");Array.from(a.children).filter(u=>u.tagName===i.tagName&&Array.from(u.classList).join(" ")===c).length>1&&(s=`${i.tagName.toLowerCase()}:nth-of-type(${He(i)})`)}catch{}t.unshift(s),n=a,o++}return t.join(" > ")}function Ue(e){const t=Object.keys(e).filter(o=>o.startsWith("__reactFiber$")||o.startsWith("__reactInternalInstance$"));if(t.length===0)return null;let n=e[t[0]];for(let o=0;o<10&&n;o++){const i=n,r=i.type;if(typeof r=="function"){const a=r.displayName??r.name;if(a&&a!=="_default")return{lib:"react",name:a}}if(typeof r=="object"&&r!==null){const a=r.displayName??r.name;if(a)return{lib:"react",name:a}}n=i.return}return{lib:"react"}}function je(e){var o,i;const t=e,n=t.__vueParentComponent;if(n){const r=((o=n.type)==null?void 0:o.name)??((i=n.type)==null?void 0:i.__name);return{lib:"vue",...r?{name:r}:{}}}return t.__vue__?{lib:"vue"}:null}function We(e){const t=window.ng;if(!(t!=null&&t.getComponent))return null;try{const n=t.getComponent(e);if(!n)return null;const o=n.constructor;return{lib:"angular",...o!=null&&o.name?{name:o.name}:{}}}catch{return null}}function Ne(e){return"__svelte_meta"in e?{lib:"svelte"}:null}function G(e){return Ue(e)??je(e)??We(e)??Ne(e)??void 0}const Ve=5e3,qe=1e3,X=1e3,Y=200,Ke=50,J=200,Ge=500,Xe=["display","position","top","right","bottom","left","width","height","min-width","min-height","max-width","max-height","margin","padding","font-family","font-size","font-weight","line-height","text-align","color","background-color","background-image","border","border-radius","opacity","visibility","overflow","z-index","transform","transition","flex","flex-direction","justify-content","align-items","gap","grid-template-columns","grid-template-rows"];function Q(e,t){return e.length<=t?e:e.slice(0,t)+`
84
+
85
+ /* … truncated, original was ${e.length} chars */`}function Ye(e){const t=getComputedStyle(e),n={};for(const o of Xe){const i=t.getPropertyValue(o);i&&i!=="normal"&&i!=="none"&&i!=="auto"&&i!=="0px"&&(n[o]=i.trim().slice(0,Ge))}return n}function Je(e){return Array.from(e.classList).slice(0,Ke).map(n=>n.length>J?n.slice(0,J):n)}function Qe(e){const t=e.getBoundingClientRect(),n=ze(e),o=e.id||null;return{selector:n.length>X?n.slice(0,X):n,tagName:e.tagName.toLowerCase(),id:o&&o.length>Y?o.slice(0,Y):o,classList:Je(e),outerHTML:Q(e.outerHTML,Ve),...e.parentElement?{parentOuterHTML:Q(e.parentElement.outerHTML,qe)}:{},computedStyles:Ye(e),boundingRect:{x:Math.round(t.x),y:Math.round(t.y),w:Math.round(t.width),h:Math.round(t.height)},...G(e)?{framework:G(e)}:{}}}function Z(){var n,o;const e=navigator;return e.userAgentData?{brand:((n=e.userAgentData.brands.find(i=>!/Not[.\-]?A.?Brand/i.test(i.brand)))==null?void 0:n.brand)??((o=e.userAgentData.brands[0])==null?void 0:o.brand)??"unknown",mobile:e.userAgentData.mobile,platform:e.userAgentData.platform}:void 0}function ee(){if(window.matchMedia("(prefers-color-scheme: dark)").matches)return"dark";if(window.matchMedia("(prefers-color-scheme: light)").matches)return"light"}function te(){return{url:window.location.href,...document.referrer?{referrer:document.referrer}:{},userAgent:navigator.userAgent,...Z()?{uaData:Z()}:{},viewport:{w:window.innerWidth,h:window.innerHeight,dpr:window.devicePixelRatio||1},screen:{w:window.screen.width,h:window.screen.height},timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,locale:navigator.language,...ee()?{theme:ee()}:{},capturedAt:new Date().toISOString()}}let B=null;async function Ze(){return B||(B=await Promise.resolve().then(()=>dn)),B}const I="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkAAIAAAoAAv/lxKUAAAAASUVORK5CYII=";function ne(e,t){if(!e||e.startsWith("data:")||e.startsWith("blob:")||e.startsWith("/")||e.startsWith("#"))return!0;try{if(new URL(e,window.location.href).origin===window.location.origin)return!0}catch{return!1}return t==="anonymous"||t==="use-credentials"}function et(){const e=[],t=[];return document.querySelectorAll("img").forEach(n=>{ne(n.src,n.crossOrigin)||(e.push({el:n,src:n.src}),n.src=I)}),document.querySelectorAll("image").forEach(n=>{const o=n,i=o.getAttribute("href"),r=o.getAttributeNS("http://www.w3.org/1999/xlink","href"),a=i||r||"";a&&!ne(a)&&(t.push({el:o,href:i,xlink:r}),i!==null&&o.setAttribute("href",I),r!==null&&o.setAttributeNS("http://www.w3.org/1999/xlink","href",I))}),()=>{for(const{el:n,src:o}of e)n.src=o;for(const{el:n,href:o,xlink:i}of t)o!==null&&n.setAttribute("href",o),i!==null&&n.setAttributeNS("http://www.w3.org/1999/xlink","href",i)}}async function oe(e={}){const{quality:t=.7,pixelRatio:n=Math.min(window.devicePixelRatio||1,2),excludeShadowRoot:o}=e,i=await Ze(),r=o?s=>{let c=s;for(;c;){if(c===o.host||c instanceof Element&&c.classList.contains("beacon-no-capture"))return!1;c=c.parentNode}return!0}:void 0,a=et();try{return await i.toJpeg(document.documentElement,{quality:t,pixelRatio:n,cacheBust:!0,...r?{filter:r}:{},imagePlaceholder:I,width:window.innerWidth,height:window.innerHeight,style:{transform:"none"}})}finally{a()}}const tt=14,nt="#ffffff",ot="#ffffff",rt=3,it="#0ea5e9";async function re(e,t,n,o,i=it){const r=i,a=i,s=await st(e),c=document.createElement("canvas");c.width=s.naturalWidth,c.height=s.naturalHeight;const d=c.getContext("2d");if(!d)throw new Error("Could not get 2D canvas context");d.drawImage(s,0,0);const u=c.width/n.w,b=c.height/n.h;for(const y of t){const w=at(y,o);if(!w)continue;const v=w.x*u,E=w.y*b,x=w.w*u,l=w.h*b;d.lineWidth=rt,d.strokeStyle=a,d.strokeRect(v,E,x,l);const f=v+x,h=E;d.beginPath(),d.fillStyle=r,d.arc(f,h,tt,0,Math.PI*2),d.fill(),d.lineWidth=3,d.strokeStyle=nt,d.stroke(),d.fillStyle=ot,d.font="bold 16px system-ui, -apple-system, sans-serif",d.textAlign="center",d.textBaseline="middle",d.fillText(String(y.number),f,h+1)}return c.toDataURL("image/jpeg",.85)}function at(e,t){const n=t==null?void 0:t.get(e);if(n&&document.contains(n)){const o=n.getBoundingClientRect();if(o.width>0||o.height>0)return{x:o.left,y:o.top,w:o.width,h:o.height}}if(e.selector)try{const o=document.querySelector(e.selector);if(o){const i=o.getBoundingClientRect();if(i.width>0||i.height>0)return{x:i.left,y:i.top,w:i.width,h:i.height}}}catch{}return e.boundingRect}function st(e){return new Promise((t,n)=>{const o=new Image;o.onload=()=>t(o),o.onerror=i=>n(i),o.src=e})}async function ct(e,t,n){const o=await fetch(e,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...n??{}},body:JSON.stringify(t)});let i=null;if((o.headers.get("Content-Type")??"").includes("application/json"))try{i=await o.json()}catch{i=null}else try{i=await o.text()}catch{i=null}return{ok:o.ok,status:o.status,body:i}}const lt=["endpoint","position","theme","severities"],ie="launch-kit-beacon-portal-styles";function dt(e){if(document.getElementById(ie))return;const t=document.createElement("style");t.id=ie,t.textContent=e,document.head.appendChild(t)}const ut=["--beacon-accent","--beacon-bg","--beacon-fg","--beacon-muted","--beacon-border","--beacon-radius","--beacon-shadow","--beacon-z-index","--beacon-bug","--beacon-idea","--beacon-ux","--beacon-a11y"],ae="#0ea5e9";class se extends HTMLElement{constructor(){super(...arguments),this._config=null,this.pins=[],this.pinElements=new WeakMap,this.description="",this.severity="bug",this.submitSucceeded=!1}static get observedAttributes(){return lt}set config(t){this._config=t}get config(){if(this._config)return this._config;const t=this.getAttribute("endpoint");return t?{endpoint:t}:null}connectedCallback(){if(!this.shadow){this.shadow=this.attachShadow({mode:"open"});const t=document.createElement("style");t.textContent=L,this.shadow.appendChild(t),this.slotEl=document.createElement("slot"),this.slotEl.name="trigger",this.shadow.appendChild(this.slotEl),this.trigger=Re(),this.shadow.appendChild(this.trigger),this.trigger.addEventListener("click",()=>this.open()),this.slotEl.addEventListener("slotchange",()=>{const n=this.slotEl.assignedElements();n.length>0&&(this.trigger&&(this.trigger.style.display="none"),n.forEach(o=>o.addEventListener("click",()=>this.open())))}),this.drawer=new $e(this.parseSeverities(),{onClose:()=>this.close(),onAnnotate:()=>this.startAnnotate(),onSubmit:()=>this.handleSubmit(),onPinNoteChange:(n,o)=>this.updatePinNote(n,o),onPinDelete:n=>this.deletePin(n),onDescriptionChange:n=>{this.description=n},onSeverityChange:n=>{this.severity=n}}),dt(L),this.drawer.root.classList.add("beacon-no-capture"),this.drawer.root.classList.add(`beacon-theme-${this.getAttribute("theme")??"auto"}`),document.body.appendChild(this.drawer.root)}this.hasAttribute("position")||this.setAttribute("position","bottom-right"),this.hasAttribute("theme")||this.setAttribute("theme","auto")}attributeChangedCallback(t,n,o){t==="severities"&&this.drawer&&console.warn("[launch-kit-beacon] severities attribute changed after mount; not yet hot-reloaded."),t==="theme"&&this.drawer&&n!==o&&(this.drawer.root.classList.remove(`beacon-theme-${n??"auto"}`),this.drawer.root.classList.add(`beacon-theme-${o??"auto"}`))}open(){var t;if(this.drawer){if(this.getAttribute("position")==="hidden"){const n=(t=this.slotEl)==null?void 0:t.assignedElements()[0];n&&ft(this.drawer.root,n)}this.submitSucceeded=!1,this.syncCustomProperties(),this.installClickBlocker(),this.drawer.open()}}close(){this.drawer&&(!this.submitSucceeded&&this.hasUnsavedData()&&!window.confirm("You have unsaved feedback. Close and discard it?")||this.forceClose())}disconnectedCallback(){this.uninstallClickBlocker(),this.drawer&&this.drawer.root.parentNode&&this.drawer.root.parentNode.removeChild(this.drawer.root)}async openWithPicker(){this.open(),setTimeout(()=>this.startAnnotate(),0)}async startAnnotate(){if(!this.drawer)return;this.drawer.minimize();const t=this.getAccentColor(),n=Ie({accent:t});for(const o of this.pins){const i=this.pinElements.get(o);i&&n.addPin(o.number,{target:i,selector:o.selector,fallbackRect:o.boundingRect})}try{let o=!0;for(;o;){const r=await Fe({shadowRoot:this.shadow,accent:t}).promise;if(!r)break;const a=r.getBoundingClientRect(),s=await Pe({shadowRoot:this.shadow,anchor:{x:a.left,y:a.bottom},pinNumber:this.pins.length+1});if(s.cancelled==="all")break;if(s.cancelled==="pin")continue;const c=Qe(r),d={number:this.pins.length+1,...c,...s.note?{note:s.note}:{}};this.pins.push(d),this.pinElements.set(d,r),n.addPin(d.number,{target:r,selector:c.selector,fallbackRect:c.boundingRect})}if(this.pins.length>0){n.setLoading("Capturing screenshot…"),await new Promise(i=>requestAnimationFrame(()=>i()));try{const i=te(),r=await oe({excludeShadowRoot:this.shadow}),a=await re(r,this.pins,i.viewport,this.pinElements,t);this.drawer.setPins(this.pins,a)}catch(i){const r=i instanceof Error?i.message:String(i);console.error("[launch-kit-beacon] screenshot capture failed:",i),this.drawer.setPins(this.pins),this.drawer.setStatus(`Screenshot capture failed: ${r}`,"error")}}}finally{n.destroy()}this.drawer.open()}updatePinNote(t,n){const o=this.pins.find(i=>i.number===t);o&&(n.trim()?o.note=n:delete o.note)}deletePin(t){var n,o;this.pins=this.pins.filter(i=>i.number!==t),this.pins.forEach((i,r)=>{i.number=r+1}),(n=this.drawer)==null||n.setAnnotatedScreenshot(void 0),(o=this.drawer)==null||o.setPins(this.pins)}async handleSubmit(){if(!this.drawer)return;const t=this.config;if(!(t!=null&&t.endpoint)){this.drawer.setStatus("Missing endpoint configuration","error");return}const n=this.drawer.getDescription().trim(),o=this.drawer.getSeverity();if(!n){this.drawer.setStatus("Description is required","error");return}this.drawer.setSubmitting(!0);let i=this.drawer.getAnnotatedScreenshot();const r=!i&&this.pins.length>0;this.drawer.setStatus(r?"Capturing screenshot…":"Sending…"),await new Promise(u=>requestAnimationFrame(()=>u()));const a=te();if(r)try{const u=await oe({excludeShadowRoot:this.shadow});i=await re(u,this.pins,a.viewport,this.pinElements,this.getAccentColor())}catch(u){console.error("[launch-kit-beacon] screenshot capture failed at submit:",u)}const s={description:n,severity:o,...i?{screenshot:{dataUrl:i,mime:"image/jpeg"}}:{},metadata:a,pins:this.pins,...this.resolveContext()?{context:this.resolveContext()}:{}},c=new CustomEvent("beacon-before-submit",{detail:{payload:s},cancelable:!0,bubbles:!0,composed:!0});if(!this.dispatchEvent(c)){this.drawer.setSubmitting(!1),this.drawer.setStatus("Submission cancelled","error");return}this.drawer.setStatus("Sending…");try{const u=this.resolveHeaders(),b=await ct(t.endpoint,s,u);this.drawer.setSubmitting(!1),b.ok?(this.submitSucceeded=!0,this.drawer.setStatus("Sent — thanks!","success"),this.dispatchEvent(new CustomEvent("beacon-after-submit",{detail:{response:b},bubbles:!0,composed:!0})),setTimeout(()=>{this.forceClose()},1500)):this.drawer.setStatus(`Failed: ${b.status}`,"error")}catch(u){this.drawer.setSubmitting(!1);const b=u instanceof Error?u.message:"Network error";this.drawer.setStatus(`Failed: ${b}`,"error")}}getAccentColor(){return typeof window>"u"?ae:getComputedStyle(this).getPropertyValue("--beacon-accent").trim()||ae}syncCustomProperties(){if(!this.drawer)return;const t=getComputedStyle(this);for(const n of ut){const o=t.getPropertyValue(n).trim();o&&this.drawer.root.style.setProperty(n,o)}}hasUnsavedData(){var n;return this.pins.length>0?!0:(((n=this.drawer)==null?void 0:n.getDescription())??"").trim().length>0}resetState(){var t;this.pins=[],this.description="",this.severity="bug",this.pinElements=new WeakMap,(t=this.drawer)==null||t.reset()}forceClose(){var t;this.uninstallClickBlocker(),this.resetState(),this.submitSucceeded=!1,(t=this.drawer)==null||t.close()}installClickBlocker(){this.documentClickBlocker||(this.documentClickBlocker=t=>{const n=t.composedPath();if(!n.includes(this.shadow.host)){for(const o of n)if(o instanceof Element&&o.classList.contains("beacon-no-capture"))return;t.preventDefault(),t.stopPropagation()}},document.addEventListener("click",this.documentClickBlocker,!0))}uninstallClickBlocker(){this.documentClickBlocker&&(document.removeEventListener("click",this.documentClickBlocker,!0),this.documentClickBlocker=void 0)}resolveHeaders(){var n;const t=(n=this.config)==null?void 0:n.headers;if(t)return typeof t=="function"?t():t}resolveContext(){var n;const t=(n=this.config)==null?void 0:n.context;if(t)return typeof t=="function"?t():t}parseSeverities(){const t=this.getAttribute("severities");return t?t.split(",").map(n=>n.trim()).filter(Boolean):["bug","idea","ux","a11y"]}}function ce(e="launch-kit-beacon"){typeof window>"u"||customElements.get(e)||customElements.define(e,se)}const le=380,S=8,ht=520;function ft(e,t){const n=t.getBoundingClientRect(),o=window.innerWidth,i=window.innerHeight;let r=Math.max(S,o-n.right);o-r-le<S&&(r=Math.max(S,o-le-S));const s=i-n.bottom-S,c=n.top-S;e.style.left="auto",e.style.right=`${r}px`,s>=ht||s>=c?(e.style.top=`${n.bottom+S}px`,e.style.bottom="auto"):(e.style.top="auto",e.style.bottom=`${i-n.top+S}px`)}ce();function pt(e,t){if(e.match(/^[a-z]+:\/\//i))return e;if(e.match(/^\/\//))return window.location.protocol+e;if(e.match(/^[a-z]+:/i))return e;const n=document.implementation.createHTMLDocument(),o=n.createElement("base"),i=n.createElement("a");return n.head.appendChild(o),n.body.appendChild(i),t&&(o.href=t),i.href=e,i.href}const bt=(()=>{let e=0;const t=()=>`0000${(Math.random()*36**4<<0).toString(36)}`.slice(-4);return()=>(e+=1,`u${t()}${e}`)})();function k(e){const t=[];for(let n=0,o=e.length;n<o;n++)t.push(e[n]);return t}let R=null;function de(e={}){return R||(e.includeStyleProperties?(R=e.includeStyleProperties,R):(R=k(window.getComputedStyle(document.documentElement)),R))}function _(e,t){const o=(e.ownerDocument.defaultView||window).getComputedStyle(e).getPropertyValue(t);return o?parseFloat(o.replace("px","")):0}function mt(e){const t=_(e,"border-left-width"),n=_(e,"border-right-width");return e.clientWidth+t+n}function gt(e){const t=_(e,"border-top-width"),n=_(e,"border-bottom-width");return e.clientHeight+t+n}function H(e,t={}){const n=t.width||mt(e),o=t.height||gt(e);return{width:n,height:o}}function yt(){let e,t;try{t=process}catch{}const n=t&&t.env?t.env.devicePixelRatio:null;return n&&(e=parseInt(n,10),Number.isNaN(e)&&(e=1)),e||window.devicePixelRatio||1}const g=16384;function wt(e){(e.width>g||e.height>g)&&(e.width>g&&e.height>g?e.width>e.height?(e.height*=g/e.width,e.width=g):(e.width*=g/e.height,e.height=g):e.width>g?(e.height*=g/e.width,e.width=g):(e.width*=g/e.height,e.height=g))}function xt(e,t={}){return e.toBlob?new Promise(n=>{e.toBlob(n,t.type?t.type:"image/png",t.quality?t.quality:1)}):new Promise(n=>{const o=window.atob(e.toDataURL(t.type?t.type:void 0,t.quality?t.quality:void 0).split(",")[1]),i=o.length,r=new Uint8Array(i);for(let a=0;a<i;a+=1)r[a]=o.charCodeAt(a);n(new Blob([r],{type:t.type?t.type:"image/png"}))})}function D(e){return new Promise((t,n)=>{const o=new Image;o.onload=()=>{o.decode().then(()=>{requestAnimationFrame(()=>t(o))})},o.onerror=n,o.crossOrigin="anonymous",o.decoding="async",o.src=e})}async function vt(e){return Promise.resolve().then(()=>new XMLSerializer().serializeToString(e)).then(encodeURIComponent).then(t=>`data:image/svg+xml;charset=utf-8,${t}`)}async function Et(e,t,n){const o="http://www.w3.org/2000/svg",i=document.createElementNS(o,"svg"),r=document.createElementNS(o,"foreignObject");return i.setAttribute("width",`${t}`),i.setAttribute("height",`${n}`),i.setAttribute("viewBox",`0 0 ${t} ${n}`),r.setAttribute("width","100%"),r.setAttribute("height","100%"),r.setAttribute("x","0"),r.setAttribute("y","0"),r.setAttribute("externalResourcesRequired","true"),i.appendChild(r),r.appendChild(e),vt(i)}const m=(e,t)=>{if(e instanceof t)return!0;const n=Object.getPrototypeOf(e);return n===null?!1:n.constructor.name===t.name||m(n,t)};function St(e){const t=e.getPropertyValue("content");return`${e.cssText} content: '${t.replace(/'|"/g,"")}';`}function kt(e,t){return de(t).map(n=>{const o=e.getPropertyValue(n),i=e.getPropertyPriority(n);return`${n}: ${o}${i?" !important":""};`}).join(" ")}function Ct(e,t,n,o){const i=`.${e}:${t}`,r=n.cssText?St(n):kt(n,o);return document.createTextNode(`${i}{${r}}`)}function ue(e,t,n,o){const i=window.getComputedStyle(e,n),r=i.getPropertyValue("content");if(r===""||r==="none")return;const a=bt();try{t.className=`${t.className} ${a}`}catch{return}const s=document.createElement("style");s.appendChild(Ct(a,n,i,o)),t.appendChild(s)}function At(e,t,n){ue(e,t,":before",n),ue(e,t,":after",n)}const he="application/font-woff",fe="image/jpeg",Lt={woff:he,woff2:he,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:fe,jpeg:fe,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml",webp:"image/webp"};function Rt(e){const t=/\.([^./]*?)$/g.exec(e);return t?t[1]:""}function z(e){const t=Rt(e).toLowerCase();return Lt[t]||""}function Tt(e){return e.split(/,/)[1]}function U(e){return e.search(/^(data:)/)!==-1}function $t(e,t){return`data:${t};base64,${e}`}async function pe(e,t,n){const o=await fetch(e,t);if(o.status===404)throw new Error(`Resource "${o.url}" not found`);const i=await o.blob();return new Promise((r,a)=>{const s=new FileReader;s.onerror=a,s.onloadend=()=>{try{r(n({res:o,result:s.result}))}catch(c){a(c)}},s.readAsDataURL(i)})}const j={};function Pt(e,t,n){let o=e.replace(/\?.*/,"");return n&&(o=e),/ttf|otf|eot|woff2?/i.test(o)&&(o=o.replace(/.*\//,"")),t?`[${t}]${o}`:o}async function W(e,t,n){const o=Pt(e,t,n.includeQueryParams);if(j[o]!=null)return j[o];n.cacheBust&&(e+=(/\?/.test(e)?"&":"?")+new Date().getTime());let i;try{const r=await pe(e,n.fetchRequestInit,({res:a,result:s})=>(t||(t=a.headers.get("Content-Type")||""),Tt(s)));i=$t(r,t)}catch(r){i=n.imagePlaceholder||"";let a=`Failed to fetch resource: ${e}`;r&&(a=typeof r=="string"?r:r.message),a&&console.warn(a)}return j[o]=i,i}async function Mt(e){const t=e.toDataURL();return t==="data:,"?e.cloneNode(!1):D(t)}async function It(e,t){if(e.currentSrc){const r=document.createElement("canvas"),a=r.getContext("2d");r.width=e.clientWidth,r.height=e.clientHeight,a==null||a.drawImage(e,0,0,r.width,r.height);const s=r.toDataURL();return D(s)}const n=e.poster,o=z(n),i=await W(n,o,t);return D(i)}async function _t(e,t){var n;try{if(!((n=e==null?void 0:e.contentDocument)===null||n===void 0)&&n.body)return await F(e.contentDocument.body,t,!0)}catch{}return e.cloneNode(!1)}async function Dt(e,t){return m(e,HTMLCanvasElement)?Mt(e):m(e,HTMLVideoElement)?It(e,t):m(e,HTMLIFrameElement)?_t(e,t):e.cloneNode(be(e))}const Ft=e=>e.tagName!=null&&e.tagName.toUpperCase()==="SLOT",be=e=>e.tagName!=null&&e.tagName.toUpperCase()==="SVG";async function Ot(e,t,n){var o,i;if(be(t))return t;let r=[];return Ft(e)&&e.assignedNodes?r=k(e.assignedNodes()):m(e,HTMLIFrameElement)&&(!((o=e.contentDocument)===null||o===void 0)&&o.body)?r=k(e.contentDocument.body.childNodes):r=k(((i=e.shadowRoot)!==null&&i!==void 0?i:e).childNodes),r.length===0||m(e,HTMLVideoElement)||await r.reduce((a,s)=>a.then(()=>F(s,n)).then(c=>{c&&t.appendChild(c)}),Promise.resolve()),t}function Bt(e,t,n){const o=t.style;if(!o)return;const i=window.getComputedStyle(e);i.cssText?(o.cssText=i.cssText,o.transformOrigin=i.transformOrigin):de(n).forEach(r=>{let a=i.getPropertyValue(r);r==="font-size"&&a.endsWith("px")&&(a=`${Math.floor(parseFloat(a.substring(0,a.length-2)))-.1}px`),m(e,HTMLIFrameElement)&&r==="display"&&a==="inline"&&(a="block"),r==="d"&&t.getAttribute("d")&&(a=`path(${t.getAttribute("d")})`),o.setProperty(r,a,i.getPropertyPriority(r))})}function Ht(e,t){m(e,HTMLTextAreaElement)&&(t.innerHTML=e.value),m(e,HTMLInputElement)&&t.setAttribute("value",e.value)}function zt(e,t){if(m(e,HTMLSelectElement)){const n=t,o=Array.from(n.children).find(i=>e.value===i.getAttribute("value"));o&&o.setAttribute("selected","")}}function Ut(e,t,n){return m(t,Element)&&(Bt(e,t,n),At(e,t,n),Ht(e,t),zt(e,t)),t}async function jt(e,t){const n=e.querySelectorAll?e.querySelectorAll("use"):[];if(n.length===0)return e;const o={};for(let r=0;r<n.length;r++){const s=n[r].getAttribute("xlink:href");if(s){const c=e.querySelector(s),d=document.querySelector(s);!c&&d&&!o[s]&&(o[s]=await F(d,t,!0))}}const i=Object.values(o);if(i.length){const r="http://www.w3.org/1999/xhtml",a=document.createElementNS(r,"svg");a.setAttribute("xmlns",r),a.style.position="absolute",a.style.width="0",a.style.height="0",a.style.overflow="hidden",a.style.display="none";const s=document.createElementNS(r,"defs");a.appendChild(s);for(let c=0;c<i.length;c++)s.appendChild(i[c]);e.appendChild(a)}return e}async function F(e,t,n){return!n&&t.filter&&!t.filter(e)?null:Promise.resolve(e).then(o=>Dt(o,t)).then(o=>Ot(e,o,t)).then(o=>Ut(e,o,t)).then(o=>jt(o,t))}const me=/url\((['"]?)([^'"]+?)\1\)/g,Wt=/url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g,Nt=/src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;function Vt(e){const t=e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1");return new RegExp(`(url\\(['"]?)(${t})(['"]?\\))`,"g")}function qt(e){const t=[];return e.replace(me,(n,o,i)=>(t.push(i),n)),t.filter(n=>!U(n))}async function Kt(e,t,n,o,i){try{const r=n?pt(t,n):t,a=z(t);let s;return i||(s=await W(r,a,o)),e.replace(Vt(t),`$1${s}$3`)}catch{}return e}function Gt(e,{preferredFontFormat:t}){return t?e.replace(Nt,n=>{for(;;){const[o,,i]=Wt.exec(n)||[];if(!i)return"";if(i===t)return`src: ${o};`}}):e}function ge(e){return e.search(me)!==-1}async function ye(e,t,n){if(!ge(e))return e;const o=Gt(e,n);return qt(o).reduce((r,a)=>r.then(s=>Kt(s,a,t,n)),Promise.resolve(o))}async function T(e,t,n){var o;const i=(o=t.style)===null||o===void 0?void 0:o.getPropertyValue(e);if(i){const r=await ye(i,null,n);return t.style.setProperty(e,r,t.style.getPropertyPriority(e)),!0}return!1}async function Xt(e,t){await T("background",e,t)||await T("background-image",e,t),await T("mask",e,t)||await T("-webkit-mask",e,t)||await T("mask-image",e,t)||await T("-webkit-mask-image",e,t)}async function Yt(e,t){const n=m(e,HTMLImageElement);if(!(n&&!U(e.src))&&!(m(e,SVGImageElement)&&!U(e.href.baseVal)))return;const o=n?e.src:e.href.baseVal,i=await W(o,z(o),t);await new Promise((r,a)=>{e.onload=r,e.onerror=t.onImageErrorHandler?(...c)=>{try{r(t.onImageErrorHandler(...c))}catch(d){a(d)}}:a;const s=e;s.decode&&(s.decode=r),s.loading==="lazy"&&(s.loading="eager"),n?(e.srcset="",e.src=i):e.href.baseVal=i})}async function Jt(e,t){const o=k(e.childNodes).map(i=>we(i,t));await Promise.all(o).then(()=>e)}async function we(e,t){m(e,Element)&&(await Xt(e,t),await Yt(e,t),await Jt(e,t))}function Qt(e,t){const{style:n}=e;t.backgroundColor&&(n.backgroundColor=t.backgroundColor),t.width&&(n.width=`${t.width}px`),t.height&&(n.height=`${t.height}px`);const o=t.style;return o!=null&&Object.keys(o).forEach(i=>{n[i]=o[i]}),e}const xe={};async function ve(e){let t=xe[e];if(t!=null)return t;const o=await(await fetch(e)).text();return t={url:e,cssText:o},xe[e]=t,t}async function Ee(e,t){let n=e.cssText;const o=/url\(["']?([^"')]+)["']?\)/g,r=(n.match(/url\([^)]+\)/g)||[]).map(async a=>{let s=a.replace(o,"$1");return s.startsWith("https://")||(s=new URL(s,e.url).href),pe(s,t.fetchRequestInit,({result:c})=>(n=n.replace(a,`url(${c})`),[a,c]))});return Promise.all(r).then(()=>n)}function Se(e){if(e==null)return[];const t=[],n=/(\/\*[\s\S]*?\*\/)/gi;let o=e.replace(n,"");const i=new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})","gi");for(;;){const c=i.exec(o);if(c===null)break;t.push(c[0])}o=o.replace(i,"");const r=/@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi,a="((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})",s=new RegExp(a,"gi");for(;;){let c=r.exec(o);if(c===null){if(c=s.exec(o),c===null)break;r.lastIndex=s.lastIndex}else s.lastIndex=r.lastIndex;t.push(c[0])}return t}async function Zt(e,t){const n=[],o=[];return e.forEach(i=>{if("cssRules"in i)try{k(i.cssRules||[]).forEach((r,a)=>{if(r.type===CSSRule.IMPORT_RULE){let s=a+1;const c=r.href,d=ve(c).then(u=>Ee(u,t)).then(u=>Se(u).forEach(b=>{try{i.insertRule(b,b.startsWith("@import")?s+=1:i.cssRules.length)}catch(y){console.error("Error inserting rule from remote css",{rule:b,error:y})}})).catch(u=>{console.error("Error loading remote css",u.toString())});o.push(d)}})}catch(r){const a=e.find(s=>s.href==null)||document.styleSheets[0];i.href!=null&&o.push(ve(i.href).then(s=>Ee(s,t)).then(s=>Se(s).forEach(c=>{a.insertRule(c,a.cssRules.length)})).catch(s=>{console.error("Error loading remote stylesheet",s)})),console.error("Error inlining remote css file",r)}}),Promise.all(o).then(()=>(e.forEach(i=>{if("cssRules"in i)try{k(i.cssRules||[]).forEach(r=>{n.push(r)})}catch(r){console.error(`Error while reading CSS rules from ${i.href}`,r)}}),n))}function en(e){return e.filter(t=>t.type===CSSRule.FONT_FACE_RULE).filter(t=>ge(t.style.getPropertyValue("src")))}async function tn(e,t){if(e.ownerDocument==null)throw new Error("Provided element is not within a Document");const n=k(e.ownerDocument.styleSheets),o=await Zt(n,t);return en(o)}function ke(e){return e.trim().replace(/["']/g,"")}function nn(e){const t=new Set;function n(o){(o.style.fontFamily||getComputedStyle(o).fontFamily).split(",").forEach(r=>{t.add(ke(r))}),Array.from(o.children).forEach(r=>{r instanceof HTMLElement&&n(r)})}return n(e),t}async function Ce(e,t){const n=await tn(e,t),o=nn(e);return(await Promise.all(n.filter(r=>o.has(ke(r.style.fontFamily))).map(r=>{const a=r.parentStyleSheet?r.parentStyleSheet.href:null;return ye(r.cssText,a,t)}))).join(`
86
+ `)}async function on(e,t){const n=t.fontEmbedCSS!=null?t.fontEmbedCSS:t.skipFonts?null:await Ce(e,t);if(n){const o=document.createElement("style"),i=document.createTextNode(n);o.appendChild(i),e.firstChild?e.insertBefore(o,e.firstChild):e.appendChild(o)}}async function Ae(e,t={}){const{width:n,height:o}=H(e,t),i=await F(e,t,!0);return await on(i,t),await we(i,t),Qt(i,t),await Et(i,n,o)}async function M(e,t={}){const{width:n,height:o}=H(e,t),i=await Ae(e,t),r=await D(i),a=document.createElement("canvas"),s=a.getContext("2d"),c=t.pixelRatio||yt(),d=t.canvasWidth||n,u=t.canvasHeight||o;return a.width=d*c,a.height=u*c,t.skipAutoScale||wt(a),a.style.width=`${d}`,a.style.height=`${u}`,t.backgroundColor&&(s.fillStyle=t.backgroundColor,s.fillRect(0,0,a.width,a.height)),s.drawImage(r,0,0,a.width,a.height),a}async function rn(e,t={}){const{width:n,height:o}=H(e,t);return(await M(e,t)).getContext("2d").getImageData(0,0,n,o).data}async function an(e,t={}){return(await M(e,t)).toDataURL()}async function sn(e,t={}){return(await M(e,t)).toDataURL("image/jpeg",t.quality||1)}async function cn(e,t={}){const n=await M(e,t);return await xt(n)}async function ln(e,t={}){return Ce(e,t)}const dn=Object.freeze(Object.defineProperty({__proto__:null,getFontEmbedCSS:ln,toBlob:cn,toCanvas:M,toJpeg:sn,toPixelData:rn,toPng:an,toSvg:Ae},Symbol.toStringTag,{value:"Module"}));C.LaunchKitBeacon=se,C.defineBeacon=ce,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});
87
+ //# sourceMappingURL=beacon.umd.js.map