clearotron 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +28 -0
- package/.nvmrc +1 -1
- package/INSTALL.md +13 -11
- package/README.md +11 -16
- package/THIRD-PARTY-NOTICES.md +1 -1
- package/bin/clearotron.mjs +22 -0
- package/bin/example.mjs +4 -0
- package/bin/onboard.mjs +195 -19
- package/bin/start.mjs +154 -8
- package/build-info.json +2 -2
- package/demo/full-country-search/run/_driver/framework.json +1 -1
- package/demo/global-preliminary-search/run/_driver/framework.json +1 -1
- package/demo/knockout-search/run/_driver/framework.json +1 -1
- package/demo/multi-country-focus-search/run/_driver/framework.json +1 -1
- package/docs/E2E.md +5 -5
- package/docs/PORTAL.md +2 -2
- package/docs/README.md +5 -4
- package/docs/SECURITY.md +17 -0
- package/docs/architecture/04-configuration-reference.md +2 -0
- package/docs/architecture/05-config-governance.md +14 -0
- package/docs/architecture/05-customer-profiles.md +2 -2
- package/docs/configuration.md +4 -3
- package/driver/CHANGELOG.md +56 -0
- package/driver/common-law-receipts.mjs +1 -1
- package/driver/config-staleness.mjs +1 -1
- package/driver/dev-portal.mjs +2 -2
- package/driver/driver.config.mjs +1 -1
- package/driver/engine/cli-version.mjs +103 -0
- package/driver/enqueue-schema.mjs +8 -8
- package/driver/feedback-store.mjs +1 -1
- package/driver/findings-model.mjs +52 -2
- package/driver/flag-snapshot.mjs +20 -0
- package/driver/framework.mjs +1 -1
- package/driver/gateway.mjs +18 -1
- package/driver/package.json +3 -3
- package/driver/party-facts.mjs +2 -2
- package/driver/phase0.mjs +1 -1
- package/driver/pipeline.mjs +5 -5
- package/driver/plain-register.mjs +120 -0
- package/driver/portal-access.mjs +1 -1
- package/driver/portal-config-view.mjs +40 -1
- package/driver/portal-families.mjs +1 -1
- package/driver/portal-report.mjs +1 -1
- package/driver/portal-service.mjs +26 -7
- package/driver/portal-upstream.mjs +2 -2
- package/driver/predelivery-lint.mjs +121 -1
- package/driver/profile-page.html +10 -2
- package/driver/profile-service.mjs +4 -4
- package/driver/profiles/README.md +3 -3
- package/driver/profiles.mjs +144 -12
- package/driver/publish/index.mjs +2 -2
- package/driver/publish/knockout.mjs +7 -1
- package/driver/publish/render-knockout.mjs +453 -118
- package/driver/publish/render.mjs +2 -2
- package/driver/reference-strip-signatures.mjs +20 -0
- package/driver/search-policy.mjs +2 -2
- package/driver/skills/blind-frame/SKILL.md +1 -1
- package/driver/skills/knockout-assess/SKILL.md +84 -0
- package/driver/skills/matter-frame/SKILL.md +6 -6
- package/driver/skills/matter-frame/watchlist-reference.md +2 -2
- package/driver/skills/prelim-common-law/SKILL.md +1 -1
- package/driver/skills/prelim-search/SKILL.md +1 -1
- package/driver/skills/prelim-search/report-prose.md +82 -0
- package/driver/skills/prelim-search/risk-framework-demo.manifest.json +1 -1
- package/driver/skills/prelim-search/risk-framework-triage.manifest.json +1 -1
- package/driver/skills/prelim-search/risk-framework.manifest.json +1 -1
- package/driver/skills/prelim-search/synthesis-rules.md +1 -1
- package/driver/skills/prelim-variants/SKILL.md +3 -3
- package/driver/stages.mjs +4 -4
- package/driver/suite-census.json +134 -38
- package/driver/unit-inventory.mjs +184 -27
- package/driver/verify.mjs +1 -1
- package/driver/whatif-memo-run.mjs +26 -4
- package/driver/whatif-memo.mjs +19 -1
- package/examples/README.md +2 -2
- package/examples/grants.example.json +6 -7
- package/mcp-server/CHANGELOG.md +2 -0
- package/mcp-server/lib/scrub.mjs +1 -1
- package/mcp-server/lib/whatif.mjs +2 -2
- package/mcp-server/package.json +1 -1
- package/mcp-server/packs/ops/EXAMPLES.md +2 -2
- package/mcp-server/server.mjs +1 -1
- package/package.json +28 -10
- package/portal-ui/dist/assets/{index-Ct3iQtZ2.css → index-1ziUJX1E.css} +43 -2
- package/portal-ui/dist/assets/{index-BUGgiYtF.js → index-CEYvXdqH.js} +226 -49
- package/portal-ui/dist/index.html +2 -2
- package/portal-ui/package.json +1 -1
- package/providers/_shared/term-shape.mjs +1 -1
- package/providers/oauth-mcp-bridge/CHANGELOG.md +2 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/providers/uspto-local/src/index-store.js +2 -2
- package/scripts/citation-line-check.mjs +121 -2
- package/scripts/env-classify.mjs +67 -3
- package/scripts/live-surface-check.mjs +38 -1
- package/scripts/nightly-notice.mjs +0 -2
- package/scripts/preinstall-node-check.mjs +24 -0
- package/scripts/strip-tracker-citations.mjs +29 -6
- package/scripts/test-run.mjs +16 -0
- package/shared/anon-overlay.mjs +3 -3
- package/shared/customer-store.mjs +1 -1
- package/shared/invocation.mjs +28 -0
- package/shared/names-in-force.mjs +2 -0
- package/shared/node-floor.mjs +97 -0
- package/shared/staff-domain.mjs +154 -0
- package/shared/store-in-repo.mjs +23 -2
- package/skills/clearotron-ops/SKILL.md +1 -1
- package/driver/recipes/README.md +0 -49
- package/driver/skills/prelim-search/risk-framework-aurora.manifest.json +0 -19
- package/driver/skills/prelim-search/risk-framework-aurora.md +0 -77
- package/driver/skills/prelim-search/risk-framework-zephyr.manifest.json +0 -14
- package/driver/skills/prelim-search/risk-framework-zephyr.md +0 -33
- package/driver/skills/prelim-search/worked-examples-aurora.md +0 -10
- package/driver/skills/prelim-search/worked-examples-zephyr.md +0 -10
- package/scripts/ai-page-render-check.mjs +0 -532
- package/scripts/clearances-render-check.mjs +0 -480
- package/scripts/composer-render-check.mjs +0 -1027
- package/scripts/home-render-check.mjs +0 -526
- package/scripts/portal-lifecycle-check.mjs +0 -639
|
@@ -598,7 +598,7 @@ table.data tr.row:hover td {
|
|
|
598
598
|
/* tracker issue 277 — A SECTION HEADER, not a decorative divider.
|
|
599
599
|
Brand owner is the organising principle of the whole list, and a reader had to work it out: the name
|
|
600
600
|
was set in the smallest, lowest-contrast, most letterspaced type on the page, which reads as a rule
|
|
601
|
-
BETWEEN rows rather than as "everything below this belongs to
|
|
601
|
+
BETWEEN rows rather than as "everything below this belongs to Foxglade Interactive".
|
|
602
602
|
Body-text size, medium weight, full-strength ink, sentence case rather than letterspaced caps — and a
|
|
603
603
|
hairline rule spanning the table beneath it, so containment is visible without reading anything. */
|
|
604
604
|
table.data tr.group-head td {
|
|
@@ -916,11 +916,21 @@ input.filter {
|
|
|
916
916
|
color: var(--text-strong);
|
|
917
917
|
}
|
|
918
918
|
|
|
919
|
+
/* Says what the row of pills below it is a row OF. Sentence case and body-weight rather than the
|
|
920
|
+
uppercase section treatment above: this is a caption belonging to the statement it follows, and
|
|
921
|
+
giving it a heading's weight would make it look like a new section — which is the misreading the
|
|
922
|
+
label exists to end. Sits tight to its pills and away from the statement above. */
|
|
923
|
+
.fw-ladder-label {
|
|
924
|
+
font-size: 12px;
|
|
925
|
+
color: var(--text-muted);
|
|
926
|
+
margin: 14px 0 0;
|
|
927
|
+
}
|
|
928
|
+
|
|
919
929
|
.fw-ladder {
|
|
920
930
|
display: flex;
|
|
921
931
|
flex-wrap: wrap;
|
|
922
932
|
gap: 6px;
|
|
923
|
-
margin:
|
|
933
|
+
margin: 6px 0 4px;
|
|
924
934
|
}
|
|
925
935
|
|
|
926
936
|
.fw-bmh {
|
|
@@ -991,6 +1001,37 @@ input.filter {
|
|
|
991
1001
|
max-width: 420px; /* tracker issue 2086 — the note's width is the note's own, not its call site's */
|
|
992
1002
|
}
|
|
993
1003
|
|
|
1004
|
+
/* The line beside the primary action: what happens next when it is available, and why it is not when
|
|
1005
|
+
it is not. Capped here rather than at the call site for the same reason the note above is — width is
|
|
1006
|
+
a decision this file makes. Narrower than the note because it sits IN the action row, beside a
|
|
1007
|
+
button, rather than replacing it. */
|
|
1008
|
+
.footer-hint {
|
|
1009
|
+
max-width: 260px;
|
|
1010
|
+
font-size: 12px;
|
|
1011
|
+
line-height: 1.4;
|
|
1012
|
+
color: var(--text-muted);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
/* The acknowledgement a save leaves beside the button that was pressed.
|
|
1016
|
+
Quiet on purpose: it is a receipt, not an alert, and it sits in the same row as the primary action
|
|
1017
|
+
without competing with it. No new colour — `--tone-minimal` (the palette's clear-green) and the hairline are what the rest of
|
|
1018
|
+
this file already uses for a settled, good state. */
|
|
1019
|
+
.save-done {
|
|
1020
|
+
display: inline-flex;
|
|
1021
|
+
align-items: center;
|
|
1022
|
+
gap: 7px;
|
|
1023
|
+
font-size: 12.5px;
|
|
1024
|
+
color: var(--text-body);
|
|
1025
|
+
background: var(--surface-sunken);
|
|
1026
|
+
border: 1px solid var(--border-hairline);
|
|
1027
|
+
border-radius: 7px;
|
|
1028
|
+
padding: 7px 11px;
|
|
1029
|
+
}
|
|
1030
|
+
.save-done svg {
|
|
1031
|
+
color: var(--tone-minimal);
|
|
1032
|
+
flex: none;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
994
1035
|
.fw-meta {
|
|
995
1036
|
font-size: 12px;
|
|
996
1037
|
color: var(--text-muted);
|
|
@@ -10415,6 +10415,7 @@ var api = {
|
|
|
10415
10415
|
accountNames: Object.fromEntries(Object.entries(asRecord(b["accountNames"])).filter(([, v]) => typeof v === "string" && v)),
|
|
10416
10416
|
concurrentRuns: asNumber(b["concurrentRuns"]),
|
|
10417
10417
|
engineMode: b["engineMode"] === "demo" ? "demo" : b["engineMode"] === "engine-unproven" ? "engine-unproven" : null,
|
|
10418
|
+
setupRoute: b["setupRoute"] === "packaged" ? "packaged" : b["setupRoute"] === "checkout" ? "checkout" : null,
|
|
10418
10419
|
brand: typeof b["brand"] === "string" ? b["brand"] : "",
|
|
10419
10420
|
stopControl: (() => {
|
|
10420
10421
|
const c = asRecord(asRecord(b["controls"])["stop"]);
|
|
@@ -10765,6 +10766,15 @@ var api = {
|
|
|
10765
10766
|
name,
|
|
10766
10767
|
modifiedAt
|
|
10767
10768
|
} : null;
|
|
10769
|
+
})(),
|
|
10770
|
+
staffRule: (() => {
|
|
10771
|
+
const s = b["staffRule"];
|
|
10772
|
+
const name = asString(s?.["name"]);
|
|
10773
|
+
const where = asString(s?.["where"]);
|
|
10774
|
+
return name && where ? {
|
|
10775
|
+
name,
|
|
10776
|
+
where
|
|
10777
|
+
} : null;
|
|
10768
10778
|
})()
|
|
10769
10779
|
})),
|
|
10770
10780
|
adminObserved: () => call("/portal/admin/observed", (b) => ({
|
|
@@ -11421,7 +11431,8 @@ function AppShell({ render }) {
|
|
|
11421
11431
|
ownerName,
|
|
11422
11432
|
ownerKeys,
|
|
11423
11433
|
go,
|
|
11424
|
-
visit
|
|
11434
|
+
visit,
|
|
11435
|
+
sidebarCollapsed: collapsed
|
|
11425
11436
|
}) : (0, import_jsx_runtime.jsx)("div", {
|
|
11426
11437
|
className: "screen",
|
|
11427
11438
|
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
@@ -14711,6 +14722,15 @@ function nameBudget(product, names) {
|
|
|
14711
14722
|
over: names - product.maxNames
|
|
14712
14723
|
};
|
|
14713
14724
|
}
|
|
14725
|
+
function missingPieces(names, classes, goods) {
|
|
14726
|
+
const out = [];
|
|
14727
|
+
if (!names.length) {
|
|
14728
|
+
out.push("Add the brand name you want cleared, in Names above.");
|
|
14729
|
+
return out;
|
|
14730
|
+
}
|
|
14731
|
+
if (!classes.length && !goods.trim()) out.push("Say what the name is used for — pick classes, or describe the goods and services. Either one is enough.");
|
|
14732
|
+
return out;
|
|
14733
|
+
}
|
|
14714
14734
|
function blockers(d, product, names = 0) {
|
|
14715
14735
|
const out = [];
|
|
14716
14736
|
if (!product) {
|
|
@@ -14737,6 +14757,25 @@ function blockers(d, product, names = 0) {
|
|
|
14737
14757
|
if (!product.available) out.push(product.unavailableNote || "That search is not available just now.");
|
|
14738
14758
|
return out;
|
|
14739
14759
|
}
|
|
14760
|
+
function readiness(i) {
|
|
14761
|
+
const NOTHING_PICKED = "Pick one of the searches above to begin.";
|
|
14762
|
+
const blocking = [
|
|
14763
|
+
[i.nameStops.length > 0, i.nameStops[0] ?? ""],
|
|
14764
|
+
[i.gaps.length > 0, i.gaps[0] ?? ""],
|
|
14765
|
+
[i.stops.length > 0, i.stops[0] ?? ""],
|
|
14766
|
+
[i.budget != null, i.budget ? `This search reads ${i.budget.allowed} name${i.budget.allowed === 1 ? "" : "s"} at a time, and you have ${i.budget.allowed + i.budget.over}.` : ""],
|
|
14767
|
+
[i.exhausted, "No searches left on today’s allowance."],
|
|
14768
|
+
[!i.hasProduct, NOTHING_PICKED]
|
|
14769
|
+
].filter(([when]) => when);
|
|
14770
|
+
if (!blocking.length) return {
|
|
14771
|
+
ready: true,
|
|
14772
|
+
blockedBy: null
|
|
14773
|
+
};
|
|
14774
|
+
return {
|
|
14775
|
+
ready: false,
|
|
14776
|
+
blockedBy: blocking.map(([, sentence]) => sentence).find((s) => s.trim().length > 0) ?? NOTHING_PICKED
|
|
14777
|
+
};
|
|
14778
|
+
}
|
|
14740
14779
|
var ALL_TERRITORIES$1 = [...REGIONS, ...COUNTRIES];
|
|
14741
14780
|
var isKnownTerritory = (entry) => {
|
|
14742
14781
|
const e = String(entry).trim().toLowerCase();
|
|
@@ -15233,6 +15272,16 @@ function useUnsaved(dirty) {
|
|
|
15233
15272
|
ref.current = dirty;
|
|
15234
15273
|
(0, import_react.useEffect)(() => registerGuard(() => ref.current), []);
|
|
15235
15274
|
}
|
|
15275
|
+
function unsavedChanges({ current, empty, saved, submitted }) {
|
|
15276
|
+
if (submitted) return false;
|
|
15277
|
+
if (current === empty) return false;
|
|
15278
|
+
return current !== saved;
|
|
15279
|
+
}
|
|
15280
|
+
//#endregion
|
|
15281
|
+
//#region src/shell/ownerPickerHint.ts
|
|
15282
|
+
function ownerPickerHint(sidebarCollapsed) {
|
|
15283
|
+
return sidebarCollapsed ? "Open the menu on the left to pick one." : "Pick one at the top left.";
|
|
15284
|
+
}
|
|
15236
15285
|
//#endregion
|
|
15237
15286
|
//#region src/screens/NewClearance.tsx
|
|
15238
15287
|
function readProblem(r) {
|
|
@@ -15288,12 +15337,23 @@ function NewClearance({ ctx }) {
|
|
|
15288
15337
|
const [saveName, setSaveName] = (0, import_react.useState)("");
|
|
15289
15338
|
const [saveText, setSaveText] = (0, import_react.useState)("");
|
|
15290
15339
|
const [saveNote, setSaveNote] = (0, import_react.useState)(null);
|
|
15340
|
+
const [saveDone, setSaveDone] = (0, import_react.useState)(null);
|
|
15291
15341
|
const [plan, setPlan] = (0, import_react.useState)(null);
|
|
15292
15342
|
const [runFailure, setRunFailure] = (0, import_react.useState)(null);
|
|
15293
15343
|
const [busy, setBusy] = (0, import_react.useState)(false);
|
|
15294
15344
|
const [problem, setProblem] = (0, import_react.useState)(null);
|
|
15295
15345
|
const [submitted, setSubmitted] = (0, import_react.useState)(null);
|
|
15296
|
-
|
|
15346
|
+
const [savedDraft, setSavedDraft] = (0, import_react.useState)(null);
|
|
15347
|
+
useUnsaved((0, import_react.useMemo)(() => unsavedChanges({
|
|
15348
|
+
current: JSON.stringify(draft),
|
|
15349
|
+
empty: JSON.stringify(EMPTY),
|
|
15350
|
+
saved: savedDraft,
|
|
15351
|
+
submitted: submitted != null
|
|
15352
|
+
}), [
|
|
15353
|
+
draft,
|
|
15354
|
+
submitted,
|
|
15355
|
+
savedDraft
|
|
15356
|
+
]));
|
|
15297
15357
|
const { result: projectRes } = useLoad(() => draft.project ? api.project(account, draft.project) : Promise.resolve({
|
|
15298
15358
|
kind: "ok",
|
|
15299
15359
|
value: null
|
|
@@ -15314,7 +15374,7 @@ function NewClearance({ ctx }) {
|
|
|
15314
15374
|
const scope = editing.recipe["scope"] ?? {};
|
|
15315
15375
|
const classes = Array.isArray(scope["classes"]) ? scope["classes"].filter((c) => typeof c === "number") : [];
|
|
15316
15376
|
const platforms = Array.isArray(scope["platforms"]) ? scope["platforms"].filter((p) => typeof p === "string") : [];
|
|
15317
|
-
|
|
15377
|
+
writeDraft((d) => ({
|
|
15318
15378
|
...d,
|
|
15319
15379
|
pick: editingPick,
|
|
15320
15380
|
savedSearch: "",
|
|
@@ -15358,8 +15418,12 @@ function NewClearance({ ctx }) {
|
|
|
15358
15418
|
platforms: marketplacesApply ? own.platforms.length + parseList(draft.platforms).length : 0,
|
|
15359
15419
|
density: own.density
|
|
15360
15420
|
};
|
|
15421
|
+
const writeDraft = (next) => {
|
|
15422
|
+
setSaveDone(null);
|
|
15423
|
+
setDraft(next);
|
|
15424
|
+
};
|
|
15361
15425
|
const edit = (patch) => {
|
|
15362
|
-
|
|
15426
|
+
writeDraft((d) => ({
|
|
15363
15427
|
...d,
|
|
15364
15428
|
...patch
|
|
15365
15429
|
}));
|
|
@@ -15382,7 +15446,7 @@ function NewClearance({ ctx }) {
|
|
|
15382
15446
|
return;
|
|
15383
15447
|
}
|
|
15384
15448
|
const { read, dropped, worldwide } = resolveRead(r.value);
|
|
15385
|
-
|
|
15449
|
+
writeDraft((d) => {
|
|
15386
15450
|
const before = {
|
|
15387
15451
|
draft: d.pick,
|
|
15388
15452
|
names: d.names,
|
|
@@ -15443,11 +15507,11 @@ function NewClearance({ ctx }) {
|
|
|
15443
15507
|
};
|
|
15444
15508
|
case "pickAccount": return {
|
|
15445
15509
|
title: "Choose a brand owner",
|
|
15446
|
-
lines: [
|
|
15510
|
+
lines: [`Pick who this clearance is for. ${ownerPickerHint(ctx.sidebarCollapsed)}`]
|
|
15447
15511
|
};
|
|
15448
15512
|
case "notFound": return {
|
|
15449
15513
|
title: "That is not available to you",
|
|
15450
|
-
lines: ["Check
|
|
15514
|
+
lines: ["Check which brand owner is selected."]
|
|
15451
15515
|
};
|
|
15452
15516
|
case "noAccess": return {
|
|
15453
15517
|
title: "This address has no access yet",
|
|
@@ -15504,6 +15568,7 @@ function NewClearance({ ctx }) {
|
|
|
15504
15568
|
} else setRunFailure(explain(r));
|
|
15505
15569
|
};
|
|
15506
15570
|
const doSave = async () => {
|
|
15571
|
+
setSaveDone(null);
|
|
15507
15572
|
const label = saveName.trim();
|
|
15508
15573
|
const slug = editingSlug ?? label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 39);
|
|
15509
15574
|
if (slug.length < 2) {
|
|
@@ -15529,6 +15594,12 @@ function NewClearance({ ctx }) {
|
|
|
15529
15594
|
});
|
|
15530
15595
|
setBusy(false);
|
|
15531
15596
|
if (isOk(r)) {
|
|
15597
|
+
setSavedDraft(JSON.stringify({
|
|
15598
|
+
...EMPTY,
|
|
15599
|
+
pick: draft.pick,
|
|
15600
|
+
classes: draft.classes,
|
|
15601
|
+
platforms: draft.platforms
|
|
15602
|
+
}));
|
|
15532
15603
|
if (editingSlug) {
|
|
15533
15604
|
ctx.go("/portal/brand/searches");
|
|
15534
15605
|
return;
|
|
@@ -15538,6 +15609,7 @@ function NewClearance({ ctx }) {
|
|
|
15538
15609
|
setSaveText("");
|
|
15539
15610
|
const uncommitted = notCommitted(r);
|
|
15540
15611
|
setSaveNote(uncommitted ? `Saved as “${label}”. ${uncommitted}` : `Saved as “${label}” — it is in your custom searches.`);
|
|
15612
|
+
setSaveDone(label);
|
|
15541
15613
|
} else if (r.kind === "conflict") setSaveNote("Someone else changed this custom search while you were editing. Reload and re-apply.");
|
|
15542
15614
|
else setSaveNote("That could not be saved. Try a different name, or check it on Custom searches.");
|
|
15543
15615
|
};
|
|
@@ -15545,7 +15617,7 @@ function NewClearance({ ctx }) {
|
|
|
15545
15617
|
go: ctx.go,
|
|
15546
15618
|
onAnother: () => {
|
|
15547
15619
|
setSubmitted(null);
|
|
15548
|
-
|
|
15620
|
+
writeDraft(EMPTY);
|
|
15549
15621
|
setEntry(null);
|
|
15550
15622
|
}
|
|
15551
15623
|
});
|
|
@@ -15553,12 +15625,17 @@ function NewClearance({ ctx }) {
|
|
|
15553
15625
|
className: "screen",
|
|
15554
15626
|
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
15555
15627
|
className: "notice",
|
|
15556
|
-
children: [(0, import_jsx_runtime.jsx)("b", { children: "Choose a brand owner first" }), (0, import_jsx_runtime.
|
|
15628
|
+
children: [(0, import_jsx_runtime.jsx)("b", { children: "Choose a brand owner first" }), (0, import_jsx_runtime.jsxs)("p", {
|
|
15557
15629
|
style: {
|
|
15558
15630
|
margin: "6px 0 0",
|
|
15559
15631
|
color: "var(--text-muted)"
|
|
15560
15632
|
},
|
|
15561
|
-
children:
|
|
15633
|
+
children: [
|
|
15634
|
+
"A clearance is filed for one brand owner. ",
|
|
15635
|
+
ownerPickerHint(ctx.sidebarCollapsed),
|
|
15636
|
+
" ",
|
|
15637
|
+
"Then start the search."
|
|
15638
|
+
]
|
|
15562
15639
|
})]
|
|
15563
15640
|
})
|
|
15564
15641
|
});
|
|
@@ -15572,9 +15649,16 @@ function NewClearance({ ctx }) {
|
|
|
15572
15649
|
const markLimit = searches.value.maxMarkName;
|
|
15573
15650
|
const nameStops = overlong.map((n) => `“${n.slice(0, 30)}…” is ${n.length} characters. A mark name may be at most ${markLimit} — it becomes this run's name and part of every report link, so it cannot carry a description. Put the goods and the description in their own fields below.`);
|
|
15574
15651
|
const budget = nameBudget(activeLevel, names.length);
|
|
15575
|
-
const overBudget = budget != null;
|
|
15576
15652
|
const exhausted = usage?.capped === true && usage.dailyRuns != null && usage.today >= usage.dailyRuns;
|
|
15577
|
-
const
|
|
15653
|
+
const gaps = missingPieces(names, classes, draft.goods);
|
|
15654
|
+
const { ready, blockedBy } = readiness({
|
|
15655
|
+
gaps,
|
|
15656
|
+
stops,
|
|
15657
|
+
nameStops,
|
|
15658
|
+
budget,
|
|
15659
|
+
exhausted,
|
|
15660
|
+
hasProduct: activeLevel != null
|
|
15661
|
+
});
|
|
15578
15662
|
const startedFrom = draft.savedSearch ? savedRow?.label ?? "a custom search" : activeLevel?.name ?? "no search picked yet";
|
|
15579
15663
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
15580
15664
|
className: "screen",
|
|
@@ -16431,6 +16515,24 @@ function NewClearance({ ctx }) {
|
|
|
16431
16515
|
})
|
|
16432
16516
|
})]
|
|
16433
16517
|
}),
|
|
16518
|
+
gaps.length ? (0, import_jsx_runtime.jsxs)("div", {
|
|
16519
|
+
className: "notice",
|
|
16520
|
+
style: {
|
|
16521
|
+
borderColor: "var(--tone-medium)",
|
|
16522
|
+
margin: 0
|
|
16523
|
+
},
|
|
16524
|
+
children: [(0, import_jsx_runtime.jsx)("b", { children: gaps.length === 1 ? "One thing left to fill in" : "A couple of things left to fill in" }), (0, import_jsx_runtime.jsx)("ul", {
|
|
16525
|
+
style: {
|
|
16526
|
+
margin: "8px 0 0",
|
|
16527
|
+
paddingLeft: 18,
|
|
16528
|
+
color: "var(--text-muted)"
|
|
16529
|
+
},
|
|
16530
|
+
children: gaps.map((g, i) => (0, import_jsx_runtime.jsx)("li", {
|
|
16531
|
+
style: { marginBottom: 3 },
|
|
16532
|
+
children: g
|
|
16533
|
+
}, `g${i}`))
|
|
16534
|
+
})]
|
|
16535
|
+
}) : null,
|
|
16434
16536
|
stops.length || nameStops.length ? (0, import_jsx_runtime.jsxs)("div", {
|
|
16435
16537
|
className: "notice",
|
|
16436
16538
|
style: {
|
|
@@ -16487,12 +16589,15 @@ function NewClearance({ ctx }) {
|
|
|
16487
16589
|
ready,
|
|
16488
16590
|
busy,
|
|
16489
16591
|
demoMode: ctx.me.engineMode === "demo",
|
|
16592
|
+
setupRoute: ctx.me.setupRoute,
|
|
16490
16593
|
saveOpen,
|
|
16491
16594
|
saveName,
|
|
16492
16595
|
saveText,
|
|
16493
16596
|
saveNote,
|
|
16597
|
+
saveDone,
|
|
16494
16598
|
editing: editingSlug != null,
|
|
16495
16599
|
canSave: !draft.savedSearch && !stops.length,
|
|
16600
|
+
blockedBy,
|
|
16496
16601
|
onSaveOpen: () => {
|
|
16497
16602
|
setSaveOpen(true);
|
|
16498
16603
|
setSaveName(activeLevel ? `${activeLevel.name}` : "Custom search");
|
|
@@ -16508,7 +16613,8 @@ function NewClearance({ ctx }) {
|
|
|
16508
16613
|
setSaveNote(null);
|
|
16509
16614
|
},
|
|
16510
16615
|
onSave: doSave,
|
|
16511
|
-
onReview: doPlan
|
|
16616
|
+
onReview: doPlan,
|
|
16617
|
+
onSeeSaved: () => ctx.go("/portal/brand/searches")
|
|
16512
16618
|
}),
|
|
16513
16619
|
plan ? (0, import_jsx_runtime.jsx)(ReviewDialog, {
|
|
16514
16620
|
plan,
|
|
@@ -16655,7 +16761,7 @@ function NameWall({ count, allowed, first, canScreen, screenName, onScreenAll })
|
|
|
16655
16761
|
}) : null]
|
|
16656
16762
|
});
|
|
16657
16763
|
}
|
|
16658
|
-
function Footer({ startedFrom, tier, detail, units, cost, duration, runs, ready, busy, demoMode, saveOpen, saveName, saveText, saveNote, editing, canSave, onSaveOpen, onSaveName, onSaveText, onSaveCancel, onSave, onReview }) {
|
|
16764
|
+
function Footer({ startedFrom, tier, detail, units, cost, duration, runs, ready, busy, demoMode, setupRoute, saveOpen, saveName, saveText, saveNote, saveDone, editing, canSave, blockedBy, onSaveOpen, onSaveName, onSaveText, onSaveCancel, onSave, onReview, onSeeSaved }) {
|
|
16659
16765
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
16660
16766
|
className: "composer-footer",
|
|
16661
16767
|
children: [
|
|
@@ -16849,6 +16955,25 @@ function Footer({ startedFrom, tier, detail, units, cost, duration, runs, ready,
|
|
|
16849
16955
|
})
|
|
16850
16956
|
]
|
|
16851
16957
|
}) : null,
|
|
16958
|
+
saveDone ? (0, import_jsx_runtime.jsxs)("span", {
|
|
16959
|
+
className: "save-done",
|
|
16960
|
+
role: "status",
|
|
16961
|
+
children: [
|
|
16962
|
+
(0, import_jsx_runtime.jsx)(Icon, {
|
|
16963
|
+
name: "check",
|
|
16964
|
+
size: 13
|
|
16965
|
+
}),
|
|
16966
|
+
"Saved as “",
|
|
16967
|
+
saveDone,
|
|
16968
|
+
"”",
|
|
16969
|
+
(0, import_jsx_runtime.jsx)("button", {
|
|
16970
|
+
type: "button",
|
|
16971
|
+
className: "link-btn",
|
|
16972
|
+
onClick: onSeeSaved,
|
|
16973
|
+
children: "See it"
|
|
16974
|
+
})
|
|
16975
|
+
]
|
|
16976
|
+
}) : null,
|
|
16852
16977
|
demoMode ? (0, import_jsx_runtime.jsxs)("div", {
|
|
16853
16978
|
className: "footer-demo-note",
|
|
16854
16979
|
role: "status",
|
|
@@ -16859,19 +16984,29 @@ function Footer({ startedFrom, tier, detail, units, cost, duration, runs, ready,
|
|
|
16859
16984
|
children: [
|
|
16860
16985
|
(0, import_jsx_runtime.jsx)("strong", { children: "No search engine is attached to this install." }),
|
|
16861
16986
|
" ",
|
|
16862
|
-
"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",
|
|
16987
|
+
"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",
|
|
16863
16988
|
" ",
|
|
16864
|
-
(0, import_jsx_runtime.jsx)(
|
|
16865
|
-
" again."
|
|
16989
|
+
(0, import_jsx_runtime.jsx)(SetupCommand, { route: setupRoute })
|
|
16866
16990
|
]
|
|
16867
|
-
}) : (0, import_jsx_runtime.jsxs)("
|
|
16868
|
-
|
|
16869
|
-
|
|
16870
|
-
|
|
16871
|
-
|
|
16872
|
-
|
|
16873
|
-
|
|
16874
|
-
|
|
16991
|
+
}) : (0, import_jsx_runtime.jsxs)("span", {
|
|
16992
|
+
style: {
|
|
16993
|
+
display: "inline-flex",
|
|
16994
|
+
alignItems: "center",
|
|
16995
|
+
gap: 10,
|
|
16996
|
+
flexWrap: "wrap"
|
|
16997
|
+
},
|
|
16998
|
+
children: [(0, import_jsx_runtime.jsxs)("button", {
|
|
16999
|
+
type: "button",
|
|
17000
|
+
className: "btn-primary",
|
|
17001
|
+
disabled: !ready || busy,
|
|
17002
|
+
onClick: onReview,
|
|
17003
|
+
children: [busy ? "Checking…" : "Start a search", (0, import_jsx_runtime.jsx)(Icon, {
|
|
17004
|
+
name: "arrow-right",
|
|
17005
|
+
size: 14
|
|
17006
|
+
})]
|
|
17007
|
+
}), (0, import_jsx_runtime.jsx)("span", {
|
|
17008
|
+
className: "footer-hint",
|
|
17009
|
+
children: blockedBy ?? "You will see the coverage and what it costs before anything runs."
|
|
16875
17010
|
})]
|
|
16876
17011
|
})
|
|
16877
17012
|
]
|
|
@@ -16879,6 +17014,18 @@ function Footer({ startedFrom, tier, detail, units, cost, duration, runs, ready,
|
|
|
16879
17014
|
]
|
|
16880
17015
|
});
|
|
16881
17016
|
}
|
|
17017
|
+
function SetupCommand({ route }) {
|
|
17018
|
+
if (route === "packaged") return (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsx)("code", { children: "npx clearotron install" }), "."] });
|
|
17019
|
+
if (route === "checkout") return (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsx)("code", { children: "npm run setup" }), "."] });
|
|
17020
|
+
return (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
17021
|
+
"— ",
|
|
17022
|
+
(0, import_jsx_runtime.jsx)("code", { children: "npx clearotron install" }),
|
|
17023
|
+
" if you installed the package, or ",
|
|
17024
|
+
(0, import_jsx_runtime.jsx)("code", { children: "npm run setup" }),
|
|
17025
|
+
" ",
|
|
17026
|
+
"from a copy of the source."
|
|
17027
|
+
] });
|
|
17028
|
+
}
|
|
16882
17029
|
function Lever({ label, hint, on, onToggle, coming }) {
|
|
16883
17030
|
return (0, import_jsx_runtime.jsxs)("button", {
|
|
16884
17031
|
type: "button",
|
|
@@ -17528,9 +17675,9 @@ function SavedSearches({ ctx }) {
|
|
|
17528
17675
|
const [busy, setBusy] = (0, import_react.useState)(null);
|
|
17529
17676
|
const [confirming, setConfirming] = (0, import_react.useState)(null);
|
|
17530
17677
|
const [problem, setProblem] = (0, import_react.useState)(null);
|
|
17531
|
-
if (needsOwner) return (0, import_jsx_runtime.jsx)(PickOwner, {});
|
|
17678
|
+
if (needsOwner) return (0, import_jsx_runtime.jsx)(PickOwner, { sidebarCollapsed: ctx.sidebarCollapsed });
|
|
17532
17679
|
if (!result) return (0, import_jsx_runtime.jsx)("div", { className: "screen" });
|
|
17533
|
-
if (result.kind === "pickAccount") return (0, import_jsx_runtime.jsx)(PickOwner, {});
|
|
17680
|
+
if (result.kind === "pickAccount") return (0, import_jsx_runtime.jsx)(PickOwner, { sidebarCollapsed: ctx.sidebarCollapsed });
|
|
17534
17681
|
if (result.kind !== "ok") return (0, import_jsx_runtime.jsxs)("div", {
|
|
17535
17682
|
className: "screen",
|
|
17536
17683
|
children: [(0, import_jsx_runtime.jsx)(Heading, {}), (0, import_jsx_runtime.jsxs)("div", {
|
|
@@ -17802,17 +17949,17 @@ function Empty({ go }) {
|
|
|
17802
17949
|
})]
|
|
17803
17950
|
});
|
|
17804
17951
|
}
|
|
17805
|
-
function PickOwner() {
|
|
17952
|
+
function PickOwner({ sidebarCollapsed }) {
|
|
17806
17953
|
return (0, import_jsx_runtime.jsx)("div", {
|
|
17807
17954
|
className: "screen",
|
|
17808
17955
|
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
17809
17956
|
className: "notice",
|
|
17810
|
-
children: [(0, import_jsx_runtime.jsx)("b", { children: "Choose a brand owner first" }), (0, import_jsx_runtime.
|
|
17957
|
+
children: [(0, import_jsx_runtime.jsx)("b", { children: "Choose a brand owner first" }), (0, import_jsx_runtime.jsxs)("p", {
|
|
17811
17958
|
style: {
|
|
17812
17959
|
margin: "6px 0 0",
|
|
17813
17960
|
color: "var(--text-muted)"
|
|
17814
17961
|
},
|
|
17815
|
-
children: "Custom searches belong to one brand owner.
|
|
17962
|
+
children: ["Custom searches belong to one brand owner. ", ownerPickerHint(sidebarCollapsed)]
|
|
17816
17963
|
})]
|
|
17817
17964
|
})
|
|
17818
17965
|
});
|
|
@@ -18490,7 +18637,7 @@ var PROFILE_FIELDS = [
|
|
|
18490
18637
|
kind: "numbers",
|
|
18491
18638
|
group: "defaults",
|
|
18492
18639
|
picker: "classes",
|
|
18493
|
-
hint: "
|
|
18640
|
+
hint: "The numbered categories a trademark is registered in — 9 is software, 25 is clothing, 41 is training. These are the Nice classes, 1 to 45. Leave this empty and each search states its own. Commas, spaces or new lines all work."
|
|
18494
18641
|
},
|
|
18495
18642
|
{
|
|
18496
18643
|
key: "defaultJurisdictions",
|
|
@@ -18503,7 +18650,7 @@ var PROFILE_FIELDS = [
|
|
|
18503
18650
|
ok: isKnownTerritory,
|
|
18504
18651
|
expected: "a territory from the picker below"
|
|
18505
18652
|
},
|
|
18506
|
-
hint: "One per line or comma-separated.
|
|
18653
|
+
hint: "One per line or comma-separated — pick from the list below. A region counts as one entry: European Union covers its member states, so there is no need to add them. Anything not in the list is kept and flagged rather than refused, because a search can name a territory this list does not carry."
|
|
18507
18654
|
},
|
|
18508
18655
|
{
|
|
18509
18656
|
key: "platforms",
|
|
@@ -18906,12 +19053,12 @@ function Profile({ ctx }) {
|
|
|
18906
19053
|
className: "screen",
|
|
18907
19054
|
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
18908
19055
|
className: "notice",
|
|
18909
|
-
children: [(0, import_jsx_runtime.jsx)("b", { children: "Choose a brand owner first" }), (0, import_jsx_runtime.
|
|
19056
|
+
children: [(0, import_jsx_runtime.jsx)("b", { children: "Choose a brand owner first" }), (0, import_jsx_runtime.jsxs)("p", {
|
|
18910
19057
|
style: {
|
|
18911
19058
|
margin: "6px 0 0",
|
|
18912
19059
|
color: "var(--text-muted)"
|
|
18913
19060
|
},
|
|
18914
|
-
children: "A profile belongs to one brand owner.
|
|
19061
|
+
children: ["A profile belongs to one brand owner. ", ownerPickerHint(ctx.sidebarCollapsed)]
|
|
18915
19062
|
})]
|
|
18916
19063
|
})
|
|
18917
19064
|
});
|
|
@@ -19091,11 +19238,15 @@ function Profile({ ctx }) {
|
|
|
19091
19238
|
children: "Save"
|
|
19092
19239
|
}),
|
|
19093
19240
|
(0, import_jsx_runtime.jsx)("span", {
|
|
19094
|
-
style: {
|
|
19241
|
+
style: dirty && !checked ? {
|
|
19242
|
+
fontSize: 13,
|
|
19243
|
+
color: "var(--tone-medium)",
|
|
19244
|
+
fontWeight: 600
|
|
19245
|
+
} : {
|
|
19095
19246
|
fontSize: 12.5,
|
|
19096
19247
|
color: "var(--text-muted)"
|
|
19097
19248
|
},
|
|
19098
|
-
children: !dirty ? "No changes." : checked ? "Checked — safe to save." : "Check
|
|
19249
|
+
children: !dirty ? "No changes." : checked ? "Checked — safe to save." : "Press Check before saving. A profile the engine cannot read stops this account searching."
|
|
19099
19250
|
})
|
|
19100
19251
|
]
|
|
19101
19252
|
})
|
|
@@ -19194,7 +19345,10 @@ function FrameworkBlock({ readOnly, framework, staff }) {
|
|
|
19194
19345
|
" rated under the Generic default — but its definitions are unavailable, so the bands cannot be shown here. This needs an administrator to look at it."
|
|
19195
19346
|
] }) : (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsx)("b", { children: "Generic default" }), " — no custom framework is on file for this brand owner; their matters are rated under the generic framework."] })
|
|
19196
19347
|
}),
|
|
19197
|
-
bands.length ? (0, import_jsx_runtime.jsx)("div", {
|
|
19348
|
+
bands.length ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsx)("div", {
|
|
19349
|
+
className: "fw-ladder-label",
|
|
19350
|
+
children: "Its ratings, strongest concern first:"
|
|
19351
|
+
}), (0, import_jsx_runtime.jsx)("div", {
|
|
19198
19352
|
className: "fw-ladder",
|
|
19199
19353
|
children: bands.map((b, i) => {
|
|
19200
19354
|
const band = rec(b);
|
|
@@ -19204,7 +19358,7 @@ function FrameworkBlock({ readOnly, framework, staff }) {
|
|
|
19204
19358
|
tone: band?.["tone"]
|
|
19205
19359
|
}, i) : null;
|
|
19206
19360
|
})
|
|
19207
|
-
}) : null,
|
|
19361
|
+
})] }) : null,
|
|
19208
19362
|
meanings.length ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsx)("div", {
|
|
19209
19363
|
className: "fw-bmh",
|
|
19210
19364
|
children: "What the bands mean"
|
|
@@ -19408,7 +19562,7 @@ function explain(r) {
|
|
|
19408
19562
|
};
|
|
19409
19563
|
case "notFound": return {
|
|
19410
19564
|
title: "That is not available to you",
|
|
19411
|
-
lines: ["Check
|
|
19565
|
+
lines: ["Check which brand owner is selected."]
|
|
19412
19566
|
};
|
|
19413
19567
|
case "noAccess": return {
|
|
19414
19568
|
title: "This address has no access yet",
|
|
@@ -19455,12 +19609,12 @@ function Projects({ ctx }) {
|
|
|
19455
19609
|
className: "screen",
|
|
19456
19610
|
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
19457
19611
|
className: "notice",
|
|
19458
|
-
children: [(0, import_jsx_runtime.jsx)("b", { children: "Choose a brand owner first" }), (0, import_jsx_runtime.
|
|
19612
|
+
children: [(0, import_jsx_runtime.jsx)("b", { children: "Choose a brand owner first" }), (0, import_jsx_runtime.jsxs)("p", {
|
|
19459
19613
|
style: {
|
|
19460
19614
|
margin: "6px 0 0",
|
|
19461
19615
|
color: "var(--text-muted)"
|
|
19462
19616
|
},
|
|
19463
|
-
children: "Projects belong to one brand owner.
|
|
19617
|
+
children: ["Projects belong to one brand owner. ", ownerPickerHint(ctx.sidebarCollapsed)]
|
|
19464
19618
|
})]
|
|
19465
19619
|
})
|
|
19466
19620
|
});
|
|
@@ -20390,7 +20544,10 @@ function GlobalConfig({ ctx }) {
|
|
|
20390
20544
|
}),
|
|
20391
20545
|
(0, import_jsx_runtime.jsx)(Group, {
|
|
20392
20546
|
title: "Engine",
|
|
20393
|
-
children: v.engine ? (0, import_jsx_runtime.jsx)(Engine, {
|
|
20547
|
+
children: v.engine ? (0, import_jsx_runtime.jsx)(Engine, {
|
|
20548
|
+
engine: v.engine,
|
|
20549
|
+
programDisputed: (v.lastRun?.disagrees ?? []).some((d) => d.what === "engine program")
|
|
20550
|
+
}) : (0, import_jsx_runtime.jsx)(NotRecorded, {
|
|
20394
20551
|
what: "which engine is running",
|
|
20395
20552
|
source: v.source
|
|
20396
20553
|
})
|
|
@@ -20525,12 +20682,13 @@ function Auth({ auth }) {
|
|
|
20525
20682
|
faults: []
|
|
20526
20683
|
}) : null] });
|
|
20527
20684
|
}
|
|
20528
|
-
function Engine({ engine }) {
|
|
20685
|
+
function Engine({ engine, programDisputed = false }) {
|
|
20529
20686
|
const billed = engine.billing.apiBilled ? "API key" : "Subscription";
|
|
20530
20687
|
const faults = [
|
|
20531
20688
|
...engine.known ? [] : [`This build does not ship an engine called ${engine.id}.`],
|
|
20532
20689
|
...engine.billing.missing.length ? [`Set to bill an API key, and ${engine.billing.missing.join(" and ")} is not set — a run is refused rather than billed to the subscription.`] : [],
|
|
20533
|
-
...engine.binaryPresent ? [] : ["The engine program cannot be found or run on this machine."]
|
|
20690
|
+
...engine.binaryPresent ? [] : ["The engine program cannot be found or run on this machine."],
|
|
20691
|
+
...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."] : []
|
|
20534
20692
|
];
|
|
20535
20693
|
return (0, import_jsx_runtime.jsx)(Row$1, {
|
|
20536
20694
|
ok: faults.length === 0,
|
|
@@ -20748,7 +20906,10 @@ function PeopleAccess({ ctx }) {
|
|
|
20748
20906
|
display: "grid",
|
|
20749
20907
|
gap: 6
|
|
20750
20908
|
},
|
|
20751
|
-
children: (0, import_jsx_runtime.jsx)(StaffRuleRow, {
|
|
20909
|
+
children: (0, import_jsx_runtime.jsx)(StaffRuleRow, {
|
|
20910
|
+
domains: v.staffDomains,
|
|
20911
|
+
rule: v.staffRule
|
|
20912
|
+
})
|
|
20752
20913
|
})] }) : null,
|
|
20753
20914
|
(0, import_jsx_runtime.jsx)("div", {
|
|
20754
20915
|
style: {
|
|
@@ -20838,15 +20999,15 @@ function Roles({ brand }) {
|
|
|
20838
20999
|
]
|
|
20839
21000
|
});
|
|
20840
21001
|
}
|
|
20841
|
-
function StaffRuleRow({ domains }) {
|
|
20842
|
-
return (0, import_jsx_runtime.
|
|
21002
|
+
function StaffRuleRow({ domains, rule }) {
|
|
21003
|
+
return (0, import_jsx_runtime.jsxs)("div", {
|
|
20843
21004
|
style: {
|
|
20844
21005
|
padding: "10px 13px",
|
|
20845
21006
|
borderRadius: 9,
|
|
20846
21007
|
border: "1px solid var(--border-hairline)",
|
|
20847
21008
|
background: "var(--surface-raised)"
|
|
20848
21009
|
},
|
|
20849
|
-
children: (0, import_jsx_runtime.jsxs)("div", {
|
|
21010
|
+
children: [(0, import_jsx_runtime.jsxs)("div", {
|
|
20850
21011
|
style: {
|
|
20851
21012
|
display: "flex",
|
|
20852
21013
|
alignItems: "baseline",
|
|
@@ -20871,7 +21032,23 @@ function StaffRuleRow({ domains }) {
|
|
|
20871
21032
|
},
|
|
20872
21033
|
children: "a rule, not a person"
|
|
20873
21034
|
})]
|
|
20874
|
-
})
|
|
21035
|
+
}), rule ? (0, import_jsx_runtime.jsxs)("p", {
|
|
21036
|
+
style: {
|
|
21037
|
+
margin: "6px 0 0",
|
|
21038
|
+
color: "var(--text-muted)",
|
|
21039
|
+
fontSize: 12.5
|
|
21040
|
+
},
|
|
21041
|
+
children: [
|
|
21042
|
+
"Granted by ",
|
|
21043
|
+
(0, import_jsx_runtime.jsx)("b", {
|
|
21044
|
+
className: "mono",
|
|
21045
|
+
children: rule.name
|
|
21046
|
+
}),
|
|
21047
|
+
", ",
|
|
21048
|
+
rule.where,
|
|
21049
|
+
". Change or remove that setting and restart this instance to undo the rule. Nothing outside this machine created it."
|
|
21050
|
+
]
|
|
21051
|
+
}) : null]
|
|
20875
21052
|
});
|
|
20876
21053
|
}
|
|
20877
21054
|
function Observed({ result }) {
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
-->
|
|
50
50
|
<link rel="preconnect" href="https://api.fontshare.com" crossorigin />
|
|
51
51
|
<link href="https://api.fontshare.com/v2/css?f[]=satoshi@400,500,700,900&display=swap" rel="stylesheet" />
|
|
52
|
-
<script type="module" crossorigin src="/portal/assets/index-
|
|
53
|
-
<link rel="stylesheet" crossorigin href="/portal/assets/index-
|
|
52
|
+
<script type="module" crossorigin src="/portal/assets/index-CEYvXdqH.js"></script>
|
|
53
|
+
<link rel="stylesheet" crossorigin href="/portal/assets/index-1ziUJX1E.css">
|
|
54
54
|
</head>
|
|
55
55
|
<body>
|
|
56
56
|
<div id="root"></div>
|