@w6w/embed 0.2.1 → 0.2.19

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 (185) hide show
  1. package/README.md +22 -5
  2. package/dist/ConfirmModal-Pv2-A_3U.js +186 -0
  3. package/dist/ConfirmModal-Pv2-A_3U.js.map +1 -0
  4. package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-DScxp_LN.js} +25 -25
  5. package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-DScxp_LN.js.map} +1 -1
  6. package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-Br4s8wmi.js} +5 -5
  7. package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-Br4s8wmi.js.map} +1 -1
  8. package/dist/ImportSpecModal-Cpzp8ndt.js +251 -0
  9. package/dist/ImportSpecModal-Cpzp8ndt.js.map +1 -0
  10. package/dist/ModelRoutesManager-1Ac5wcas.js +345 -0
  11. package/dist/ModelRoutesManager-1Ac5wcas.js.map +1 -0
  12. package/dist/WorkflowEditor-CmhXHRxi.js +1109 -0
  13. package/dist/WorkflowEditor-CmhXHRxi.js.map +1 -0
  14. package/dist/apps-ItBvnWX3.js +92 -0
  15. package/dist/apps-ItBvnWX3.js.map +1 -0
  16. package/dist/{callables-3mFrMVG_.js → callables-tOlflvbl.js} +11 -11
  17. package/dist/{callables-3mFrMVG_.js.map → callables-tOlflvbl.js.map} +1 -1
  18. package/dist/chrome/ConfirmModal.d.ts +4 -1
  19. package/dist/chrome/DangerZone.d.ts +4 -3
  20. package/dist/chrome/ExecutionProfileHeader.d.ts +3 -3
  21. package/dist/chrome/JsonToggle.d.ts +29 -20
  22. package/dist/chrome/Modal.d.ts +3 -1
  23. package/dist/chrome/RightRail.d.ts +6 -1
  24. package/dist/chrome/VersionHistoryModal.d.ts +2 -0
  25. package/dist/chrome/index.d.ts +1 -0
  26. package/dist/chrome/workspace.d.ts +36 -1
  27. package/dist/coerce-input-DFJ4n_wc.js +150 -0
  28. package/dist/coerce-input-DFJ4n_wc.js.map +1 -0
  29. package/dist/connections-CzsCyIxY.js +119 -0
  30. package/dist/connections-CzsCyIxY.js.map +1 -0
  31. package/dist/credentials-Cn92LGhJ.js +171 -0
  32. package/dist/credentials-Cn92LGhJ.js.map +1 -0
  33. package/dist/data-stores-UeQvwVCa.js +170 -0
  34. package/dist/data-stores-UeQvwVCa.js.map +1 -0
  35. package/dist/document-sources-DNmBojx6.js +169 -0
  36. package/dist/document-sources-DNmBojx6.js.map +1 -0
  37. package/dist/draft/use-workflow-draft.d.ts +2 -0
  38. package/dist/draft.mjs +2 -2
  39. package/dist/editor/BindingBanner.d.ts +13 -0
  40. package/dist/editor/CallableEditorFrame.d.ts +7 -0
  41. package/dist/editor/EndpointCards.d.ts +4 -1
  42. package/dist/editor/PublishControl.d.ts +19 -0
  43. package/dist/editor/PublishTooltip.d.ts +7 -0
  44. package/dist/editor/SetupIncompleteBanner.d.ts +12 -0
  45. package/dist/editor/StartingStateModal.d.ts +14 -0
  46. package/dist/editor/TargetSelector.d.ts +15 -0
  47. package/dist/editor/TargetSelector.types.d.ts +2 -0
  48. package/dist/editor/WorkflowSettingsModal.d.ts +6 -1
  49. package/dist/editor/WorkflowVariablesEditor.d.ts +6 -0
  50. package/dist/editor/definition.d.ts +6 -0
  51. package/dist/editor/json-apply.d.ts +29 -0
  52. package/dist/editor/step-problems-feed.d.ts +5 -0
  53. package/dist/editor/types.d.ts +2 -2
  54. package/dist/editor-apps-DkkC7wOQ.js +152 -0
  55. package/dist/editor-apps-DkkC7wOQ.js.map +1 -0
  56. package/dist/editor-tools-BR27RGto.js +1683 -0
  57. package/dist/editor-tools-BR27RGto.js.map +1 -0
  58. package/dist/editor.mjs +1 -1
  59. package/dist/editors.mjs +855 -650
  60. package/dist/editors.mjs.map +1 -1
  61. package/dist/{endpoints-B2ynbZo-.js → endpoints-DSRo1Lc5.js} +113 -107
  62. package/dist/endpoints-DSRo1Lc5.js.map +1 -0
  63. package/dist/fields-DvS8XZFc.js +21 -0
  64. package/dist/fields-DvS8XZFc.js.map +1 -0
  65. package/dist/forms/ModelBudgetsManager.d.ts +9 -0
  66. package/dist/forms/ModelRoutesManager.d.ts +14 -0
  67. package/dist/forms.d.ts +4 -0
  68. package/dist/forms.mjs +611 -212
  69. package/dist/forms.mjs.map +1 -1
  70. package/dist/{rail-settings-XYGToh00.js → import-bindings-EUtxZ9Ti.js} +90 -24
  71. package/dist/import-bindings-EUtxZ9Ti.js.map +1 -0
  72. package/dist/index.mjs +154 -117
  73. package/dist/index.mjs.map +1 -1
  74. package/dist/lib/binding-problems.d.ts +42 -0
  75. package/dist/lib/code-rail.d.ts +4 -2
  76. package/dist/lib/history-query.d.ts +45 -0
  77. package/dist/lib/import-bindings.d.ts +89 -0
  78. package/dist/lib/index.d.ts +4 -0
  79. package/dist/lib/invoke-error.d.ts +1 -0
  80. package/dist/lib/rail-settings.d.ts +1 -1
  81. package/dist/lib/sdk-snippets.d.ts +1 -1
  82. package/dist/lib/setup-incomplete.d.ts +22 -0
  83. package/dist/lib/starting-data.d.ts +31 -0
  84. package/dist/lib/state-panel.d.ts +29 -0
  85. package/dist/lib/target-fields.d.ts +11 -15
  86. package/dist/lib/trigger-preview.d.ts +1 -0
  87. package/dist/lib/workflow-live-run.d.ts +93 -8
  88. package/dist/lib/workflow-nodes.d.ts +5 -0
  89. package/dist/lib/workflow-validity.d.ts +65 -16
  90. package/dist/lib/workflow-variables.d.ts +1 -1
  91. package/dist/lib/workflow-version.d.ts +2 -0
  92. package/dist/lib.mjs +86 -69
  93. package/dist/lists/ConnectionDependents.d.ts +31 -0
  94. package/dist/lists/ConnectionDetail.d.ts +4 -1
  95. package/dist/lists/ConnectionList.d.ts +4 -1
  96. package/dist/lists/CredentialDetail.d.ts +15 -0
  97. package/dist/lists/CredentialList.d.ts +14 -0
  98. package/dist/lists/DataStoreList.d.ts +17 -0
  99. package/dist/lists/DataStoreView.d.ts +19 -0
  100. package/dist/lists/Logs.d.ts +19 -0
  101. package/dist/lists/ModelCatalog.d.ts +12 -0
  102. package/dist/lists/ModelUsage.d.ts +12 -0
  103. package/dist/lists.d.ts +14 -0
  104. package/dist/lists.mjs +1766 -609
  105. package/dist/lists.mjs.map +1 -1
  106. package/dist/models-bAayQPJ_.js +270 -0
  107. package/dist/models-bAayQPJ_.js.map +1 -0
  108. package/dist/{project-context-BiCjv_E3.js → project-context-Tvp-La7A.js} +3 -3
  109. package/dist/{project-context-BiCjv_E3.js.map → project-context-Tvp-La7A.js.map} +1 -1
  110. package/dist/rail/ConnectionsTool.d.ts +2 -0
  111. package/dist/rail/HistoryTool.d.ts +2 -0
  112. package/dist/rail/StartingStateTool.d.ts +2 -0
  113. package/dist/rail/settings-sections.d.ts +4 -1
  114. package/dist/rail.mjs +4 -4
  115. package/dist/repos/agents-studio-agents.d.ts +52 -0
  116. package/dist/repos/agents-studio-assets.d.ts +68 -0
  117. package/dist/repos/connections.d.ts +30 -12
  118. package/dist/repos/constants.d.ts +12 -0
  119. package/dist/repos/credentials.d.ts +83 -0
  120. package/dist/repos/data-stores.d.ts +84 -0
  121. package/dist/repos/endpoints.d.ts +9 -3
  122. package/dist/repos/fields.d.ts +34 -0
  123. package/dist/repos/functions.d.ts +7 -5
  124. package/dist/repos/history.d.ts +9 -0
  125. package/dist/repos/index.d.ts +7 -0
  126. package/dist/repos/models.d.ts +289 -0
  127. package/dist/repos/spec-export.d.ts +3 -3
  128. package/dist/repos/spec-import.d.ts +30 -1
  129. package/dist/repos/step-tests.d.ts +2 -0
  130. package/dist/repos/webhook-listen.d.ts +35 -0
  131. package/dist/repos/workflows.d.ts +105 -2
  132. package/dist/repos.mjs +655 -176
  133. package/dist/repos.mjs.map +1 -1
  134. package/dist/setup-incomplete-BHs3Lpfy.js +199 -0
  135. package/dist/setup-incomplete-BHs3Lpfy.js.map +1 -0
  136. package/dist/{slug-C4ktDPdy.js → slug-BVdgiP_L.js} +64 -60
  137. package/dist/slug-BVdgiP_L.js.map +1 -0
  138. package/dist/{spec-export-Cf3VQSQS.js → spec-export-DGy5ijps.js} +73 -60
  139. package/dist/spec-export-DGy5ijps.js.map +1 -0
  140. package/dist/spec-import-SWOonsNr.js +116 -0
  141. package/dist/spec-import-SWOonsNr.js.map +1 -0
  142. package/dist/{step-tests-CivICmTq.js → step-tests-B4E4W3ly.js} +8 -7
  143. package/dist/step-tests-B4E4W3ly.js.map +1 -0
  144. package/dist/theme-context-E2ZhlXDX.js +6 -0
  145. package/dist/theme-context-E2ZhlXDX.js.map +1 -0
  146. package/dist/theme-context.d.ts +2 -0
  147. package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DCauHt5o.js} +23 -23
  148. package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DCauHt5o.js.map} +1 -1
  149. package/dist/use-workflow-draft-l3P5KZzw.js +338 -0
  150. package/dist/use-workflow-draft-l3P5KZzw.js.map +1 -0
  151. package/dist/{workflow-blank-DyL3_RUA.js → workflow-blank-DFpGObrn.js} +6 -6
  152. package/dist/{workflow-blank-DyL3_RUA.js.map → workflow-blank-DFpGObrn.js.map} +1 -1
  153. package/dist/workflows-BZN4Hyz1.js +623 -0
  154. package/dist/workflows-BZN4Hyz1.js.map +1 -0
  155. package/package.json +3 -2
  156. package/src/styles.css +155 -7
  157. package/dist/ConfirmModal-RLbZT5_k.js +0 -181
  158. package/dist/ConfirmModal-RLbZT5_k.js.map +0 -1
  159. package/dist/ImportSpecModal-BDQIf6rg.js +0 -136
  160. package/dist/ImportSpecModal-BDQIf6rg.js.map +0 -1
  161. package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
  162. package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
  163. package/dist/apps-1FNUwbGv.js +0 -77
  164. package/dist/apps-1FNUwbGv.js.map +0 -1
  165. package/dist/coerce-input-BicYr7nc.js +0 -139
  166. package/dist/coerce-input-BicYr7nc.js.map +0 -1
  167. package/dist/connections-CjjYeRqb.js +0 -78
  168. package/dist/connections-CjjYeRqb.js.map +0 -1
  169. package/dist/document-sources-C0grrtdq.js +0 -86
  170. package/dist/document-sources-C0grrtdq.js.map +0 -1
  171. package/dist/editor-apps-BdenSV1o.js +0 -95
  172. package/dist/editor-apps-BdenSV1o.js.map +0 -1
  173. package/dist/editor-tools-RxmY5iyi.js +0 -1279
  174. package/dist/editor-tools-RxmY5iyi.js.map +0 -1
  175. package/dist/endpoints-B2ynbZo-.js.map +0 -1
  176. package/dist/rail-settings-XYGToh00.js.map +0 -1
  177. package/dist/slug-C4ktDPdy.js.map +0 -1
  178. package/dist/spec-export-Cf3VQSQS.js.map +0 -1
  179. package/dist/spec-import-CjmxyZDR.js +0 -465
  180. package/dist/spec-import-CjmxyZDR.js.map +0 -1
  181. package/dist/step-tests-CivICmTq.js.map +0 -1
  182. package/dist/trigger-preview-VPkrryDl.js +0 -120
  183. package/dist/trigger-preview-VPkrryDl.js.map +0 -1
  184. package/dist/use-workflow-draft-DzAyUeA6.js +0 -316
  185. package/dist/use-workflow-draft-DzAyUeA6.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"forms.mjs","sources":["../src/forms/VarsManager.tsx","../src/forms/SecretsManager.tsx"],"sourcesContent":["/**\n * `<VarsManager>` — list, add, edit and delete the project's variables. Variables are\n * plaintext typed values scoped to ONE project (secrets, by contrast, are per account — see\n * `SecretsManager`).\n *\n * The project comes from `useEditorProject(project)`: omitted defers to `<W6WEmbedProvider\n * project>`; `null` or `\"\"` REFUSES — the list query is disabled, no `/vars` request is sent and\n * \"Add\" is disabled. Every list/create/update/delete call names the resolved project, never\n * `undefined` (a project-less write lands in the account default project).\n */\nimport { ApiError } from \"@w6w/sdk\";\nimport type { Var, VarType } from \"@w6w/sdk\";\nimport { Copyable, DeleteButton, EditButton, useEnterSubmit } from \"@w6w/ui\";\nimport { type ReactNode, useState } from \"react\";\nimport { CallFromCodeButton } from \"../chrome/CallFromCodeButton.tsx\";\nimport { ConfirmModal } from \"../chrome/ConfirmModal.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport { useEditorProject } from \"../project-context.ts\";\nimport {\n useCreateVarMutation,\n useDeleteVarMutation,\n useUpdateVarMutation,\n useVarsQuery,\n} from \"../repos/vars.ts\";\n\nconst TYPES: readonly VarType[] = [\"string\", \"number\", \"boolean\", \"json\"];\n\n/** What a function-form `actions` slot receives. */\nexport interface ConfigManagerActionsApi {\n /** Open the create form (a no-op while the manager is refusing, e.g. no project). */\n openCreate: () => void;\n /** `false` when the create control must be disabled (no project). */\n canCreate: boolean;\n}\n\n/**\n * Each slot: omitted ⇒ the built-in default; `null` ⇒ nothing; a node replaces it. `actions` also\n * accepts a function so a host that replaces the default \"+ Add\" button can still open the form.\n */\nexport interface VarsManagerSlots {\n /** The section heading + description. */\n header?: ReactNode;\n /** The trailing control(s) of the head row (the \"+ Add variable\" button). */\n actions?: ReactNode | ((api: ConfigManagerActionsApi) => ReactNode);\n /** Shown instead of the list when there are no variables. */\n empty?: ReactNode;\n}\n\nexport interface VarsManagerProps {\n /**\n * The project whose variables are managed. Omitted: the `<W6WEmbedProvider project>`. `null` or\n * `\"\"`: no project — nothing is requested and nothing can be written.\n */\n project?: string | null;\n slots?: VarsManagerSlots;\n}\n\n/** One-line preview of a var's current value, safe against long strings. */\nfunction previewValue(v: Var): string {\n if (v.type === \"boolean\") return String(v.value);\n if (v.type === \"number\") return String(v.value);\n if (v.type === \"string\") return String(v.value);\n const s = JSON.stringify(v.value);\n return s.length > 80 ? `${s.slice(0, 80)}…` : s;\n}\n\nexport function VarsManager(props: VarsManagerProps): ReactNode {\n const slots = props.slots;\n const project = useEditorProject(props.project);\n const [modal, setModal] = useState<{ mode: \"create\" } | { mode: \"edit\"; v: Var } | null>(null);\n const [pending, setPending] = useState<Var | null>(null);\n\n const varsQuery = useVarsQuery(project ?? undefined, project != null);\n const deleteMut = useDeleteVarMutation();\n const canCreate = project != null;\n const openCreate = () => {\n if (project != null) setModal({ mode: \"create\" });\n };\n\n const header =\n slots?.header === undefined ? (\n <div>\n <h3>Variables</h3>\n <p className=\"muted small\">\n User-defined typed values addressable by name. Plaintext — use <strong>Secrets</strong>{\" \"}\n for sensitive values.\n </p>\n </div>\n ) : (\n slots.header\n );\n const actionsSlot = slots?.actions;\n const actions =\n actionsSlot === undefined ? (\n <button type=\"button\" className=\"btn\" disabled={!canCreate} onClick={openCreate}>\n + Add variable\n </button>\n ) : typeof actionsSlot === \"function\" ? (\n actionsSlot({ openCreate, canCreate })\n ) : (\n actionsSlot\n );\n const empty =\n slots?.empty === undefined ? <p className=\"muted\">No variables yet.</p> : slots.empty;\n\n return (\n <div className=\"w6w-embed-root\">\n <section className=\"section\">\n {(header != null || actions != null) && (\n <div className=\"section-head\">\n {header}\n {actions}\n </div>\n )}\n\n <div className=\"card\">\n {varsQuery.isLoading && <p className=\"muted\">Loading…</p>}\n {varsQuery.data?.length === 0 && empty}\n <ul className=\"list\">\n {varsQuery.data?.map((v) => (\n <li key={v.id}>\n <div className=\"list-main\">\n <strong className=\"list-name\" title={v.name}>\n {v.name}\n </strong>{\" \"}\n <span className=\"tag\">{v.type}</span>\n <div className=\"muted small list-preview\" title={previewValue(v)}>\n <Copyable value={previewValue(v)} readOnly>\n {/* `.w6w-copyable`'s flex rule only targets `> input, > textarea, > pre` —\n never `> code` — so this `<code>` keeps flexbox's automatic min-content\n floor unless told otherwise. `overflowWrap: \"anywhere\"` alone still\n leaves the content unshrunk, pushing the Copy button outside\n `.list-preview`'s clipped box at narrow widths. `minWidth: 0` lets the\n flex item shrink to the box; `overflow`/`textOverflow` give IT the\n ellipsis, restoring the single-line truncation `.list-preview` set up. */}\n <code\n style={{\n overflowWrap: \"anywhere\",\n display: \"block\",\n minWidth: 0,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n flex: 1,\n }}\n >\n {previewValue(v)}\n </code>\n </Copyable>\n {v.description && <> · {v.description}</>}\n </div>\n </div>\n <div style={{ display: \"flex\", gap: \"var(--w6w-sp-1-5)\" }}>\n <CallFromCodeButton resource={{ kind: \"var\", name: v.name }} />\n <EditButton\n label=\"Edit\"\n onClick={() => setModal({ mode: \"edit\", v })}\n data-testid={`var-edit-${v.id}`}\n />\n <DeleteButton\n label=\"Delete\"\n onClick={() => setPending(v)}\n disabled={deleteMut.isPending}\n data-testid={`var-delete-${v.id}`}\n />\n </div>\n </li>\n ))}\n </ul>\n </div>\n\n {modal && project != null && (\n <VarModal\n project={project}\n initial={modal.mode === \"edit\" ? modal.v : undefined}\n onClose={() => setModal(null)}\n onSaved={() => setModal(null)}\n />\n )}\n\n {pending && project != null && (\n <ConfirmModal\n title=\"Delete variable\"\n message={`Delete the variable \"${pending.name}\"? This cannot be undone.`}\n confirmLabel=\"Delete\"\n onConfirm={() => {\n deleteMut.mutate({ id: pending.id, project });\n setPending(null);\n }}\n onClose={() => setPending(null)}\n />\n )}\n </section>\n </div>\n );\n}\n\n/**\n * Create/edit modal. The value widget switches on `type`; the raw string in the form is parsed to\n * the declared type at submit time so what's stored round-trips faithfully (e.g. the number `42`,\n * not the string `\"42\"`).\n */\nfunction VarModal(props: {\n project: string;\n initial?: Var;\n onClose: () => void;\n onSaved: () => void;\n}) {\n const isEdit = !!props.initial;\n const [name, setName] = useState(props.initial?.name ?? \"\");\n const [type, setType] = useState<VarType>(props.initial?.type ?? \"string\");\n const [raw, setRaw] = useState<string>(() => {\n if (!props.initial) return \"\";\n if (props.initial.type === \"string\") return String(props.initial.value ?? \"\");\n return JSON.stringify(props.initial.value, null, 2);\n });\n const [description, setDescription] = useState(props.initial?.description ?? \"\");\n const [error, setError] = useState<string | null>(null);\n\n /** Parse the raw string into a value that matches `type`. */\n function parseValue(): { ok: true; value: unknown } | { ok: false; error: string } {\n if (type === \"string\") return { ok: true, value: raw };\n if (type === \"boolean\") {\n if (raw === \"true\") return { ok: true, value: true };\n if (raw === \"false\") return { ok: true, value: false };\n return { ok: false, error: \"Value must be `true` or `false`.\" };\n }\n if (type === \"number\") {\n const n = Number(raw);\n if (!Number.isFinite(n)) return { ok: false, error: \"Value must be a finite number.\" };\n return { ok: true, value: n };\n }\n // json\n try {\n return { ok: true, value: JSON.parse(raw) };\n } catch (e) {\n return { ok: false, error: `Invalid JSON: ${(e as Error).message}` };\n }\n }\n\n const createMut = useCreateVarMutation();\n const updateMut = useUpdateVarMutation();\n const saving = createMut.isPending || updateMut.isPending;\n\n function save() {\n const parsed = parseValue();\n if (!parsed.ok) {\n setError(parsed.error);\n return;\n }\n setError(null);\n const onSettled = {\n onSuccess: () => props.onSaved(),\n onError: (e: unknown) => setError(e instanceof ApiError ? e.message : (e as Error).message),\n };\n if (props.initial) {\n updateMut.mutate(\n {\n id: props.initial.id,\n patch: { type, value: parsed.value, description },\n project: props.project,\n },\n onSettled,\n );\n return;\n }\n createMut.mutate(\n { input: { name, type, value: parsed.value, description }, project: props.project },\n onSettled,\n );\n }\n\n const enterSubmit = useEnterSubmit(save, { enabled: !!name && !saving });\n\n return (\n <Modal\n title={props.initial ? `Edit ${props.initial.name}` : \"Add variable\"}\n onClose={props.onClose}\n >\n <div className=\"modal-body\">\n <label className=\"field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={name}\n disabled={isEdit}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. api_base_url\"\n maxLength={64}\n {...enterSubmit}\n />\n {!isEdit && (\n <span className=\"hint\">\n Lowercase letters, digits, and underscores. Must start with a letter or underscore.\n </span>\n )}\n </label>\n\n <label className=\"field\">\n <span>Type</span>\n <select value={type} onChange={(e) => setType(e.target.value as VarType)}>\n {TYPES.map((t) => (\n <option key={t} value={t}>\n {t}\n </option>\n ))}\n </select>\n </label>\n\n <label className=\"field\" htmlFor=\"var-value\">\n <span>Value</span>\n {type === \"boolean\" ? (\n <select id=\"var-value\" value={raw || \"true\"} onChange={(e) => setRaw(e.target.value)}>\n <option value=\"true\">true</option>\n <option value=\"false\">false</option>\n </select>\n ) : type === \"number\" ? (\n <input\n id=\"var-value\"\n type=\"number\"\n value={raw}\n onChange={(e) => setRaw(e.target.value)}\n placeholder=\"0\"\n {...enterSubmit}\n />\n ) : type === \"json\" ? (\n <textarea\n id=\"var-value\"\n className=\"code\"\n rows={6}\n value={raw}\n onChange={(e) => setRaw(e.target.value)}\n placeholder='{\"key\": \"value\"}'\n />\n ) : (\n <input\n id=\"var-value\"\n type=\"text\"\n value={raw}\n onChange={(e) => setRaw(e.target.value)}\n placeholder=\"\"\n {...enterSubmit}\n />\n )}\n </label>\n\n <label className=\"field\">\n <span>Description</span>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional\"\n {...enterSubmit}\n />\n </label>\n\n {error && <div className=\"result error\">{error}</div>}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"btn\" disabled={!name || saving} onClick={save}>\n {saving ? \"Saving…\" : isEdit ? \"Save changes\" : \"Save variable\"}\n </button>\n </div>\n </Modal>\n );\n}\n","/**\n * `<SecretsManager>` — list, add, rotate and delete the account's secrets (vault). Secrets are\n * per ACCOUNT, not per project (variables are per project — see `VarsManager`), so there is no\n * `project` prop.\n *\n * WRITE-ONLY. A secret's value is typed into a form and sent; it is never read back. The value\n * field starts empty in create and in rotate; a blank rotate sends no `value` key; a blank create\n * is refused before any request; rows render only `name`, `description`, `updatedAt` and a fixed\n * mask — a row object is never spread or stringified, so a server that wrongly returns `value`\n * cannot reach the DOM. No prop receives, and no callback is handed, a secret value, and nothing\n * here writes the `[\"secrets\"]` cache (only the repo's own invalidation).\n */\nimport { ApiError } from \"@w6w/sdk\";\nimport { DeleteButton, EditButton, useEnterSubmit } from \"@w6w/ui\";\nimport { type ReactNode, useState } from \"react\";\nimport { ConfirmModal } from \"../chrome/ConfirmModal.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport {\n type VaultSecretSummary,\n useCreateSecretMutation,\n useDeleteSecretMutation,\n useSecretsQuery,\n useUpdateSecretMutation,\n} from \"../repos/vault.ts\";\nimport type { ConfigManagerActionsApi } from \"./VarsManager.tsx\";\n\n/** Same contract as `VarsManagerSlots`: omitted ⇒ default, `null` ⇒ nothing, a node replaces. */\nexport interface SecretsManagerSlots {\n header?: ReactNode;\n actions?: ReactNode | ((api: ConfigManagerActionsApi) => ReactNode);\n empty?: ReactNode;\n}\n\nexport interface SecretsManagerProps {\n slots?: SecretsManagerSlots;\n}\n\nexport function SecretsManager(props: SecretsManagerProps): ReactNode {\n const slots = props.slots;\n const [modal, setModal] = useState<\n { mode: \"create\" } | { mode: \"edit\"; s: VaultSecretSummary } | null\n >(null);\n const [pending, setPending] = useState<VaultSecretSummary | null>(null);\n\n const secretsQuery = useSecretsQuery();\n const deleteMut = useDeleteSecretMutation();\n const openCreate = () => setModal({ mode: \"create\" });\n\n const header =\n slots?.header === undefined ? (\n <div>\n <h3>Secrets</h3>\n <p className=\"muted small\">\n Secrets addressable by name. Stored encrypted at rest and never returned from the server —\n to change a secret, overwrite it.\n </p>\n </div>\n ) : (\n slots.header\n );\n const actionsSlot = slots?.actions;\n const actions =\n actionsSlot === undefined ? (\n <button type=\"button\" className=\"btn\" onClick={openCreate}>\n + Add secret\n </button>\n ) : typeof actionsSlot === \"function\" ? (\n actionsSlot({ openCreate, canCreate: true })\n ) : (\n actionsSlot\n );\n const empty = slots?.empty === undefined ? <p className=\"muted\">No secrets yet.</p> : slots.empty;\n\n return (\n <div className=\"w6w-embed-root\">\n <section className=\"section\">\n {(header != null || actions != null) && (\n <div className=\"section-head\">\n {header}\n {actions}\n </div>\n )}\n\n <div className=\"card\">\n {secretsQuery.isLoading && <p className=\"muted\">Loading…</p>}\n {secretsQuery.data?.length === 0 && empty}\n <ul className=\"list\">\n {secretsQuery.data?.map((s) => (\n <li key={s.id}>\n <div className=\"list-main\">\n <strong className=\"list-name\" title={s.name}>\n {s.name}\n </strong>{\" \"}\n <code className=\"muted small\">••••••••</code>\n <div className=\"muted small list-preview\">\n {s.description && <>{s.description} · </>}\n updated {new Date(s.updatedAt).toLocaleString()}\n </div>\n </div>\n <div style={{ display: \"flex\", gap: \"var(--w6w-sp-1-5)\" }}>\n <EditButton\n label=\"Rotate\"\n onClick={() => setModal({ mode: \"edit\", s })}\n data-testid={`secret-rotate-${s.id}`}\n />\n <DeleteButton\n label=\"Delete\"\n onClick={() => setPending(s)}\n disabled={deleteMut.isPending}\n data-testid={`secret-delete-${s.id}`}\n />\n </div>\n </li>\n ))}\n </ul>\n </div>\n\n {modal && (\n <SecretModal\n initial={modal.mode === \"edit\" ? modal.s : undefined}\n onClose={() => setModal(null)}\n onSaved={() => setModal(null)}\n />\n )}\n\n {pending && (\n <ConfirmModal\n title=\"Delete secret\"\n message={`Delete the secret \"${pending.name}\"? This cannot be undone.`}\n confirmLabel=\"Delete\"\n onConfirm={() => {\n deleteMut.mutate(pending.id);\n setPending(null);\n }}\n onClose={() => setPending(null)}\n />\n )}\n </section>\n </div>\n );\n}\n\n/**\n * Create/rotate a secret. On edit, the current value is intentionally not pre-filled — the server\n * never returns it. Leaving the value blank in edit mode updates only the description.\n */\nfunction SecretModal(props: {\n initial?: VaultSecretSummary;\n onClose: () => void;\n onSaved: () => void;\n}) {\n const isEdit = !!props.initial;\n const [name, setName] = useState(props.initial?.name ?? \"\");\n const [value, setValue] = useState(\"\");\n const [description, setDescription] = useState(props.initial?.description ?? \"\");\n const [error, setError] = useState<string | null>(null);\n\n const createMut = useCreateSecretMutation();\n const updateMut = useUpdateSecretMutation(props.initial?.id ?? \"\");\n const saveMut = isEdit ? updateMut : createMut;\n const canSave = !!name && (isEdit || !!value) && !saveMut.isPending;\n\n function handleSave() {\n setError(null);\n if (isEdit) {\n updateMut.mutate(\n { value: value === \"\" ? undefined : value, description },\n {\n onSuccess: () => props.onSaved(),\n onError: (e) => setError(e instanceof ApiError ? e.message : (e as Error).message),\n },\n );\n return;\n }\n if (value === \"\") {\n setError(\"A secret value is required.\");\n return;\n }\n createMut.mutate(\n { name, value, description },\n {\n onSuccess: () => props.onSaved(),\n onError: (e) => setError(e instanceof ApiError ? e.message : (e as Error).message),\n },\n );\n }\n const enterSubmit = useEnterSubmit(handleSave, { enabled: canSave });\n\n return (\n <Modal\n title={props.initial ? `Rotate ${props.initial.name}` : \"Add secret\"}\n onClose={props.onClose}\n >\n <div className=\"modal-body\">\n <label className=\"field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={name}\n disabled={isEdit}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. openai_api_key\"\n maxLength={64}\n {...enterSubmit}\n />\n {!isEdit && (\n <span className=\"hint\">\n Lowercase letters, digits, and underscores. Must start with a letter or underscore.\n </span>\n )}\n </label>\n\n <label className=\"field\">\n <span>{isEdit ? \"New value\" : \"Value\"}</span>\n <textarea\n className=\"code\"\n rows={3}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n placeholder={isEdit ? \"Leave blank to keep the current value\" : \"sk-…\"}\n autoComplete=\"off\"\n spellCheck={false}\n />\n <span className=\"hint\">\n Stored encrypted at rest. Once saved, it is not readable through the UI.\n </span>\n </label>\n\n <label className=\"field\">\n <span>Description</span>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional\"\n {...enterSubmit}\n />\n </label>\n\n {error && <div className=\"result error\">{error}</div>}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"btn\" disabled={!canSave} onClick={handleSave}>\n {saveMut.isPending ? \"Saving…\" : isEdit ? \"Save changes\" : \"Save secret\"}\n </button>\n </div>\n </Modal>\n );\n}\n"],"names":["TYPES","previewValue","v","s","VarsManager","props","slots","project","useEditorProject","modal","setModal","useState","pending","setPending","varsQuery","useVarsQuery","deleteMut","useDeleteVarMutation","canCreate","openCreate","header","jsx","jsxs","actionsSlot","actions","empty","_a","_b","Copyable","Fragment","CallFromCodeButton","EditButton","DeleteButton","VarModal","ConfirmModal","isEdit","name","setName","type","setType","raw","setRaw","description","setDescription","_c","error","setError","parseValue","n","e","createMut","useCreateVarMutation","updateMut","useUpdateVarMutation","saving","save","parsed","onSettled","ApiError","enterSubmit","useEnterSubmit","Modal","t","SecretsManager","secretsQuery","useSecretsQuery","useDeleteSecretMutation","SecretModal","value","setValue","useCreateSecretMutation","useUpdateSecretMutation","saveMut","canSave","handleSave"],"mappings":"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"}
1
+ {"version":3,"file":"forms.mjs","sources":["../src/forms/VarsManager.tsx","../src/forms/SecretsManager.tsx","../src/forms/ModelBudgetsManager.tsx"],"sourcesContent":["/**\n * `<VarsManager>` — list, add, edit and delete the project's variables. Variables are\n * plaintext typed values scoped to ONE project (secrets, by contrast, are per account — see\n * `SecretsManager`).\n *\n * The project comes from `useEditorProject(project)`: omitted defers to `<W6WEmbedProvider\n * project>`; `null` or `\"\"` REFUSES — the list query is disabled, no `/vars` request is sent and\n * \"Add\" is disabled. Every list/create/update/delete call names the resolved project, never\n * `undefined` (a project-less write lands in the account default project).\n */\nimport { ApiError } from \"@w6w/sdk\";\nimport type { Var, VarType } from \"@w6w/sdk\";\nimport {\n Copyable,\n DataTable,\n type DataTableColumn,\n DeleteButton,\n EditButton,\n EmptyState,\n useEnterSubmit,\n} from \"@w6w/ui\";\nimport { type ReactNode, useState } from \"react\";\nimport { CallFromCodeButton } from \"../chrome/CallFromCodeButton.tsx\";\nimport { ConfirmModal } from \"../chrome/ConfirmModal.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport { useEditorProject } from \"../project-context.ts\";\nimport {\n useCreateVarMutation,\n useDeleteVarMutation,\n useUpdateVarMutation,\n useVarsQuery,\n} from \"../repos/vars.ts\";\n\nconst TYPES: readonly VarType[] = [\"string\", \"number\", \"boolean\", \"json\"];\n\n/** What a function-form `actions` slot receives. */\nexport interface ConfigManagerActionsApi {\n /** Open the create form (a no-op while the manager is refusing, e.g. no project). */\n openCreate: () => void;\n /** `false` when the create control must be disabled (no project). */\n canCreate: boolean;\n}\n\n/**\n * Each slot: omitted ⇒ the built-in default; `null` ⇒ nothing; a node replaces it. `actions` also\n * accepts a function so a host that replaces the default \"+ Add\" button can still open the form.\n */\nexport interface VarsManagerSlots {\n /** The section heading + description. */\n header?: ReactNode;\n /** The trailing control(s) of the head row (the \"+ Add variable\" button). */\n actions?: ReactNode | ((api: ConfigManagerActionsApi) => ReactNode);\n /** Shown instead of the list when there are no variables. */\n empty?: ReactNode;\n}\n\nexport interface VarsManagerProps {\n /**\n * The project whose variables are managed. Omitted: the `<W6WEmbedProvider project>`. `null` or\n * `\"\"`: no project — nothing is requested and nothing can be written.\n */\n project?: string | null;\n slots?: VarsManagerSlots;\n}\n\n/** One-line preview of a var's current value, safe against long strings. */\nfunction previewValue(v: Var): string {\n if (v.type === \"boolean\") return String(v.value);\n if (v.type === \"number\") return String(v.value);\n if (v.type === \"string\") return String(v.value);\n const s = JSON.stringify(v.value);\n return s.length > 80 ? `${s.slice(0, 80)}…` : s;\n}\n\nexport function VarsManager(props: VarsManagerProps): ReactNode {\n const slots = props.slots;\n const project = useEditorProject(props.project);\n const [modal, setModal] = useState<{ mode: \"create\" } | { mode: \"edit\"; v: Var } | null>(null);\n const [pending, setPending] = useState<Var | null>(null);\n\n const varsQuery = useVarsQuery(project ?? undefined, project != null);\n const deleteMut = useDeleteVarMutation();\n const canCreate = project != null;\n const openCreate = () => {\n if (project != null) setModal({ mode: \"create\" });\n };\n\n const header =\n slots?.header === undefined ? (\n <div>\n <h3>Variables</h3>\n <p className=\"muted small\">\n User-defined typed values addressable by name. Plaintext — use <strong>Secrets</strong>{\" \"}\n for sensitive values.\n </p>\n </div>\n ) : (\n slots.header\n );\n const actionsSlot = slots?.actions;\n const actions =\n actionsSlot === undefined ? (\n <button type=\"button\" className=\"btn\" disabled={!canCreate} onClick={openCreate}>\n + Add variable\n </button>\n ) : typeof actionsSlot === \"function\" ? (\n actionsSlot({ openCreate, canCreate })\n ) : (\n actionsSlot\n );\n const empty =\n slots?.empty === undefined ? (\n <EmptyState testId=\"vars-manager-empty\">No variables yet.</EmptyState>\n ) : (\n slots.empty\n );\n\n const columns: DataTableColumn<Var>[] = [\n {\n key: \"name\",\n header: \"Variable\",\n render: (v) => (\n <div className=\"list-main\" style={{ maxWidth: 0, minWidth: \"100%\" }}>\n <strong className=\"list-name\" title={v.name}>\n {v.name}\n </strong>{\" \"}\n <span className=\"tag\">{v.type}</span>\n <div className=\"muted small list-preview\" title={previewValue(v)}>\n <Copyable value={previewValue(v)} readOnly>\n {/* `.w6w-copyable`'s flex rule only targets `> input, > textarea, > pre` —\n never `> code` — so this `<code>` keeps flexbox's automatic min-content\n floor unless told otherwise. `overflowWrap: \"anywhere\"` alone still\n leaves the content unshrunk, pushing the Copy button outside\n `.list-preview`'s clipped box at narrow widths. `minWidth: 0` lets the\n flex item shrink to the box; `overflow`/`textOverflow` give IT the\n ellipsis, restoring the single-line truncation `.list-preview` set up. */}\n <code\n style={{\n overflowWrap: \"anywhere\",\n display: \"block\",\n minWidth: 0,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n flex: 1,\n }}\n >\n {previewValue(v)}\n </code>\n </Copyable>\n {v.description && <> · {v.description}</>}\n </div>\n </div>\n ),\n },\n {\n key: \"actions\",\n header: \"\",\n align: \"right\",\n link: false,\n render: (v) => (\n <div style={{ display: \"flex\", gap: \"var(--w6w-sp-1-5)\" }}>\n <CallFromCodeButton resource={{ kind: \"var\", name: v.name }} />\n <EditButton\n label=\"Edit\"\n onClick={() => setModal({ mode: \"edit\", v })}\n data-testid={`var-edit-${v.id}`}\n />\n <DeleteButton\n label=\"Delete\"\n onClick={() => setPending(v)}\n disabled={deleteMut.isPending}\n data-testid={`var-delete-${v.id}`}\n />\n </div>\n ),\n },\n ];\n\n return (\n <div className=\"w6w-embed-root\">\n <section className=\"section\">\n {(header != null || actions != null) && (\n <div className=\"section-head\">\n {header}\n {actions}\n </div>\n )}\n\n <div className=\"card\">\n {varsQuery.isLoading && <p className=\"muted\">Loading…</p>}\n {varsQuery.data?.length === 0 && empty}\n {varsQuery.data != null && varsQuery.data.length > 0 && (\n <DataTable columns={columns} rows={varsQuery.data} rowKey={(v) => v.id} />\n )}\n </div>\n\n {modal && project != null && (\n <VarModal\n project={project}\n initial={modal.mode === \"edit\" ? modal.v : undefined}\n onClose={() => setModal(null)}\n onSaved={() => setModal(null)}\n />\n )}\n\n {pending && project != null && (\n <ConfirmModal\n title=\"Delete variable\"\n message={`Delete the variable \"${pending.name}\"? This cannot be undone.`}\n confirmLabel=\"Delete\"\n onConfirm={() => {\n deleteMut.mutate({ id: pending.id, project });\n setPending(null);\n }}\n onClose={() => setPending(null)}\n />\n )}\n </section>\n </div>\n );\n}\n\n/**\n * Create/edit modal. The value widget switches on `type`; the raw string in the form is parsed to\n * the declared type at submit time so what's stored round-trips faithfully (e.g. the number `42`,\n * not the string `\"42\"`).\n */\nfunction VarModal(props: {\n project: string;\n initial?: Var;\n onClose: () => void;\n onSaved: () => void;\n}) {\n const isEdit = !!props.initial;\n const [name, setName] = useState(props.initial?.name ?? \"\");\n const [type, setType] = useState<VarType>(props.initial?.type ?? \"string\");\n const [raw, setRaw] = useState<string>(() => {\n if (!props.initial) return \"\";\n if (props.initial.type === \"string\") return String(props.initial.value ?? \"\");\n return JSON.stringify(props.initial.value, null, 2);\n });\n const [description, setDescription] = useState(props.initial?.description ?? \"\");\n const [error, setError] = useState<string | null>(null);\n\n /** Parse the raw string into a value that matches `type`. */\n function parseValue(): { ok: true; value: unknown } | { ok: false; error: string } {\n if (type === \"string\") return { ok: true, value: raw };\n if (type === \"boolean\") {\n if (raw === \"true\") return { ok: true, value: true };\n if (raw === \"false\") return { ok: true, value: false };\n return { ok: false, error: \"Value must be `true` or `false`.\" };\n }\n if (type === \"number\") {\n const n = Number(raw);\n if (!Number.isFinite(n)) return { ok: false, error: \"Value must be a finite number.\" };\n return { ok: true, value: n };\n }\n // json\n try {\n return { ok: true, value: JSON.parse(raw) };\n } catch (e) {\n return { ok: false, error: `Invalid JSON: ${(e as Error).message}` };\n }\n }\n\n const createMut = useCreateVarMutation();\n const updateMut = useUpdateVarMutation();\n const saving = createMut.isPending || updateMut.isPending;\n\n function save() {\n const parsed = parseValue();\n if (!parsed.ok) {\n setError(parsed.error);\n return;\n }\n setError(null);\n const onSettled = {\n onSuccess: () => props.onSaved(),\n onError: (e: unknown) => setError(e instanceof ApiError ? e.message : (e as Error).message),\n };\n if (props.initial) {\n updateMut.mutate(\n {\n id: props.initial.id,\n patch: { type, value: parsed.value, description },\n project: props.project,\n },\n onSettled,\n );\n return;\n }\n createMut.mutate(\n { input: { name, type, value: parsed.value, description }, project: props.project },\n onSettled,\n );\n }\n\n const enterSubmit = useEnterSubmit(save, { enabled: !!name && !saving });\n\n return (\n <Modal\n title={props.initial ? `Edit ${props.initial.name}` : \"Add variable\"}\n onClose={props.onClose}\n >\n <div className=\"modal-body\">\n <label className=\"field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={name}\n disabled={isEdit}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. api_base_url\"\n maxLength={64}\n {...enterSubmit}\n />\n {!isEdit && (\n <span className=\"hint\">\n Letters, digits, and underscores. Must start with a letter or underscore.\n Case-sensitive.\n </span>\n )}\n </label>\n\n <label className=\"field\">\n <span>Type</span>\n <select value={type} onChange={(e) => setType(e.target.value as VarType)}>\n {TYPES.map((t) => (\n <option key={t} value={t}>\n {t}\n </option>\n ))}\n </select>\n </label>\n\n <label className=\"field\" htmlFor=\"var-value\">\n <span>Value</span>\n {type === \"boolean\" ? (\n <select id=\"var-value\" value={raw || \"true\"} onChange={(e) => setRaw(e.target.value)}>\n <option value=\"true\">true</option>\n <option value=\"false\">false</option>\n </select>\n ) : type === \"number\" ? (\n <input\n id=\"var-value\"\n type=\"number\"\n value={raw}\n onChange={(e) => setRaw(e.target.value)}\n placeholder=\"0\"\n {...enterSubmit}\n />\n ) : type === \"json\" ? (\n <textarea\n id=\"var-value\"\n className=\"code\"\n rows={6}\n value={raw}\n onChange={(e) => setRaw(e.target.value)}\n placeholder='{\"key\": \"value\"}'\n />\n ) : (\n <input\n id=\"var-value\"\n type=\"text\"\n value={raw}\n onChange={(e) => setRaw(e.target.value)}\n placeholder=\"\"\n {...enterSubmit}\n />\n )}\n </label>\n\n <label className=\"field\">\n <span>Description</span>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional\"\n {...enterSubmit}\n />\n </label>\n\n {error && <div className=\"result error\">{error}</div>}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"btn\" disabled={!name || saving} onClick={save}>\n {saving ? \"Saving…\" : isEdit ? \"Save changes\" : \"Save variable\"}\n </button>\n </div>\n </Modal>\n );\n}\n","/**\n * `<SecretsManager>` — list, add, rotate and delete the account's secrets (vault). Secrets are\n * per ACCOUNT, not per project (variables are per project — see `VarsManager`), so there is no\n * `project` prop.\n *\n * WRITE-ONLY. A secret's value is typed into a form and sent; it is never read back. The value\n * field starts empty in create and in rotate; a blank rotate sends no `value` key; a blank create\n * is refused before any request; rows render only `name`, `description`, `updatedAt` and a fixed\n * mask — a row object is never spread or stringified, so a server that wrongly returns `value`\n * cannot reach the DOM. No prop receives, and no callback is handed, a secret value, and nothing\n * here writes the `[\"secrets\"]` cache (only the repo's own invalidation).\n */\nimport { ApiError } from \"@w6w/sdk\";\nimport {\n DataTable,\n type DataTableColumn,\n DeleteButton,\n EditButton,\n EmptyState,\n useEnterSubmit,\n} from \"@w6w/ui\";\nimport { type ReactNode, useState } from \"react\";\nimport { ConfirmModal } from \"../chrome/ConfirmModal.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport {\n type VaultSecretSummary,\n useCreateSecretMutation,\n useDeleteSecretMutation,\n useSecretsQuery,\n useUpdateSecretMutation,\n} from \"../repos/vault.ts\";\nimport type { ConfigManagerActionsApi } from \"./VarsManager.tsx\";\n\n/** Same contract as `VarsManagerSlots`: omitted ⇒ default, `null` ⇒ nothing, a node replaces. */\nexport interface SecretsManagerSlots {\n header?: ReactNode;\n actions?: ReactNode | ((api: ConfigManagerActionsApi) => ReactNode);\n empty?: ReactNode;\n}\n\nexport interface SecretsManagerProps {\n slots?: SecretsManagerSlots;\n}\n\nexport function SecretsManager(props: SecretsManagerProps): ReactNode {\n const slots = props.slots;\n const [modal, setModal] = useState<\n { mode: \"create\" } | { mode: \"edit\"; s: VaultSecretSummary } | null\n >(null);\n const [pending, setPending] = useState<VaultSecretSummary | null>(null);\n\n const secretsQuery = useSecretsQuery();\n const deleteMut = useDeleteSecretMutation();\n const openCreate = () => setModal({ mode: \"create\" });\n\n const header =\n slots?.header === undefined ? (\n <div>\n <h3>Secrets</h3>\n <p className=\"muted small\">\n Secrets addressable by name. Stored encrypted at rest and never returned from the server —\n to change a secret, overwrite it.\n </p>\n </div>\n ) : (\n slots.header\n );\n const actionsSlot = slots?.actions;\n const actions =\n actionsSlot === undefined ? (\n <button type=\"button\" className=\"btn\" onClick={openCreate}>\n + Add secret\n </button>\n ) : typeof actionsSlot === \"function\" ? (\n actionsSlot({ openCreate, canCreate: true })\n ) : (\n actionsSlot\n );\n const empty =\n slots?.empty === undefined ? (\n <EmptyState testId=\"secrets-manager-empty\">No secrets yet.</EmptyState>\n ) : (\n slots.empty\n );\n\n const columns: DataTableColumn<VaultSecretSummary>[] = [\n {\n key: \"name\",\n header: \"Secret\",\n render: (s) => (\n <div className=\"list-main\" style={{ maxWidth: 0, minWidth: \"100%\" }}>\n <strong className=\"list-name\" title={s.name}>\n {s.name}\n </strong>{\" \"}\n <code className=\"muted small\">••••••••</code>\n <div className=\"muted small list-preview\">\n {s.description && <>{s.description} · </>}\n updated {new Date(s.updatedAt).toLocaleString()}\n </div>\n </div>\n ),\n },\n {\n key: \"actions\",\n header: \"\",\n align: \"right\",\n link: false,\n render: (s) => (\n <div style={{ display: \"flex\", gap: \"var(--w6w-sp-1-5)\" }}>\n <EditButton\n label=\"Rotate\"\n onClick={() => setModal({ mode: \"edit\", s })}\n data-testid={`secret-rotate-${s.id}`}\n />\n <DeleteButton\n label=\"Delete\"\n onClick={() => setPending(s)}\n disabled={deleteMut.isPending}\n data-testid={`secret-delete-${s.id}`}\n />\n </div>\n ),\n },\n ];\n\n return (\n <div className=\"w6w-embed-root\">\n <section className=\"section\">\n {(header != null || actions != null) && (\n <div className=\"section-head\">\n {header}\n {actions}\n </div>\n )}\n\n <div className=\"card\">\n {secretsQuery.isLoading && <p className=\"muted\">Loading…</p>}\n {secretsQuery.data?.length === 0 && empty}\n {secretsQuery.data != null && secretsQuery.data.length > 0 && (\n <DataTable columns={columns} rows={secretsQuery.data} rowKey={(s) => s.id} />\n )}\n </div>\n\n {modal && (\n <SecretModal\n initial={modal.mode === \"edit\" ? modal.s : undefined}\n onClose={() => setModal(null)}\n onSaved={() => setModal(null)}\n />\n )}\n\n {pending && (\n <ConfirmModal\n title=\"Delete secret\"\n message={`Delete the secret \"${pending.name}\"? This cannot be undone.`}\n confirmLabel=\"Delete\"\n onConfirm={() => {\n deleteMut.mutate(pending.id);\n setPending(null);\n }}\n onClose={() => setPending(null)}\n />\n )}\n </section>\n </div>\n );\n}\n\n/**\n * Create/rotate a secret. On edit, the current value is intentionally not pre-filled — the server\n * never returns it. Leaving the value blank in edit mode updates only the description.\n */\nfunction SecretModal(props: {\n initial?: VaultSecretSummary;\n onClose: () => void;\n onSaved: () => void;\n}) {\n const isEdit = !!props.initial;\n const [name, setName] = useState(props.initial?.name ?? \"\");\n const [value, setValue] = useState(\"\");\n const [description, setDescription] = useState(props.initial?.description ?? \"\");\n const [error, setError] = useState<string | null>(null);\n\n const createMut = useCreateSecretMutation();\n const updateMut = useUpdateSecretMutation(props.initial?.id ?? \"\");\n const saveMut = isEdit ? updateMut : createMut;\n const canSave = !!name && (isEdit || !!value) && !saveMut.isPending;\n\n function handleSave() {\n setError(null);\n if (isEdit) {\n updateMut.mutate(\n { value: value === \"\" ? undefined : value, description },\n {\n onSuccess: () => props.onSaved(),\n onError: (e) => setError(e instanceof ApiError ? e.message : (e as Error).message),\n },\n );\n return;\n }\n if (value === \"\") {\n setError(\"A secret value is required.\");\n return;\n }\n createMut.mutate(\n { name, value, description },\n {\n onSuccess: () => props.onSaved(),\n onError: (e) => setError(e instanceof ApiError ? e.message : (e as Error).message),\n },\n );\n }\n const enterSubmit = useEnterSubmit(handleSave, { enabled: canSave });\n\n return (\n <Modal\n title={props.initial ? `Rotate ${props.initial.name}` : \"Add secret\"}\n onClose={props.onClose}\n >\n <div className=\"modal-body\">\n <label className=\"field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={name}\n disabled={isEdit}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. openai_api_key\"\n maxLength={64}\n {...enterSubmit}\n />\n {!isEdit && (\n <span className=\"hint\">\n Letters, digits, and underscores. Must start with a letter or underscore.\n Case-sensitive.\n </span>\n )}\n </label>\n\n <label className=\"field\">\n <span>{isEdit ? \"New value\" : \"Value\"}</span>\n <textarea\n className=\"code\"\n rows={3}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n placeholder={isEdit ? \"Leave blank to keep the current value\" : \"sk-…\"}\n autoComplete=\"off\"\n spellCheck={false}\n />\n <span className=\"hint\">\n Stored encrypted at rest. Once saved, it is not readable through the UI.\n </span>\n </label>\n\n <label className=\"field\">\n <span>Description</span>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional\"\n {...enterSubmit}\n />\n </label>\n\n {error && <div className=\"result error\">{error}</div>}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"btn\" disabled={!canSave} onClick={handleSave}>\n {saveMut.isPending ? \"Saving…\" : isEdit ? \"Save changes\" : \"Save secret\"}\n </button>\n </div>\n </Modal>\n );\n}\n","/**\n * `<ModelBudgetsManager>` — list, add, edit and delete the project's model budgets, each with a\n * usage meter fed by the budget's usage endpoint (spend so far and what is reserved for in-flight\n * calls, against the limit).\n *\n * The project comes from `useEditorProject(projectId)`: omitted defers to `<W6WEmbedProvider\n * project>`; `null` or `\"\"` REFUSES — the list query is disabled, no `/model-budgets` request is\n * sent and \"Add\" is disabled. Every write names the resolved project, never `undefined`.\n *\n * A budget is a scope (`scopeKind`, plus a `scopeId` for the route and connection kinds only), a\n * `window` (`day` or `month`) and one or more `limits`. The row's meter measures ONE of them —\n * cost when the budget has a cost limit, else tokens, else requests — because a meter needs a\n * single number pair; the limits column prints them all.\n */\nimport { ApiError } from \"@w6w/sdk\";\nimport {\n BudgetMeter,\n DataTable,\n type DataTableColumn,\n DeleteButton,\n EditButton,\n EmptyState,\n useEnterSubmit,\n} from \"@w6w/ui\";\nimport { type ReactNode, useState } from \"react\";\nimport { ConfirmModal } from \"../chrome/ConfirmModal.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport { useEditorProject } from \"../project-context.ts\";\nimport {\n type ModelBudget,\n type ModelBudgetLimits,\n useCreateModelBudgetMutation,\n useDeleteModelBudgetMutation,\n useModelBudgetUsageQuery,\n useModelBudgetsQuery,\n useUpdateModelBudgetMutation,\n} from \"../repos/models.ts\";\n\nexport interface ModelBudgetsManagerProps {\n /**\n * The project whose budgets are managed. Omitted: the `<W6WEmbedProvider project>`. `null` or\n * `\"\"`: no project — nothing is requested and nothing can be written.\n */\n projectId?: string | null;\n}\n\ntype MeterUnit = \"costMinor\" | \"tokens\" | \"requests\";\n\nconst UNIT_LABEL: Record<MeterUnit, string> = {\n costMinor: \"Cost\",\n tokens: \"Tokens\",\n requests: \"Requests\",\n};\n\nconst BREACHES = [\"block\", \"warn\"] as const;\n\n/**\n * The scopes the server accepts (`admin/model-budgets.ts` `SCOPE_KINDS`). `route` and `connection`\n * REQUIRE a scope id (the route name/id, the connection id); the other three refuse one — they cap\n * the caller's own tenant, account or project.\n */\nconst SCOPE_KINDS = [\"tenant\", \"account\", \"project\", \"route\", \"connection\"] as const;\ntype ScopeKind = (typeof SCOPE_KINDS)[number];\nconst SCOPE_LABEL: Record<ScopeKind, string> = {\n tenant: \"Tenant\",\n account: \"Account\",\n project: \"Project\",\n route: \"Model route\",\n connection: \"Connection\",\n};\nconst needsScopeId = (kind: string): boolean => kind === \"route\" || kind === \"connection\";\n\n/** The windows the server accepts; limits reset at the start of each UTC day or month. */\nconst WINDOWS = [\"day\", \"month\"] as const;\n\n/** Plain thousands separators — no `Intl`, so the text is identical in every host and test. */\nfunction grouped(n: number): string {\n return String(n).replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n}\n\n/** Minor units print as `<CUR> 12.34`; counts keep the plain grouping. */\nfunction meterFormatter(unit: MeterUnit, currency: string): (n: number) => string {\n if (unit === \"costMinor\") return (n) => `${currency} ${(n / 100).toFixed(2)}`;\n return grouped;\n}\n\n/** Which limit the row's meter measures: cost if set, else tokens, else requests. */\nfunction meterUnit(limits: ModelBudgetLimits): MeterUnit | null {\n if (limits.costMinor != null) return \"costMinor\";\n if (limits.tokens != null) return \"tokens\";\n if (limits.requests != null) return \"requests\";\n return null;\n}\n\nfunction costLimitText(limits: ModelBudgetLimits): string | null {\n if (limits.costMinor == null) return null;\n return `${limits.currency ?? \"USD\"} ${(limits.costMinor / 100).toFixed(2)}`;\n}\n\n/** Every configured limit, one line — the meter covers only the primary one. */\nfunction limitsSummary(limits: ModelBudgetLimits): string {\n const parts: string[] = [];\n if (limits.requests != null) parts.push(`${grouped(limits.requests)} requests`);\n if (limits.tokens != null) parts.push(`${grouped(limits.tokens)} tokens`);\n const cost = costLimitText(limits);\n if (cost != null) parts.push(cost);\n return parts.length === 0 ? \"no limit\" : parts.join(\" · \");\n}\n\nfunction scopeSummary(b: ModelBudget): string {\n return b.scopeId == null ? `this ${b.scopeKind}` : `${b.scopeKind} ${b.scopeId}`;\n}\n\n/** Unknown-but-named failures fall back to the server's own message. */\nfunction budgetErrorCopy(e: unknown): string {\n if (e instanceof ApiError) return e.message;\n return e instanceof Error ? e.message : String(e);\n}\n\n/** `null` for a blank field so an unset limit stays absent instead of becoming `0`. */\nfunction optionalNumber(raw: string): number | null {\n const trimmed = raw.trim();\n if (trimmed === \"\") return null;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : null;\n}\n\nexport function ModelBudgetsManager(props: ModelBudgetsManagerProps): ReactNode {\n const project = useEditorProject(props.projectId);\n const [editing, setEditing] = useState<{ budget?: ModelBudget } | null>(null);\n const [pending, setPending] = useState<ModelBudget | null>(null);\n const [deleteError, setDeleteError] = useState<string | null>(null);\n\n const budgetsQuery = useModelBudgetsQuery(project ?? undefined);\n const deleteMut = useDeleteModelBudgetMutation();\n const budgets = budgetsQuery.data ?? [];\n const canCreate = project != null;\n\n const columns: DataTableColumn<ModelBudget>[] = [\n {\n key: \"scope\",\n header: \"Scope\",\n render: (b) => (\n <div className=\"list-main\" style={{ maxWidth: 0, minWidth: \"100%\" }}>\n <strong className=\"list-name\" title={scopeSummary(b)}>\n {b.scopeKind}\n </strong>{\" \"}\n <span className={b.onBreach === \"warn\" ? \"tag warn\" : \"tag\"}>{b.onBreach}</span>\n <div className=\"muted small list-preview\" title={scopeSummary(b)}>\n {b.scopeId == null ? `the whole ${b.scopeKind}` : b.scopeId}\n </div>\n </div>\n ),\n },\n {\n key: \"window\",\n header: \"Window\",\n render: (b) => b.window,\n },\n {\n key: \"limits\",\n header: \"Limit\",\n render: (b) => <span className=\"muted small\">{limitsSummary(b.limits)}</span>,\n },\n {\n key: \"usage\",\n header: \"Used\",\n // Rows only exist once the project-scoped query ran, so `project` is set here.\n render: (b) => (project == null ? null : <BudgetRowMeter budget={b} projectId={project} />),\n },\n {\n key: \"actions\",\n header: \"\",\n align: \"right\",\n link: false,\n render: (b) => (\n <div style={{ display: \"flex\", gap: \"var(--w6w-sp-1-5)\" }}>\n <EditButton\n label=\"Edit\"\n onClick={() => setEditing({ budget: b })}\n data-testid={`model-budget-edit-${b.id}`}\n />\n <DeleteButton\n label=\"Delete\"\n onClick={() => setPending(b)}\n disabled={deleteMut.isPending}\n data-testid={`model-budget-delete-${b.id}`}\n />\n </div>\n ),\n },\n ];\n\n return (\n <div className=\"w6w-embed-root\">\n <section className=\"section\">\n <div className=\"section-head\">\n <div>\n <h3>Model budgets</h3>\n <p className=\"muted small\">\n Caps on what a tenant, account, project, route or connection may spend. A breached\n budget either warns or blocks the call, per its own setting.\n </p>\n </div>\n <button\n type=\"button\"\n className=\"btn\"\n disabled={!canCreate}\n onClick={() => setEditing({})}\n data-testid=\"model-budget-add\"\n >\n + Add budget\n </button>\n </div>\n\n {deleteError && (\n <div className=\"result error\" role=\"alert\" data-testid=\"model-budget-delete-error\">\n {deleteError}\n </div>\n )}\n\n <div className=\"card\">\n {budgetsQuery.isLoading && <p className=\"muted\">Loading…</p>}\n {budgetsQuery.data?.length === 0 && (\n <EmptyState testId=\"model-budgets-empty\">\n No model budgets yet. Add one to cap spend or request volume.\n </EmptyState>\n )}\n {budgets.length > 0 && (\n <DataTable\n columns={columns}\n rows={budgets}\n rowKey={(b) => b.id}\n testId=\"model-budgets-table\"\n />\n )}\n </div>\n\n {editing != null && project != null && (\n <BudgetModal\n project={project}\n initial={editing.budget}\n onClose={() => setEditing(null)}\n onSaved={() => setEditing(null)}\n />\n )}\n\n {pending != null && project != null && (\n <ConfirmModal\n title=\"Delete model budget\"\n message={`Delete the budget on ${scopeSummary(pending)}? Calls stop being capped by it immediately.`}\n confirmLabel=\"Delete\"\n onConfirm={() => {\n const target = pending;\n setDeleteError(null);\n deleteMut.mutate(\n { project, id: target.id },\n {\n onError: (e: unknown) =>\n setDeleteError(\n `Could not delete the budget on ${scopeSummary(target)}: ${budgetErrorCopy(e)}`,\n ),\n },\n );\n setPending(null);\n }}\n onClose={() => setPending(null)}\n />\n )}\n </section>\n </div>\n );\n}\n\n/**\n * One budget's meter, from ITS usage endpoint: `used` and `reserved` come from the server, never\n * from the list row, so the pair a call is measured against is the one the server enforces.\n */\nfunction BudgetRowMeter(props: { budget: ModelBudget; projectId: string }): ReactNode {\n const usageQuery = useModelBudgetUsageQuery(props.budget.id, props.projectId);\n if (usageQuery.isLoading) return <span className=\"muted small\">Loading…</span>;\n const usage = usageQuery.data;\n if (usage == null) return <span className=\"muted small\">—</span>;\n // The usage endpoint reports the limits actually in force (it echoes the budget's own).\n const limits = usage.limits ?? props.budget.limits;\n const unit = meterUnit(limits);\n if (unit == null) return <span className=\"muted small\">no limit</span>;\n return (\n <BudgetMeter\n label={UNIT_LABEL[unit]}\n used={usage.used[unit]}\n limit={limits[unit] ?? 0}\n reserved={usage.reserved[unit]}\n format={meterFormatter(unit, limits.currency ?? \"USD\")}\n testId={`model-budget-meter-${props.budget.id}`}\n />\n );\n}\n\n/**\n * Create/edit modal. `scopeKind`/`scopeId` are the budget's address and are fixed once created\n * (the server patches a budget by id); window, limits and the breach behaviour stay editable.\n */\nfunction BudgetModal(props: {\n project: string;\n initial?: ModelBudget;\n onClose: () => void;\n onSaved: () => void;\n}) {\n const isEdit = !!props.initial;\n const [scopeKind, setScopeKind] = useState(props.initial?.scopeKind ?? \"project\");\n const [scopeId, setScopeId] = useState(props.initial?.scopeId ?? \"\");\n const [window, setWindow] = useState(props.initial?.window ?? \"day\");\n const [requests, setRequests] = useState(\n props.initial?.limits.requests != null ? String(props.initial.limits.requests) : \"\",\n );\n const [tokens, setTokens] = useState(\n props.initial?.limits.tokens != null ? String(props.initial.limits.tokens) : \"\",\n );\n const [cost, setCost] = useState(\n props.initial?.limits.costMinor != null ? String(props.initial.limits.costMinor / 100) : \"\",\n );\n const [currency, setCurrency] = useState(props.initial?.limits.currency ?? \"\");\n const [onBreach, setOnBreach] = useState<\"block\" | \"warn\">(props.initial?.onBreach ?? \"warn\");\n const [error, setError] = useState<string | null>(null);\n\n const createMut = useCreateModelBudgetMutation();\n const updateMut = useUpdateModelBudgetMutation();\n const saving = createMut.isPending || updateMut.isPending;\n const scopeIdRequired = needsScopeId(scopeKind);\n const canSave =\n !!scopeKind && !!window && (!scopeIdRequired || isEdit || scopeId.trim() !== \"\") && !saving;\n\n /** The typed limits, with blank fields left out; `cost` is entered in major units. */\n function buildLimits(): ModelBudgetLimits | null {\n const limits: ModelBudgetLimits = {};\n const req = optionalNumber(requests);\n if (req != null) limits.requests = req;\n const tok = optionalNumber(tokens);\n if (tok != null) limits.tokens = tok;\n const costMajor = optionalNumber(cost);\n if (costMajor != null) limits.costMinor = Math.round(costMajor * 100);\n if (limits.costMinor != null && currency.trim() !== \"\") limits.currency = currency.trim();\n return Object.keys(limits).length === 0 ? null : limits;\n }\n\n function save() {\n const limits = buildLimits();\n if (limits == null) {\n setError(\"Set at least one limit: requests, tokens or cost.\");\n return;\n }\n setError(null);\n const onSettled = {\n onSuccess: () => props.onSaved(),\n onError: (e: unknown) => setError(budgetErrorCopy(e)),\n };\n if (props.initial) {\n updateMut.mutate(\n { project: props.project, id: props.initial.id, patch: { window, limits, onBreach } },\n onSettled,\n );\n return;\n }\n createMut.mutate(\n {\n project: props.project,\n input: {\n scopeKind,\n // Only route/connection budgets carry a scope id; the server refuses one elsewhere.\n ...(scopeIdRequired ? { scopeId: scopeId.trim() } : {}),\n window,\n limits,\n onBreach,\n },\n },\n onSettled,\n );\n }\n\n const enterSubmit = useEnterSubmit(save, { enabled: canSave });\n\n return (\n <Modal title={props.initial ? \"Edit model budget\" : \"Add model budget\"} onClose={props.onClose}>\n <div className=\"modal-body\">\n <label className=\"field\">\n <span>Scope</span>\n <select\n value={scopeKind}\n disabled={isEdit}\n onChange={(e) => setScopeKind(e.target.value)}\n data-testid=\"model-budget-scope-kind\"\n >\n {/* An existing row's kind is shown even if this list does not know it. */}\n {!(SCOPE_KINDS as readonly string[]).includes(scopeKind) && (\n <option value={scopeKind}>{scopeKind}</option>\n )}\n {SCOPE_KINDS.map((k) => (\n <option key={k} value={k}>\n {SCOPE_LABEL[k]}\n </option>\n ))}\n </select>\n {!isEdit && (\n <span className=\"hint\">\n What the budget caps — this tenant, account or project as a whole, or one model route\n or connection. Fixed once created.\n </span>\n )}\n </label>\n\n {scopeIdRequired && (\n <label className=\"field\">\n <span>{scopeKind === \"route\" ? \"Route\" : \"Connection id\"} *</span>\n <input\n type=\"text\"\n value={scopeId}\n disabled={isEdit}\n onChange={(e) => setScopeId(e.target.value)}\n placeholder={scopeKind === \"route\" ? \"e.g. fast\" : \"e.g. conn_…\"}\n data-testid=\"model-budget-scope-id\"\n {...enterSubmit}\n />\n {!isEdit && (\n <span className=\"hint\">\n {scopeKind === \"route\"\n ? \"The route's name or id. Required for a route budget.\"\n : \"The model-provider connection's id. Required for a connection budget.\"}\n </span>\n )}\n </label>\n )}\n\n <label className=\"field\">\n <span>Window</span>\n <select\n value={window}\n onChange={(e) => setWindow(e.target.value)}\n data-testid=\"model-budget-window\"\n >\n {!(WINDOWS as readonly string[]).includes(window) && (\n <option value={window}>{window}</option>\n )}\n {WINDOWS.map((w) => (\n <option key={w} value={w}>\n {w}\n </option>\n ))}\n </select>\n <span className=\"hint\">The period the limits reset over, in UTC.</span>\n </label>\n\n <label className=\"field\">\n <span>Requests</span>\n <input\n type=\"number\"\n min={0}\n value={requests}\n onChange={(e) => setRequests(e.target.value)}\n placeholder=\"Unlimited\"\n data-testid=\"model-budget-requests\"\n {...enterSubmit}\n />\n </label>\n\n <label className=\"field\">\n <span>Tokens</span>\n <input\n type=\"number\"\n min={0}\n value={tokens}\n onChange={(e) => setTokens(e.target.value)}\n placeholder=\"Unlimited\"\n data-testid=\"model-budget-tokens\"\n {...enterSubmit}\n />\n </label>\n\n <label className=\"field\">\n <span>Cost</span>\n <input\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={cost}\n onChange={(e) => setCost(e.target.value)}\n placeholder=\"Unlimited\"\n data-testid=\"model-budget-cost\"\n {...enterSubmit}\n />\n <span className=\"hint\">In major units of the currency below (12.50 = 12.50 USD).</span>\n </label>\n\n <label className=\"field\">\n <span>Currency</span>\n <input\n type=\"text\"\n value={currency}\n onChange={(e) => setCurrency(e.target.value)}\n placeholder=\"USD\"\n maxLength={8}\n data-testid=\"model-budget-currency\"\n {...enterSubmit}\n />\n </label>\n\n <label className=\"field\">\n <span>On breach</span>\n <select\n value={onBreach}\n onChange={(e) => setOnBreach(e.target.value as \"block\" | \"warn\")}\n data-testid=\"model-budget-on-breach\"\n >\n {BREACHES.map((b) => (\n <option key={b} value={b}>\n {b}\n </option>\n ))}\n </select>\n <span className=\"hint\">\n `block` refuses calls past the limit; `warn` lets them through and flags them.\n </span>\n </label>\n\n {error && (\n <div className=\"result error\" data-testid=\"model-budget-error\">\n {error}\n </div>\n )}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"btn\"\n disabled={!canSave}\n onClick={save}\n data-testid=\"model-budget-save\"\n >\n {saving ? \"Saving…\" : isEdit ? \"Save changes\" : \"Save budget\"}\n </button>\n </div>\n </Modal>\n );\n}\n"],"names":["TYPES","previewValue","v","s","VarsManager","props","slots","project","useEditorProject","modal","setModal","useState","pending","setPending","varsQuery","useVarsQuery","deleteMut","useDeleteVarMutation","canCreate","openCreate","header","jsx","jsxs","actionsSlot","actions","empty","EmptyState","columns","Copyable","Fragment","CallFromCodeButton","EditButton","DeleteButton","_a","DataTable","VarModal","ConfirmModal","isEdit","name","setName","type","setType","_b","raw","setRaw","description","setDescription","_c","error","setError","parseValue","n","e","createMut","useCreateVarMutation","updateMut","useUpdateVarMutation","saving","save","parsed","onSettled","ApiError","enterSubmit","useEnterSubmit","Modal","t","SecretsManager","secretsQuery","useSecretsQuery","useDeleteSecretMutation","SecretModal","value","setValue","useCreateSecretMutation","useUpdateSecretMutation","saveMut","canSave","handleSave","UNIT_LABEL","BREACHES","SCOPE_KINDS","SCOPE_LABEL","needsScopeId","kind","WINDOWS","grouped","meterFormatter","unit","currency","meterUnit","limits","costLimitText","limitsSummary","parts","cost","scopeSummary","b","budgetErrorCopy","optionalNumber","trimmed","ModelBudgetsManager","editing","setEditing","deleteError","setDeleteError","budgetsQuery","useModelBudgetsQuery","useDeleteModelBudgetMutation","budgets","BudgetRowMeter","BudgetModal","target","usageQuery","useModelBudgetUsageQuery","usage","BudgetMeter","scopeKind","setScopeKind","scopeId","setScopeId","window","setWindow","requests","setRequests","_d","tokens","setTokens","_e","setCost","_f","setCurrency","_g","onBreach","setOnBreach","_h","useCreateModelBudgetMutation","useUpdateModelBudgetMutation","scopeIdRequired","buildLimits","req","tok","costMajor","k","w"],"mappings":";;;;;;;;;;;AAiCA,MAAMA,KAA4B,CAAC,UAAU,UAAU,WAAW,MAAM;AAiCxE,SAASC,EAAaC,GAAgB;AAGpC,MAFIA,EAAE,SAAS,aACXA,EAAE,SAAS,YACXA,EAAE,SAAS,SAAU,QAAO,OAAOA,EAAE,KAAK;AAC9C,QAAMC,IAAI,KAAK,UAAUD,EAAE,KAAK;AAChC,SAAOC,EAAE,SAAS,KAAK,GAAGA,EAAE,MAAM,GAAG,EAAE,CAAC,MAAMA;AAChD;AAEO,SAASC,GAAYC,GAAoC;;AAC9D,QAAMC,IAAQD,EAAM,OACdE,IAAUC,GAAiBH,EAAM,OAAO,GACxC,CAACI,GAAOC,CAAQ,IAAIC,EAA+D,IAAI,GACvF,CAACC,GAASC,CAAU,IAAIF,EAAqB,IAAI,GAEjDG,IAAYC,GAAaR,KAAW,QAAWA,KAAW,IAAI,GAC9DS,IAAYC,GAAA,GACZC,IAAYX,KAAW,MACvBY,IAAa,MAAM;AACvB,IAAIZ,KAAW,QAAMG,EAAS,EAAE,MAAM,UAAU;AAAA,EAClD,GAEMU,KACJd,KAAA,gBAAAA,EAAO,YAAW,2BACf,OAAA,EACC,UAAA;AAAA,IAAA,gBAAAe,EAAC,QAAG,UAAA,YAAA,CAAS;AAAA,IACb,gBAAAC,EAAC,KAAA,EAAE,WAAU,eAAc,UAAA;AAAA,MAAA;AAAA,MACsC,gBAAAD,EAAC,YAAO,UAAA,UAAA,CAAO;AAAA,MAAU;AAAA,MAAI;AAAA,IAAA,EAAA,CAE9F;AAAA,EAAA,EAAA,CACF,IAEAf,EAAM,QAEJiB,IAAcjB,KAAA,gBAAAA,EAAO,SACrBkB,IACJD,MAAgB,SACd,gBAAAF,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,OAAM,UAAU,CAACH,GAAW,SAASC,GAAY,UAAA,iBAAA,CAEjF,IACE,OAAOI,KAAgB,aACzBA,EAAY,EAAE,YAAAJ,GAAY,WAAAD,EAAA,CAAW,IAErCK,GAEEE,KACJnB,KAAA,gBAAAA,EAAO,WAAU,SACf,gBAAAe,EAACK,KAAW,QAAO,sBAAqB,UAAA,oBAAA,CAAiB,IAEzDpB,EAAM,OAGJqB,IAAkC;AAAA,IACtC;AAAA,MACE,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ,CAACzB,MACP,gBAAAoB,EAAC,OAAA,EAAI,WAAU,aAAY,OAAO,EAAE,UAAU,GAAG,UAAU,UACzD,UAAA;AAAA,QAAA,gBAAAD,EAAC,YAAO,WAAU,aAAY,OAAOnB,EAAE,MACpC,YAAE,KAAA,CACL;AAAA,QAAU;AAAA,QACV,gBAAAmB,EAAC,QAAA,EAAK,WAAU,OAAO,YAAE,MAAK;AAAA,0BAC7B,OAAA,EAAI,WAAU,4BAA2B,OAAOpB,EAAaC,CAAC,GAC7D,UAAA;AAAA,UAAA,gBAAAmB,EAACO,MAAS,OAAO3B,EAAaC,CAAC,GAAG,UAAQ,IAQxC,UAAA,gBAAAmB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,gBACL,cAAc;AAAA,gBACd,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV,UAAU;AAAA,gBACV,cAAc;AAAA,gBACd,MAAM;AAAA,cAAA;AAAA,cAGP,YAAanB,CAAC;AAAA,YAAA;AAAA,UAAA,GAEnB;AAAA,UACCA,EAAE,eAAe,gBAAAoB,EAAAO,IAAA,EAAE,UAAA;AAAA,YAAA;AAAA,YAAI3B,EAAE;AAAA,UAAA,EAAA,CAAY;AAAA,QAAA,EAAA,CACxC;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,IAGJ;AAAA,MACE,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,MACN,QAAQ,CAACA,MACP,gBAAAoB,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,oBAAA,GAClC,UAAA;AAAA,QAAA,gBAAAD,EAACS,IAAA,EAAmB,UAAU,EAAE,MAAM,OAAO,MAAM5B,EAAE,QAAQ;AAAA,QAC7D,gBAAAmB;AAAA,UAACU;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,SAAS,MAAMrB,EAAS,EAAE,MAAM,QAAQ,GAAAR,GAAG;AAAA,YAC3C,eAAa,YAAYA,EAAE,EAAE;AAAA,UAAA;AAAA,QAAA;AAAA,QAE/B,gBAAAmB;AAAA,UAACW;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,SAAS,MAAMnB,EAAWX,CAAC;AAAA,YAC3B,UAAUc,EAAU;AAAA,YACpB,eAAa,cAAcd,EAAE,EAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MACjC,EAAA,CACF;AAAA,IAAA;AAAA,EAEJ;AAGF,2BACG,OAAA,EAAI,WAAU,kBACb,UAAA,gBAAAoB,EAAC,WAAA,EAAQ,WAAU,WACf,UAAA;AAAA,KAAAF,KAAU,QAAQI,KAAW,SAC7B,gBAAAF,EAAC,OAAA,EAAI,WAAU,gBACZ,UAAA;AAAA,MAAAF;AAAA,MACAI;AAAA,IAAA,GACH;AAAA,IAGF,gBAAAF,EAAC,OAAA,EAAI,WAAU,QACZ,UAAA;AAAA,MAAAR,EAAU,aAAa,gBAAAO,EAAC,KAAA,EAAE,WAAU,SAAQ,UAAA,YAAQ;AAAA,QACpDY,IAAAnB,EAAU,SAAV,gBAAAmB,EAAgB,YAAW,KAAKR;AAAA,MAChCX,EAAU,QAAQ,QAAQA,EAAU,KAAK,SAAS,KACjD,gBAAAO,EAACa,GAAA,EAAU,SAAAP,GAAkB,MAAMb,EAAU,MAAM,QAAQ,CAACZ,MAAMA,EAAE,GAAA,CAAI;AAAA,IAAA,GAE5E;AAAA,IAECO,KAASF,KAAW,QACnB,gBAAAc;AAAA,MAACc;AAAA,MAAA;AAAA,QACC,SAAA5B;AAAA,QACA,SAASE,EAAM,SAAS,SAASA,EAAM,IAAI;AAAA,QAC3C,SAAS,MAAMC,EAAS,IAAI;AAAA,QAC5B,SAAS,MAAMA,EAAS,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,IAI/BE,KAAWL,KAAW,QACrB,gBAAAc;AAAA,MAACe;AAAA,MAAA;AAAA,QACC,OAAM;AAAA,QACN,SAAS,wBAAwBxB,EAAQ,IAAI;AAAA,QAC7C,cAAa;AAAA,QACb,WAAW,MAAM;AACf,UAAAI,EAAU,OAAO,EAAE,IAAIJ,EAAQ,IAAI,SAAAL,GAAS,GAC5CM,EAAW,IAAI;AAAA,QACjB;AAAA,QACA,SAAS,MAAMA,EAAW,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,EAChC,EAAA,CAEJ,EAAA,CACF;AAEJ;AAOA,SAASsB,GAAS9B,GAKf;;AACD,QAAMgC,IAAS,CAAC,CAAChC,EAAM,SACjB,CAACiC,GAAMC,CAAO,IAAI5B,IAASsB,IAAA5B,EAAM,YAAN,gBAAA4B,EAAe,SAAQ,EAAE,GACpD,CAACO,GAAMC,CAAO,IAAI9B,IAAkB+B,IAAArC,EAAM,YAAN,gBAAAqC,EAAe,SAAQ,QAAQ,GACnE,CAACC,GAAKC,CAAM,IAAIjC,EAAiB,MAChCN,EAAM,UACPA,EAAM,QAAQ,SAAS,WAAiB,OAAOA,EAAM,QAAQ,SAAS,EAAE,IACrE,KAAK,UAAUA,EAAM,QAAQ,OAAO,MAAM,CAAC,IAFvB,EAG5B,GACK,CAACwC,GAAaC,CAAc,IAAInC,IAASoC,IAAA1C,EAAM,YAAN,gBAAA0C,EAAe,gBAAe,EAAE,GACzE,CAACC,GAAOC,CAAQ,IAAItC,EAAwB,IAAI;AAGtD,WAASuC,IAA0E;AACjF,QAAIV,MAAS,SAAU,QAAO,EAAE,IAAI,IAAM,OAAOG,EAAA;AACjD,QAAIH,MAAS;AACX,aAAIG,MAAQ,SAAe,EAAE,IAAI,IAAM,OAAO,GAAA,IAC1CA,MAAQ,UAAgB,EAAE,IAAI,IAAM,OAAO,GAAA,IACxC,EAAE,IAAI,IAAO,OAAO,mCAAA;AAE7B,QAAIH,MAAS,UAAU;AACrB,YAAMW,IAAI,OAAOR,CAAG;AACpB,aAAK,OAAO,SAASQ,CAAC,IACf,EAAE,IAAI,IAAM,OAAOA,EAAA,IADM,EAAE,IAAI,IAAO,OAAO,iCAAA;AAAA,IAEtD;AAEA,QAAI;AACF,aAAO,EAAE,IAAI,IAAM,OAAO,KAAK,MAAMR,CAAG,EAAA;AAAA,IAC1C,SAASS,GAAG;AACV,aAAO,EAAE,IAAI,IAAO,OAAO,iBAAkBA,EAAY,OAAO,GAAA;AAAA,IAClE;AAAA,EACF;AAEA,QAAMC,IAAYC,GAAA,GACZC,IAAYC,GAAA,GACZC,IAASJ,EAAU,aAAaE,EAAU;AAEhD,WAASG,IAAO;AACd,UAAMC,IAAST,EAAA;AACf,QAAI,CAACS,EAAO,IAAI;AACd,MAAAV,EAASU,EAAO,KAAK;AACrB;AAAA,IACF;AACA,IAAAV,EAAS,IAAI;AACb,UAAMW,IAAY;AAAA,MAChB,WAAW,MAAMvD,EAAM,QAAA;AAAA,MACvB,SAAS,CAAC+C,MAAeH,GAASG,aAAaS,GAAWT,EAAE,QAA8B;AAAA,IAAA;AAE5F,QAAI/C,EAAM,SAAS;AACjB,MAAAkD,EAAU;AAAA,QACR;AAAA,UACE,IAAIlD,EAAM,QAAQ;AAAA,UAClB,OAAO,EAAE,MAAAmC,GAAM,OAAOmB,EAAO,OAAO,aAAAd,EAAA;AAAA,UACpC,SAASxC,EAAM;AAAA,QAAA;AAAA,QAEjBuD;AAAA,MAAA;AAEF;AAAA,IACF;AACA,IAAAP,EAAU;AAAA,MACR,EAAE,OAAO,EAAE,MAAAf,GAAM,MAAAE,GAAM,OAAOmB,EAAO,OAAO,aAAAd,EAAA,GAAe,SAASxC,EAAM,QAAA;AAAA,MAC1EuD;AAAA,IAAA;AAAA,EAEJ;AAEA,QAAME,IAAcC,EAAeL,GAAM,EAAE,SAAS,CAAC,CAACpB,KAAQ,CAACmB,GAAQ;AAEvE,SACE,gBAAAnC;AAAA,IAAC0C;AAAA,IAAA;AAAA,MACC,OAAO3D,EAAM,UAAU,QAAQA,EAAM,QAAQ,IAAI,KAAK;AAAA,MACtD,SAASA,EAAM;AAAA,MAEf,UAAA;AAAA,QAAA,gBAAAiB,EAAC,OAAA,EAAI,WAAU,cACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,YAAA,gBAAAD,EAAC,UAAK,UAAA,OAAA,CAAI;AAAA,YACV,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAOiB;AAAA,gBACP,UAAUD;AAAA,gBACV,UAAU,CAACe,MAAMb,EAAQa,EAAE,OAAO,KAAK;AAAA,gBACvC,aAAY;AAAA,gBACZ,WAAW;AAAA,gBACV,GAAGU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEL,CAACzB,KACA,gBAAAhB,EAAC,QAAA,EAAK,WAAU,QAAO,UAAA,4FAAA,CAGvB;AAAA,UAAA,GAEJ;AAAA,UAEA,gBAAAC,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,YAAA,gBAAAD,EAAC,UAAK,UAAA,OAAA,CAAI;AAAA,YACV,gBAAAA,EAAC,YAAO,OAAOmB,GAAM,UAAU,CAACY,MAAMX,EAAQW,EAAE,OAAO,KAAgB,GACpE,UAAApD,GAAM,IAAI,CAACiE,MACV,gBAAA5C,EAAC,UAAA,EAAe,OAAO4C,GACpB,UAAAA,KADUA,CAEb,CACD,EAAA,CACH;AAAA,UAAA,GACF;AAAA,UAEA,gBAAA3C,EAAC,SAAA,EAAM,WAAU,SAAQ,SAAQ,aAC/B,UAAA;AAAA,YAAA,gBAAAD,EAAC,UAAK,UAAA,QAAA,CAAK;AAAA,YACVmB,MAAS,YACR,gBAAAlB,EAAC,UAAA,EAAO,IAAG,aAAY,OAAOqB,KAAO,QAAQ,UAAU,CAACS,MAAMR,EAAOQ,EAAE,OAAO,KAAK,GACjF,UAAA;AAAA,cAAA,gBAAA/B,EAAC,UAAA,EAAO,OAAM,QAAO,UAAA,QAAI;AAAA,cACzB,gBAAAA,EAAC,UAAA,EAAO,OAAM,SAAQ,UAAA,QAAA,CAAK;AAAA,YAAA,GAC7B,IACEmB,MAAS,WACX,gBAAAnB;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,MAAK;AAAA,gBACL,OAAOsB;AAAA,gBACP,UAAU,CAACS,MAAMR,EAAOQ,EAAE,OAAO,KAAK;AAAA,gBACtC,aAAY;AAAA,gBACX,GAAGU;AAAA,cAAA;AAAA,YAAA,IAEJtB,MAAS,SACX,gBAAAnB;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,WAAU;AAAA,gBACV,MAAM;AAAA,gBACN,OAAOsB;AAAA,gBACP,UAAU,CAACS,MAAMR,EAAOQ,EAAE,OAAO,KAAK;AAAA,gBACtC,aAAY;AAAA,cAAA;AAAA,YAAA,IAGd,gBAAA/B;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,MAAK;AAAA,gBACL,OAAOsB;AAAA,gBACP,UAAU,CAACS,MAAMR,EAAOQ,EAAE,OAAO,KAAK;AAAA,gBACtC,aAAY;AAAA,gBACX,GAAGU;AAAA,cAAA;AAAA,YAAA;AAAA,UACN,GAEJ;AAAA,UAEA,gBAAAxC,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,YAAA,gBAAAD,EAAC,UAAK,UAAA,cAAA,CAAW;AAAA,YACjB,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAOwB;AAAA,gBACP,UAAU,CAACO,MAAMN,EAAeM,EAAE,OAAO,KAAK;AAAA,gBAC9C,aAAY;AAAA,gBACX,GAAGU;AAAA,cAAA;AAAA,YAAA;AAAA,UACN,GACF;AAAA,UAECd,KAAS,gBAAA3B,EAAC,OAAA,EAAI,WAAU,gBAAgB,UAAA2B,EAAA,CAAM;AAAA,QAAA,GACjD;AAAA,QACA,gBAAA1B,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAA,gBAAAD,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,aAAY,SAAShB,EAAM,SAAS,UAAA,SAAA,CAEpE;AAAA,4BACC,UAAA,EAAO,MAAK,UAAS,WAAU,OAAM,UAAU,CAACiC,KAAQmB,GAAQ,SAASC,GACvE,UAAAD,IAAS,YAAYpB,IAAS,iBAAiB,gBAAA,CAClD;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AC/VO,SAAS6B,GAAe7D,GAAuC;;AACpE,QAAMC,IAAQD,EAAM,OACd,CAACI,GAAOC,CAAQ,IAAIC,EAExB,IAAI,GACA,CAACC,GAASC,CAAU,IAAIF,EAAoC,IAAI,GAEhEwD,IAAeC,GAAA,GACfpD,IAAYqD,GAAA,GACZlD,IAAa,MAAMT,EAAS,EAAE,MAAM,UAAU,GAE9CU,KACJd,KAAA,gBAAAA,EAAO,YAAW,2BACf,OAAA,EACC,UAAA;AAAA,IAAA,gBAAAe,EAAC,QAAG,UAAA,UAAA,CAAO;AAAA,IACX,gBAAAA,EAAC,KAAA,EAAE,WAAU,eAAc,UAAA,+HAAA,CAG3B;AAAA,EAAA,EAAA,CACF,IAEAf,EAAM,QAEJiB,IAAcjB,KAAA,gBAAAA,EAAO,SACrBkB,IACJD,MAAgB,SACd,gBAAAF,EAAC,YAAO,MAAK,UAAS,WAAU,OAAM,SAASF,GAAY,0BAE3D,IACE,OAAOI,KAAgB,aACzBA,EAAY,EAAE,YAAAJ,GAAY,WAAW,GAAA,CAAM,IAE3CI,GAEEE,KACJnB,KAAA,gBAAAA,EAAO,WAAU,SACf,gBAAAe,EAACK,KAAW,QAAO,yBAAwB,UAAA,kBAAA,CAAe,IAE1DpB,EAAM,OAGJqB,IAAiD;AAAA,IACrD;AAAA,MACE,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ,CAACxB,MACP,gBAAAmB,EAAC,OAAA,EAAI,WAAU,aAAY,OAAO,EAAE,UAAU,GAAG,UAAU,UACzD,UAAA;AAAA,QAAA,gBAAAD,EAAC,YAAO,WAAU,aAAY,OAAOlB,EAAE,MACpC,YAAE,KAAA,CACL;AAAA,QAAU;AAAA,QACV,gBAAAkB,EAAC,QAAA,EAAK,WAAU,eAAc,UAAA,YAAQ;AAAA,QACtC,gBAAAC,EAAC,OAAA,EAAI,WAAU,4BACZ,UAAA;AAAA,UAAAnB,EAAE,eAAe,gBAAAmB,EAAAO,IAAA,EAAG,UAAA;AAAA,YAAA1B,EAAE;AAAA,YAAY;AAAA,UAAA,GAAG;AAAA,UAAI;AAAA,UACjC,IAAI,KAAKA,EAAE,SAAS,EAAE,eAAA;AAAA,QAAe,EAAA,CAChD;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,IAGJ;AAAA,MACE,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,MACN,QAAQ,CAACA,MACP,gBAAAmB,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,oBAAA,GAClC,UAAA;AAAA,QAAA,gBAAAD;AAAA,UAACU;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,SAAS,MAAMrB,EAAS,EAAE,MAAM,QAAQ,GAAAP,GAAG;AAAA,YAC3C,eAAa,iBAAiBA,EAAE,EAAE;AAAA,UAAA;AAAA,QAAA;AAAA,QAEpC,gBAAAkB;AAAA,UAACW;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,SAAS,MAAMnB,EAAWV,CAAC;AAAA,YAC3B,UAAUa,EAAU;AAAA,YACpB,eAAa,iBAAiBb,EAAE,EAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MACpC,EAAA,CACF;AAAA,IAAA;AAAA,EAEJ;AAGF,2BACG,OAAA,EAAI,WAAU,kBACb,UAAA,gBAAAmB,EAAC,WAAA,EAAQ,WAAU,WACf,UAAA;AAAA,KAAAF,KAAU,QAAQI,KAAW,SAC7B,gBAAAF,EAAC,OAAA,EAAI,WAAU,gBACZ,UAAA;AAAA,MAAAF;AAAA,MACAI;AAAA,IAAA,GACH;AAAA,IAGF,gBAAAF,EAAC,OAAA,EAAI,WAAU,QACZ,UAAA;AAAA,MAAA6C,EAAa,aAAa,gBAAA9C,EAAC,KAAA,EAAE,WAAU,SAAQ,UAAA,YAAQ;AAAA,QACvDY,IAAAkC,EAAa,SAAb,gBAAAlC,EAAmB,YAAW,KAAKR;AAAA,MACnC0C,EAAa,QAAQ,QAAQA,EAAa,KAAK,SAAS,KACvD,gBAAA9C,EAACa,GAAA,EAAU,SAAAP,GAAkB,MAAMwC,EAAa,MAAM,QAAQ,CAAChE,MAAMA,EAAE,GAAA,CAAI;AAAA,IAAA,GAE/E;AAAA,IAECM,KACC,gBAAAY;AAAA,MAACiD;AAAA,MAAA;AAAA,QACC,SAAS7D,EAAM,SAAS,SAASA,EAAM,IAAI;AAAA,QAC3C,SAAS,MAAMC,EAAS,IAAI;AAAA,QAC5B,SAAS,MAAMA,EAAS,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,IAI/BE,KACC,gBAAAS;AAAA,MAACe;AAAA,MAAA;AAAA,QACC,OAAM;AAAA,QACN,SAAS,sBAAsBxB,EAAQ,IAAI;AAAA,QAC3C,cAAa;AAAA,QACb,WAAW,MAAM;AACf,UAAAI,EAAU,OAAOJ,EAAQ,EAAE,GAC3BC,EAAW,IAAI;AAAA,QACjB;AAAA,QACA,SAAS,MAAMA,EAAW,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,EAChC,EAAA,CAEJ,EAAA,CACF;AAEJ;AAMA,SAASyD,GAAYjE,GAIlB;;AACD,QAAMgC,IAAS,CAAC,CAAChC,EAAM,SACjB,CAACiC,GAAMC,CAAO,IAAI5B,IAASsB,IAAA5B,EAAM,YAAN,gBAAA4B,EAAe,SAAQ,EAAE,GACpD,CAACsC,GAAOC,CAAQ,IAAI7D,EAAS,EAAE,GAC/B,CAACkC,GAAaC,CAAc,IAAInC,IAAS+B,IAAArC,EAAM,YAAN,gBAAAqC,EAAe,gBAAe,EAAE,GACzE,CAACM,GAAOC,CAAQ,IAAItC,EAAwB,IAAI,GAEhD0C,IAAYoB,GAAA,GACZlB,IAAYmB,KAAwB3B,IAAA1C,EAAM,YAAN,gBAAA0C,EAAe,OAAM,EAAE,GAC3D4B,IAAUtC,IAASkB,IAAYF,GAC/BuB,IAAU,CAAC,CAACtC,MAASD,KAAU,CAAC,CAACkC,MAAU,CAACI,EAAQ;AAE1D,WAASE,IAAa;AAEpB,QADA5B,EAAS,IAAI,GACTZ,GAAQ;AACV,MAAAkB,EAAU;AAAA,QACR,EAAE,OAAOgB,MAAU,KAAK,SAAYA,GAAO,aAAA1B,EAAA;AAAA,QAC3C;AAAA,UACE,WAAW,MAAMxC,EAAM,QAAA;AAAA,UACvB,SAAS,CAAC+C,MAAMH,GAASG,aAAaS,GAAWT,EAAE,QAA8B;AAAA,QAAA;AAAA,MACnF;AAEF;AAAA,IACF;AACA,QAAImB,MAAU,IAAI;AAChB,MAAAtB,EAAS,6BAA6B;AACtC;AAAA,IACF;AACA,IAAAI,EAAU;AAAA,MACR,EAAE,MAAAf,GAAM,OAAAiC,GAAO,aAAA1B,EAAA;AAAA,MACf;AAAA,QACE,WAAW,MAAMxC,EAAM,QAAA;AAAA,QACvB,SAAS,CAAC+C,MAAMH,GAASG,aAAaS,GAAWT,EAAE,QAA8B;AAAA,MAAA;AAAA,IACnF;AAAA,EAEJ;AACA,QAAMU,IAAcC,EAAec,GAAY,EAAE,SAASD,GAAS;AAEnE,SACE,gBAAAtD;AAAA,IAAC0C;AAAA,IAAA;AAAA,MACC,OAAO3D,EAAM,UAAU,UAAUA,EAAM,QAAQ,IAAI,KAAK;AAAA,MACxD,SAASA,EAAM;AAAA,MAEf,UAAA;AAAA,QAAA,gBAAAiB,EAAC,OAAA,EAAI,WAAU,cACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,YAAA,gBAAAD,EAAC,UAAK,UAAA,OAAA,CAAI;AAAA,YACV,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAOiB;AAAA,gBACP,UAAUD;AAAA,gBACV,UAAU,CAACe,MAAMb,EAAQa,EAAE,OAAO,KAAK;AAAA,gBACvC,aAAY;AAAA,gBACZ,WAAW;AAAA,gBACV,GAAGU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEL,CAACzB,KACA,gBAAAhB,EAAC,QAAA,EAAK,WAAU,QAAO,UAAA,4FAAA,CAGvB;AAAA,UAAA,GAEJ;AAAA,UAEA,gBAAAC,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,YAAA,gBAAAD,EAAC,QAAA,EAAM,UAAAgB,IAAS,cAAc,SAAQ;AAAA,YACtC,gBAAAhB;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,MAAM;AAAA,gBACN,OAAAkD;AAAA,gBACA,UAAU,CAACnB,MAAMoB,EAASpB,EAAE,OAAO,KAAK;AAAA,gBACxC,aAAaf,IAAS,0CAA0C;AAAA,gBAChE,cAAa;AAAA,gBACb,YAAY;AAAA,cAAA;AAAA,YAAA;AAAA,YAEd,gBAAAhB,EAAC,QAAA,EAAK,WAAU,QAAO,UAAA,2EAAA,CAEvB;AAAA,UAAA,GACF;AAAA,UAEA,gBAAAC,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,YAAA,gBAAAD,EAAC,UAAK,UAAA,cAAA,CAAW;AAAA,YACjB,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAOwB;AAAA,gBACP,UAAU,CAACO,MAAMN,EAAeM,EAAE,OAAO,KAAK;AAAA,gBAC9C,aAAY;AAAA,gBACX,GAAGU;AAAA,cAAA;AAAA,YAAA;AAAA,UACN,GACF;AAAA,UAECd,KAAS,gBAAA3B,EAAC,OAAA,EAAI,WAAU,gBAAgB,UAAA2B,EAAA,CAAM;AAAA,QAAA,GACjD;AAAA,QACA,gBAAA1B,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,UAAA,gBAAAD,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,aAAY,SAAShB,EAAM,SAAS,UAAA,SAAA,CAEpE;AAAA,4BACC,UAAA,EAAO,MAAK,UAAS,WAAU,OAAM,UAAU,CAACuE,GAAS,SAASC,GAChE,UAAAF,EAAQ,YAAY,YAAYtC,IAAS,iBAAiB,cAAA,CAC7D;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;ACtOA,MAAMyC,KAAwC;AAAA,EAC5C,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,UAAU;AACZ,GAEMC,KAAW,CAAC,SAAS,MAAM,GAO3BC,KAAc,CAAC,UAAU,WAAW,WAAW,SAAS,YAAY,GAEpEC,KAAyC;AAAA,EAC7C,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,YAAY;AACd,GACMC,KAAe,CAACC,MAA0BA,MAAS,WAAWA,MAAS,cAGvEC,KAAU,CAAC,OAAO,OAAO;AAG/B,SAASC,EAAQlC,GAAmB;AAClC,SAAO,OAAOA,CAAC,EAAE,QAAQ,yBAAyB,GAAG;AACvD;AAGA,SAASmC,GAAeC,GAAiBC,GAAyC;AAChF,SAAID,MAAS,cAAoB,CAACpC,MAAM,GAAGqC,CAAQ,KAAKrC,IAAI,KAAK,QAAQ,CAAC,CAAC,KACpEkC;AACT;AAGA,SAASI,GAAUC,GAA6C;AAC9D,SAAIA,EAAO,aAAa,OAAa,cACjCA,EAAO,UAAU,OAAa,WAC9BA,EAAO,YAAY,OAAa,aAC7B;AACT;AAEA,SAASC,GAAcD,GAA0C;AAC/D,SAAIA,EAAO,aAAa,OAAa,OAC9B,GAAGA,EAAO,YAAY,KAAK,KAAKA,EAAO,YAAY,KAAK,QAAQ,CAAC,CAAC;AAC3E;AAGA,SAASE,GAAcF,GAAmC;AACxD,QAAMG,IAAkB,CAAA;AACxB,EAAIH,EAAO,YAAY,QAAMG,EAAM,KAAK,GAAGR,EAAQK,EAAO,QAAQ,CAAC,WAAW,GAC1EA,EAAO,UAAU,QAAMG,EAAM,KAAK,GAAGR,EAAQK,EAAO,MAAM,CAAC,SAAS;AACxE,QAAMI,IAAOH,GAAcD,CAAM;AACjC,SAAII,KAAQ,QAAMD,EAAM,KAAKC,CAAI,GAC1BD,EAAM,WAAW,IAAI,aAAaA,EAAM,KAAK,KAAK;AAC3D;AAEA,SAASE,EAAaC,GAAwB;AAC5C,SAAOA,EAAE,WAAW,OAAO,QAAQA,EAAE,SAAS,KAAK,GAAGA,EAAE,SAAS,IAAIA,EAAE,OAAO;AAChF;AAGA,SAASC,GAAgB7C,GAAoB;AAC3C,SAAIA,aAAaS,KACVT,aAAa,QADcA,EAAE,UACI,OAAOA,CAAC;AAClD;AAGA,SAAS8C,EAAevD,GAA4B;AAClD,QAAMwD,IAAUxD,EAAI,KAAA;AACpB,MAAIwD,MAAY,GAAI,QAAO;AAC3B,QAAMhD,IAAI,OAAOgD,CAAO;AACxB,SAAO,OAAO,SAAShD,CAAC,IAAIA,IAAI;AAClC;AAEO,SAASiD,GAAoB/F,GAA4C;;AAC9E,QAAME,IAAUC,GAAiBH,EAAM,SAAS,GAC1C,CAACgG,GAASC,CAAU,IAAI3F,EAA0C,IAAI,GACtE,CAACC,GAASC,CAAU,IAAIF,EAA6B,IAAI,GACzD,CAAC4F,GAAaC,CAAc,IAAI7F,EAAwB,IAAI,GAE5D8F,IAAeC,GAAqBnG,KAAW,MAAS,GACxDS,IAAY2F,GAAA,GACZC,IAAUH,EAAa,QAAQ,CAAA,GAC/BvF,IAAYX,KAAW,MAEvBoB,IAA0C;AAAA,IAC9C;AAAA,MACE,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ,CAACqE,MACP,gBAAA1E,EAAC,OAAA,EAAI,WAAU,aAAY,OAAO,EAAE,UAAU,GAAG,UAAU,UACzD,UAAA;AAAA,QAAA,gBAAAD,EAAC,UAAA,EAAO,WAAU,aAAY,OAAO0E,EAAaC,CAAC,GAChD,YAAE,UAAA,CACL;AAAA,QAAU;AAAA,QACV,gBAAA3E,EAAC,UAAK,WAAW2E,EAAE,aAAa,SAAS,aAAa,OAAQ,UAAAA,EAAE,SAAA,CAAS;AAAA,0BACxE,OAAA,EAAI,WAAU,4BAA2B,OAAOD,EAAaC,CAAC,GAC5D,UAAAA,EAAE,WAAW,OAAO,aAAaA,EAAE,SAAS,KAAKA,EAAE,QAAA,CACtD;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,IAGJ;AAAA,MACE,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ,CAACA,MAAMA,EAAE;AAAA,IAAA;AAAA,IAEnB;AAAA,MACE,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ,CAACA,MAAM,gBAAA3E,EAAC,QAAA,EAAK,WAAU,eAAe,UAAAuE,GAAcI,EAAE,MAAM,EAAA,CAAE;AAAA,IAAA;AAAA,IAExE;AAAA,MACE,KAAK;AAAA,MACL,QAAQ;AAAA;AAAA,MAER,QAAQ,CAACA,MAAOzF,KAAW,OAAO,OAAO,gBAAAc,EAACwF,IAAA,EAAe,QAAQb,GAAG,WAAWzF,EAAA,CAAS;AAAA,IAAA;AAAA,IAE1F;AAAA,MACE,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,MACN,QAAQ,CAACyF,MACP,gBAAA1E,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,oBAAA,GAClC,UAAA;AAAA,QAAA,gBAAAD;AAAA,UAACU;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,SAAS,MAAMuE,EAAW,EAAE,QAAQN,GAAG;AAAA,YACvC,eAAa,qBAAqBA,EAAE,EAAE;AAAA,UAAA;AAAA,QAAA;AAAA,QAExC,gBAAA3E;AAAA,UAACW;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,SAAS,MAAMnB,EAAWmF,CAAC;AAAA,YAC3B,UAAUhF,EAAU;AAAA,YACpB,eAAa,uBAAuBgF,EAAE,EAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAC1C,EAAA,CACF;AAAA,IAAA;AAAA,EAEJ;AAGF,2BACG,OAAA,EAAI,WAAU,kBACb,UAAA,gBAAA1E,EAAC,WAAA,EAAQ,WAAU,WACjB,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EACC,UAAA;AAAA,QAAA,gBAAAD,EAAC,QAAG,UAAA,gBAAA,CAAa;AAAA,QACjB,gBAAAA,EAAC,KAAA,EAAE,WAAU,eAAc,UAAA,kJAAA,CAG3B;AAAA,MAAA,GACF;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,CAACH;AAAA,UACX,SAAS,MAAMoF,EAAW,EAAE;AAAA,UAC5B,eAAY;AAAA,UACb,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GACF;AAAA,IAECC,uBACE,OAAA,EAAI,WAAU,gBAAe,MAAK,SAAQ,eAAY,6BACpD,UAAAA,EAAA,CACH;AAAA,IAGF,gBAAAjF,EAAC,OAAA,EAAI,WAAU,QACZ,UAAA;AAAA,MAAAmF,EAAa,aAAa,gBAAApF,EAAC,KAAA,EAAE,WAAU,SAAQ,UAAA,YAAQ;AAAA,QACvDY,IAAAwE,EAAa,SAAb,gBAAAxE,EAAmB,YAAW,uBAC5BP,GAAA,EAAW,QAAO,uBAAsB,UAAA,gEAAA,CAEzC;AAAA,MAEDkF,EAAQ,SAAS,KAChB,gBAAAvF;AAAA,QAACa;AAAA,QAAA;AAAA,UACC,SAAAP;AAAA,UACA,MAAMiF;AAAA,UACN,QAAQ,CAACZ,MAAMA,EAAE;AAAA,UACjB,QAAO;AAAA,QAAA;AAAA,MAAA;AAAA,IACT,GAEJ;AAAA,IAECK,KAAW,QAAQ9F,KAAW,QAC7B,gBAAAc;AAAA,MAACyF;AAAA,MAAA;AAAA,QACC,SAAAvG;AAAA,QACA,SAAS8F,EAAQ;AAAA,QACjB,SAAS,MAAMC,EAAW,IAAI;AAAA,QAC9B,SAAS,MAAMA,EAAW,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,IAIjC1F,KAAW,QAAQL,KAAW,QAC7B,gBAAAc;AAAA,MAACe;AAAA,MAAA;AAAA,QACC,OAAM;AAAA,QACN,SAAS,wBAAwB2D,EAAanF,CAAO,CAAC;AAAA,QACtD,cAAa;AAAA,QACb,WAAW,MAAM;AACf,gBAAMmG,IAASnG;AACf,UAAA4F,EAAe,IAAI,GACnBxF,EAAU;AAAA,YACR,EAAE,SAAAT,GAAS,IAAIwG,EAAO,GAAA;AAAA,YACtB;AAAA,cACE,SAAS,CAAC3D,MACRoD;AAAA,gBACE,kCAAkCT,EAAagB,CAAM,CAAC,KAAKd,GAAgB7C,CAAC,CAAC;AAAA,cAAA;AAAA,YAC/E;AAAA,UACJ,GAEFvC,EAAW,IAAI;AAAA,QACjB;AAAA,QACA,SAAS,MAAMA,EAAW,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,EAChC,EAAA,CAEJ,EAAA,CACF;AAEJ;AAMA,SAASgG,GAAexG,GAA8D;AACpF,QAAM2G,IAAaC,GAAyB5G,EAAM,OAAO,IAAIA,EAAM,SAAS;AAC5E,MAAI2G,EAAW,UAAW,0BAAQ,QAAA,EAAK,WAAU,eAAc,UAAA,YAAQ;AACvE,QAAME,IAAQF,EAAW;AACzB,MAAIE,KAAS,KAAM,0BAAQ,QAAA,EAAK,WAAU,eAAc,UAAA,KAAC;AAEzD,QAAMxB,IAASwB,EAAM,UAAU7G,EAAM,OAAO,QACtCkF,IAAOE,GAAUC,CAAM;AAC7B,SAAIH,KAAQ,yBAAc,QAAA,EAAK,WAAU,eAAc,UAAA,YAAQ,IAE7D,gBAAAlE;AAAA,IAAC8F;AAAA,IAAA;AAAA,MACC,OAAOrC,GAAWS,CAAI;AAAA,MACtB,MAAM2B,EAAM,KAAK3B,CAAI;AAAA,MACrB,OAAOG,EAAOH,CAAI,KAAK;AAAA,MACvB,UAAU2B,EAAM,SAAS3B,CAAI;AAAA,MAC7B,QAAQD,GAAeC,GAAMG,EAAO,YAAY,KAAK;AAAA,MACrD,QAAQ,sBAAsBrF,EAAM,OAAO,EAAE;AAAA,IAAA;AAAA,EAAA;AAGnD;AAMA,SAASyG,GAAYzG,GAKlB;;AACD,QAAMgC,IAAS,CAAC,CAAChC,EAAM,SACjB,CAAC+G,GAAWC,CAAY,IAAI1G,IAASsB,IAAA5B,EAAM,YAAN,gBAAA4B,EAAe,cAAa,SAAS,GAC1E,CAACqF,GAASC,CAAU,IAAI5G,IAAS+B,IAAArC,EAAM,YAAN,gBAAAqC,EAAe,YAAW,EAAE,GAC7D,CAAC8E,GAAQC,CAAS,IAAI9G,IAASoC,IAAA1C,EAAM,YAAN,gBAAA0C,EAAe,WAAU,KAAK,GAC7D,CAAC2E,GAAUC,CAAW,IAAIhH;AAAA,MAC9BiH,IAAAvH,EAAM,YAAN,gBAAAuH,EAAe,OAAO,aAAY,OAAO,OAAOvH,EAAM,QAAQ,OAAO,QAAQ,IAAI;AAAA,EAAA,GAE7E,CAACwH,GAAQC,CAAS,IAAInH;AAAA,MAC1BoH,IAAA1H,EAAM,YAAN,gBAAA0H,EAAe,OAAO,WAAU,OAAO,OAAO1H,EAAM,QAAQ,OAAO,MAAM,IAAI;AAAA,EAAA,GAEzE,CAACyF,GAAMkC,CAAO,IAAIrH;AAAA,MACtBsH,IAAA5H,EAAM,YAAN,gBAAA4H,EAAe,OAAO,cAAa,OAAO,OAAO5H,EAAM,QAAQ,OAAO,YAAY,GAAG,IAAI;AAAA,EAAA,GAErF,CAACmF,GAAU0C,CAAW,IAAIvH,IAASwH,IAAA9H,EAAM,YAAN,gBAAA8H,EAAe,OAAO,aAAY,EAAE,GACvE,CAACC,GAAUC,CAAW,IAAI1H,IAA2B2H,IAAAjI,EAAM,YAAN,gBAAAiI,EAAe,aAAY,MAAM,GACtF,CAACtF,GAAOC,CAAQ,IAAItC,EAAwB,IAAI,GAEhD0C,IAAYkF,GAAA,GACZhF,IAAYiF,GAAA,GACZ/E,IAASJ,EAAU,aAAaE,EAAU,WAC1CkF,IAAkBvD,GAAakC,CAAS,GACxCxC,IACJ,CAAC,CAACwC,KAAa,CAAC,CAACI,MAAW,CAACiB,KAAmBpG,KAAUiF,EAAQ,KAAA,MAAW,OAAO,CAAC7D;AAGvF,WAASiF,KAAwC;AAC/C,UAAMhD,IAA4B,CAAA,GAC5BiD,IAAMzC,EAAewB,CAAQ;AACnC,IAAIiB,KAAO,SAAMjD,EAAO,WAAWiD;AACnC,UAAMC,IAAM1C,EAAe2B,CAAM;AACjC,IAAIe,KAAO,SAAMlD,EAAO,SAASkD;AACjC,UAAMC,IAAY3C,EAAeJ,CAAI;AACrC,WAAI+C,KAAa,SAAMnD,EAAO,YAAY,KAAK,MAAMmD,IAAY,GAAG,IAChEnD,EAAO,aAAa,QAAQF,EAAS,WAAW,OAAIE,EAAO,WAAWF,EAAS,KAAA,IAC5E,OAAO,KAAKE,CAAM,EAAE,WAAW,IAAI,OAAOA;AAAA,EACnD;AAEA,WAAShC,IAAO;AACd,UAAMgC,IAASgD,GAAA;AACf,QAAIhD,KAAU,MAAM;AAClB,MAAAzC,EAAS,mDAAmD;AAC5D;AAAA,IACF;AACA,IAAAA,EAAS,IAAI;AACb,UAAMW,IAAY;AAAA,MAChB,WAAW,MAAMvD,EAAM,QAAA;AAAA,MACvB,SAAS,CAAC+C,MAAeH,EAASgD,GAAgB7C,CAAC,CAAC;AAAA,IAAA;AAEtD,QAAI/C,EAAM,SAAS;AACjB,MAAAkD,EAAU;AAAA,QACR,EAAE,SAASlD,EAAM,SAAS,IAAIA,EAAM,QAAQ,IAAI,OAAO,EAAE,QAAAmH,GAAQ,QAAA9B,GAAQ,UAAA0C,IAAS;AAAA,QAClFxE;AAAA,MAAA;AAEF;AAAA,IACF;AACA,IAAAP,EAAU;AAAA,MACR;AAAA,QACE,SAAShD,EAAM;AAAA,QACf,OAAO;AAAA,UACL,WAAA+G;AAAA;AAAA,UAEA,GAAIqB,IAAkB,EAAE,SAASnB,EAAQ,KAAA,EAAK,IAAM,CAAA;AAAA,UACpD,QAAAE;AAAA,UACA,QAAA9B;AAAA,UACA,UAAA0C;AAAA,QAAA;AAAA,MACF;AAAA,MAEFxE;AAAA,IAAA;AAAA,EAEJ;AAEA,QAAME,IAAcC,EAAeL,GAAM,EAAE,SAASkB,GAAS;AAE7D,SACE,gBAAAtD,EAAC0C,KAAM,OAAO3D,EAAM,UAAU,sBAAsB,oBAAoB,SAASA,EAAM,SACrF,UAAA;AAAA,IAAA,gBAAAiB,EAAC,OAAA,EAAI,WAAU,cACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,QAAA,gBAAAD,EAAC,UAAK,UAAA,QAAA,CAAK;AAAA,QACX,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO8F;AAAA,YACP,UAAU/E;AAAA,YACV,UAAU,CAACe,MAAMiE,EAAajE,EAAE,OAAO,KAAK;AAAA,YAC5C,eAAY;AAAA,YAGX,UAAA;AAAA,cAAA,CAAE4B,GAAkC,SAASoC,CAAS,uBACpD,UAAA,EAAO,OAAOA,GAAY,UAAAA,EAAA,CAAU;AAAA,cAEtCpC,GAAY,IAAI,CAAC8D,MAChB,gBAAAzH,EAAC,UAAA,EAAe,OAAOyH,GACpB,UAAA7D,GAAY6D,CAAC,EAAA,GADHA,CAEb,CACD;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAEF,CAACzG,KACA,gBAAAhB,EAAC,QAAA,EAAK,WAAU,QAAO,UAAA,2HAAA,CAGvB;AAAA,MAAA,GAEJ;AAAA,MAECoH,KACC,gBAAAnH,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,QAAA,gBAAAA,EAAC,QAAA,EAAM,UAAA;AAAA,UAAA8F,MAAc,UAAU,UAAU;AAAA,UAAgB;AAAA,QAAA,GAAE;AAAA,QAC3D,gBAAA/F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAOiG;AAAA,YACP,UAAUjF;AAAA,YACV,UAAU,CAACe,MAAMmE,EAAWnE,EAAE,OAAO,KAAK;AAAA,YAC1C,aAAagE,MAAc,UAAU,cAAc;AAAA,YACnD,eAAY;AAAA,YACX,GAAGtD;AAAA,UAAA;AAAA,QAAA;AAAA,QAEL,CAACzB,KACA,gBAAAhB,EAAC,QAAA,EAAK,WAAU,QACb,UAAA+F,MAAc,UACX,yDACA,wEAAA,CACN;AAAA,MAAA,GAEJ;AAAA,MAGF,gBAAA9F,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,QAAA,gBAAAD,EAAC,UAAK,UAAA,SAAA,CAAM;AAAA,QACZ,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAOkG;AAAA,YACP,UAAU,CAACpE,MAAMqE,EAAUrE,EAAE,OAAO,KAAK;AAAA,YACzC,eAAY;AAAA,YAEX,UAAA;AAAA,cAAA,CAAEgC,GAA8B,SAASoC,CAAM,uBAC7C,UAAA,EAAO,OAAOA,GAAS,UAAAA,EAAA,CAAO;AAAA,cAEhCpC,GAAQ,IAAI,CAAC2D,MACZ,gBAAA1H,EAAC,YAAe,OAAO0H,GACpB,UAAAA,EAAA,GADUA,CAEb,CACD;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAEH,gBAAA1H,EAAC,QAAA,EAAK,WAAU,QAAO,UAAA,4CAAA,CAAyC;AAAA,MAAA,GAClE;AAAA,MAEA,gBAAAC,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,QAAA,gBAAAD,EAAC,UAAK,UAAA,WAAA,CAAQ;AAAA,QACd,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAK;AAAA,YACL,OAAOqG;AAAA,YACP,UAAU,CAACtE,MAAMuE,EAAYvE,EAAE,OAAO,KAAK;AAAA,YAC3C,aAAY;AAAA,YACZ,eAAY;AAAA,YACX,GAAGU;AAAA,UAAA;AAAA,QAAA;AAAA,MACN,GACF;AAAA,MAEA,gBAAAxC,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,QAAA,gBAAAD,EAAC,UAAK,UAAA,SAAA,CAAM;AAAA,QACZ,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAK;AAAA,YACL,OAAOwG;AAAA,YACP,UAAU,CAACzE,MAAM0E,EAAU1E,EAAE,OAAO,KAAK;AAAA,YACzC,aAAY;AAAA,YACZ,eAAY;AAAA,YACX,GAAGU;AAAA,UAAA;AAAA,QAAA;AAAA,MACN,GACF;AAAA,MAEA,gBAAAxC,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,QAAA,gBAAAD,EAAC,UAAK,UAAA,OAAA,CAAI;AAAA,QACV,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAK;AAAA,YACL,MAAK;AAAA,YACL,OAAOyE;AAAA,YACP,UAAU,CAAC1C,MAAM4E,EAAQ5E,EAAE,OAAO,KAAK;AAAA,YACvC,aAAY;AAAA,YACZ,eAAY;AAAA,YACX,GAAGU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEN,gBAAAzC,EAAC,QAAA,EAAK,WAAU,QAAO,UAAA,4DAAA,CAAyD;AAAA,MAAA,GAClF;AAAA,MAEA,gBAAAC,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,QAAA,gBAAAD,EAAC,UAAK,UAAA,WAAA,CAAQ;AAAA,QACd,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAOmE;AAAA,YACP,UAAU,CAACpC,MAAM8E,EAAY9E,EAAE,OAAO,KAAK;AAAA,YAC3C,aAAY;AAAA,YACZ,WAAW;AAAA,YACX,eAAY;AAAA,YACX,GAAGU;AAAA,UAAA;AAAA,QAAA;AAAA,MACN,GACF;AAAA,MAEA,gBAAAxC,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,QAAA,gBAAAD,EAAC,UAAK,UAAA,YAAA,CAAS;AAAA,QACf,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO+G;AAAA,YACP,UAAU,CAAChF,MAAMiF,EAAYjF,EAAE,OAAO,KAAyB;AAAA,YAC/D,eAAY;AAAA,YAEX,UAAA2B,GAAS,IAAI,CAACiB,MACb,gBAAA3E,EAAC,YAAe,OAAO2E,GACpB,UAAAA,EAAA,GADUA,CAEb,CACD;AAAA,UAAA;AAAA,QAAA;AAAA,QAEH,gBAAA3E,EAAC,QAAA,EAAK,WAAU,QAAO,UAAA,iFAAA,CAEvB;AAAA,MAAA,GACF;AAAA,MAEC2B,KACC,gBAAA3B,EAAC,OAAA,EAAI,WAAU,gBAAe,eAAY,sBACvC,UAAA2B,EAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IACA,gBAAA1B,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAA,gBAAAD,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,aAAY,SAAShB,EAAM,SAAS,UAAA,SAAA,CAEpE;AAAA,MACA,gBAAAgB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,CAACuD;AAAA,UACX,SAASlB;AAAA,UACT,eAAY;AAAA,UAEX,UAAAD,IAAS,YAAYpB,IAAS,iBAAiB;AAAA,QAAA;AAAA,MAAA;AAAA,IAClD,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
@@ -1,4 +1,4 @@
1
- function s(e, n) {
1
+ function f(e, n) {
2
2
  let t;
3
3
  try {
4
4
  t = JSON.parse(e);
@@ -17,7 +17,7 @@ function s(e, n) {
17
17
  }
18
18
  return { parsed: o, blockedReason: null };
19
19
  }
20
- function i(e) {
20
+ function p(e) {
21
21
  switch (e) {
22
22
  case "function":
23
23
  case "endpoint":
@@ -28,10 +28,10 @@ function i(e) {
28
28
  return ["id"];
29
29
  }
30
30
  }
31
- function c(e) {
31
+ function k(e) {
32
32
  return e === "function" || e === "endpoint";
33
33
  }
34
- function l(e) {
34
+ function m(e) {
35
35
  switch (e) {
36
36
  case "function":
37
37
  case "workflow":
@@ -41,7 +41,7 @@ function l(e) {
41
41
  return !1;
42
42
  }
43
43
  }
44
- function u(e) {
44
+ function y(e) {
45
45
  switch (e) {
46
46
  case "function":
47
47
  case "workflow":
@@ -51,18 +51,19 @@ function u(e) {
51
51
  return !1;
52
52
  }
53
53
  }
54
- function d(e) {
54
+ function b(e) {
55
55
  switch (e) {
56
56
  case "function":
57
57
  return "functions";
58
58
  case "endpoint":
59
59
  return "endpoints";
60
60
  case "workflow":
61
+ return "workflows";
61
62
  case "connection":
62
63
  return null;
63
64
  }
64
65
  }
65
- function f(e, n) {
66
+ function h(e, n) {
66
67
  let t;
67
68
  try {
68
69
  t = JSON.parse(e);
@@ -74,13 +75,13 @@ function f(e, n) {
74
75
  const o = t;
75
76
  return o.id !== n.id ? { parsed: o, blockedReason: "id cannot be changed here." } : o.key !== n.key ? { parsed: o, blockedReason: "key cannot be changed here." } : { parsed: o, blockedReason: null };
76
77
  }
77
- function p(e, n) {
78
+ function v(e, n) {
78
79
  return e === void 0 ? { allowed: !1, reason: "Workflow not loaded yet." } : (n === void 0 ? null : n) !== e ? {
79
80
  allowed: !1,
80
81
  reason: "key cannot be changed here — use the Settings panel's Key field."
81
82
  } : { allowed: !0, reason: null };
82
83
  }
83
- function k(e) {
84
+ function g(e) {
84
85
  if (!e) return { activeTool: null };
85
86
  try {
86
87
  const n = JSON.parse(e);
@@ -89,23 +90,88 @@ function k(e) {
89
90
  return { activeTool: null };
90
91
  }
91
92
  }
92
- function a(e) {
93
+ function u(e) {
93
94
  return e.status === "archived" || e.archivedAt != null;
94
95
  }
95
- function h(e, n) {
96
- return n ? e.slice() : e.filter((t) => !a(t));
96
+ function w(e, n) {
97
+ return n ? e.slice() : e.filter((t) => !u(t));
98
+ }
99
+ function l(e) {
100
+ return e.kind === "store" ? e.dynamic ? ["unconfigured"] : e.canCreate ? ["bind", "create", "unconfigured"] : ["bind", "unconfigured"] : ["bind", "unconfigured"];
101
+ }
102
+ function c(e, n) {
103
+ return l(e).includes(n.mode);
104
+ }
105
+ function R(e) {
106
+ return e.map((n) => ({
107
+ key: n.key,
108
+ dep: n,
109
+ options: [...n.options],
110
+ selection: n.suggested,
111
+ createName: n.suggested.mode === "create" ? n.suggested.name : n.name
112
+ }));
113
+ }
114
+ function s(e, n, t) {
115
+ return e.map((o) => o.key === n ? t(o) : o);
116
+ }
117
+ function N(e, n, t) {
118
+ return s(e, n, (o) => {
119
+ const r = o.options.find((a) => a.id === t);
120
+ if (!r || r.compatible === !1) return o;
121
+ const i = { mode: "bind", target: t };
122
+ return c(o.dep, i) ? { ...o, selection: i } : o;
123
+ });
124
+ }
125
+ function A(e, n, t) {
126
+ return s(e, n, (o) => {
127
+ const r = { mode: "create", name: t };
128
+ return c(o.dep, r) ? { ...o, selection: r, createName: t } : o;
129
+ });
130
+ }
131
+ function S(e, n) {
132
+ return s(e, n, (t) => ({ ...t, selection: { mode: "unconfigured" } }));
133
+ }
134
+ function J(e, n, t, o) {
135
+ return s(e, n, (r) => {
136
+ if (r.dep.kind !== "connection") return r;
137
+ const i = r.options.some((a) => a.id === t) ? r.options : [...r.options, { id: t, label: o, source: "connection" }];
138
+ return { ...r, options: i, selection: { mode: "bind", target: t } };
139
+ });
140
+ }
141
+ function d(e) {
142
+ return e.selection.mode !== "create" || e.selection.name.trim() !== "";
143
+ }
144
+ function O(e) {
145
+ return e.every(d);
146
+ }
147
+ function T(e) {
148
+ const n = {};
149
+ for (const t of e) {
150
+ const o = t.selection;
151
+ n[t.key] = o.mode === "create" ? { mode: "create", name: o.name.trim() } : o;
152
+ }
153
+ return n;
97
154
  }
98
155
  export {
99
- u as a,
100
- l as b,
101
- f as e,
102
- c as h,
103
- a as i,
104
- i as m,
105
- s as p,
106
- k as r,
107
- d as s,
108
- h as v,
109
- p as w
156
+ l as a,
157
+ R as b,
158
+ y as c,
159
+ m as d,
160
+ h as e,
161
+ d as f,
162
+ O as g,
163
+ k as h,
164
+ u as i,
165
+ A as j,
166
+ S as k,
167
+ b as l,
168
+ p as m,
169
+ v as n,
170
+ f as p,
171
+ g as r,
172
+ N as s,
173
+ T as t,
174
+ w as v,
175
+ J as w
110
176
  };
111
- //# sourceMappingURL=rail-settings-XYGToh00.js.map
177
+ //# sourceMappingURL=import-bindings-EUtxZ9Ti.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-bindings-EUtxZ9Ti.js","sources":["../src/lib/import-paste.ts","../src/lib/rail-settings.ts","../src/lib/import-bindings.ts"],"sourcesContent":["/**\n * Pure decision behind `ImportSpecModal`'s Submit gate (T1.2.1, generalizing T3.2.1's A3 over all\n * three spec kinds).\n *\n * `/spec/import` accepts all three spec kinds at one route (T2.1.2 §B), and this affordance is now\n * mounted on the Functions, Endpoints and Workflows lists alike — each instance passing its own\n * `expectedKind`. Pasting a document of the WRONG kind onto a given list would still create a row\n * server-side and then send the operator to e.g. `functions/<ep_…>`, which 404s in the target\n * page's editor. So this module refuses, client-side, before any request is ever sent: (1) text\n * that isn't JSON, (2) a parse result that isn't a plain object, (3) a parsed `kind` that doesn't\n * match `expectedKind`.\n *\n * Nothing beyond that is checked here — `specVersion`, `callable`'s shape,\n * connection/reference resolvability, all of it is the SERVER's job\n * (T2.1.2 §B); duplicating any of it here would drift from what the route\n * actually enforces.\n *\n * `node --test` throws `ERR_UNKNOWN_FILE_EXTENSION` on anything reaching the\n * `@w6w/ui` import graph (`src/lib/alias-rail.ts`'s docblock), so this module\n * takes no value import at all — it has no dependency to avoid in the first\n * place.\n */\n\n/** The parsed paste, once it is confirmed to be a plain JSON object. */\nexport type ParsedSpecDocument = Record<string, unknown>;\n\n/** The one kind a given mount of the Import affordance expects — see `ImportSpecModal`'s `kind` prop. */\nexport type ExpectedSpecKind = \"function\" | \"endpoint\" | \"workflow\";\n\nexport interface ImportPasteResult {\n /**\n * The parsed JSON when it is a plain object — populated even when\n * `blockedReason` names a wrong `kind`, so a caller could still inspect\n * what was found. `null` when the text didn't even parse to an object.\n */\n parsed: ParsedSpecDocument | null;\n /** `null` exactly when the paste is a plausible spec document of `expectedKind`. */\n blockedReason: string | null;\n}\n\n/**\n * Total: never throws, always returns. `JSON.parse` is the only thing here\n * that can throw, and it is caught.\n */\nexport function parseImportPaste(text: string, expectedKind: ExpectedSpecKind): ImportPasteResult {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n return { parsed: null, blockedReason: \"Not valid JSON.\" };\n }\n\n if (value === null || Array.isArray(value) || typeof value !== \"object\") {\n return { parsed: null, blockedReason: \"Expected a JSON object, not a bare value or a list.\" };\n }\n\n const parsed = value as ParsedSpecDocument;\n\n if (parsed.kind !== expectedKind) {\n const found = typeof parsed.kind === \"string\" ? parsed.kind : \"unknown\";\n return {\n parsed,\n blockedReason: `This document's kind is \"${found}\", not \"${expectedKind}\" — paste a \"${expectedKind}\" spec document here.`,\n };\n }\n\n return { parsed, blockedReason: null };\n}\n","/**\n * Pure decisions behind the right rail's Settings tool (`src/ui/rail/SettingsTool.tsx`,\n * `id: \"aliases\"`, `title: \"Settings\"` since T3.1.2 — the tool widened past aliases alone\n * into a resource Settings panel: a metadata block and, for Functions and Endpoints, an\n * Export / Edit JSON action row (T3.3.1 — the definition itself no longer renders in the\n * panel, only the two buttons that open it in a modal), alongside the alias list\n * `../lib/alias-rail.ts` already decides). Split out so `node --test` can gate them\n * directly — same reasoning as\n * `alias-rail.ts`'s own header: `node --test` throws `ERR_UNKNOWN_FILE_EXTENSION` on\n * anything reaching the `@w6w/ui` / `Layout.tsx` import graph, and `src/ui/workspace.tsx`\n * sits one hop from that barrel through `Layout.tsx`'s import graph. So this module\n * declares its own structural mirror of the kinds it cares about instead of importing\n * `WorkspaceKind`, and takes only `import type` throughout.\n *\n * T4.1.1 widens this file's scope past the Settings tool itself: `restoreRailState`\n * (A2, `RightRail.tsx`'s persisted-state read path) and `isRowArchived`/`visibleRows`\n * (A6, the three listing pages' \"Show archived\" toggle) are pure decisions with the\n * exact same `node --test`-reachability constraint, so they land here rather than in\n * a new sibling module the contract's `inputs.touch` list didn't ask for.\n */\n\n/** Structural mirror of `WorkspaceCallable[\"kind\"]` (`src/ui/workspace.tsx`) — every kind\n * the rail can have open, not only the two this tool's action-row/metadata sections\n * apply to. */\nexport type RailSettingsKind = \"workflow\" | \"function\" | \"endpoint\" | \"connection\";\n\n/**\n * A4/T3.1.1: which metadata rows the Settings panel shows for this kind. `id` always\n * (every kind the tool is available on carries one). `key` for `function`/`endpoint`\n * (unchanged) AND, since T3.1.1, `workflow` too — `GET /workflows` now carries `key`\n * on every row (`string | null`, D-1: nullable, no backfill), and the panel renders it\n * as an editable control for `function`/`workflow` and the existing read-only `<code>`\n * for `endpoint` (`SettingsTool.tsx` gates that render choice on `ctx.kind` directly,\n * never on this array — an Endpoint's `key` entry here must not be read as \"editable\").\n * `updatedAt` stays `function`/`endpoint`-only: nothing asks for a Workflow Updated row,\n * and adding one would be a second, unrelated rail row. Deliberately never `createdAt`\n * (note 6): neither `GET /functions/:id` nor `GET /endpoints/:id` returns it, so\n * surfacing it would take a server change for one cosmetic field — this function's own\n * absence of a `createdAt` arm is half of that gate, the other half is the negative\n * assertion in the caller's markup.\n */\nexport function metadataFieldsForKind(\n kind: RailSettingsKind,\n): ReadonlyArray<\"id\" | \"key\" | \"updatedAt\"> {\n switch (kind) {\n case \"function\":\n case \"endpoint\":\n return [\"id\", \"key\", \"updatedAt\"];\n case \"workflow\":\n return [\"id\", \"key\"];\n case \"connection\":\n return [\"id\"];\n }\n}\n\n/**\n * A2/A5: the Export / Edit JSON action row exists for `function`/`endpoint` only. A\n * Workflow already has its own read-only Definition card\n * (`pages/WorkflowDetailPage.tsx:371-388`); a Connection has no stored definition shaped\n * like these two to show at all. (T3.3.1: renamed from the panel's earlier JSON-section\n * name — there is no JSON section left in the panel to describe, only the two buttons\n * that open one in a modal.)\n */\nexport function hasDefinitionActions(kind: RailSettingsKind): boolean {\n return kind === \"function\" || kind === \"endpoint\";\n}\n\n/**\n * A1/T3.1.1: does this kind have a version-history browser (the read-only browse list plus\n * Publish and Enable/Disable) in the Settings panel? `true` for `function`/`workflow`/`endpoint`,\n * `false` for `connection` — written as a `switch` naming every one of the four `RailSettingsKind`\n * arms explicitly, with no `default:`, matching {@link specCollectionForKind}'s shape and the\n * reason its own docblock gives (`:69` below — \"every one of the four `RailSettingsKind` arms is\n * named explicitly below\" so a kind can never silently fall through). Deliberately NOT derived\n * from {@link hasDefinitionActions}, which is `function`/`endpoint`-only: History covers Workflow\n * too, so deriving one from the other would silently drop it.\n */\nexport function hasVersionHistory(kind: RailSettingsKind): boolean {\n switch (kind) {\n case \"function\":\n case \"workflow\":\n case \"endpoint\":\n return true;\n case \"connection\":\n return false;\n }\n}\n\n/**\n * A1/T1.3.1: does this kind get a Delete (or, for `workflow`, Archive-then-Delete) affordance at\n * the bottom of the Settings panel? `true` for `function`/`workflow`/`endpoint`, `false` for\n * `connection` — written as a named `switch` naming every one of the four `RailSettingsKind` arms\n * explicitly, with no `default:`, matching {@link hasVersionHistory}'s exact shape (`:72-81` above)\n * for the same reason its own doc comment gives: a kind can never silently fall through. Deliberately\n * NOT derived from {@link hasVersionHistory} even though the two currently agree on every arm — a\n * future kind that gets history but not deletion (or vice versa) must not silently inherit the\n * wrong answer from a sibling predicate.\n */\nexport function hasDelete(kind: RailSettingsKind): boolean {\n switch (kind) {\n case \"function\":\n case \"workflow\":\n case \"endpoint\":\n return true;\n case \"connection\":\n return false;\n }\n}\n\n/**\n * A4: which `/<collection>/:id/spec` route the Export button's `useSpecQuery`\n * (`../repos/spec-export.ts`) must call for this kind — `null` for the two kinds A2's\n * action row never renders on. Kept in lockstep with {@link hasDefinitionActions}\n * (both are `function`/`endpoint`-only) but expressed as its own total function rather\n * than derived from it, so a Function can never be exported through\n * `/endpoints/:id/spec` by a wrong `if`/`else` fallthrough — every one of the four\n * `RailSettingsKind` arms is named explicitly below.\n */\nexport function specCollectionForKind(\n kind: RailSettingsKind,\n): \"functions\" | \"endpoints\" | \"workflows\" | null {\n switch (kind) {\n case \"function\":\n return \"functions\";\n case \"endpoint\":\n return \"endpoints\";\n case \"workflow\":\n return \"workflows\";\n case \"connection\":\n return null;\n }\n}\n\n/** What A8's `evaluateEdit` needs to know about the row already on screen — deliberately\n * narrower than a whole `FunctionDef`/`EndpointDef`: the two fields a hand-edit must not\n * be allowed to change out from under the row it opened on. */\nexport interface EditStored {\n id: string;\n key: string;\n}\n\n/** A8's total function's result: the parsed body (when parseable and a plain object, even\n * if it goes on to fail arm 2 or 3 — the modal still has something to inspect for the\n * render, just never something Save may submit) plus the one reason Save is refused, or\n * `null` when the edit is allowed through. */\nexport interface EditEvaluation {\n parsed: Record<string, unknown> | null;\n blockedReason: string | null;\n}\n\n/**\n * A8: is this edited text a Save the rail may submit? A total function over the modal's\n * OWN text state — never `JsonEditor`'s `onValidityChange` (note 10: the only browser\n * harness this repo has stubs `JsonEditor` with a callback that is wired but never\n * invoked, so a Save gated on it would look gated and be inert; parsing `text` here is\n * behaviourally identical and fully observable by a page guard).\n *\n * Three refusals, evaluated in order, each named for the near-miss it kills:\n * 1. the text does not parse as JSON, or parses to something that is not a plain object\n * (`null` and an array both fail here, not a dedicated fourth arm — a\n * `FunctionDef`/`EndpointDef` is never legitimately either);\n * 2. `parsed.id !== stored.id` (note 9 — `FunctionsRepo.upsert` selects the row by\n * `definition.id`, so an edited id does not edit this row, it creates or hijacks a\n * different one);\n * 3. `parsed.key !== stored.key` (note 8 — `POST /endpoints` 409s on a changed key while\n * `POST /functions` silently accepts one; locking it here keeps both kinds behaving\n * the same from this one modal).\n */\nexport function evaluateEdit(text: string, stored: EditStored): EditEvaluation {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n return { parsed: null, blockedReason: \"Not valid JSON.\" };\n }\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return { parsed: null, blockedReason: \"Not valid JSON.\" };\n }\n const parsed = value as Record<string, unknown>;\n if (parsed.id !== stored.id) {\n return { parsed, blockedReason: \"id cannot be changed here.\" };\n }\n if (parsed.key !== stored.key) {\n return { parsed, blockedReason: \"key cannot be changed here.\" };\n }\n return { parsed, blockedReason: null };\n}\n\n/** A7/D-3's total function's result: may the save proceed, and if not, why —\n * rendered verbatim in `WorkflowsPage.tsx`'s existing error/banner idiom. */\nexport interface KeyEditEvaluation {\n allowed: boolean;\n reason: string | null;\n}\n\n/**\n * D-3: is a Workflow save carrying this `key` one `WorkflowsPage.tsx`'s raw-JSON\n * editor may submit? The right rail's Key control (`SettingsTool.tsx`) is the ONLY\n * path allowed to assign or change a workflow's key (see this project's Requirement);\n * this total function is what keeps a hand-edit of the JSON — via the Save button OR\n * auto-save, both of which must fold this in (see `WorkflowsPage.tsx`'s `canSave`) —\n * from doing it silently instead.\n *\n * `loadedKey` is the key `WorkflowsPage.tsx` most recently loaded FROM THE SERVER\n * (its own `loadedKeyRef`, captured at both of its load sites — the initial `editId`\n * effect and `reloadFromServer`). `undefined` means nothing has loaded yet, which\n * refuses unconditionally: there is nothing yet to compare the parsed text against,\n * so allowing the save through would let an unloaded/stale comparison pass by\n * accident. Once loaded, `loadedKey` is `string | null` (P5's unset state, D-1).\n *\n * `parsedKey` is whatever the parsed JSON text's own `key` field currently holds.\n * `undefined` (the field is absent from the text) is treated exactly like an\n * explicit `null` — both mean \"no key\" on the wire, and a definition that dropped\n * the field entirely must be refused exactly like one that changed it, never waved\n * through as \"nothing to compare\".\n */\nexport function workflowKeyEditAllowed(\n loadedKey: string | null | undefined,\n parsedKey: unknown,\n): KeyEditEvaluation {\n if (loadedKey === undefined) {\n return { allowed: false, reason: \"Workflow not loaded yet.\" };\n }\n const normalizedParsed = parsedKey === undefined ? null : parsedKey;\n if (normalizedParsed !== loadedKey) {\n return {\n allowed: false,\n reason: \"key cannot be changed here — use the Settings panel's Key field.\",\n };\n }\n return { allowed: true, reason: null };\n}\n\n/**\n * T4.1.1/A2: the shape actually written to `localStorage` for the right\n * rail's persisted state (`RightRail.tsx`'s `PersistedRail`) — `activeTool`\n * ONLY. `open` is deliberately absent from this interface, not merely\n * unwritten: {@link restoreRailState} below has nothing to read it FROM, so\n * a pre-existing `{\"open\":true,…}` value written before this task cannot\n * reopen the rail even by accident.\n */\nexport interface StoredRailState {\n activeTool: string | null;\n}\n\n/**\n * A2: parses `localStorage`'s raw rail entry into {@link StoredRailState}.\n * Missing/unparsable input, or a non-string `activeTool`, all fall back to\n * `{ activeTool: null }` — the same defensive shape `RightRail.tsx`'s own\n * `readStoredState` used before this task, minus the `open` field entirely.\n * `RightRail.tsx` is the one caller; it combines this result with a hardcoded\n * `open: false` on every read (D-I0-2) — that combination happens there, not\n * here, because `open`'s absence from THIS function's return type is the\n * proof a page guard can pin: there is no `open` member left to misread.\n */\nexport function restoreRailState(raw: string | null): StoredRailState {\n if (!raw) return { activeTool: null };\n try {\n const parsed = JSON.parse(raw) as Partial<Record<string, unknown>>;\n return { activeTool: typeof parsed.activeTool === \"string\" ? parsed.activeTool : null };\n } catch {\n return { activeTool: null };\n }\n}\n\n/**\n * A6: a listing row either Workflow, Function or Endpoint's list carries —\n * whichever archived signal the row's own kind uses. Workflow rows signal\n * archived via the existing `status === \"archived\"` (`WorkflowSummary`);\n * Function/Endpoint rows via the new `archivedAt` column T1.1.1 ships\n * (`string | null`). Both fields optional so one predicate below covers all\n * three wire shapes without a per-kind branch at each listing page's call\n * site.\n */\nexport interface ArchivableRow {\n status?: string;\n archivedAt?: string | null;\n}\n\n/**\n * A6: is this row archived? Archived when the row's `status` is `\"archived\"` OR it carries a\n * non-null `archivedAt` (Endpoint rows carry both fields; Workflow rows carry a `status` that is\n * `\"archived\"` exactly when `archivedAt` is set).\n */\nexport function isRowArchived(row: ArchivableRow): boolean {\n return row.status === \"archived\" || row.archivedAt != null;\n}\n\n/**\n * A6: which rows a listing page's \"Show archived\" toggle should render.\n * `showArchived` false (the default) drops every archived row; `true`\n * reveals them ALONGSIDE the live ones — an include, never a toggle that\n * hides the rest (the contract's mutation M6: a toggle that hides LIVE rows\n * once ON must fail the \"both a live and an archived row survive together\"\n * case below; M7: defaulting to showing archived rows must fail the\n * toggle-OFF case). One pure function shared by `WorkflowsPage.tsx`,\n * `FunctionsPage.tsx` and `EndpointsPage.tsx` rather than three inline\n * `.filter`s.\n */\nexport function visibleRows<T extends ArchivableRow>(\n rows: readonly T[],\n showArchived: boolean,\n): T[] {\n return showArchived ? rows.slice() : rows.filter((row) => !isRowArchived(row));\n}\n","/**\n * Pure row logic behind `ImportSpecModal`'s configure step (T2.1.1, IF-1 / D-B8 / D-B9).\n *\n * Turns the server's `POST /spec/preview` dependencies into editable rows and back into the\n * `selections` map the import body carries. The client NEVER ranks: a row's initial selection is\n * exactly the server's `suggested`. Every dependency yields exactly one selection on the way out —\n * `{mode:\"unconfigured\"}` included, never omitted and never upgraded to a suggestion the user\n * cleared.\n *\n * `node --test` throws `ERR_UNKNOWN_FILE_EXTENSION` on anything reaching the `@w6w/ui` import graph\n * (see `lib/import-paste.ts`), so this module takes no value import at all.\n */\n\nexport type DependencyKind = \"connection\" | \"var\" | \"secret\" | \"const\" | \"store\";\n\nexport type Selection =\n | { mode: \"bind\"; target: string }\n | { mode: \"create\"; name: string }\n | { mode: \"unconfigured\" };\n\nexport type SelectionMode = Selection[\"mode\"];\n\nexport interface DependencyOption {\n id: string;\n label: string;\n source: \"connection\" | \"built-in\" | \"var\" | \"secret\" | \"const\" | \"store\";\n authKey?: string;\n compatible?: boolean;\n reason?: string;\n}\n\nexport interface SpecDependency {\n key: string;\n kind: DependencyKind;\n name: string;\n app?: string;\n authHint?: { method: \"built-in\" } | { method: \"authKey\"; authKey: string };\n usages: { nodeId: string | null; path: string; access?: \"read\" | \"write\" | \"delete\" }[];\n store?: {\n kind: \"kv\" | \"doc\" | \"table\" | null;\n schema: unknown | null;\n access: { read: boolean; write: boolean; delete: boolean };\n };\n dynamic?: true;\n}\n\nexport interface PreviewDependency extends SpecDependency {\n options: DependencyOption[];\n suggested: Selection;\n canCreate: boolean;\n}\n\nexport interface ImportRow {\n key: string;\n dep: PreviewDependency;\n /** Options offered to the row (the server's, plus any connection created in-modal). */\n options: DependencyOption[];\n selection: Selection;\n /** Remembered name for `create`, so toggling modes does not lose an edit. */\n createName: string;\n}\n\n/** IF-1 \"Allowed modes\". */\nexport function allowedModes(dep: PreviewDependency): SelectionMode[] {\n if (dep.kind === \"store\") {\n if (dep.dynamic) return [\"unconfigured\"];\n return dep.canCreate ? [\"bind\", \"create\", \"unconfigured\"] : [\"bind\", \"unconfigured\"];\n }\n return [\"bind\", \"unconfigured\"];\n}\n\nfunction selectionAllowed(dep: PreviewDependency, s: Selection): boolean {\n return allowedModes(dep).includes(s.mode);\n}\n\n/** One row per dependency; the initial selection is `suggested` verbatim (D-B9). */\nexport function buildRows(deps: readonly PreviewDependency[]): ImportRow[] {\n return deps.map((dep) => ({\n key: dep.key,\n dep,\n options: [...dep.options],\n selection: dep.suggested,\n createName: dep.suggested.mode === \"create\" ? dep.suggested.name : dep.name,\n }));\n}\n\nfunction update(\n rows: readonly ImportRow[],\n key: string,\n fn: (row: ImportRow) => ImportRow,\n): ImportRow[] {\n return rows.map((r) => (r.key === key ? fn(r) : r));\n}\n\n/** Bind a row to an option. Refused (row unchanged) for an unknown / incompatible option or a disallowed mode. */\nexport function setBind(rows: readonly ImportRow[], key: string, target: string): ImportRow[] {\n return update(rows, key, (row) => {\n const opt = row.options.find((o) => o.id === target);\n if (!opt || opt.compatible === false) return row;\n const next: Selection = { mode: \"bind\", target };\n return selectionAllowed(row.dep, next) ? { ...row, selection: next } : row;\n });\n}\n\n/** Switch a store row to `create` / edit its name. Refused unless `create` is allowed. */\nexport function setCreateName(rows: readonly ImportRow[], key: string, name: string): ImportRow[] {\n return update(rows, key, (row) => {\n const next: Selection = { mode: \"create\", name };\n return selectionAllowed(row.dep, next) ? { ...row, selection: next, createName: name } : row;\n });\n}\n\n/** Leave the dependency unconfigured (always allowed). */\nexport function setUnconfigured(rows: readonly ImportRow[], key: string): ImportRow[] {\n return update(rows, key, (row) => ({ ...row, selection: { mode: \"unconfigured\" } }));\n}\n\n/** A connection was just created via \"Add connection\": offer it and bind the row to it. */\nexport function withCreatedConnection(\n rows: readonly ImportRow[],\n key: string,\n id: string,\n label: string,\n): ImportRow[] {\n return update(rows, key, (row) => {\n if (row.dep.kind !== \"connection\") return row;\n const options = row.options.some((o) => o.id === id)\n ? row.options\n : [...row.options, { id, label, source: \"connection\" as const }];\n return { ...row, options, selection: { mode: \"bind\", target: id } };\n });\n}\n\n/** Whether a row can be submitted: a `create` needs a non-blank name. */\nexport function rowReady(row: ImportRow): boolean {\n return row.selection.mode !== \"create\" || row.selection.name.trim() !== \"\";\n}\n\nexport function rowsReady(rows: readonly ImportRow[]): boolean {\n return rows.every(rowReady);\n}\n\n/** The import body's `selections`: ONE entry per dependency key, `unconfigured` included. */\nexport function toSelections(rows: readonly ImportRow[]): Record<string, Selection> {\n const out: Record<string, Selection> = {};\n for (const row of rows) {\n const s = row.selection;\n out[row.key] = s.mode === \"create\" ? { mode: \"create\", name: s.name.trim() } : s;\n }\n return out;\n}\n"],"names":["parseImportPaste","text","expectedKind","value","parsed","found","metadataFieldsForKind","kind","hasDefinitionActions","hasVersionHistory","hasDelete","specCollectionForKind","evaluateEdit","stored","workflowKeyEditAllowed","loadedKey","parsedKey","restoreRailState","raw","isRowArchived","row","visibleRows","rows","showArchived","allowedModes","dep","selectionAllowed","s","buildRows","deps","update","key","fn","r","setBind","target","opt","o","next","setCreateName","name","setUnconfigured","withCreatedConnection","id","label","options","rowReady","rowsReady","toSelections","out"],"mappings":"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"}