clearotron 0.3.2-beta.7 → 0.3.2-beta.9

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 (272) hide show
  1. package/.env.example +58 -26
  2. package/CONTRIBUTING.md +8 -8
  3. package/INSTALL.md +148 -81
  4. package/README.md +3 -3
  5. package/SECURITY.md +3 -3
  6. package/bin/brandowner.mjs +3 -3
  7. package/bin/framework-preflight.mjs +1 -1
  8. package/bin/onboard.mjs +637 -216
  9. package/bin/start.mjs +151 -27
  10. package/bin/update.mjs +58 -11
  11. package/build-info.json +2 -2
  12. package/docs/DELIVERY.md +2 -1
  13. package/docs/INTAKE.md +1 -1
  14. package/docs/ONBOARDING.md +1 -1
  15. package/docs/architecture/03-run-lifecycle.md +6 -6
  16. package/docs/architecture/04-configuration-reference.md +32 -14
  17. package/docs/architecture/05-config-governance.md +23 -8
  18. package/docs/architecture/05-customer-profiles.md +2 -2
  19. package/docs/architecture/06-operations-runbook.md +3 -3
  20. package/docs/architecture/08-development-guide.md +6 -6
  21. package/docs/configuration.md +5 -5
  22. package/docs/decisions/0003-credential-model.md +1 -1
  23. package/docs/writing-standard.md +4 -0
  24. package/driver/CHANGELOG.md +124 -0
  25. package/driver/README.md +3 -3
  26. package/driver/band-size.mjs +59 -0
  27. package/driver/binding-layers.mjs +1 -1
  28. package/driver/citation-census.json +3 -3
  29. package/driver/{prelim-variants-record.mjs → clearance-variants-record.mjs} +24 -24
  30. package/driver/common-law-receipts.mjs +2 -2
  31. package/driver/company-bundle.mjs +3 -3
  32. package/driver/compose-read.mjs +8 -14
  33. package/driver/config-inventory.mjs +112 -9
  34. package/driver/consumption-ledger.mjs +2 -2
  35. package/driver/contract-arm2-baseline.json +2 -5
  36. package/driver/contract-dictation-registry.mjs +19 -19
  37. package/driver/contract-e3-backlog.mjs +43 -43
  38. package/driver/contract-e3-baseline.json +14 -14
  39. package/driver/contract-vocabulary.mjs +68 -27
  40. package/driver/deliver-trigger.sh +16 -16
  41. package/driver/demo-container.mjs +3 -3
  42. package/driver/dev-portal.mjs +3 -3
  43. package/driver/disposition-call.mjs +1 -1
  44. package/driver/door-gates.mjs +41 -7
  45. package/driver/doubt-ledger.mjs +2 -2
  46. package/driver/drainer-identity.mjs +34 -8
  47. package/driver/driver.config.mjs +367 -104
  48. package/driver/engine/CONTRACT.md +10 -3
  49. package/driver/engine/README.md +2 -2
  50. package/driver/engine/anthropic-agent.mjs +77 -21
  51. package/driver/engine/auth.mjs +129 -10
  52. package/driver/engine/jx-turn.mjs +7 -6
  53. package/driver/engine/mcp/README.md +1 -1
  54. package/driver/engine/mcp/dispositions-server.mjs +3 -3
  55. package/driver/engine/mcp/gather-config.mjs +9 -9
  56. package/driver/engine/mcp/perplexity-server.mjs +2 -2
  57. package/driver/engine/mcp/recording-server.mjs +18 -5
  58. package/driver/engine/openai-agent.mjs +4 -2
  59. package/driver/engine/probe.mjs +110 -23
  60. package/driver/enqueue-schema.mjs +6 -2
  61. package/driver/findings-model.mjs +6 -3
  62. package/driver/flag-snapshot.mjs +34 -8
  63. package/driver/form-neighbourhood.mjs +54 -7
  64. package/driver/framework.mjs +4 -4
  65. package/driver/gateway.mjs +36 -24
  66. package/driver/jx-lanes.mjs +23 -4
  67. package/driver/jx-units.mjs +7 -4
  68. package/driver/jx.mjs +34 -4
  69. package/driver/knockout-review-record.mjs +56 -4
  70. package/driver/known-conflicts.mjs +1 -1
  71. package/driver/matter-frame-record.mjs +90 -1
  72. package/driver/named-band.mjs +1 -1
  73. package/driver/ordinary-words.mjs +51 -0
  74. package/driver/outbox-backoff.mjs +31 -16
  75. package/driver/package.json +1 -1
  76. package/driver/partial-payload-baseline.json +2 -2
  77. package/driver/phase0.mjs +3 -3
  78. package/driver/pipeline-knockout.mjs +5 -5
  79. package/driver/pipeline.mjs +396 -81
  80. package/driver/placement-form.mjs +77 -1
  81. package/driver/placement-model.mjs +1 -1
  82. package/driver/portal-config-view.mjs +30 -1
  83. package/driver/portal-report.mjs +107 -6
  84. package/driver/portal-service.mjs +80 -14
  85. package/driver/portal-upstream.mjs +1 -1
  86. package/driver/predelivery-lint.mjs +12 -2
  87. package/driver/preserve-merge.mjs +3 -3
  88. package/driver/product-rows.mjs +2 -2
  89. package/driver/products.mjs +1 -1
  90. package/driver/profiles/README.md +3 -3
  91. package/driver/profiles/demo-brand-owner.json +2 -2
  92. package/driver/profiles.mjs +55 -17
  93. package/driver/progress.mjs +18 -8
  94. package/driver/provider-usage.mjs +8 -8
  95. package/driver/publish/index.mjs +154 -8
  96. package/driver/publish/knockout.mjs +39 -5
  97. package/driver/publish/pool-admin.mjs +1 -1
  98. package/driver/publish/publish-inputs.mjs +18 -2
  99. package/driver/publish/render-knockout.mjs +184 -31
  100. package/driver/publish/render.mjs +323 -93
  101. package/driver/publish/report-data.mjs +4 -1
  102. package/driver/publish/report-topbar.mjs +58 -0
  103. package/driver/publish/search-depth.mjs +133 -4
  104. package/driver/publish/templates/report.css +78 -4
  105. package/driver/publish/xlsx.mjs +20 -1
  106. package/driver/queue-order.mjs +2 -2
  107. package/driver/recording-agreement.mjs +1 -1
  108. package/driver/reference-score.mjs +1 -1
  109. package/driver/register-availability.mjs +2 -2
  110. package/driver/register-count.mjs +50 -5
  111. package/driver/register-coverage.mjs +161 -1
  112. package/driver/register-digest-record.mjs +236 -11
  113. package/driver/register-grant-vocabulary.mjs +1 -1
  114. package/driver/register-plan.mjs +189 -2
  115. package/driver/registry-fidelity.mjs +3 -3
  116. package/driver/repair-composers.mjs +1 -1
  117. package/driver/repair-contract.mjs +1 -1
  118. package/driver/replay-archive.mjs +6 -6
  119. package/driver/report-overview-record.mjs +2 -2
  120. package/driver/result-noun-fields.mjs +2 -2
  121. package/driver/run-economics.mjs +41 -10
  122. package/driver/run-requirements.mjs +173 -9
  123. package/driver/runner.mjs +5 -5
  124. package/driver/scope-facts.mjs +20 -5
  125. package/driver/scope-ledger.mjs +5 -5
  126. package/driver/search-policy.mjs +22 -12
  127. package/driver/skills/README.md +15 -15
  128. package/driver/skills/blind-frame/SKILL.md +2 -2
  129. package/driver/skills/case-law-citation/SKILL.md +4 -4
  130. package/driver/skills/case-law-citation/sources/eurlex.md +1 -1
  131. package/driver/skills/{prelim-common-law → clearance-common-law}/SKILL.md +22 -22
  132. package/driver/skills/{prelim-common-law → clearance-common-law}/perplexity-prompts.md +1 -1
  133. package/driver/skills/{prelim-register → clearance-register}/SKILL.md +10 -10
  134. package/driver/skills/{prelim-register → clearance-register}/digest.md +2 -2
  135. package/driver/skills/{prelim-register → clearance-register}/providers/README.md +1 -1
  136. package/driver/skills/{prelim-register → clearance-register}/providers/clarivate.md +37 -35
  137. package/driver/skills/{prelim-register → clearance-register}/providers/corsearch.md +20 -11
  138. package/driver/skills/{prelim-register → clearance-register}/providers/signa.md +5 -5
  139. package/driver/skills/{prelim-register → clearance-register}/register-recipes.md +3 -3
  140. package/driver/skills/{prelim-register → clearance-register}/status-rules.md +2 -2
  141. package/driver/skills/{prelim-register → clearance-register}/stealth-filer-indicators.md +1 -1
  142. package/driver/skills/{prelim-register → clearance-register}/unit.md +2 -2
  143. package/driver/skills/{prelim-search → clearance-search}/SKILL.md +31 -31
  144. package/driver/skills/{prelim-search → clearance-search}/delivery-contract.md +1 -1
  145. package/driver/skills/{prelim-search → clearance-search}/phase2-execution.md +18 -18
  146. package/driver/skills/{prelim-search → clearance-search}/synthesis-rules.md +7 -7
  147. package/driver/skills/{prelim-variants → clearance-variants}/SKILL.md +18 -18
  148. package/driver/skills/{prelim-variants → clearance-variants}/transliteration-scripts.md +5 -5
  149. package/driver/skills/frame-diff/SKILL.md +1 -1
  150. package/driver/skills/knockout-assess/SKILL.md +10 -7
  151. package/driver/skills/matter-frame/SKILL.md +3 -3
  152. package/driver/skills/narrative-refutation/SKILL.md +9 -9
  153. package/driver/skills/placement-inquiry/SKILL.md +5 -5
  154. package/driver/stage-context.mjs +1 -1
  155. package/driver/stages-knockout.mjs +4 -4
  156. package/driver/stages.mjs +65 -61
  157. package/driver/status-snapshot.mjs +2 -2
  158. package/driver/suite-census.json +340 -136
  159. package/driver/surface-exit-verdict.mjs +58 -0
  160. package/driver/systemd/README.md +9 -6
  161. package/driver/systemd/clearotron-worker.service +1 -1
  162. package/driver/terminal-clamp.mjs +109 -1
  163. package/driver/tokens.mjs +169 -3
  164. package/driver/unit-environment.mjs +42 -15
  165. package/driver/unit-inventory.mjs +19 -2
  166. package/driver/usage-ledger.mjs +1 -1
  167. package/driver/variant-manifest-model.mjs +4 -4
  168. package/driver/verify-knockout.mjs +27 -0
  169. package/driver/verify.mjs +94 -6
  170. package/driver/whatif-queue.mjs +1 -1
  171. package/driver/wordlists/en.txt +63906 -0
  172. package/mcp-server/CHANGELOG.md +8 -0
  173. package/mcp-server/README.md +1 -1
  174. package/mcp-server/lib/README.md +1 -1
  175. package/mcp-server/lib/options.mjs +8 -7
  176. package/mcp-server/lib/plan.mjs +18 -2
  177. package/mcp-server/lib/runs.mjs +1 -1
  178. package/mcp-server/lib/usage.mjs +3 -3
  179. package/mcp-server/lib/whatif.mjs +1 -1
  180. package/mcp-server/package.json +1 -1
  181. package/mcp-server/server.mjs +18 -1
  182. package/package.json +12 -11
  183. package/portal-ui/dist/assets/{index-CVOIvdhc.css → index-CtvwLCti.css} +207 -3
  184. package/portal-ui/dist/assets/{index-5UyqAyNM.js → index-EVaSo5-g.js} +1580 -527
  185. package/portal-ui/dist/index.html +2 -2
  186. package/portal-ui/package.json +1 -1
  187. package/providers/README.md +1 -1
  188. package/providers/_shared/enumerate.mjs +6 -6
  189. package/providers/_shared/execute-plan.mjs +3 -3
  190. package/providers/_shared/ledger.mjs +119 -5
  191. package/providers/_shared/provider-text.mjs +2 -2
  192. package/providers/_shared/screen.mjs +2 -2
  193. package/providers/_shared/script-form.mjs +3 -3
  194. package/providers/_shared/territory-codes.mjs +23 -3
  195. package/providers/clarivate/README.md +1 -1
  196. package/providers/clarivate/src/capabilities.js +12 -12
  197. package/providers/clarivate/src/core.js +37 -43
  198. package/providers/corsearch/README.md +1 -1
  199. package/providers/corsearch/src/capabilities.js +5 -5
  200. package/providers/corsearch/src/core.js +3 -3
  201. package/providers/jx/README.md +2 -1
  202. package/providers/jx/src/turn-envelope.mjs +8 -3
  203. package/providers/oauth-mcp-bridge/CHANGELOG.md +8 -0
  204. package/providers/oauth-mcp-bridge/package.json +1 -1
  205. package/providers/perplexity/src/core.js +1 -1
  206. package/providers/signa/README.md +1 -1
  207. package/providers/signa/src/capabilities.js +42 -49
  208. package/providers/signa/src/core.js +106 -29
  209. package/providers/uspto-local/README.md +1 -1
  210. package/providers/uspto-local/src/sync.js +1 -1
  211. package/scripts/README.md +1 -0
  212. package/scripts/ask-ai-render-check.mjs +127 -1
  213. package/scripts/authority-boundary-probe.mjs +8 -6
  214. package/scripts/backfill-started-at.mjs +2 -2
  215. package/scripts/census-merge-driver.mjs +33 -2
  216. package/scripts/citation-anchor-report.mjs +181 -0
  217. package/scripts/dead-names.mjs +1 -1
  218. package/scripts/deprecate-below.mjs +66 -8
  219. package/scripts/drain-preflight.mjs +1 -1
  220. package/scripts/e2e.mjs +174 -0
  221. package/scripts/env-audit.mjs +39 -6
  222. package/scripts/env-classify.mjs +20 -2
  223. package/scripts/freeze-example-run.mjs +61 -18
  224. package/scripts/generated-files-are-current.mjs +69 -4
  225. package/scripts/live-surface-check.mjs +124 -41
  226. package/scripts/markdown-link-check.mjs +1 -1
  227. package/scripts/merge-shape-check.mjs +242 -0
  228. package/scripts/mint-names-in-force.mjs +5 -5
  229. package/scripts/mint-offered-territories.mjs +72 -0
  230. package/scripts/mint-public-residue.mjs +2 -2
  231. package/scripts/mint-reference-strip-backlog.mjs +2 -2
  232. package/scripts/mint-suite-census.mjs +75 -2
  233. package/scripts/mint-writing-standard-backlog.mjs +2 -2
  234. package/scripts/purge-runs.mjs +7 -7
  235. package/scripts/reconcile-runs.mjs +2 -2
  236. package/scripts/release-approve-parked.mjs +20 -2
  237. package/scripts/release-await-cut.mjs +120 -1
  238. package/scripts/release-note-required.mjs +76 -8
  239. package/scripts/report-header-render-check.mjs +164 -0
  240. package/scripts/settings-render-check.mjs +75 -2
  241. package/scripts/test-full.mjs +96 -3
  242. package/scripts/test-run.mjs +10 -0
  243. package/shared/brand.mjs +27 -0
  244. package/shared/connect-clients.mjs +39 -11
  245. package/shared/deployment-box.mjs +7 -2
  246. package/shared/driver-dir.mjs +1 -1
  247. package/shared/env-aliases.mjs +1 -1
  248. package/shared/identifier-scan.mjs +65 -9
  249. package/shared/identifier-sentinels.mjs +22 -0
  250. package/shared/names-in-force.mjs +4 -2
  251. package/shared/offered-territories.json +738 -0
  252. package/shared/pre-rename-spellings.mjs +53 -0
  253. package/shared/reference-guard-classes.mjs +40 -2
  254. package/shared/stdio-connect.mjs +39 -4
  255. package/shared/tree-commit.mjs +48 -0
  256. /package/driver/skills/{prelim-register → clearance-register}/providers/euipo.md +0 -0
  257. /package/driver/skills/{prelim-register → clearance-register}/providers/free-tier.md +0 -0
  258. /package/driver/skills/{prelim-register → clearance-register}/providers/uspto-local.md +0 -0
  259. /package/driver/skills/{prelim-search → clearance-search}/field-doctrine-pharma.md +0 -0
  260. /package/driver/skills/{prelim-search → clearance-search}/firm-wide-reasoning.md +0 -0
  261. /package/driver/skills/{prelim-search → clearance-search}/report-prose.md +0 -0
  262. /package/driver/skills/{prelim-search → clearance-search}/risk-framework-demo.manifest.json +0 -0
  263. /package/driver/skills/{prelim-search → clearance-search}/risk-framework-demo.md +0 -0
  264. /package/driver/skills/{prelim-search → clearance-search}/risk-framework-triage.manifest.json +0 -0
  265. /package/driver/skills/{prelim-search → clearance-search}/risk-framework-triage.md +0 -0
  266. /package/driver/skills/{prelim-search → clearance-search}/risk-framework.manifest.json +0 -0
  267. /package/driver/skills/{prelim-search → clearance-search}/risk-framework.md +0 -0
  268. /package/driver/skills/{prelim-search → clearance-search}/template-formatting.md +0 -0
  269. /package/driver/skills/{prelim-search → clearance-search}/templates/email/generic.md +0 -0
  270. /package/driver/skills/{prelim-search → clearance-search}/templates/search-request-form.html +0 -0
  271. /package/driver/skills/{prelim-search → clearance-search}/worked-examples-demo.md +0 -0
  272. /package/driver/skills/{prelim-search → clearance-search}/worked-examples.md +0 -0
@@ -11926,6 +11926,7 @@ var api = {
11926
11926
  };
11927
11927
  }),
11928
11928
  ...!("territories" in b) ? {} : { registerTerritories: b["territories"] === null ? null : asArray(b["territories"]).filter((t) => typeof t === "string") },
11929
+ ...asString(b["registerLabel"]) ? { registerLabel: asString(b["registerLabel"]) } : {},
11929
11930
  recipes: asArray(b["recipes"]).map((x) => {
11930
11931
  const r = x;
11931
11932
  return {
@@ -12193,11 +12194,38 @@ var api = {
12193
12194
  billing: {
12194
12195
  mode: asString(bill["mode"]) ?? "unknown",
12195
12196
  apiBilled: bill["apiBilled"] === true,
12196
- missing: asStrings(bill["missing"])
12197
+ missing: asStrings(bill["missing"]),
12198
+ cloud: asString(bill["cloud"]),
12199
+ cloudName: asString(bill["cloudName"]),
12200
+ reason: bill["reason"] != null ? (() => {
12201
+ const raw = bill["reason"];
12202
+ const r = typeof raw === "object" && !Array.isArray(raw) ? asRecord(raw) : {};
12203
+ return {
12204
+ kind: asString(r["kind"]) ?? "unclassified",
12205
+ mode: asString(r["mode"]),
12206
+ defaulted: r["defaulted"] === true,
12207
+ setting: asString(r["setting"]) ?? "",
12208
+ clouds: asArray(r["clouds"]).flatMap((c) => {
12209
+ const x = asRecord(c);
12210
+ const name = asString(x["name"]);
12211
+ const setting = asString(x["setting"]);
12212
+ return name && setting ? [{
12213
+ name,
12214
+ setting
12215
+ }] : [];
12216
+ }),
12217
+ modes: asStrings(r["modes"]),
12218
+ gateway: asString(r["gateway"]),
12219
+ engineSetting: asString(r["engineSetting"]),
12220
+ engineChoice: asString(r["engineChoice"])
12221
+ };
12222
+ })() : null
12197
12223
  },
12198
12224
  binaryPresent: e["binaryPresent"] === true,
12199
12225
  program: asString(e["program"]),
12200
- install: asString(e["install"])
12226
+ install: asString(e["install"]),
12227
+ programSetting: asString(e["programSetting"]),
12228
+ setupRoute: e["setupRoute"] === "packaged" ? "packaged" : e["setupRoute"] === "checkout" ? "checkout" : null
12201
12229
  };
12202
12230
  })() : null,
12203
12231
  providers: Array.isArray(b["providers"]) ? asArray(b["providers"]).map((p) => {
@@ -12310,14 +12338,24 @@ var api = {
12310
12338
  method: "POST",
12311
12339
  body: JSON.stringify(input)
12312
12340
  }),
12313
- roster: () => call("/portal/admin/roster", (b) => asArray(b["customers"]).map((c) => {
12314
- const r = c;
12315
- return {
12316
- key: asString(r["key"]) ?? "",
12317
- name: asString(r["name"]) ?? "",
12318
- facts: asCompanyFacts(r),
12319
- org: asString(r["org"]) ?? null
12320
- };
12341
+ roster: () => call("/portal/admin/roster", (b) => ({
12342
+ companies: asArray(b["customers"]).map((c) => {
12343
+ const r = c;
12344
+ return {
12345
+ key: asString(r["key"]) ?? "",
12346
+ name: asString(r["name"]) ?? "",
12347
+ facts: asCompanyFacts(r),
12348
+ org: asString(r["org"]) ?? null
12349
+ };
12350
+ }),
12351
+ unreadable: asArray(b["unreadable"]).flatMap((u) => {
12352
+ const r = u;
12353
+ const key = asString(r["key"]);
12354
+ return key ? [{
12355
+ key,
12356
+ reason: asString(r["reason"]) ?? ""
12357
+ }] : [];
12358
+ })
12321
12359
  }))
12322
12360
  };
12323
12361
  //#endregion
@@ -12330,13 +12368,6 @@ var NAV = [
12330
12368
  icon: "panel-left",
12331
12369
  scope: "account"
12332
12370
  },
12333
- {
12334
- id: "ai",
12335
- label: "Connect your AI",
12336
- path: "/portal/ai",
12337
- icon: "sparkles",
12338
- scope: "account"
12339
- },
12340
12371
  {
12341
12372
  id: "people",
12342
12373
  label: "People",
@@ -12424,6 +12455,14 @@ var NAV = [
12424
12455
  }
12425
12456
  ]
12426
12457
  },
12458
+ {
12459
+ id: "ai",
12460
+ label: "Connect your AI",
12461
+ path: "/portal/ai",
12462
+ icon: "sparkles",
12463
+ scope: "account",
12464
+ rail: "foot"
12465
+ },
12427
12466
  {
12428
12467
  id: "new-company",
12429
12468
  label: "New company",
@@ -12463,11 +12502,13 @@ function navFor(who, entries = NAV) {
12463
12502
  children: e.children.filter((c) => visible(c, who) && !c.hidden)
12464
12503
  } : e);
12465
12504
  }
12505
+ var railSideOf = (e) => e.rail ?? ((e.scope ?? "account") === "account" ? "above" : "below");
12466
12506
  function navGroupsFor(who, entries = NAV) {
12467
12507
  const visibleEntries = navFor(who, entries);
12468
12508
  return {
12469
- account: visibleEntries.filter((e) => (e.scope ?? "account") === "account"),
12470
- owner: visibleEntries.filter((e) => e.scope === "owner")
12509
+ account: visibleEntries.filter((e) => railSideOf(e) === "above"),
12510
+ owner: visibleEntries.filter((e) => railSideOf(e) === "below"),
12511
+ foot: visibleEntries.filter((e) => railSideOf(e) === "foot")
12471
12512
  };
12472
12513
  }
12473
12514
  function scopeOf(id, entries = NAV) {
@@ -13154,16 +13195,30 @@ function usePath() {
13154
13195
  ];
13155
13196
  }
13156
13197
  function NavList({ entries, current, go, collapsed }) {
13198
+ const [folded, setFolded] = (0, import_react.useState)(null);
13199
+ const within = (id) => current === id || (current?.startsWith(id + ".") ?? false);
13200
+ (0, import_react.useEffect)(() => {
13201
+ if (folded !== null && current !== folded && !(current?.startsWith(folded + ".") ?? false)) setFolded(null);
13202
+ }, [current, folded]);
13157
13203
  return (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: entries.map((e) => {
13158
- const active = current === e.id || (current?.startsWith(e.id + ".") ?? false);
13204
+ const active = within(e.id);
13205
+ const open = Boolean(e.children) && active && folded !== e.id;
13159
13206
  return (0, import_jsx_runtime.jsxs)("div", { children: [(0, import_jsx_runtime.jsxs)("button", {
13160
13207
  type: "button",
13161
13208
  className: `nav-item${active ? " active" : ""}`,
13162
- onClick: () => go(e.path),
13209
+ onClick: () => {
13210
+ if (e.children && active && !collapsed) {
13211
+ setFolded(open ? e.id : null);
13212
+ return;
13213
+ }
13214
+ setFolded(null);
13215
+ go(e.path);
13216
+ },
13163
13217
  "aria-current": active ? "page" : void 0,
13218
+ "aria-expanded": e.children && !collapsed ? open : void 0,
13164
13219
  title: collapsed ? e.label : void 0,
13165
13220
  children: [(0, import_jsx_runtime.jsx)(Icon, { name: e.icon }), collapsed ? null : (0, import_jsx_runtime.jsx)("span", { children: e.label })]
13166
- }), e.children && active && !collapsed ? (0, import_jsx_runtime.jsx)("div", {
13221
+ }), e.children && open && !collapsed ? (0, import_jsx_runtime.jsx)("div", {
13167
13222
  className: "nav-sub",
13168
13223
  children: e.children.map((c) => (0, import_jsx_runtime.jsxs)("div", { children: [c.groupLabel ? (0, import_jsx_runtime.jsx)("div", {
13169
13224
  className: "eyebrow nav-group",
@@ -13231,7 +13286,10 @@ function AppShell({ render }) {
13231
13286
  const readsRoster = meResult?.kind === "ok" && meResult.value.allAccounts;
13232
13287
  const { result: rosterResult, reload: reloadRoster } = useLoad(() => readsRoster ? api.roster() : Promise.resolve({
13233
13288
  kind: "ok",
13234
- value: []
13289
+ value: {
13290
+ companies: [],
13291
+ unreadable: []
13292
+ }
13235
13293
  }), [readsRoster]);
13236
13294
  (0, import_react.useEffect)(() => {
13237
13295
  document.documentElement.classList.toggle("anon-on", anon);
@@ -13266,7 +13324,7 @@ function AppShell({ render }) {
13266
13324
  const groups = navGroupsFor(me);
13267
13325
  const entry = screenForPath(path, me) ?? (path === "/portal" || path === "/portal/" ? HOME : null);
13268
13326
  const personal = entry !== null && avatarEntryOf(entry.id, me) !== null;
13269
- const names = ownerNameMap(me.accountNames, rosterResult?.kind === "ok" ? rosterResult.value : []);
13327
+ const names = ownerNameMap(me.accountNames, rosterResult?.kind === "ok" ? rosterResult.value.companies : []);
13270
13328
  const ownerName = (key) => {
13271
13329
  if (key === null || !isGenericKey(key)) return ownerNameFrom(names, key);
13272
13330
  const plain = ownerNameFrom(names, GENERIC_ACCOUNT);
@@ -13274,17 +13332,17 @@ function AppShell({ render }) {
13274
13332
  if (!org || me.organisations.length < 2) return plain;
13275
13333
  return `${plain} · ${me.organisations.find((o) => o.key === org)?.name ?? org}`;
13276
13334
  };
13277
- const facts = companyFactsMap(me.accountFacts, rosterResult?.kind === "ok" ? rosterResult.value : []);
13335
+ const facts = companyFactsMap(me.accountFacts, rosterResult?.kind === "ok" ? rosterResult.value.companies : []);
13278
13336
  const factsFor = (key) => facts[isGenericKey(key) ? GENERIC_ACCOUNT : key];
13279
- const ownerKeys = switcherKeys(me, rosterResult?.kind === "ok" ? rosterResult.value : null);
13280
- const rosterOrgs = Object.fromEntries((rosterResult?.kind === "ok" ? rosterResult.value : []).flatMap((c) => c.org ? [[c.key, c.org]] : []));
13337
+ const ownerKeys = switcherKeys(me, rosterResult?.kind === "ok" ? rosterResult.value.companies : null);
13338
+ const rosterOrgs = Object.fromEntries((rosterResult?.kind === "ok" ? rosterResult.value.companies : []).flatMap((c) => c.org ? [[c.key, c.org]] : []));
13281
13339
  const orgOf = (key) => orgOfGeneric(key) ?? me.accountOrgs[key] ?? rosterOrgs[key] ?? null;
13282
13340
  const organisations = me.organisations;
13283
13341
  const refreshCompanies = () => {
13284
13342
  reloadMe();
13285
13343
  reloadRoster();
13286
13344
  };
13287
- const sole = ownerKeys.length === 1 ? ownerKeys[0] ?? null : null;
13345
+ const sole = !(readsRoster && !!rosterResult && rosterResult.kind !== "ok") && ownerKeys.length === 1 ? ownerKeys[0] ?? null : null;
13288
13346
  const ownerInView = owner ?? sole;
13289
13347
  const body = entry ? render(entry.id, {
13290
13348
  me,
@@ -13375,6 +13433,15 @@ function AppShell({ render }) {
13375
13433
  })]
13376
13434
  }) : null]
13377
13435
  }),
13436
+ groups.foot.length ? (0, import_jsx_runtime.jsx)("div", {
13437
+ className: "sidebar-pinned",
13438
+ children: (0, import_jsx_runtime.jsx)(NavList, {
13439
+ entries: groups.foot,
13440
+ current: entry?.id ?? null,
13441
+ go,
13442
+ collapsed: collapsed && !mobile
13443
+ })
13444
+ }) : null,
13378
13445
  !mobile ? (0, import_jsx_runtime.jsx)("div", {
13379
13446
  className: "sidebar-foot",
13380
13447
  children: (0, import_jsx_runtime.jsxs)("button", {
@@ -13388,141 +13455,166 @@ function AppShell({ render }) {
13388
13455
  }),
13389
13456
  (0, import_jsx_runtime.jsxs)("div", {
13390
13457
  className: "main",
13391
- children: [(0, import_jsx_runtime.jsxs)("header", {
13392
- className: "topbar",
13393
- children: [
13394
- mobile ? (0, import_jsx_runtime.jsx)("button", {
13395
- type: "button",
13396
- className: "icon-btn",
13397
- "aria-label": "Open menu",
13398
- onClick: () => setDrawer(true),
13399
- children: (0, import_jsx_runtime.jsx)(Icon, { name: "menu" })
13400
- }) : null,
13401
- (0, import_jsx_runtime.jsx)("h1", {
13402
- "data-anon": personal ? void 0 : "mark",
13403
- children: !entry ? "Not found" : personal ? entry.label : scopeOf(entry.id) === "owner" ? ownerName(ownerInView) : ""
13404
- }),
13405
- (0, import_jsx_runtime.jsxs)("div", {
13406
- style: {
13407
- marginLeft: "auto",
13408
- display: "flex",
13409
- alignItems: "center",
13410
- gap: 4,
13411
- position: "relative"
13412
- },
13413
- children: [
13414
- !mobile && accountName ? (0, import_jsx_runtime.jsxs)("div", {
13415
- style: {
13416
- textAlign: "right",
13417
- marginRight: 8,
13418
- minWidth: 0
13419
- },
13420
- children: [(0, import_jsx_runtime.jsx)("div", {
13421
- className: "eyebrow",
13422
- children: "Organisation"
13423
- }), (0, import_jsx_runtime.jsx)("div", {
13458
+ children: [
13459
+ (0, import_jsx_runtime.jsxs)("header", {
13460
+ className: "topbar",
13461
+ children: [
13462
+ mobile ? (0, import_jsx_runtime.jsx)("button", {
13463
+ type: "button",
13464
+ className: "icon-btn",
13465
+ "aria-label": "Open menu",
13466
+ onClick: () => setDrawer(true),
13467
+ children: (0, import_jsx_runtime.jsx)(Icon, { name: "menu" })
13468
+ }) : null,
13469
+ (0, import_jsx_runtime.jsx)("h1", {
13470
+ "data-anon": personal ? void 0 : "mark",
13471
+ children: !entry ? "Not found" : personal ? entry.label : scopeOf(entry.id) === "owner" ? ownerName(ownerInView) : ""
13472
+ }),
13473
+ (0, import_jsx_runtime.jsxs)("div", {
13474
+ style: {
13475
+ marginLeft: "auto",
13476
+ display: "flex",
13477
+ alignItems: "center",
13478
+ gap: 4,
13479
+ position: "relative"
13480
+ },
13481
+ children: [
13482
+ !mobile && accountName ? (0, import_jsx_runtime.jsxs)("div", {
13424
13483
  style: {
13425
- fontWeight: 700,
13426
- color: "var(--text-strong)",
13427
- fontSize: 14,
13428
- lineHeight: 1.2,
13429
- whiteSpace: "nowrap"
13484
+ textAlign: "right",
13485
+ marginRight: 8,
13486
+ minWidth: 0
13430
13487
  },
13431
- "data-anon": "mark",
13432
- children: accountName
13433
- })]
13434
- }) : null,
13435
- (0, import_jsx_runtime.jsx)("button", {
13436
- type: "button",
13437
- className: "icon-btn",
13438
- "aria-pressed": anon,
13439
- "aria-label": "Blur names for screen sharing",
13440
- title: "Blur names for screen sharing",
13441
- onClick: () => setAnon((a) => !a),
13442
- children: (0, import_jsx_runtime.jsx)(Icon, { name: anon ? "eye-off" : "eye" })
13443
- }),
13444
- (0, import_jsx_runtime.jsx)("button", {
13445
- type: "button",
13446
- className: "icon-btn",
13447
- "aria-pressed": theme === "dark",
13448
- "aria-label": "Switch light or dark theme",
13449
- title: "Switch light or dark theme",
13450
- onClick: toggleTheme,
13451
- children: (0, import_jsx_runtime.jsx)(Icon, { name: "theme" })
13452
- }),
13453
- (0, import_jsx_runtime.jsx)("button", {
13454
- type: "button",
13455
- className: "icon-btn avatar",
13456
- "aria-haspopup": "menu",
13457
- "aria-expanded": avatarOpen,
13458
- "aria-label": "Settings and about",
13459
- "aria-current": personal ? "true" : void 0,
13460
- onClick: () => setAvatarOpen((o) => !o),
13461
- children: initials(me.email)
13462
- }),
13463
- avatarOpen ? (0, import_jsx_runtime.jsxs)("div", {
13464
- className: "float",
13465
- role: "menu",
13466
- style: {
13467
- position: "absolute",
13468
- right: 0,
13469
- top: 40,
13470
- width: 240,
13471
- padding: 6,
13472
- zIndex: 50
13473
- },
13474
- children: [
13475
- (0, import_jsx_runtime.jsxs)("div", {
13488
+ children: [(0, import_jsx_runtime.jsx)("div", {
13489
+ className: "eyebrow",
13490
+ children: "Organisation"
13491
+ }), (0, import_jsx_runtime.jsx)("div", {
13476
13492
  style: {
13477
- padding: "8px 10px",
13478
- borderBottom: "1px solid var(--border-hairline)"
13493
+ fontWeight: 700,
13494
+ color: "var(--text-strong)",
13495
+ fontSize: 14,
13496
+ lineHeight: 1.2,
13497
+ whiteSpace: "nowrap"
13479
13498
  },
13480
- children: [
13481
- (0, import_jsx_runtime.jsx)("div", {
13482
- className: "eyebrow",
13483
- children: "Signed in as"
13484
- }),
13485
- (0, import_jsx_runtime.jsx)("div", {
13486
- style: {
13487
- fontSize: 13,
13488
- wordBreak: "break-all"
13489
- },
13490
- "data-anon": "mark",
13491
- children: me.email
13492
- }),
13493
- (0, import_jsx_runtime.jsx)("div", {
13494
- style: {
13495
- fontSize: 12,
13496
- color: "var(--text-muted)",
13497
- marginTop: 2
13498
- },
13499
- children: permissionsPhrase(me.permissions)
13500
- })
13501
- ]
13502
- }),
13503
- avatarMenuFor(me).map((e) => (0, import_jsx_runtime.jsxs)("div", { children: [e.groupLabel ? (0, import_jsx_runtime.jsx)("div", {
13504
- className: "eyebrow nav-group",
13505
- style: { padding: "8px 10px 2px" },
13506
- children: e.groupLabel
13507
- }) : null, (0, import_jsx_runtime.jsx)("button", {
13508
- type: "button",
13509
- className: "nav-item",
13510
- role: "menuitem",
13511
- onClick: () => go(e.path),
13512
- children: e.label
13513
- })] }, e.id)),
13514
- (0, import_jsx_runtime.jsx)("a", {
13515
- className: "nav-item",
13516
- role: "menuitem",
13517
- href: "/portal/sign-out",
13518
- children: "Log out"
13519
- })
13520
- ]
13521
- }) : null
13499
+ "data-anon": "mark",
13500
+ children: accountName
13501
+ })]
13502
+ }) : null,
13503
+ (0, import_jsx_runtime.jsx)("button", {
13504
+ type: "button",
13505
+ className: "icon-btn",
13506
+ "aria-pressed": anon,
13507
+ "aria-label": "Blur names for screen sharing",
13508
+ title: "Blur names for screen sharing",
13509
+ onClick: () => setAnon((a) => !a),
13510
+ children: (0, import_jsx_runtime.jsx)(Icon, { name: anon ? "eye-off" : "eye" })
13511
+ }),
13512
+ (0, import_jsx_runtime.jsx)("button", {
13513
+ type: "button",
13514
+ className: "icon-btn",
13515
+ "aria-pressed": theme === "dark",
13516
+ "aria-label": "Switch light or dark theme",
13517
+ title: "Switch light or dark theme",
13518
+ onClick: toggleTheme,
13519
+ children: (0, import_jsx_runtime.jsx)(Icon, { name: "theme" })
13520
+ }),
13521
+ (0, import_jsx_runtime.jsx)("button", {
13522
+ type: "button",
13523
+ className: "icon-btn avatar",
13524
+ "aria-haspopup": "menu",
13525
+ "aria-expanded": avatarOpen,
13526
+ "aria-label": "Settings and about",
13527
+ "aria-current": personal ? "true" : void 0,
13528
+ onClick: () => setAvatarOpen((o) => !o),
13529
+ children: initials(me.email)
13530
+ }),
13531
+ avatarOpen ? (0, import_jsx_runtime.jsxs)("div", {
13532
+ className: "float",
13533
+ role: "menu",
13534
+ style: {
13535
+ position: "absolute",
13536
+ right: 0,
13537
+ top: 40,
13538
+ width: 240,
13539
+ padding: 6,
13540
+ zIndex: 50
13541
+ },
13542
+ children: [
13543
+ (0, import_jsx_runtime.jsxs)("div", {
13544
+ style: {
13545
+ padding: "8px 10px",
13546
+ borderBottom: "1px solid var(--border-hairline)"
13547
+ },
13548
+ children: [
13549
+ (0, import_jsx_runtime.jsx)("div", {
13550
+ className: "eyebrow",
13551
+ children: "Signed in as"
13552
+ }),
13553
+ (0, import_jsx_runtime.jsx)("div", {
13554
+ style: {
13555
+ fontSize: 13,
13556
+ wordBreak: "break-all"
13557
+ },
13558
+ "data-anon": "mark",
13559
+ children: me.email
13560
+ }),
13561
+ (0, import_jsx_runtime.jsx)("div", {
13562
+ style: {
13563
+ fontSize: 12,
13564
+ color: "var(--text-muted)",
13565
+ marginTop: 2
13566
+ },
13567
+ children: permissionsPhrase(me.permissions)
13568
+ })
13569
+ ]
13570
+ }),
13571
+ avatarMenuFor(me).map((e) => (0, import_jsx_runtime.jsxs)("div", { children: [e.groupLabel ? (0, import_jsx_runtime.jsx)("div", {
13572
+ className: "eyebrow nav-group",
13573
+ style: { padding: "8px 10px 2px" },
13574
+ children: e.groupLabel
13575
+ }) : null, (0, import_jsx_runtime.jsx)("button", {
13576
+ type: "button",
13577
+ className: "nav-item",
13578
+ role: "menuitem",
13579
+ onClick: () => go(e.path),
13580
+ children: e.label
13581
+ })] }, e.id)),
13582
+ (0, import_jsx_runtime.jsx)("a", {
13583
+ className: "nav-item",
13584
+ role: "menuitem",
13585
+ href: "/portal/sign-out",
13586
+ children: "Log out"
13587
+ })
13588
+ ]
13589
+ }) : null
13590
+ ]
13591
+ })
13592
+ ]
13593
+ }),
13594
+ readsRoster && rosterResult?.kind === "ok" && rosterResult.value.unreadable.length ? (0, import_jsx_runtime.jsx)("div", {
13595
+ className: "notice",
13596
+ role: "status",
13597
+ style: { margin: "12px 24px 0" },
13598
+ children: rosterResult.value.unreadable.map((u) => (0, import_jsx_runtime.jsxs)("p", {
13599
+ style: { margin: "0 0 4px" },
13600
+ children: [
13601
+ (0, import_jsx_runtime.jsx)("span", {
13602
+ className: "mono",
13603
+ "data-anon": "mark",
13604
+ children: u.key
13605
+ }),
13606
+ " ",
13607
+ (0, import_jsx_runtime.jsx)("b", {
13608
+ style: { color: "var(--tone-high)" },
13609
+ children: "This company’s framework could not be read."
13610
+ }),
13611
+ " ",
13612
+ "This needs an administrator to look at it."
13522
13613
  ]
13523
- })
13524
- ]
13525
- }), body]
13614
+ }, u.key))
13615
+ }) : null,
13616
+ body
13617
+ ]
13526
13618
  })
13527
13619
  ]
13528
13620
  });
@@ -13776,7 +13868,7 @@ function rolledUp(fam) {
13776
13868
  //#region src/contract/failure.ts
13777
13869
  var STAGE_PHRASE = {
13778
13870
  "matter-frame": "while framing the matter",
13779
- "prelim-variants": "while working out which variants to search",
13871
+ "clearance-variants": "while working out which variants to search",
13780
13872
  "blind-frame": "while framing the matter",
13781
13873
  "common-law": "during the common-law search",
13782
13874
  "common-law-half": "during the common-law search",
@@ -13813,54 +13905,751 @@ function readableFailure(failedStage, reason) {
13813
13905
  raw
13814
13906
  };
13815
13907
  }
13908
+ var offered_territories_default = {
13909
+ _generated: "by scripts/mint-offered-territories.mjs from searchableTerritories() — do not edit; re-mint",
13910
+ regions: [
13911
+ {
13912
+ "code": "EU",
13913
+ "name": "European Union"
13914
+ },
13915
+ {
13916
+ "code": "BX",
13917
+ "name": "Benelux"
13918
+ },
13919
+ {
13920
+ "code": "AP",
13921
+ "name": "African Regional (ARIPO)"
13922
+ }
13923
+ ],
13924
+ countries: [
13925
+ {
13926
+ "code": "AF",
13927
+ "name": "Afghanistan"
13928
+ },
13929
+ {
13930
+ "code": "AL",
13931
+ "name": "Albania"
13932
+ },
13933
+ {
13934
+ "code": "DZ",
13935
+ "name": "Algeria"
13936
+ },
13937
+ {
13938
+ "code": "AD",
13939
+ "name": "Andorra"
13940
+ },
13941
+ {
13942
+ "code": "AO",
13943
+ "name": "Angola"
13944
+ },
13945
+ {
13946
+ "code": "AI",
13947
+ "name": "Anguilla"
13948
+ },
13949
+ {
13950
+ "code": "AG",
13951
+ "name": "Antigua & Barbuda"
13952
+ },
13953
+ {
13954
+ "code": "AR",
13955
+ "name": "Argentina"
13956
+ },
13957
+ {
13958
+ "code": "AM",
13959
+ "name": "Armenia"
13960
+ },
13961
+ {
13962
+ "code": "AW",
13963
+ "name": "Aruba"
13964
+ },
13965
+ {
13966
+ "code": "AU",
13967
+ "name": "Australia"
13968
+ },
13969
+ {
13970
+ "code": "AT",
13971
+ "name": "Austria"
13972
+ },
13973
+ {
13974
+ "code": "AZ",
13975
+ "name": "Azerbaijan"
13976
+ },
13977
+ {
13978
+ "code": "BS",
13979
+ "name": "Bahamas"
13980
+ },
13981
+ {
13982
+ "code": "BH",
13983
+ "name": "Bahrain"
13984
+ },
13985
+ {
13986
+ "code": "BD",
13987
+ "name": "Bangladesh"
13988
+ },
13989
+ {
13990
+ "code": "BB",
13991
+ "name": "Barbados"
13992
+ },
13993
+ {
13994
+ "code": "BY",
13995
+ "name": "Belarus"
13996
+ },
13997
+ {
13998
+ "code": "BE",
13999
+ "name": "Belgium"
14000
+ },
14001
+ {
14002
+ "code": "BZ",
14003
+ "name": "Belize"
14004
+ },
14005
+ {
14006
+ "code": "BM",
14007
+ "name": "Bermuda"
14008
+ },
14009
+ {
14010
+ "code": "BT",
14011
+ "name": "Bhutan"
14012
+ },
14013
+ {
14014
+ "code": "BO",
14015
+ "name": "Bolivia"
14016
+ },
14017
+ {
14018
+ "code": "BA",
14019
+ "name": "Bosnia & Herzegovina"
14020
+ },
14021
+ {
14022
+ "code": "BW",
14023
+ "name": "Botswana"
14024
+ },
14025
+ {
14026
+ "code": "BR",
14027
+ "name": "Brazil"
14028
+ },
14029
+ {
14030
+ "code": "VG",
14031
+ "name": "British Virgin Islands"
14032
+ },
14033
+ {
14034
+ "code": "BN",
14035
+ "name": "Brunei"
14036
+ },
14037
+ {
14038
+ "code": "BG",
14039
+ "name": "Bulgaria"
14040
+ },
14041
+ {
14042
+ "code": "BI",
14043
+ "name": "Burundi"
14044
+ },
14045
+ {
14046
+ "code": "KH",
14047
+ "name": "Cambodia"
14048
+ },
14049
+ {
14050
+ "code": "CA",
14051
+ "name": "Canada"
14052
+ },
14053
+ {
14054
+ "code": "CV",
14055
+ "name": "Cape Verde"
14056
+ },
14057
+ {
14058
+ "code": "BQ",
14059
+ "name": "Caribbean Netherlands"
14060
+ },
14061
+ {
14062
+ "code": "KY",
14063
+ "name": "Cayman Islands"
14064
+ },
14065
+ {
14066
+ "code": "CL",
14067
+ "name": "Chile"
14068
+ },
14069
+ {
14070
+ "code": "CN",
14071
+ "name": "China"
14072
+ },
14073
+ {
14074
+ "code": "CO",
14075
+ "name": "Colombia"
14076
+ },
14077
+ {
14078
+ "code": "CD",
14079
+ "name": "Congo - Kinshasa"
14080
+ },
14081
+ {
14082
+ "code": "CR",
14083
+ "name": "Costa Rica"
14084
+ },
14085
+ {
14086
+ "code": "HR",
14087
+ "name": "Croatia"
14088
+ },
14089
+ {
14090
+ "code": "CU",
14091
+ "name": "Cuba"
14092
+ },
14093
+ {
14094
+ "code": "CW",
14095
+ "name": "Curaçao"
14096
+ },
14097
+ {
14098
+ "code": "CY",
14099
+ "name": "Cyprus"
14100
+ },
14101
+ {
14102
+ "code": "CZ",
14103
+ "name": "Czechia"
14104
+ },
14105
+ {
14106
+ "code": "DK",
14107
+ "name": "Denmark"
14108
+ },
14109
+ {
14110
+ "code": "DM",
14111
+ "name": "Dominica"
14112
+ },
14113
+ {
14114
+ "code": "DO",
14115
+ "name": "Dominican Republic"
14116
+ },
14117
+ {
14118
+ "code": "EC",
14119
+ "name": "Ecuador"
14120
+ },
14121
+ {
14122
+ "code": "EG",
14123
+ "name": "Egypt"
14124
+ },
14125
+ {
14126
+ "code": "SV",
14127
+ "name": "El Salvador"
14128
+ },
14129
+ {
14130
+ "code": "EE",
14131
+ "name": "Estonia"
14132
+ },
14133
+ {
14134
+ "code": "SZ",
14135
+ "name": "Eswatini"
14136
+ },
14137
+ {
14138
+ "code": "ET",
14139
+ "name": "Ethiopia"
14140
+ },
14141
+ {
14142
+ "code": "FJ",
14143
+ "name": "Fiji"
14144
+ },
14145
+ {
14146
+ "code": "FI",
14147
+ "name": "Finland"
14148
+ },
14149
+ {
14150
+ "code": "FR",
14151
+ "name": "France"
14152
+ },
14153
+ {
14154
+ "code": "GM",
14155
+ "name": "Gambia"
14156
+ },
14157
+ {
14158
+ "code": "GE",
14159
+ "name": "Georgia"
14160
+ },
14161
+ {
14162
+ "code": "DE",
14163
+ "name": "Germany"
14164
+ },
14165
+ {
14166
+ "code": "GH",
14167
+ "name": "Ghana"
14168
+ },
14169
+ {
14170
+ "code": "GI",
14171
+ "name": "Gibraltar"
14172
+ },
14173
+ {
14174
+ "code": "GR",
14175
+ "name": "Greece"
14176
+ },
14177
+ {
14178
+ "code": "GD",
14179
+ "name": "Grenada"
14180
+ },
14181
+ {
14182
+ "code": "GT",
14183
+ "name": "Guatemala"
14184
+ },
14185
+ {
14186
+ "code": "GG",
14187
+ "name": "Guernsey"
14188
+ },
14189
+ {
14190
+ "code": "GY",
14191
+ "name": "Guyana"
14192
+ },
14193
+ {
14194
+ "code": "HT",
14195
+ "name": "Haiti"
14196
+ },
14197
+ {
14198
+ "code": "HN",
14199
+ "name": "Honduras"
14200
+ },
14201
+ {
14202
+ "code": "HK",
14203
+ "name": "Hong Kong"
14204
+ },
14205
+ {
14206
+ "code": "HU",
14207
+ "name": "Hungary"
14208
+ },
14209
+ {
14210
+ "code": "IS",
14211
+ "name": "Iceland"
14212
+ },
14213
+ {
14214
+ "code": "IN",
14215
+ "name": "India"
14216
+ },
14217
+ {
14218
+ "code": "ID",
14219
+ "name": "Indonesia"
14220
+ },
14221
+ {
14222
+ "code": "IR",
14223
+ "name": "Iran"
14224
+ },
14225
+ {
14226
+ "code": "IQ",
14227
+ "name": "Iraq"
14228
+ },
14229
+ {
14230
+ "code": "IE",
14231
+ "name": "Ireland"
14232
+ },
14233
+ {
14234
+ "code": "IL",
14235
+ "name": "Israel"
14236
+ },
14237
+ {
14238
+ "code": "IT",
14239
+ "name": "Italy"
14240
+ },
14241
+ {
14242
+ "code": "JM",
14243
+ "name": "Jamaica"
14244
+ },
14245
+ {
14246
+ "code": "JP",
14247
+ "name": "Japan"
14248
+ },
14249
+ {
14250
+ "code": "JE",
14251
+ "name": "Jersey"
14252
+ },
14253
+ {
14254
+ "code": "JO",
14255
+ "name": "Jordan"
14256
+ },
14257
+ {
14258
+ "code": "KZ",
14259
+ "name": "Kazakhstan"
14260
+ },
14261
+ {
14262
+ "code": "KE",
14263
+ "name": "Kenya"
14264
+ },
14265
+ {
14266
+ "code": "KW",
14267
+ "name": "Kuwait"
14268
+ },
14269
+ {
14270
+ "code": "KG",
14271
+ "name": "Kyrgyzstan"
14272
+ },
14273
+ {
14274
+ "code": "LA",
14275
+ "name": "Laos"
14276
+ },
14277
+ {
14278
+ "code": "LV",
14279
+ "name": "Latvia"
14280
+ },
14281
+ {
14282
+ "code": "LB",
14283
+ "name": "Lebanon"
14284
+ },
14285
+ {
14286
+ "code": "LS",
14287
+ "name": "Lesotho"
14288
+ },
14289
+ {
14290
+ "code": "LR",
14291
+ "name": "Liberia"
14292
+ },
14293
+ {
14294
+ "code": "LY",
14295
+ "name": "Libya"
14296
+ },
14297
+ {
14298
+ "code": "LI",
14299
+ "name": "Liechtenstein"
14300
+ },
14301
+ {
14302
+ "code": "LT",
14303
+ "name": "Lithuania"
14304
+ },
14305
+ {
14306
+ "code": "LU",
14307
+ "name": "Luxembourg"
14308
+ },
14309
+ {
14310
+ "code": "MO",
14311
+ "name": "Macau"
14312
+ },
14313
+ {
14314
+ "code": "MG",
14315
+ "name": "Madagascar"
14316
+ },
14317
+ {
14318
+ "code": "MW",
14319
+ "name": "Malawi"
14320
+ },
14321
+ {
14322
+ "code": "MY",
14323
+ "name": "Malaysia"
14324
+ },
14325
+ {
14326
+ "code": "MV",
14327
+ "name": "Maldives"
14328
+ },
14329
+ {
14330
+ "code": "MT",
14331
+ "name": "Malta"
14332
+ },
14333
+ {
14334
+ "code": "MU",
14335
+ "name": "Mauritius"
14336
+ },
14337
+ {
14338
+ "code": "MX",
14339
+ "name": "Mexico"
14340
+ },
14341
+ {
14342
+ "code": "MD",
14343
+ "name": "Moldova"
14344
+ },
14345
+ {
14346
+ "code": "MC",
14347
+ "name": "Monaco"
14348
+ },
14349
+ {
14350
+ "code": "MN",
14351
+ "name": "Mongolia"
14352
+ },
14353
+ {
14354
+ "code": "ME",
14355
+ "name": "Montenegro"
14356
+ },
14357
+ {
14358
+ "code": "MS",
14359
+ "name": "Montserrat"
14360
+ },
14361
+ {
14362
+ "code": "MA",
14363
+ "name": "Morocco"
14364
+ },
14365
+ {
14366
+ "code": "MZ",
14367
+ "name": "Mozambique"
14368
+ },
14369
+ {
14370
+ "code": "MM",
14371
+ "name": "Myanmar (Burma)"
14372
+ },
14373
+ {
14374
+ "code": "NA",
14375
+ "name": "Namibia"
14376
+ },
14377
+ {
14378
+ "code": "NP",
14379
+ "name": "Nepal"
14380
+ },
14381
+ {
14382
+ "code": "NL",
14383
+ "name": "Netherlands"
14384
+ },
14385
+ {
14386
+ "code": "NZ",
14387
+ "name": "New Zealand"
14388
+ },
14389
+ {
14390
+ "code": "NI",
14391
+ "name": "Nicaragua"
14392
+ },
14393
+ {
14394
+ "code": "NG",
14395
+ "name": "Nigeria"
14396
+ },
14397
+ {
14398
+ "code": "MK",
14399
+ "name": "North Macedonia"
14400
+ },
14401
+ {
14402
+ "code": "NO",
14403
+ "name": "Norway"
14404
+ },
14405
+ {
14406
+ "code": "OM",
14407
+ "name": "Oman"
14408
+ },
14409
+ {
14410
+ "code": "PK",
14411
+ "name": "Pakistan"
14412
+ },
14413
+ {
14414
+ "code": "PA",
14415
+ "name": "Panama"
14416
+ },
14417
+ {
14418
+ "code": "PG",
14419
+ "name": "Papua New Guinea"
14420
+ },
14421
+ {
14422
+ "code": "PY",
14423
+ "name": "Paraguay"
14424
+ },
14425
+ {
14426
+ "code": "PE",
14427
+ "name": "Peru"
14428
+ },
14429
+ {
14430
+ "code": "PH",
14431
+ "name": "Philippines"
14432
+ },
14433
+ {
14434
+ "code": "PL",
14435
+ "name": "Poland"
14436
+ },
14437
+ {
14438
+ "code": "PT",
14439
+ "name": "Portugal"
14440
+ },
14441
+ {
14442
+ "code": "QA",
14443
+ "name": "Qatar"
14444
+ },
14445
+ {
14446
+ "code": "RO",
14447
+ "name": "Romania"
14448
+ },
14449
+ {
14450
+ "code": "RU",
14451
+ "name": "Russia"
14452
+ },
14453
+ {
14454
+ "code": "RW",
14455
+ "name": "Rwanda"
14456
+ },
14457
+ {
14458
+ "code": "WS",
14459
+ "name": "Samoa"
14460
+ },
14461
+ {
14462
+ "code": "ST",
14463
+ "name": "São Tomé & Príncipe"
14464
+ },
14465
+ {
14466
+ "code": "SA",
14467
+ "name": "Saudi Arabia"
14468
+ },
14469
+ {
14470
+ "code": "RS",
14471
+ "name": "Serbia"
14472
+ },
14473
+ {
14474
+ "code": "SC",
14475
+ "name": "Seychelles"
14476
+ },
14477
+ {
14478
+ "code": "SL",
14479
+ "name": "Sierra Leone"
14480
+ },
14481
+ {
14482
+ "code": "SG",
14483
+ "name": "Singapore"
14484
+ },
14485
+ {
14486
+ "code": "SX",
14487
+ "name": "Sint Maarten"
14488
+ },
14489
+ {
14490
+ "code": "SK",
14491
+ "name": "Slovakia"
14492
+ },
14493
+ {
14494
+ "code": "SI",
14495
+ "name": "Slovenia"
14496
+ },
14497
+ {
14498
+ "code": "SB",
14499
+ "name": "Solomon Islands"
14500
+ },
14501
+ {
14502
+ "code": "ZA",
14503
+ "name": "South Africa"
14504
+ },
14505
+ {
14506
+ "code": "KR",
14507
+ "name": "South Korea"
14508
+ },
14509
+ {
14510
+ "code": "ES",
14511
+ "name": "Spain"
14512
+ },
14513
+ {
14514
+ "code": "LK",
14515
+ "name": "Sri Lanka"
14516
+ },
14517
+ {
14518
+ "code": "KN",
14519
+ "name": "St. Kitts & Nevis"
14520
+ },
14521
+ {
14522
+ "code": "LC",
14523
+ "name": "St. Lucia"
14524
+ },
14525
+ {
14526
+ "code": "VC",
14527
+ "name": "St. Vincent & Grenadines"
14528
+ },
14529
+ {
14530
+ "code": "SD",
14531
+ "name": "Sudan"
14532
+ },
14533
+ {
14534
+ "code": "SR",
14535
+ "name": "Suriname"
14536
+ },
14537
+ {
14538
+ "code": "SE",
14539
+ "name": "Sweden"
14540
+ },
14541
+ {
14542
+ "code": "CH",
14543
+ "name": "Switzerland"
14544
+ },
14545
+ {
14546
+ "code": "SY",
14547
+ "name": "Syria"
14548
+ },
14549
+ {
14550
+ "code": "TW",
14551
+ "name": "Taiwan"
14552
+ },
14553
+ {
14554
+ "code": "TJ",
14555
+ "name": "Tajikistan"
14556
+ },
14557
+ {
14558
+ "code": "TZ",
14559
+ "name": "Tanzania"
14560
+ },
14561
+ {
14562
+ "code": "TH",
14563
+ "name": "Thailand"
14564
+ },
14565
+ {
14566
+ "code": "TO",
14567
+ "name": "Tonga"
14568
+ },
14569
+ {
14570
+ "code": "TT",
14571
+ "name": "Trinidad & Tobago"
14572
+ },
14573
+ {
14574
+ "code": "TN",
14575
+ "name": "Tunisia"
14576
+ },
14577
+ {
14578
+ "code": "TR",
14579
+ "name": "Turkey"
14580
+ },
14581
+ {
14582
+ "code": "TM",
14583
+ "name": "Turkmenistan"
14584
+ },
14585
+ {
14586
+ "code": "TC",
14587
+ "name": "Turks & Caicos Islands"
14588
+ },
14589
+ {
14590
+ "code": "UG",
14591
+ "name": "Uganda"
14592
+ },
14593
+ {
14594
+ "code": "UA",
14595
+ "name": "Ukraine"
14596
+ },
14597
+ {
14598
+ "code": "AE",
14599
+ "name": "United Arab Emirates"
14600
+ },
14601
+ {
14602
+ "code": "GB",
14603
+ "name": "United Kingdom"
14604
+ },
14605
+ {
14606
+ "code": "US",
14607
+ "name": "United States"
14608
+ },
14609
+ {
14610
+ "code": "UY",
14611
+ "name": "Uruguay"
14612
+ },
14613
+ {
14614
+ "code": "UZ",
14615
+ "name": "Uzbekistan"
14616
+ },
14617
+ {
14618
+ "code": "VE",
14619
+ "name": "Venezuela"
14620
+ },
14621
+ {
14622
+ "code": "VN",
14623
+ "name": "Vietnam"
14624
+ },
14625
+ {
14626
+ "code": "YE",
14627
+ "name": "Yemen"
14628
+ },
14629
+ {
14630
+ "code": "ZM",
14631
+ "name": "Zambia"
14632
+ },
14633
+ {
14634
+ "code": "ZW",
14635
+ "name": "Zimbabwe"
14636
+ }
14637
+ ],
14638
+ left_out: {
14639
+ "unnamed": ["OA", "WO"],
14640
+ "untiered": []
14641
+ }
14642
+ };
13816
14643
  //#endregion
13817
14644
  //#region src/contract/composerProduct.ts
13818
14645
  var EMPTY_DRAFT = {
13819
14646
  product: null,
13820
14647
  territories: [],
14648
+ replacesOwnTerritories: false,
13821
14649
  nativeLanguage: false
13822
14650
  };
13823
- var REGIONS = [
13824
- "European Union",
13825
- "Benelux",
13826
- "African Regional (ARIPO)"
13827
- ];
13828
- var COUNTRIES = [
13829
- "United States",
13830
- "United Kingdom",
13831
- "Ireland",
13832
- "France",
13833
- "Germany",
13834
- "Spain",
13835
- "Italy",
13836
- "Netherlands",
13837
- "Switzerland",
13838
- "Austria",
13839
- "Sweden",
13840
- "Norway",
13841
- "Poland",
13842
- "Bulgaria",
13843
- "Greece",
13844
- "Turkey",
13845
- "Canada",
13846
- "Mexico",
13847
- "Brazil",
13848
- "Argentina",
13849
- "China",
13850
- "Hong Kong",
13851
- "Taiwan",
13852
- "Macau",
13853
- "Japan",
13854
- "South Korea",
13855
- "Singapore",
13856
- "India",
13857
- "Thailand",
13858
- "Australia",
13859
- "New Zealand",
13860
- "United Arab Emirates",
13861
- "Saudi Arabia",
13862
- "South Africa"
13863
- ];
14651
+ var REGIONS = offered_territories_default.regions.map((t) => t.name);
14652
+ var COUNTRIES = offered_territories_default.countries.map((t) => t.name);
13864
14653
  var ALIASES$1 = {
13865
14654
  "European Union": ["eu", "europe"],
13866
14655
  "United States": [
@@ -13880,45 +14669,7 @@ function tierOf(name) {
13880
14669
  if (COUNTRIES.includes(name)) return "country";
13881
14670
  return null;
13882
14671
  }
13883
- var TERRITORY_CODES = Object.freeze({
13884
- "European Union": "EU",
13885
- "Benelux": "BX",
13886
- "African Regional (ARIPO)": "AP",
13887
- "United States": "US",
13888
- "United Kingdom": "GB",
13889
- "Ireland": "IE",
13890
- "France": "FR",
13891
- "Germany": "DE",
13892
- "Spain": "ES",
13893
- "Italy": "IT",
13894
- "Netherlands": "NL",
13895
- "Switzerland": "CH",
13896
- "Austria": "AT",
13897
- "Sweden": "SE",
13898
- "Norway": "NO",
13899
- "Poland": "PL",
13900
- "Bulgaria": "BG",
13901
- "Greece": "GR",
13902
- "Turkey": "TR",
13903
- "Canada": "CA",
13904
- "Mexico": "MX",
13905
- "Brazil": "BR",
13906
- "Argentina": "AR",
13907
- "China": "CN",
13908
- "Hong Kong": "HK",
13909
- "Taiwan": "TW",
13910
- "Macau": "MO",
13911
- "Japan": "JP",
13912
- "South Korea": "KR",
13913
- "Singapore": "SG",
13914
- "India": "IN",
13915
- "Thailand": "TH",
13916
- "Australia": "AU",
13917
- "New Zealand": "NZ",
13918
- "United Arab Emirates": "AE",
13919
- "Saudi Arabia": "SA",
13920
- "South Africa": "ZA"
13921
- });
14672
+ var TERRITORY_CODES = Object.freeze(Object.fromEntries([...offered_territories_default.regions, ...offered_territories_default.countries].map((t) => [t.name, t.code])));
13922
14673
  var territoryCode = (name) => TERRITORY_CODES[name] ?? name;
13923
14674
  var WITH_ARTICLE = new Set([
13924
14675
  "European Union",
@@ -13939,10 +14690,13 @@ function offerableFor(product) {
13939
14690
  }
13940
14691
  function reachesTerritory(name, covered) {
13941
14692
  if (!Array.isArray(covered)) return true;
13942
- return covered.includes(name);
14693
+ const key = territoryKeyOf(name);
14694
+ return covered.some((c) => territoryKeyOf(c) === key);
13943
14695
  }
13944
- function vocabularyFor(product, covered) {
13945
- return offerableFor(product).filter((n) => reachesTerritory(n, covered));
14696
+ var worldwideLine = (registerLabel) => registerLabel ? `Worldwide, searched on ${registerLabel}` : "Worldwide";
14697
+ function territoryKeyOf(value) {
14698
+ const v = String(value ?? "").trim();
14699
+ return TERRITORY_CODES[v] ?? TERRITORY_CODES[ALL_TERRITORIES$1.find((t) => t.toLowerCase() === v.toLowerCase()) ?? ""] ?? canonicalJurisdictionCode(v);
13946
14700
  }
13947
14701
  function territoryMatches(query, chosen, product, limit = 8, _covered) {
13948
14702
  return matchTerritoriesIn(offerableFor(product), query, chosen, limit);
@@ -13959,8 +14713,9 @@ function matchTerritoriesIn(vocabulary, query, chosen, limit = 8) {
13959
14713
  };
13960
14714
  return vocabulary.filter((n) => !taken.has(n.toLowerCase()) && hit(n)).slice(0, limit);
13961
14715
  }
13962
- function addTerritory(d, name, product, _covered) {
14716
+ function addTerritory(d, name, product, covered) {
13963
14717
  if (!offerableFor(product).includes(name)) return d;
14718
+ if (!reachesTerritory(name, covered)) return d;
13964
14719
  if (d.territories.includes(name)) return d;
13965
14720
  if (product?.geography === "exactly one country") return {
13966
14721
  ...d,
@@ -13977,14 +14732,35 @@ function removeTerritory(d, name) {
13977
14732
  territories: d.territories.filter((t) => t !== name)
13978
14733
  };
13979
14734
  }
13980
- function geographyFor(d) {
13981
- return d.territories.length ? {
14735
+ function notAvailableLine(names, registerLabel) {
14736
+ const named = names.join(", ");
14737
+ const who = typeof registerLabel === "string" && registerLabel.trim() ? registerLabel.trim() : null;
14738
+ return `${named ? `${named} \u00b7 ` : ""}not available${who ? ` with register ${who}` : ""}`;
14739
+ }
14740
+ function takeOverOwnTerritories(d, own, without) {
14741
+ return {
14742
+ ...d,
14743
+ territories: own.filter((t) => t !== without),
14744
+ replacesOwnTerritories: true
14745
+ };
14746
+ }
14747
+ function geographyFor(d, product = null, resolved = []) {
14748
+ if (product?.geography === "worldwide, and nothing else") return {
14749
+ mode: "worldwide",
14750
+ territories: []
14751
+ };
14752
+ if (d.territories.length) return {
13982
14753
  mode: "named",
13983
14754
  territories: [...d.territories]
13984
- } : {
14755
+ };
14756
+ if (d.replacesOwnTerritories) return {
13985
14757
  mode: "worldwide",
13986
14758
  territories: []
13987
14759
  };
14760
+ return {
14761
+ mode: "account-default",
14762
+ territories: [...resolved]
14763
+ };
13988
14764
  }
13989
14765
  function nativeLanguageControl(product) {
13990
14766
  if (product?.nativeLanguage === "offered") return "toggle";
@@ -14003,18 +14779,10 @@ function chooseProduct(d, product) {
14003
14779
  return {
14004
14780
  product: product?.key ?? null,
14005
14781
  territories,
14782
+ replacesOwnTerritories: d.replacesOwnTerritories,
14006
14783
  nativeLanguage: nativeLanguageControl(product) === "toggle" ? d.nativeLanguage : false
14007
14784
  };
14008
14785
  }
14009
- function geographyNote(product) {
14010
- if (!product) return null;
14011
- switch (product.geography) {
14012
- case "worldwide, and nothing else": return "Worldwide. This search is not narrowed — that is what it is. To search particular places, pick a different search above.";
14013
- case "exactly one country": return "One country. Regions are not offered here: the case-law and opposition reading is per-country practice, and there is no such thing as one region’s precedent.";
14014
- case "a region, or two or more countries": return "A region, or two or more countries. One country on its own is a Full country search — pick that one instead.";
14015
- default: return "Worldwide, or any set of territories you name.";
14016
- }
14017
- }
14018
14786
  function recommendSearch(products, names, territories) {
14019
14787
  if (territories.length === 0 && names <= 1) return null;
14020
14788
  const live = products.filter((p) => p.available);
@@ -14485,6 +15253,7 @@ function draftFromSaved(recipe, products) {
14485
15253
  return chooseProduct({
14486
15254
  product: base,
14487
15255
  territories: Array.isArray(scope["jurisdictions"]) ? scope["jurisdictions"].filter((j) => typeof j === "string") : [],
15256
+ replacesOwnTerritories: false,
14488
15257
  nativeLanguage: recipe["nativeLanguage"] === true
14489
15258
  }, product);
14490
15259
  }
@@ -15373,7 +16142,43 @@ function pageWindow(rows, page, size) {
15373
16142
  total: rows.length
15374
16143
  };
15375
16144
  }
15376
- function clearancesColumns(mode) {
16145
+ function clearancesColumns(mode, width = { wide: false }) {
16146
+ if (width.wide) {
16147
+ const wide = [{
16148
+ key: "twisty",
16149
+ share: 4
16150
+ }];
16151
+ if (mode.pick) wide.push({
16152
+ key: "pick",
16153
+ share: 3
16154
+ });
16155
+ wide.push({
16156
+ key: "name",
16157
+ share: 0
16158
+ });
16159
+ if (mode.owner) wide.push({
16160
+ key: "company",
16161
+ share: 11
16162
+ });
16163
+ wide.push({
16164
+ key: "status",
16165
+ share: 16
16166
+ }, {
16167
+ key: "risk",
16168
+ share: 12
16169
+ }, {
16170
+ key: "updated",
16171
+ share: 10
16172
+ }, {
16173
+ key: "actions",
16174
+ share: 25
16175
+ });
16176
+ const left = 100 - wide.reduce((n, c) => n + c.share, 0);
16177
+ return wide.map((c) => c.key === "name" ? {
16178
+ key: "name",
16179
+ share: left
16180
+ } : c);
16181
+ }
15377
16182
  const cols = [{
15378
16183
  key: "twisty",
15379
16184
  share: 4
@@ -15392,16 +16197,16 @@ function clearancesColumns(mode) {
15392
16197
  });
15393
16198
  cols.push({
15394
16199
  key: "status",
15395
- share: mode.owner ? 16 : 19
16200
+ share: mode.owner ? 14 : 16
15396
16201
  }, {
15397
16202
  key: "risk",
15398
16203
  share: mode.owner ? 14 : 15
15399
16204
  }, {
15400
16205
  key: "updated",
15401
- share: 12
16206
+ share: 14
15402
16207
  }, {
15403
16208
  key: "actions",
15404
- share: mode.pick ? 25 : 22
16209
+ share: mode.pick ? 21 : 20
15405
16210
  });
15406
16211
  const rest = 100 - cols.reduce((n, c) => n + c.share, 0);
15407
16212
  return cols.map((c) => c.key === "name" ? {
@@ -15485,11 +16290,11 @@ function RiskDot({ tone, label }) {
15485
16290
  children: "—"
15486
16291
  });
15487
16292
  return (0, import_jsx_runtime.jsxs)("span", {
16293
+ className: "risk-dot",
15488
16294
  style: {
15489
16295
  display: "inline-flex",
15490
16296
  alignItems: "center",
15491
- gap: 8,
15492
- whiteSpace: "nowrap"
16297
+ gap: 8
15493
16298
  },
15494
16299
  children: [(0, import_jsx_runtime.jsx)("span", {
15495
16300
  className: "dot",
@@ -15510,7 +16315,7 @@ function resumeWording(iso) {
15510
16315
  });
15511
16316
  return t.toDateString() === new Date().toDateString() ? `at ${time}` : `${t.toLocaleDateString([], { weekday: "long" })} at ${time}`;
15512
16317
  }
15513
- function StatusCell({ state, step, stepN, stepTotal, reason, failedStage, pausedKind = null, resetsAt = null, stopRequestedAt = null, detailed = false, count = null }) {
16318
+ function StatusCell({ state, step, reason, failedStage, pausedKind = null, resetsAt = null, stopRequestedAt = null, detailed = false, count = null }) {
15514
16319
  if (stopRequestedAt && state !== "delivered" && state !== "failed" && state !== "cancelled") return (0, import_jsx_runtime.jsxs)("span", { children: [(0, import_jsx_runtime.jsxs)("span", {
15515
16320
  className: "status",
15516
16321
  children: [(0, import_jsx_runtime.jsx)("span", {
@@ -15577,7 +16382,7 @@ function StatusCell({ state, step, stepN, stepTotal, reason, failedStage, paused
15577
16382
  ] });
15578
16383
  }
15579
16384
  const label = state === "queued" ? "Queued" : state === "paused" ? "Paused" : "Running";
15580
- const detail = state === "paused" ? pausedKind === "recovering" ? "Held after a problem — retrying on its own" : pausedKind === "operator" ? "Paused by a system restart — resumes on its own" : resetsAt ? `Paused by a provider limit — resumes ${resumeWording(resetsAt)}` : "Paused by a provider limit — resumes on its own" : step ? stepN != null && stepTotal != null ? `${step} · ${stepN} of ${stepTotal}` : step : null;
16385
+ const detail = state === "paused" ? pausedKind === "recovering" ? "Held after a problem — retrying on its own" : pausedKind === "operator" ? "Paused by a system restart — resumes on its own" : resetsAt ? `Paused by a provider limit — resumes ${resumeWording(resetsAt)}` : "Paused by a provider limit — resumes on its own" : step;
15581
16386
  return (0, import_jsx_runtime.jsxs)("span", { children: [(0, import_jsx_runtime.jsxs)("span", {
15582
16387
  className: "status",
15583
16388
  children: [(0, import_jsx_runtime.jsx)("span", { className: `dot ${state}` }), count ? (0, import_jsx_runtime.jsxs)("span", { children: [
@@ -15593,6 +16398,89 @@ function StatusCell({ state, step, stepN, stepTotal, reason, failedStage, paused
15593
16398
  children: detail
15594
16399
  }) : null] });
15595
16400
  }
16401
+ //#endregion
16402
+ //#region src/components/PinnedScrollbar.tsx
16403
+ function PinnedScrollbar({ target }) {
16404
+ const track = (0, import_react.useRef)(null);
16405
+ const [g, setG] = (0, import_react.useState)({
16406
+ scrolls: false,
16407
+ thumb: 0,
16408
+ left: 0
16409
+ });
16410
+ const drag = (0, import_react.useRef)(null);
16411
+ (0, import_react.useEffect)(() => {
16412
+ const el = target.current;
16413
+ if (!el) return;
16414
+ const measure = () => {
16415
+ const scrolls = /auto|scroll/.test(getComputedStyle(el).overflowX) && el.scrollWidth > el.clientWidth + 1;
16416
+ const ratio = el.clientWidth / Math.max(1, el.scrollWidth);
16417
+ const room = Math.max(1, el.scrollWidth - el.clientWidth);
16418
+ setG({
16419
+ scrolls,
16420
+ thumb: ratio * 100,
16421
+ left: el.scrollLeft / room * (100 - ratio * 100)
16422
+ });
16423
+ el.classList.toggle("has-pinned-bar", scrolls);
16424
+ };
16425
+ const ro = new ResizeObserver(measure);
16426
+ ro.observe(el);
16427
+ if (el.firstElementChild) ro.observe(el.firstElementChild);
16428
+ measure();
16429
+ el.addEventListener("scroll", measure, { passive: true });
16430
+ return () => {
16431
+ ro.disconnect();
16432
+ el.removeEventListener("scroll", measure);
16433
+ el.classList.remove("has-pinned-bar");
16434
+ };
16435
+ }, [target]);
16436
+ if (!g.scrolls) return null;
16437
+ const scale = () => {
16438
+ const el = target.current, t = track.current;
16439
+ return el && t ? el.scrollWidth / Math.max(1, t.clientWidth) : 0;
16440
+ };
16441
+ const onThumbDown = (e) => {
16442
+ const el = target.current;
16443
+ if (!el) return;
16444
+ e.stopPropagation();
16445
+ e.currentTarget.setPointerCapture(e.pointerId);
16446
+ drag.current = {
16447
+ x: e.clientX,
16448
+ scroll: el.scrollLeft
16449
+ };
16450
+ };
16451
+ const onThumbMove = (e) => {
16452
+ const el = target.current, d = drag.current;
16453
+ if (el && d) el.scrollLeft = d.scroll + (e.clientX - d.x) * scale();
16454
+ };
16455
+ const onThumbUp = () => {
16456
+ drag.current = null;
16457
+ };
16458
+ const onTrackDown = (e) => {
16459
+ const el = target.current, t = track.current;
16460
+ if (!el || !t) return;
16461
+ el.scrollLeft = (e.clientX - t.getBoundingClientRect().left) * scale() - el.clientWidth / 2;
16462
+ };
16463
+ return (0, import_jsx_runtime.jsx)("div", {
16464
+ className: "pinned-bar",
16465
+ "aria-hidden": "true",
16466
+ children: (0, import_jsx_runtime.jsx)("div", {
16467
+ ref: track,
16468
+ className: "pinned-track",
16469
+ onPointerDown: onTrackDown,
16470
+ children: (0, import_jsx_runtime.jsx)("div", {
16471
+ className: "pinned-thumb",
16472
+ style: {
16473
+ width: `${g.thumb}%`,
16474
+ left: `${g.left}%`
16475
+ },
16476
+ onPointerDown: onThumbDown,
16477
+ onPointerMove: onThumbMove,
16478
+ onPointerUp: onThumbUp,
16479
+ onPointerCancel: onThumbUp
16480
+ })
16481
+ })
16482
+ });
16483
+ }
15596
16484
  function searchesLeft(usage) {
15597
16485
  if (!usage || !usage.capped || usage.dailyRuns == null) return null;
15598
16486
  return Math.max(0, usage.dailyRuns - usage.today);
@@ -15602,7 +16490,7 @@ function allowanceLine(usage, brand) {
15602
16490
  if (left == null) return null;
15603
16491
  if (left > 5) return null;
15604
16492
  const who = operatorName(brand);
15605
- if (left === 0) return `You have used all ${usage?.dailyRuns ?? 0} of this account's searches for today. The allowance resets at midnight UTC — or ask your ${who} contact to run this one for you.`;
16493
+ if (left === 0) return `You have used all ${usage?.dailyRuns ?? 0} of this account's searches for today. The allowance resets at midnight UTC — or ask ${who} to run this one for you.`;
15606
16494
  return `${left} search${left === 1 ? "" : "es"} left today. The allowance resets at midnight UTC, or ask ${who} to run one for you.`;
15607
16495
  }
15608
16496
  //#endregion
@@ -15643,11 +16531,12 @@ function issuedOn(run) {
15643
16531
  day: "2-digit"
15644
16532
  }).format(t);
15645
16533
  }
15646
- function reportPhrase(mark, date, kind = "clearance") {
16534
+ function reportPhrase(mark, date, kind = "clearance", finding = null) {
15647
16535
  const name = String(mark ?? "").trim() || "this mark";
15648
16536
  const noun = kind === "knockout-batch" ? "knockout search" : "clearance";
15649
16537
  const when = readableDate(date);
15650
- return when ? `the ${name} ${noun} from ${when}` : `the ${name} ${noun}`;
16538
+ const report = when ? `the ${name} ${noun} from ${when}` : `the ${name} ${noun}`;
16539
+ return finding === null ? report : `finding ${finding} of ${report}`;
15651
16540
  }
15652
16541
  function askAiPrompt(mark, date, kind = "clearance") {
15653
16542
  return `Brief me on ${reportPhrase(mark, date, kind)}.`;
@@ -15671,12 +16560,30 @@ var ASK_AI_QUESTIONS = [
15671
16560
  }
15672
16561
  ];
15673
16562
  function askAiQuestion(index, run) {
15674
- return (ASK_AI_QUESTIONS[index] ?? ASK_AI_QUESTIONS[0]).compose(reportPhrase(run.markName, run.date, run.kind));
16563
+ return (ASK_AI_QUESTIONS[index] ?? ASK_AI_QUESTIONS[0]).compose(reportPhrase(run.markName, run.date, run.kind, run.finding ?? null));
16564
+ }
16565
+ function findingAsked(asked, kind, pickedMark) {
16566
+ if (!asked) return null;
16567
+ if (kind !== "knockout-batch") return {
16568
+ ordinal: asked.ordinal,
16569
+ markName: null,
16570
+ nonce: asked.nonce
16571
+ };
16572
+ return pickedMark ? {
16573
+ ordinal: asked.ordinal,
16574
+ markName: pickedMark,
16575
+ nonce: asked.nonce
16576
+ } : {
16577
+ ordinal: null,
16578
+ markName: null,
16579
+ nonce: asked.nonce
16580
+ };
15675
16581
  }
15676
16582
  function askAiHeading(run) {
15677
16583
  const text = (s) => String(s ?? "").trim() || null;
15678
16584
  return {
15679
16585
  mark: text(run.markName),
16586
+ finding: run.finding ?? null,
15680
16587
  product: text(run.productName),
15681
16588
  searched: text(run.date)
15682
16589
  };
@@ -15740,18 +16647,38 @@ function askAiOffer(run, access) {
15740
16647
  }
15741
16648
  //#endregion
15742
16649
  //#region src/components/AskAi.tsx
15743
- function AskAi({ runId, markSlug = null, markName, date, kind, productName, access, go, quiet = false, openOnArrival = false }) {
16650
+ function AskAi({ runId, markSlug = null, markName, date, kind, productName, access, go, quiet = false, openOnArrival = false, fromFinding = null, hideButton = false, onClose }) {
15744
16651
  const [open, setOpen] = (0, import_react.useState)(openOnArrival);
16652
+ const [about, setAbout] = (0, import_react.useState)(null);
15745
16653
  const [askAnyway, setAskAnyway] = (0, import_react.useState)(false);
15746
16654
  const [picked, setPicked] = (0, import_react.useState)(0);
15747
16655
  const box = (0, import_react.useRef)(null);
15748
16656
  const rows = (0, import_react.useRef)([]);
16657
+ const asked = about?.markName ?? markName;
15749
16658
  const run = {
16659
+ markName: asked,
16660
+ date,
16661
+ kind,
16662
+ finding: about?.ordinal ?? null
16663
+ };
16664
+ const offer = askAiOffer({
15750
16665
  markName,
15751
16666
  date,
15752
16667
  kind
15753
- };
15754
- const offer = askAiOffer(run, access);
16668
+ }, access);
16669
+ (0, import_react.useEffect)(() => {
16670
+ if (!fromFinding) return;
16671
+ if (open && about?.ordinal === fromFinding.ordinal && about?.markName === fromFinding.markName) {
16672
+ setOpen(false);
16673
+ return;
16674
+ }
16675
+ setAbout({
16676
+ ordinal: fromFinding.ordinal,
16677
+ markName: fromFinding.markName
16678
+ });
16679
+ setPicked(0);
16680
+ setOpen(true);
16681
+ }, [fromFinding]);
15755
16682
  (0, import_react.useEffect)(() => {
15756
16683
  if (!open) return;
15757
16684
  function onDown(e) {
@@ -15767,12 +16694,16 @@ function AskAi({ runId, markSlug = null, markName, date, kind, productName, acce
15767
16694
  document.removeEventListener("keydown", onKey);
15768
16695
  };
15769
16696
  }, [open]);
16697
+ (0, import_react.useEffect)(() => {
16698
+ if (!open && hideButton) onClose?.();
16699
+ }, [open]);
15770
16700
  if (!offer.drawn) return null;
15771
16701
  const asking = offer.connected || askAnyway;
15772
16702
  const heading = askAiHeading({
15773
- markName,
16703
+ markName: asked,
15774
16704
  productName,
15775
- date
16705
+ date,
16706
+ finding: about?.ordinal ?? null
15776
16707
  });
15777
16708
  const ask = () => {
15778
16709
  setOpen(false);
@@ -15800,6 +16731,7 @@ function AskAi({ runId, markSlug = null, markName, date, kind, productName, acce
15800
16731
  "data-anon": "mark",
15801
16732
  children: heading.mark
15802
16733
  }, "mark") : null,
16734
+ heading.finding !== null ? (0, import_jsx_runtime.jsxs)("span", { children: ["finding ", heading.finding] }, "finding") : null,
15803
16735
  heading.product ? (0, import_jsx_runtime.jsx)("span", { children: heading.product }, "product") : null,
15804
16736
  heading.searched ? (0, import_jsx_runtime.jsxs)("span", {
15805
16737
  className: "ask-ai-when",
@@ -15814,12 +16746,15 @@ function AskAi({ runId, markSlug = null, markName, date, kind, productName, acce
15814
16746
  className: "ask-ai",
15815
16747
  "data-ask-ai": asking ? "ask" : "connect",
15816
16748
  children: [
15817
- (0, import_jsx_runtime.jsxs)("button", {
16749
+ hideButton ? null : (0, import_jsx_runtime.jsxs)("button", {
15818
16750
  type: "button",
15819
16751
  className: quiet ? "btn-ghost ask-ai-btn is-quiet" : "btn-ghost ask-ai-btn",
15820
16752
  "aria-haspopup": "dialog",
15821
16753
  "aria-expanded": open,
15822
- onClick: () => setOpen((v) => !v),
16754
+ onClick: () => {
16755
+ setAbout(null);
16756
+ setOpen((v) => !v);
16757
+ },
15823
16758
  children: [(0, import_jsx_runtime.jsx)(Icon, {
15824
16759
  name: "sparkles",
15825
16760
  size: 14
@@ -15958,6 +16893,18 @@ function writeGroupPref(on) {
15958
16893
  } catch {}
15959
16894
  }
15960
16895
  function Clearances({ ctx }) {
16896
+ const [tableWidth, setTableWidth] = (0, import_react.useState)(0);
16897
+ const widthWatch = (0, import_react.useRef)(null);
16898
+ const namesWrapEl = (0, import_react.useRef)(null);
16899
+ const namesWrap = (0, import_react.useCallback)((el) => {
16900
+ namesWrapEl.current = el;
16901
+ widthWatch.current?.disconnect();
16902
+ widthWatch.current = null;
16903
+ if (!el) return;
16904
+ widthWatch.current = new ResizeObserver(() => setTableWidth(el.clientWidth));
16905
+ widthWatch.current.observe(el);
16906
+ setTableWidth(el.clientWidth);
16907
+ }, []);
15961
16908
  const [filter, setFilter] = (0, import_react.useState)("all");
15962
16909
  const [sort, setSort] = (0, import_react.useState)({
15963
16910
  key: "date",
@@ -15986,6 +16933,7 @@ function Clearances({ ctx }) {
15986
16933
  const families = famResult?.kind === "ok" ? famResult.value : NO_FAMILIES;
15987
16934
  const { result: aiResult } = useLoad(() => api.mcpAccess(), []);
15988
16935
  const aiAccess = aiResult?.kind === "ok" ? aiResult.value : null;
16936
+ const [askFor, setAskFor] = (0, import_react.useState)(null);
15989
16937
  const [picked, setPicked] = (0, import_react.useState)(new Set());
15990
16938
  const canGroup = canManage(ctx.me) && seesAll;
15991
16939
  const [showRetired, setShowRetired] = (0, import_react.useState)(false);
@@ -16132,7 +17080,7 @@ function Clearances({ ctx }) {
16132
17080
  else next.add(id);
16133
17081
  return next;
16134
17082
  });
16135
- const askAi = (_name, read) => (0, import_jsx_runtime.jsx)(AskAi, {
17083
+ const askAi = (_name, read) => askFor !== read.runId ? null : (0, import_jsx_runtime.jsx)(AskAi, {
16136
17084
  runId: read.runId,
16137
17085
  markName: read.markName,
16138
17086
  date: read.date,
@@ -16140,7 +17088,18 @@ function Clearances({ ctx }) {
16140
17088
  productName: runProductLabel(read.productName, read.marks.length),
16141
17089
  access: aiAccess,
16142
17090
  go: ctx.go,
16143
- quiet: true
17091
+ quiet: true,
17092
+ hideButton: true,
17093
+ openOnArrival: true,
17094
+ onClose: () => setAskFor(null)
17095
+ });
17096
+ const askMenu = (read) => ({
17097
+ show: askAiOffer({
17098
+ markName: read.markName,
17099
+ date: read.date,
17100
+ kind: read.kind
17101
+ }, aiAccess).drawn,
17102
+ open: () => setAskFor(read.runId)
16144
17103
  });
16145
17104
  const sortBtn = (key, label) => (0, import_jsx_runtime.jsxs)("button", {
16146
17105
  type: "button",
@@ -16323,13 +17282,14 @@ function Clearances({ ctx }) {
16323
17282
  }) : null,
16324
17283
  (0, import_jsx_runtime.jsx)("div", {
16325
17284
  className: "table-wrap names-wrap",
17285
+ ref: namesWrap,
16326
17286
  children: (0, import_jsx_runtime.jsxs)("table", {
16327
17287
  className: "data fixed",
16328
17288
  children: [
16329
17289
  (0, import_jsx_runtime.jsx)("colgroup", { children: clearancesColumns({
16330
17290
  pick: canGroup,
16331
17291
  owner: showOwnerColumn
16332
- }).map((c) => (0, import_jsx_runtime.jsx)("col", { style: { width: `${c.share}%` } }, c.key)) }),
17292
+ }, { wide: tableWidth >= 960 }).map((c) => (0, import_jsx_runtime.jsx)("col", { style: { width: `${c.share}%` } }, c.key)) }),
16333
17293
  (0, import_jsx_runtime.jsx)("thead", { children: (0, import_jsx_runtime.jsxs)("tr", { children: [
16334
17294
  (0, import_jsx_runtime.jsx)("th", {}),
16335
17295
  canGroup ? (0, import_jsx_runtime.jsx)("th", { "aria-label": "Select for grouping" }) : null,
@@ -16376,7 +17336,8 @@ function Clearances({ ctx }) {
16376
17336
  onUngroup: canGroup ? ungroupFamily : void 0,
16377
17337
  onRetire: canGroup ? retireMark : void 0,
16378
17338
  onRetireRun: canGroup ? retireRun : void 0,
16379
- askAi
17339
+ askAi,
17340
+ askMenu
16380
17341
  }) : (0, import_jsx_runtime.jsx)(MarkRow, {
16381
17342
  mark: r,
16382
17343
  open: open.has(r.id),
@@ -16389,12 +17350,14 @@ function Clearances({ ctx }) {
16389
17350
  onPick: () => pick(r.id),
16390
17351
  onRetire: canGroup ? retireMark : void 0,
16391
17352
  onRetireRun: canGroup ? retireRun : void 0,
16392
- askAi
17353
+ askAi,
17354
+ askMenu
16393
17355
  })] }, r.id);
16394
17356
  })] })
16395
17357
  ]
16396
17358
  })
16397
17359
  }),
17360
+ (0, import_jsx_runtime.jsx)(PinnedScrollbar, { target: namesWrapEl }),
16398
17361
  !rows.length ? (0, import_jsx_runtime.jsx)("div", {
16399
17362
  className: "empty",
16400
17363
  children: "No names match this view."
@@ -16614,34 +17577,37 @@ function MenuItem({ onSelect, title, children }) {
16614
17577
  });
16615
17578
  }
16616
17579
  function RowActions({ open, ask, menu }) {
16617
- return (0, import_jsx_runtime.jsxs)("div", {
16618
- className: "row-actions",
16619
- children: [
16620
- (0, import_jsx_runtime.jsx)("span", {
16621
- className: "row-actions-open",
16622
- children: open ? (0, import_jsx_runtime.jsx)("button", {
16623
- type: "button",
16624
- className: "row-open",
16625
- onClick: (e) => {
16626
- e.stopPropagation();
16627
- open.go();
16628
- },
16629
- children: open.label
16630
- }) : null
16631
- }),
16632
- (0, import_jsx_runtime.jsx)("span", {
16633
- className: "row-actions-ask",
16634
- onClick: (e) => e.stopPropagation(),
16635
- children: ask
16636
- }),
16637
- (0, import_jsx_runtime.jsx)("span", {
16638
- className: "row-actions-more",
16639
- children: menu
16640
- })
16641
- ]
17580
+ return (0, import_jsx_runtime.jsx)("div", {
17581
+ className: "row-actions-box",
17582
+ children: (0, import_jsx_runtime.jsxs)("div", {
17583
+ className: "row-actions",
17584
+ children: [
17585
+ (0, import_jsx_runtime.jsx)("span", {
17586
+ className: "row-actions-open",
17587
+ children: open ? (0, import_jsx_runtime.jsx)("button", {
17588
+ type: "button",
17589
+ className: "row-open",
17590
+ onClick: (e) => {
17591
+ e.stopPropagation();
17592
+ open.go();
17593
+ },
17594
+ children: open.label
17595
+ }) : null
17596
+ }),
17597
+ (0, import_jsx_runtime.jsx)("span", {
17598
+ className: "row-actions-ask",
17599
+ onClick: (e) => e.stopPropagation(),
17600
+ children: ask
17601
+ }),
17602
+ (0, import_jsx_runtime.jsx)("span", {
17603
+ className: "row-actions-more",
17604
+ children: menu
17605
+ })
17606
+ ]
17607
+ })
16642
17608
  });
16643
17609
  }
16644
- function FamilyRows({ family, isOpen, onToggle, go, picking, showOwner = false, ownerLabel = "", isPicked, onPick, onUngroup, onRetire, onRetireRun, askAi }) {
17610
+ function FamilyRows({ family, isOpen, onToggle, go, picking, showOwner = false, ownerLabel = "", isPicked, onPick, onUngroup, onRetire, onRetireRun, askAi, askMenu }) {
16645
17611
  const open = isOpen(family.id);
16646
17612
  const busy = groupStatus(family);
16647
17613
  return (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsxs)("tr", {
@@ -16681,15 +17647,10 @@ function FamilyRows({ family, isOpen, onToggle, go, picking, showOwner = false,
16681
17647
  }) : null,
16682
17648
  (0, import_jsx_runtime.jsx)("td", { children: busy ? (0, import_jsx_runtime.jsxs)("span", {
16683
17649
  className: "status",
16684
- children: [(0, import_jsx_runtime.jsx)("span", { className: `dot ${busy.state}` }), (0, import_jsx_runtime.jsx)("span", {
16685
- className: "status-count",
16686
- children: busy.text
16687
- })]
17650
+ children: [(0, import_jsx_runtime.jsx)("span", { className: `dot ${busy.state}` }), (0, import_jsx_runtime.jsx)("span", { children: busy.text.replace(/^(\d+) /, "$1\xA0") })]
16688
17651
  }) : (0, import_jsx_runtime.jsx)(StatusCell, {
16689
17652
  state: family.state,
16690
17653
  step: null,
16691
- stepN: null,
16692
- stepTotal: null,
16693
17654
  reason: null,
16694
17655
  failedStage: null
16695
17656
  }) }),
@@ -16737,10 +17698,11 @@ function FamilyRows({ family, isOpen, onToggle, go, picking, showOwner = false,
16737
17698
  onPick: () => onPick(m.id),
16738
17699
  onRetire,
16739
17700
  onRetireRun,
16740
- askAi
17701
+ askAi,
17702
+ askMenu
16741
17703
  }, m.id)) : null] });
16742
17704
  }
16743
- function MarkRow({ mark, open, onToggle, go, indent = false, picking = false, showOwner = false, ownerLabel = "", picked = false, onPick, onRetire, onRetireRun, askAi }) {
17705
+ function MarkRow({ mark, open, onToggle, go, indent = false, picking = false, showOwner = false, ownerLabel = "", picked = false, onPick, onRetire, onRetireRun, askAi, askMenu }) {
16744
17706
  const run = mark.current;
16745
17707
  const threaded = mark.reads.length > 1;
16746
17708
  const report = shownReport(mark);
@@ -16798,8 +17760,6 @@ function MarkRow({ mark, open, onToggle, go, indent = false, picking = false, sh
16798
17760
  (0, import_jsx_runtime.jsx)("td", { children: (0, import_jsx_runtime.jsx)(StatusCell, {
16799
17761
  state: run.state,
16800
17762
  step: run.step,
16801
- stepN: run.stepN,
16802
- stepTotal: run.stepTotal,
16803
17763
  reason: run.reason,
16804
17764
  failedStage: run.failedStage,
16805
17765
  pausedKind: run.pausedKind,
@@ -16843,13 +17803,16 @@ function MarkRow({ mark, open, onToggle, go, indent = false, picking = false, sh
16843
17803
  go: openReport
16844
17804
  } : null,
16845
17805
  ask: actions.askAbout ? askAi(mark.name, actions.askAbout) : null,
16846
- menu: onRetire ? (0, import_jsx_runtime.jsx)(RowMenu$1, {
17806
+ menu: onRetire || actions.askAbout && askMenu(actions.askAbout).show ? (0, import_jsx_runtime.jsxs)(RowMenu$1, {
16847
17807
  label: `More actions for ${mark.name}`,
16848
- children: (0, import_jsx_runtime.jsx)(MenuItem, {
17808
+ children: [onRetire ? (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: (0, import_jsx_runtime.jsx)(MenuItem, {
16849
17809
  title: threaded ? `Retire all ${mark.reads.length} searches of ${mark.name} — the whole name comes off this list for everyone; the reports and their links stay, and "Show retired" brings it back. To retire ONE search, open the row and use that search's menu.` : `Retire ${mark.name} — it comes off this list for everyone; the reports and their links stay, and "Show retired" brings it back`,
16850
17810
  onSelect: () => onRetire(mark),
16851
17811
  children: threaded ? `Retire all ${mark.reads.length}` : "Retire"
16852
- })
17812
+ }) }) : null, actions.askAbout && askMenu(actions.askAbout).show ? (0, import_jsx_runtime.jsx)(MenuItem, {
17813
+ onSelect: () => askMenu(actions.askAbout).open(),
17814
+ children: "Ask AI"
17815
+ }) : null]
16853
17816
  }) : null
16854
17817
  })
16855
17818
  })
@@ -16936,8 +17899,6 @@ function ReadRow({ read, go, picking, indent, showOwner = false, latest = false,
16936
17899
  (0, import_jsx_runtime.jsx)("td", { children: (0, import_jsx_runtime.jsx)(StatusCell, {
16937
17900
  state: read.state,
16938
17901
  step: read.step,
16939
- stepN: read.stepN,
16940
- stepTotal: read.stepTotal,
16941
17902
  reason: read.reason,
16942
17903
  failedStage: read.failedStage,
16943
17904
  stopRequestedAt: read.stopRequestedAt,
@@ -17220,6 +18181,38 @@ function readCommandFailure(data, sameSource) {
17220
18181
  message: typeof m.message === "string" ? m.message : "it did not say why"
17221
18182
  };
17222
18183
  }
18184
+ function readAskAi(data, sameSource) {
18185
+ if (!sameSource) return null;
18186
+ if (typeof data !== "object" || data === null) return null;
18187
+ const m = data;
18188
+ if (m.source !== "cordillera-report" || m.type !== "askAi") return null;
18189
+ const whole = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0 ? v : null;
18190
+ return {
18191
+ ordinal: whole(m.ordinal),
18192
+ markIndex: whole(m.markIndex)
18193
+ };
18194
+ }
18195
+ function readFrameSections(data, sameSource) {
18196
+ if (!sameSource) return null;
18197
+ if (typeof data !== "object" || data === null) return null;
18198
+ const msg = data;
18199
+ if (msg.source !== "cordillera-report" || msg.type !== "sections") return null;
18200
+ if (!Array.isArray(msg.sections)) return null;
18201
+ const out = [];
18202
+ for (const raw of msg.sections) {
18203
+ if (typeof raw !== "object" || raw === null) continue;
18204
+ const { id, label } = raw;
18205
+ if (typeof id !== "string" || typeof label !== "string") continue;
18206
+ const trimmed = label.trim().slice(0, 40);
18207
+ if (!id.trim() || !trimmed) continue;
18208
+ out.push({
18209
+ id,
18210
+ label: trimmed
18211
+ });
18212
+ if (out.length === 12) break;
18213
+ }
18214
+ return out;
18215
+ }
17223
18216
  function frameCommand(command, value) {
17224
18217
  return {
17225
18218
  source: FRAME_TAG,
@@ -17235,6 +18228,8 @@ function useReportFrame() {
17235
18228
  const [height, setHeight] = (0, import_react.useState)(FIRST_PAINT);
17236
18229
  const [failed, setFailed] = (0, import_react.useState)(null);
17237
18230
  const [controls, setControls] = (0, import_react.useState)(null);
18231
+ const [sections, setSections] = (0, import_react.useState)(null);
18232
+ const [askedFrom, setAskedFrom] = (0, import_react.useState)(null);
17238
18233
  (0, import_react.useEffect)(() => {
17239
18234
  function onMessage(e) {
17240
18235
  const frame = ref.current;
@@ -17249,6 +18244,11 @@ function useReportFrame() {
17249
18244
  setControls(has);
17250
18245
  return;
17251
18246
  }
18247
+ const secs = readFrameSections(e.data, mine);
18248
+ if (secs !== null) {
18249
+ setSections(secs);
18250
+ return;
18251
+ }
17252
18252
  const jump = readFrameScroll(e.data, mine);
17253
18253
  if (jump !== null) {
17254
18254
  if (frame) {
@@ -17267,6 +18267,14 @@ function useReportFrame() {
17267
18267
  setFailed(`That did not work — the report could not ${bad.command}. (${bad.message})`);
17268
18268
  return;
17269
18269
  }
18270
+ const asked = readAskAi(e.data, mine);
18271
+ if (asked) {
18272
+ setAskedFrom((prev) => ({
18273
+ ...asked,
18274
+ nonce: (prev?.nonce ?? 0) + 1
18275
+ }));
18276
+ return;
18277
+ }
17270
18278
  }
17271
18279
  window.addEventListener("message", onMessage);
17272
18280
  return () => window.removeEventListener("message", onMessage);
@@ -17280,6 +18288,8 @@ function useReportFrame() {
17280
18288
  }, []),
17281
18289
  failed,
17282
18290
  controls,
18291
+ sections,
18292
+ askedFrom,
17283
18293
  clearFailed: () => setFailed(null)
17284
18294
  };
17285
18295
  }
@@ -17436,6 +18446,10 @@ function Result({ ctx, runId, markSlug }) {
17436
18446
  const run = (0, import_react.useMemo)(() => runs.find((r) => r.runId === runId) ?? null, [runs, runId]);
17437
18447
  const reads = (0, import_react.useMemo)(() => run ? readsFor(runs, run) : [], [runs, run]);
17438
18448
  const frame = useReportFrame();
18449
+ const [atSection, setAtSection] = (0, import_react.useState)(null);
18450
+ (0, import_react.useEffect)(() => {
18451
+ setAtSection(null);
18452
+ }, [runId, markSlug]);
17439
18453
  const grouped = run !== null && showsAssessment(run, markSlug);
17440
18454
  const { result: summaryResult } = useLoad(() => grouped ? api.runSummary(runId) : Promise.resolve({ kind: "notFound" }), [runId, grouped]);
17441
18455
  const assessment = summaryResult?.kind === "ok" ? summaryResult.value : [];
@@ -17494,9 +18508,9 @@ function Result({ ctx, runId, markSlug }) {
17494
18508
  })] })
17495
18509
  ]
17496
18510
  }),
17497
- (0, import_jsx_runtime.jsx)("div", {
18511
+ (0, import_jsx_runtime.jsxs)("div", {
17498
18512
  className: "report-head",
17499
- children: (0, import_jsx_runtime.jsxs)("div", {
18513
+ children: [(0, import_jsx_runtime.jsxs)("div", {
17500
18514
  style: {
17501
18515
  display: "flex",
17502
18516
  alignItems: "center",
@@ -17555,7 +18569,8 @@ function Result({ ctx, runId, markSlug }) {
17555
18569
  productName: product,
17556
18570
  access,
17557
18571
  go: ctx.go,
17558
- openOnArrival: askOnArrival
18572
+ openOnArrival: askOnArrival,
18573
+ fromFinding: findingAsked(frame.askedFrom, run.kind, pickedMark)
17559
18574
  }),
17560
18575
  doc ? (0, import_jsx_runtime.jsx)(ExportMenu, {
17561
18576
  send: frame.send,
@@ -17563,46 +18578,74 @@ function Result({ ctx, runId, markSlug }) {
17563
18578
  offered: frame.controls ?? []
17564
18579
  }) : null
17565
18580
  ]
17566
- })
17567
- }),
17568
- hasThread(reads) ? (0, import_jsx_runtime.jsxs)("div", {
17569
- style: {
17570
- display: "flex",
17571
- gap: 8,
17572
- flexWrap: "wrap",
17573
- margin: "18px 0 4px"
17574
- },
17575
- children: [(0, import_jsx_runtime.jsx)("span", {
17576
- className: "eyebrow",
17577
- style: { alignSelf: "center" },
17578
- children: "Reads"
17579
- }), reads.map((r) => {
17580
- const active = r.runId === run.runId;
17581
- return (0, import_jsx_runtime.jsxs)("button", {
17582
- type: "button",
17583
- className: "pill",
17584
- "aria-current": active ? "true" : void 0,
17585
- onClick: () => ctx.go(resultPath(r.runId)),
17586
- style: {
17587
- cursor: "pointer",
17588
- display: "inline-flex",
17589
- alignItems: "center",
17590
- gap: 7,
17591
- background: active ? "var(--accent-wash)" : "var(--surface-sunken)",
17592
- borderColor: active ? "var(--accent)" : "var(--border-hairline)",
17593
- color: active ? "var(--text-accent)" : "var(--text-muted)"
17594
- },
17595
- children: [r.tone ? (0, import_jsx_runtime.jsx)("span", {
17596
- className: "dot",
18581
+ }), hasThread(reads) || (frame.sections?.length ?? 0) > 1 ? (0, import_jsx_runtime.jsxs)("div", {
18582
+ className: "report-nav",
18583
+ children: [
18584
+ hasThread(reads) ? (0, import_jsx_runtime.jsxs)("div", {
17597
18585
  style: {
17598
- background: `var(--tone-${r.tone})`,
17599
- width: 7,
17600
- height: 7
17601
- }
17602
- }) : null, readLabel(r)]
17603
- }, r.runId);
17604
- })]
17605
- }) : null,
18586
+ display: "flex",
18587
+ gap: 8,
18588
+ flexWrap: "wrap",
18589
+ alignItems: "center"
18590
+ },
18591
+ children: [(0, import_jsx_runtime.jsx)("span", {
18592
+ className: "eyebrow",
18593
+ style: { alignSelf: "center" },
18594
+ children: "Reads"
18595
+ }), reads.map((r) => {
18596
+ const active = r.runId === run.runId;
18597
+ return (0, import_jsx_runtime.jsxs)("button", {
18598
+ type: "button",
18599
+ className: "pill",
18600
+ "aria-current": active ? "true" : void 0,
18601
+ onClick: () => ctx.go(resultPath(r.runId)),
18602
+ style: {
18603
+ cursor: "pointer",
18604
+ display: "inline-flex",
18605
+ alignItems: "center",
18606
+ gap: 7,
18607
+ background: active ? "var(--accent-wash)" : "var(--surface-sunken)",
18608
+ borderColor: active ? "var(--accent)" : "var(--border-hairline)",
18609
+ color: active ? "var(--text-accent)" : "var(--text-muted)"
18610
+ },
18611
+ children: [r.tone ? (0, import_jsx_runtime.jsx)("span", {
18612
+ className: "dot",
18613
+ style: {
18614
+ background: `var(--tone-${r.tone})`,
18615
+ width: 7,
18616
+ height: 7
18617
+ }
18618
+ }) : null, readLabel(r)]
18619
+ }, r.runId);
18620
+ })]
18621
+ }) : null,
18622
+ hasThread(reads) && (frame.sections?.length ?? 0) > 1 ? (0, import_jsx_runtime.jsx)("span", {
18623
+ className: "report-nav-sep",
18624
+ "aria-hidden": "true"
18625
+ }) : null,
18626
+ (frame.sections?.length ?? 0) > 1 ? (0, import_jsx_runtime.jsx)("nav", {
18627
+ className: "report-sections",
18628
+ "aria-label": "Sections of this report",
18629
+ children: (frame.sections ?? []).map((sec, i) => {
18630
+ const now = atSection === null ? i === 0 : atSection === sec.id;
18631
+ return (0, import_jsx_runtime.jsxs)("button", {
18632
+ type: "button",
18633
+ className: "report-section",
18634
+ "aria-current": now ? "true" : void 0,
18635
+ onClick: () => {
18636
+ setAtSection(sec.id);
18637
+ frame.send("section", sec.id);
18638
+ },
18639
+ children: [(0, import_jsx_runtime.jsx)("span", {
18640
+ className: "report-section-dot",
18641
+ "aria-hidden": "true"
18642
+ }), sec.label]
18643
+ }, sec.id);
18644
+ })
18645
+ }) : null
18646
+ ]
18647
+ }) : null]
18648
+ }),
17606
18649
  frame.failed ? (0, import_jsx_runtime.jsxs)("div", {
17607
18650
  className: "notice",
17608
18651
  style: { borderLeftColor: "var(--tone-high)" },
@@ -17764,26 +18807,68 @@ function Missing({ go, reason }) {
17764
18807
  }
17765
18808
  //#endregion
17766
18809
  //#region src/contract/engineState.ts
18810
+ var SETUP_COMMAND = "`npx clearotron install`";
18811
+ var listed = (xs, and = "and") => xs.length <= 1 ? xs[0] ?? "" : `${xs.slice(0, -1).join(", ")} ${and} ${xs[xs.length - 1]}`;
18812
+ var PAID_BY = {
18813
+ subscription: "subscription",
18814
+ "api-key": "an API key",
18815
+ cloud: "a cloud account"
18816
+ };
18817
+ var paidBy = (mode) => mode !== null && Object.hasOwn(PAID_BY, mode) ? PAID_BY[mode] : mode ?? "a way of paying";
18818
+ var COUNT = [
18819
+ "no",
18820
+ "one",
18821
+ "two",
18822
+ "three",
18823
+ "four"
18824
+ ];
18825
+ var NAMES_CLOUDS = new Set([
18826
+ "switch-beside-mode",
18827
+ "two-clouds",
18828
+ "no-cloud"
18829
+ ]);
18830
+ function billingRefusalSentence(r) {
18831
+ const setting = r.setting || "the billing setting";
18832
+ const generic = `Searches will be refused over how this machine is set to pay. Check ${setting} and the settings beside it.`;
18833
+ if (NAMES_CLOUDS.has(r.kind) && r.clouds.length === 0) return generic;
18834
+ const paid = r.defaulted ? `${paidBy(r.mode)}, the default while ${setting} is not set` : `set to ${paidBy(r.mode)}`;
18835
+ switch (r.kind) {
18836
+ case "switch-beside-mode": {
18837
+ const one = r.clouds.length === 1;
18838
+ const names = listed(r.clouds.map((c) => c.name));
18839
+ const switches = listed(r.clouds.map((c) => c.setting));
18840
+ const keep = r.mode === "api-key" ? "to pay with the API key" : "to pay by subscription";
18841
+ return `Searches will be refused: payment is ${r.defaulted ? "by " : ""}${paid}, but the ${names} ${one ? "switch" : "switches"} (${switches}) ${one ? "is" : "are"} also on. ` + (one ? `Turn ${switches} off ${keep}, or set ${setting} to cloud to pay through ${names}.` : `Turn them off ${keep}, or set ${setting} to cloud and leave one on.`);
18842
+ }
18843
+ case "two-clouds": return `Searches will be refused: payment is set to a cloud account, but ${COUNT[r.clouds.length] ?? r.clouds.length} clouds are switched on, ${listed(r.clouds.map((c) => `${c.name} (${c.setting})`))}. Turn off all but the one you pay through.`;
18844
+ case "no-cloud": return `Searches will be refused: payment is set to a cloud account, but no cloud is chosen. Turn on your cloud's switch (${listed(r.clouds.map((c) => `${c.setting} for ${c.name}`), "or")}) with the settings that cloud needs` + (r.gateway ? `, set ${r.gateway} for a gateway,` : ",") + ` or set ${setting} to subscription.`;
18845
+ case "not-a-mode": return `Searches will be refused: ${setting} is set to a word Clearotron does not know. Set it to ${listed(r.modes, "or")}.`;
18846
+ case "cloud-on-codex": return `Searches will be refused: payment is set to a cloud account, which pays only for Claude, and this machine runs the Codex engine. Set ${setting} to ${listed(r.modes, "or")}` + (r.engineSetting && r.engineChoice ? `, or set ${r.engineSetting} to ${r.engineChoice} to pay for Claude through your cloud.` : ".");
18847
+ default: return generic;
18848
+ }
18849
+ }
17767
18850
  function engineRowFaults(engine, { programDisputed = false } = {}) {
18851
+ const reason = engine.billing.reason ?? null;
17768
18852
  return [
17769
18853
  ...engine.known ? [] : [`This build does not ship an engine called ${engine.id}.`],
17770
18854
  ...engine.billing.missing.length ? ["Set to bill an API key, and no key is set — a run is refused rather than billed to the subscription."] : [],
17771
- ...engine.binaryPresent ? [] : engine.program && engine.install ? [`The engine program \`${engine.program}\` cannot be found or run on this machine. Install it with \`${engine.install}\`, then restart this service so it looks for the program again.`] : ["The engine program cannot be found or run on this machine."],
17772
- ...programDisputed && engine.binaryPresent ? ["The engine program is on this machine, but the engine could not find it when it last started — so a new search will refuse. Restart the engine service, or install the CLI where the service can see it."] : []
18855
+ ...reason && !engine.billing.missing.length ? [billingRefusalSentence(reason)] : [],
18856
+ ...engine.binaryPresent ? [] : engine.program ? [`The engine program \`${engine.program}\` cannot be found or run on this machine. Run the setup wizard, ${SETUP_COMMAND}: it offers to install the program and proves it with one turn. Then restart Clearotron's services, which look for the program when they start.`] : ["The engine program cannot be found or run on this machine."],
18857
+ ...programDisputed && engine.binaryPresent ? [`The engine program is on this machine, but the engine could not find it when it last started — so a new search will refuse. Restart the engine service so it looks again. If it still cannot find it, set ${engine.programSetting ?? "the engine's program setting"} to the program's full path in the settings file the service reads, then restart it again.`] : []
17773
18858
  ];
17774
18859
  }
17775
18860
  function engineNotice({ programDisputed }) {
17776
18861
  if (programDisputed === true) return {
17777
18862
  state: "disputed",
17778
18863
  headline: "The engine program is on this machine, but the engine could not find it when it last started.",
17779
- before: "So a new search will refuse. Restart the engine service, or install the CLI where the service can see it — installing it again where it already is will not change this.",
18864
+ before: "So a new search will refuse. Restart the engine service so it looks again. If it still cannot find it, set the engine's program setting to the program's full path in the settings file the service reads — installing it again where it already is will not change this.",
17780
18865
  namesSetupCommand: false,
17781
18866
  after: ""
17782
18867
  };
17783
18868
  return {
17784
18869
  state: "absent",
17785
18870
  headline: "No search engine is attached to this install.",
17786
- before: "Everything else works — the example report, its audit trail and the assistant connection are live right now. To start new searches, install a reasoning CLI and sign in, then run the setup wizard again",
18871
+ before: "Everything else works — the example report, its audit trail and the assistant connection are live right now. The setup wizard offers to install a reasoning CLI if this machine has none, and asks how it is paid for. To start new searches, run the setup wizard",
17787
18872
  namesSetupCommand: true,
17788
18873
  after: "Then restart the service: this reading was taken when it started, and it will not notice a new install until it starts again."
17789
18874
  };
@@ -17794,7 +18879,7 @@ function engineRow(engine, { programDisputed = false } = {}) {
17794
18879
  ok: faults.length === 0,
17795
18880
  name: engine.vendor ?? engine.id,
17796
18881
  mono: engine.id,
17797
- state: engine.billing.apiBilled ? "API key" : "Subscription",
18882
+ state: engine.billing.missing.length || engine.billing.reason ? "Refused" : engine.billing.cloudName ?? (engine.billing.apiBilled ? "API key" : "Subscription"),
17798
18883
  faults
17799
18884
  };
17800
18885
  }
@@ -18270,6 +19355,7 @@ function NewClearance({ ctx }) {
18270
19355
  const { result: usageRes } = useLoad(() => api.usage(account), [account]);
18271
19356
  const levels = searches?.kind === "ok" ? searches.value.products : [];
18272
19357
  const registerTerritories = searches?.kind === "ok" ? searches.value.registerTerritories : void 0;
19358
+ const registerLabel = searches?.kind === "ok" ? searches.value.registerLabel : void 0;
18273
19359
  const savedSearches = searches?.kind === "ok" ? searches.value.recipes : [];
18274
19360
  const readCan = searches?.kind === "ok" ? searches.value.read : {
18275
19361
  available: false,
@@ -18362,7 +19448,6 @@ function NewClearance({ ctx }) {
18362
19448
  const activePipeline = activeLevel?.pipeline ?? null;
18363
19449
  const marketplacesApply = activePipeline !== "knockout";
18364
19450
  const whereLevel = pickedByHand || draft.savedSearch || editingSlug ? activeLevel : null;
18365
- const geoNote = geographyNote(whereLevel);
18366
19451
  const nativeControl = nativeLanguageControl(activeLevel);
18367
19452
  const machinery = machineryFor(draft.pick, activeLevel);
18368
19453
  const knockout = (0, import_react.useMemo)(() => levels.filter((l) => l.available && l.maxNames > 1).sort((a, b) => b.maxNames - a.maxNames)[0] ?? null, [levels]);
@@ -18387,10 +19472,11 @@ function NewClearance({ ctx }) {
18387
19472
  setSaveNote(null);
18388
19473
  };
18389
19474
  const setPick = (next) => edit({ pick: next });
18390
- const recommendation = (0, import_react.useMemo)(() => recommendSearch(levels, names.length, draft.pick.territories), [
19475
+ const recommendation = (0, import_react.useMemo)(() => recommendSearch(levels, names.length, draft.pick.territories.length ? draft.pick.territories : own.territories), [
18391
19476
  levels,
18392
19477
  names.length,
18393
- draft.pick.territories
19478
+ draft.pick.territories,
19479
+ own.territories
18394
19480
  ]);
18395
19481
  (0, import_react.useEffect)(() => {
18396
19482
  if (pickedByHand || draft.savedSearch || editingSlug || !recommendation) return;
@@ -18427,7 +19513,7 @@ function NewClearance({ ctx }) {
18427
19513
  deadline: d.deadline
18428
19514
  };
18429
19515
  let after = applyRead(before, read, own.classes, { worldwide });
18430
- const fits = recommendSearch(levels, parseNames(after.names).length, after.draft.territories);
19516
+ const fits = recommendSearch(levels, parseNames(after.names).length, after.draft.territories.length ? after.draft.territories : own.territories);
18431
19517
  if (read.product == null && !pickedByHand && !d.savedSearch && fits) after = {
18432
19518
  ...after,
18433
19519
  draft: chooseProduct(after.draft, fits.product)
@@ -18456,7 +19542,7 @@ function NewClearance({ ctx }) {
18456
19542
  ...draft.savedSearch ? { recipeKey: draft.savedSearch } : draft.pick.product ? { product: draft.pick.product } : {},
18457
19543
  ...draft.project ? { projectKey: draft.project } : {},
18458
19544
  ...draft.pick.territories.length ? { jurisdictions: [...draft.pick.territories] } : {},
18459
- geography: { mode: geographyFor(draft.pick).mode },
19545
+ geography: { mode: geographyFor(draft.pick, activeLevel, own.territories).mode },
18460
19546
  ...marketplacesApply && parseList(draft.platforms).length ? { platforms: parseList(draft.platforms) } : {},
18461
19547
  ...!draft.savedSearch && nativeControl === "toggle" && draft.pick.nativeLanguage ? { nativeLanguage: true } : {},
18462
19548
  ...draft.ref.trim() ? { ref: draft.ref.trim() } : {},
@@ -18767,162 +19853,131 @@ function NewClearance({ ctx }) {
18767
19853
  children: [names.length, " names, one search."]
18768
19854
  }) : null
18769
19855
  ] }),
18770
- (0, import_jsx_runtime.jsxs)("div", { children: [
19856
+ (0, import_jsx_runtime.jsxs)("div", { children: [(0, import_jsx_runtime.jsx)("div", {
19857
+ className: "section-title",
19858
+ children: "Where"
19859
+ }), whereLevel?.geography === "worldwide, and nothing else" ? (0, import_jsx_runtime.jsx)("div", {
19860
+ style: {
19861
+ display: "flex",
19862
+ flexWrap: "wrap",
19863
+ gap: 6,
19864
+ margin: "9px 0 0"
19865
+ },
19866
+ children: (0, import_jsx_runtime.jsx)("span", {
19867
+ className: "chip",
19868
+ children: worldwideLine(registerLabel)
19869
+ })
19870
+ }) : (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
18771
19871
  (0, import_jsx_runtime.jsx)("div", {
18772
- className: "section-title",
18773
- children: "Where"
18774
- }),
18775
- geoNote ? (0, import_jsx_runtime.jsx)("p", {
18776
- className: "section-hint",
18777
- children: geoNote
18778
- }) : null,
18779
- whereLevel?.geography === "worldwide, and nothing else" ? (0, import_jsx_runtime.jsx)("div", {
18780
19872
  style: {
18781
19873
  display: "flex",
18782
19874
  flexWrap: "wrap",
18783
19875
  gap: 6,
18784
- margin: "9px 0 0"
19876
+ margin: "9px 0 12px"
18785
19877
  },
18786
- children: (0, import_jsx_runtime.jsx)("span", {
18787
- className: "chip",
18788
- children: "Worldwide"
18789
- })
18790
- }) : (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
18791
- (0, import_jsx_runtime.jsx)("div", {
19878
+ children: draft.pick.territories.length === 0 ? own.territories.length ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [own.territories.map((t) => (0, import_jsx_runtime.jsxs)("span", {
19879
+ "data-anon": "mark",
19880
+ className: reachesTerritory(t, registerTerritories) ? "chip" : "chip chip-deferred",
19881
+ title: reachesTerritory(t, registerTerritories) ? void 0 : notAvailableLine([t], registerLabel),
19882
+ children: [reachesTerritory(t, registerTerritories) ? t : notAvailableLine([t], registerLabel), (0, import_jsx_runtime.jsx)("button", {
19883
+ type: "button",
19884
+ "aria-label": `Remove ${t}`,
19885
+ className: "chip-x",
19886
+ onClick: () => setPick(takeOverOwnTerritories(draft.pick, own.territories, t)),
19887
+ children: (0, import_jsx_runtime.jsx)(Icon, {
19888
+ name: "x",
19889
+ size: 13
19890
+ })
19891
+ })]
19892
+ }, t)), (0, import_jsx_runtime.jsx)("span", {
18792
19893
  style: {
18793
- display: "flex",
18794
- flexWrap: "wrap",
18795
- gap: 6,
18796
- margin: "9px 0 12px"
19894
+ fontSize: 11,
19895
+ color: "var(--text-faint)",
19896
+ alignSelf: "center"
18797
19897
  },
18798
- children: draft.pick.territories.length === 0 ? own.territories.length ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [own.territories.map((t) => (0, import_jsx_runtime.jsx)("span", {
18799
- className: "chip",
18800
- "data-anon": "mark",
18801
- children: t
18802
- }, t)), (0, import_jsx_runtime.jsx)("span", {
18803
- style: {
18804
- fontSize: 11,
18805
- color: "var(--text-faint)",
18806
- alignSelf: "center"
18807
- },
18808
- children: own.territoriesFrom
18809
- })] }) : (0, import_jsx_runtime.jsx)("span", {
18810
- className: "chip",
18811
- children: "Worldwide"
18812
- }) : draft.pick.territories.map((t) => (0, import_jsx_runtime.jsxs)("span", {
18813
- className: reachesTerritory(t, registerTerritories) ? "chip chip-own" : "chip chip-own chip-deferred",
18814
- title: reachesTerritory(t, registerTerritories) ? void 0 : "The register wired to this deployment does not reach this territory — it is disclosed in the report as deferred coverage rather than searched.",
18815
- children: [
18816
- t,
18817
- reachesTerritory(t, registerTerritories) ? "" : " · register deferred",
18818
- (0, import_jsx_runtime.jsx)("button", {
18819
- type: "button",
18820
- "aria-label": `Remove ${t}`,
18821
- className: "chip-x",
18822
- onClick: () => setPick(removeTerritory(draft.pick, t)),
18823
- children: (0, import_jsx_runtime.jsx)(Icon, {
18824
- name: "x",
18825
- size: 13
18826
- })
18827
- })
18828
- ]
18829
- }, t))
18830
- }),
18831
- (0, import_jsx_runtime.jsx)("div", {
18832
- className: "field-label",
18833
- children: whereLevel?.geography === "exactly one country" ? "Add a country" : "Add a country or region"
18834
- }),
18835
- (0, import_jsx_runtime.jsxs)("div", {
18836
- className: "fld-medium",
18837
- style: { position: "relative" },
18838
- children: [(0, import_jsx_runtime.jsx)("input", {
18839
- value: territoryQuery,
18840
- onChange: (e) => setTerritoryQuery(e.target.value),
18841
- autoComplete: "off",
18842
- "aria-label": "Add a territory",
18843
- className: "ctx-input"
18844
- }), territoryMatches(territoryQuery, draft.pick.territories, whereLevel, 8, registerTerritories).length ? (0, import_jsx_runtime.jsx)("div", {
18845
- className: "typeahead",
18846
- children: territoryMatches(territoryQuery, draft.pick.territories, whereLevel, 8, registerTerritories).map((t) => (0, import_jsx_runtime.jsxs)("button", {
18847
- type: "button",
18848
- onClick: () => {
18849
- setPick(addTerritory(draft.pick, t, whereLevel, registerTerritories));
18850
- setTerritoryQuery("");
18851
- },
18852
- children: [t, reachesTerritory(t, registerTerritories) ? null : (0, import_jsx_runtime.jsx)("span", {
18853
- className: "typeahead-note",
18854
- children: "register deferred"
18855
- })]
18856
- }, t))
18857
- }) : null]
18858
- }),
18859
- Array.isArray(registerTerritories) ? (0, import_jsx_runtime.jsxs)("p", {
18860
- className: "section-hint",
18861
- style: { marginTop: 10 },
18862
- children: [
18863
- "The trademark register wired to this deployment reaches",
18864
- " ",
18865
- vocabularyFor(whereLevel, registerTerritories).length,
18866
- " of the",
18867
- " ",
18868
- offerableFor(whereLevel).length,
18869
- " territories you can name here:",
18870
- " ",
18871
- vocabularyFor(whereLevel, registerTerritories).join(", "),
18872
- ". Anywhere else can still be ordered — it is disclosed in the report as deferred coverage rather than searched at the register."
18873
- ]
18874
- }) : null,
18875
- whereLevel?.geography === "exactly one country" && draft.pick.territories.length === 1 ? (0, import_jsx_runtime.jsxs)("div", {
18876
- className: "callout-accent",
18877
- children: [draft.pick.territories[0], " — naming another country replaces it, because this search reads one at a time."]
18878
- }) : null
18879
- ] })
18880
- ] }),
18881
- (0, import_jsx_runtime.jsxs)("div", { children: [
18882
- (0, import_jsx_runtime.jsx)("div", {
18883
- className: "section-title",
18884
- children: "Goods or services"
18885
- }),
18886
- (0, import_jsx_runtime.jsx)("p", {
18887
- className: "section-hint",
18888
- children: "Optional. Say what the name is for, to focus the search. Without it, the classes below are used."
19898
+ children: own.territoriesFrom
19899
+ })] }) : (0, import_jsx_runtime.jsx)("span", {
19900
+ className: "chip",
19901
+ children: worldwideLine(registerLabel)
19902
+ }) : draft.pick.territories.map((t) => (0, import_jsx_runtime.jsxs)("span", {
19903
+ className: reachesTerritory(t, registerTerritories) ? "chip chip-own" : "chip chip-own chip-deferred",
19904
+ title: reachesTerritory(t, registerTerritories) ? void 0 : notAvailableLine([t], registerLabel),
19905
+ children: [reachesTerritory(t, registerTerritories) ? t : notAvailableLine([t], registerLabel), (0, import_jsx_runtime.jsx)("button", {
19906
+ type: "button",
19907
+ "aria-label": `Remove ${t}`,
19908
+ className: "chip-x",
19909
+ onClick: () => setPick(removeTerritory(draft.pick, t)),
19910
+ children: (0, import_jsx_runtime.jsx)(Icon, {
19911
+ name: "x",
19912
+ size: 13
19913
+ })
19914
+ })]
19915
+ }, t))
18889
19916
  }),
18890
- (0, import_jsx_runtime.jsx)("textarea", {
18891
- value: draft.goods,
18892
- onChange: (e) => edit({ goods: e.target.value }),
18893
- rows: 3,
18894
- "aria-label": "Goods or services",
18895
- placeholder: "Example: energy drinks; dietary supplements",
18896
- className: "ctx-input",
18897
- style: {
18898
- resize: "vertical",
18899
- lineHeight: 1.5
18900
- }
18901
- })
18902
- ] }),
18903
- (0, import_jsx_runtime.jsxs)("div", { children: [
18904
19917
  (0, import_jsx_runtime.jsx)("div", {
18905
- className: "section-title",
18906
- children: "Context (optional)"
19918
+ className: "field-label",
19919
+ children: whereLevel?.geography === "exactly one country" ? "Add a country" : "Add a country or region"
18907
19920
  }),
18908
- (0, import_jsx_runtime.jsx)("textarea", {
18909
- value: draft.instructions,
18910
- onChange: (e) => edit({ instructions: e.target.value }),
18911
- rows: 3,
18912
- "aria-label": "Context (optional)",
18913
- placeholder: "Example: we already own the mark in the US and this is about the EU launch. Our launch page is https://example.com/press/aquaplus-launch, and there is a LinkedIn post announcing it from 3 June.",
18914
- className: "ctx-input",
18915
- style: {
18916
- resize: "vertical",
18917
- lineHeight: 1.5
18918
- }
19921
+ (0, import_jsx_runtime.jsxs)("div", {
19922
+ className: "fld-medium",
19923
+ style: { position: "relative" },
19924
+ children: [(0, import_jsx_runtime.jsx)("input", {
19925
+ value: territoryQuery,
19926
+ onChange: (e) => setTerritoryQuery(e.target.value),
19927
+ autoComplete: "off",
19928
+ "aria-label": "Add a territory",
19929
+ className: "ctx-input"
19930
+ }), territoryMatches(territoryQuery, draft.pick.territories, whereLevel, 8, registerTerritories).length ? (0, import_jsx_runtime.jsx)("div", {
19931
+ className: "typeahead",
19932
+ children: territoryMatches(territoryQuery, draft.pick.territories, whereLevel, 8, registerTerritories).map((t) => (0, import_jsx_runtime.jsxs)("button", {
19933
+ type: "button",
19934
+ disabled: !reachesTerritory(t, registerTerritories),
19935
+ onClick: () => {
19936
+ setPick(addTerritory(draft.pick, t, whereLevel, registerTerritories));
19937
+ setTerritoryQuery("");
19938
+ },
19939
+ children: [t, reachesTerritory(t, registerTerritories) ? null : (0, import_jsx_runtime.jsx)("span", {
19940
+ className: "typeahead-note",
19941
+ children: notAvailableLine([], registerLabel)
19942
+ })]
19943
+ }, t))
19944
+ }) : null]
18919
19945
  }),
18920
- (0, import_jsx_runtime.jsx)("p", {
18921
- className: "section-hint",
18922
- style: { margin: "7px 0 0" },
18923
- children: "A search started by an agent through the connector can reference emails or documents it can already read, so there is nothing to paste in that case."
18924
- })
18925
- ] }),
19946
+ whereLevel?.geography === "exactly one country" && draft.pick.territories.length === 1 ? (0, import_jsx_runtime.jsxs)("div", {
19947
+ className: "callout-accent",
19948
+ children: [draft.pick.territories[0], " — naming another country replaces it, because this search reads one at a time."]
19949
+ }) : null
19950
+ ] })] }),
19951
+ (0, import_jsx_runtime.jsxs)("div", { children: [(0, import_jsx_runtime.jsx)("div", {
19952
+ className: "section-title",
19953
+ children: "Goods or services"
19954
+ }), (0, import_jsx_runtime.jsx)("textarea", {
19955
+ value: draft.goods,
19956
+ onChange: (e) => edit({ goods: e.target.value }),
19957
+ rows: 3,
19958
+ "aria-label": "Goods or services",
19959
+ placeholder: "Example: energy drinks; dietary supplements",
19960
+ className: "ctx-input",
19961
+ style: {
19962
+ resize: "vertical",
19963
+ lineHeight: 1.5
19964
+ }
19965
+ })] }),
19966
+ (0, import_jsx_runtime.jsxs)("div", { children: [(0, import_jsx_runtime.jsx)("div", {
19967
+ className: "section-title",
19968
+ children: "Context (optional)"
19969
+ }), (0, import_jsx_runtime.jsx)("textarea", {
19970
+ value: draft.instructions,
19971
+ onChange: (e) => edit({ instructions: e.target.value }),
19972
+ rows: 3,
19973
+ "aria-label": "Context (optional)",
19974
+ placeholder: "Example: we already own the mark in the US and this is about the EU launch. Our launch page is https://example.com/press/aquaplus-launch, and there is a LinkedIn post announcing it from 3 June.",
19975
+ className: "ctx-input",
19976
+ style: {
19977
+ resize: "vertical",
19978
+ lineHeight: 1.5
19979
+ }
19980
+ })] }),
18926
19981
  (0, import_jsx_runtime.jsxs)("div", {
18927
19982
  className: "ctx-card",
18928
19983
  children: [
@@ -19292,7 +20347,7 @@ function NewClearance({ ctx }) {
19292
20347
  })
19293
20348
  })]
19294
20349
  }),
19295
- !untouched && gaps.length ? (0, import_jsx_runtime.jsxs)("div", {
20350
+ !untouched && gaps.length && !(gaps.length === 1 && gaps[0] === blockedBy) ? (0, import_jsx_runtime.jsxs)("div", {
19296
20351
  className: "notice",
19297
20352
  style: {
19298
20353
  borderColor: "var(--tone-medium)",
@@ -19397,6 +20452,7 @@ function NewClearance({ ctx }) {
19397
20452
  plan ? (0, import_jsx_runtime.jsx)(ReviewDialog, {
19398
20453
  uses: runCount(effort),
19399
20454
  left: searchesLeft(usage),
20455
+ registerLabel,
19400
20456
  plan,
19401
20457
  busy,
19402
20458
  owner: ownerLabel,
@@ -19933,7 +20989,7 @@ function PickRow({ selected, onPick, title, tagline, description, chips, recomme
19933
20989
  }) : null]
19934
20990
  });
19935
20991
  }
19936
- function ReviewDialog({ plan, busy, owner, project, names, goods, nativeOn, onStart, onBack, failure, onReview, uses, left }) {
20992
+ function ReviewDialog({ plan, busy, owner, project, names, goods, nativeOn, onStart, onBack, failure, onReview, uses, left, registerLabel }) {
19937
20993
  (0, import_react.useEffect)(() => {
19938
20994
  const on = (e) => {
19939
20995
  if (e.key === "Escape") onBack();
@@ -20014,17 +21070,11 @@ function ReviewDialog({ plan, busy, owner, project, names, goods, nativeOn, onSt
20014
21070
  ]
20015
21071
  }) : (0, import_jsx_runtime.jsx)(Row$3, {
20016
21072
  label: "Where",
20017
- children: "Worldwide"
21073
+ children: worldwideLine(registerLabel)
20018
21074
  }),
20019
21075
  (0, import_jsx_runtime.jsx)(Row$3, {
20020
21076
  label: "Registers to search",
20021
- children: plan.coverage ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [plan.coverage.reached.length ? joinAnd(plan.coverage.reached) : "None", plan.coverage.missing.length ? (0, import_jsx_runtime.jsxs)(Muted, { children: [
20022
- ". ",
20023
- joinAnd(plan.coverage.missing),
20024
- " ",
20025
- plan.coverage.missing.length === 1 ? "is" : "are",
20026
- " not reached by the register wired here, and will be disclosed in the report as deferred coverage rather than searched."
20027
- ] }) : null] }) : places.length ? joinAnd(places) : "Worldwide"
21077
+ children: plan.coverage ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [plan.coverage.reached.length ? joinAnd(plan.coverage.reached) : "None", plan.coverage.missing.length ? (0, import_jsx_runtime.jsxs)(Muted, { children: [". ", notAvailableLine(plan.coverage.missing, registerLabel)] }) : null] }) : places.length ? joinAnd(places) : worldwideLine(registerLabel)
20028
21078
  }),
20029
21079
  scope && scope.classes.length ? (0, import_jsx_runtime.jsxs)(Row$3, {
20030
21080
  label: "Classes",
@@ -24221,6 +25271,7 @@ function useSourceRepo() {
24221
25271
  return result && isOk(result) && result.value.sourceRepo ? result.value.sourceRepo : null;
24222
25272
  }
24223
25273
  function PeopleAccess({ ctx }) {
25274
+ const peopleWrap = (0, import_react.useRef)(null);
24224
25275
  const { result } = useLoad(() => api.adminAccess(), []);
24225
25276
  const repo = useSourceRepo();
24226
25277
  const seesAll = ctx.me.allAccounts;
@@ -24339,6 +25390,7 @@ function PeopleAccess({ ctx }) {
24339
25390
  }) : null,
24340
25391
  (0, import_jsx_runtime.jsx)("div", {
24341
25392
  className: "table-wrap",
25393
+ ref: peopleWrap,
24342
25394
  children: (0, import_jsx_runtime.jsxs)("table", {
24343
25395
  className: "data",
24344
25396
  children: [(0, import_jsx_runtime.jsx)("thead", { children: (0, import_jsx_runtime.jsxs)("tr", { children: [
@@ -24358,6 +25410,7 @@ function PeopleAccess({ ctx }) {
24358
25410
  }, p.email)) })]
24359
25411
  })
24360
25412
  }),
25413
+ (0, import_jsx_runtime.jsx)(PinnedScrollbar, { target: peopleWrap }),
24361
25414
  (0, import_jsx_runtime.jsx)("dl", {
24362
25415
  className: "perm-key",
24363
25416
  children: PERMISSIONS_KEY.map((k) => (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [(0, import_jsx_runtime.jsx)("dt", { children: k.term }), (0, import_jsx_runtime.jsx)("dd", { children: k.means })] }, k.term))
@@ -25476,7 +26529,7 @@ function About() {
25476
26529
  (0, import_jsx_runtime.jsx)("dt", { children: "Copyright" }),
25477
26530
  (0, import_jsx_runtime.jsx)("dd", { children: info.copyright.replace(/^Copyright\s+/i, "") }),
25478
26531
  (0, import_jsx_runtime.jsx)("dt", { children: "Model access" }),
25479
- (0, import_jsx_runtime.jsx)("dd", { children: "This runs on your own model access — a subscription or your own API key — and the paid registers on your own agreements with those providers. The reasoning stages are a proprietary third-party CLI that you install and license under that vendor’s own terms; this licence grants nothing over any of them." }),
26532
+ (0, import_jsx_runtime.jsx)("dd", { children: "This runs on your own model access — a subscription, an API key, or your own cloud account — and the paid registers on your own agreements with those providers. The reasoning stages are a third-party command-line program, Claude Code (proprietary) or the Codex CLI (Apache-2.0), that you install and license under that vendor’s own terms; this licence grants nothing over any of them." }),
25480
26533
  (0, import_jsx_runtime.jsx)("dt", { children: "Trade marks" }),
25481
26534
  (0, import_jsx_runtime.jsxs)("dd", { children: [
25482
26535
  (0, import_jsx_runtime.jsx)("strong", { children: info.name }),