@world-engines/project-host 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +46 -0
- package/assets/gui/WELogo-title.svg +11 -0
- package/assets/gui/app.js +1326 -0
- package/assets/gui/index.html +118 -0
- package/assets/gui/local-preview-asset-urls.js +61 -0
- package/assets/gui/local-preview-bridge.js +393 -0
- package/assets/gui/spatial-template-panel.js +233 -0
- package/assets/gui/styles.css +115 -0
- package/assets/gui/terrain-render.js +120 -0
- package/assets/gui/workspace-status.css +17 -0
- package/assets/gui/workspace-status.js +255 -0
- package/assets/gui/world-map-globe.js +187 -0
- package/assets/gui/world-map-worker.js +62 -0
- package/assets/gui/world-map.css +30 -0
- package/assets/gui/world-map.js +2466 -0
- package/dist/account-model-proxy.d.ts +21 -0
- package/dist/account-model-proxy.js +470 -0
- package/dist/authoring-browser-runtime.d.ts +7 -0
- package/dist/authoring-browser-runtime.js +110 -0
- package/dist/authoring-ingestion.d.ts +38 -0
- package/dist/authoring-ingestion.js +410 -0
- package/dist/authoring-model-connection.d.ts +166 -0
- package/dist/authoring-model-connection.js +757 -0
- package/dist/chinese-lexical.d.ts +152 -0
- package/dist/chinese-lexical.js +555 -0
- package/dist/chromium-preview-browser-driver.d.ts +43 -0
- package/dist/chromium-preview-browser-driver.js +575 -0
- package/dist/cli/download.d.ts +12 -0
- package/dist/cli/download.js +50 -0
- package/dist/cli/dump.d.ts +32 -0
- package/dist/cli/dump.js +91 -0
- package/dist/cli/ingest.d.ts +49 -0
- package/dist/cli/ingest.js +225 -0
- package/dist/cli/review.d.ts +10 -0
- package/dist/cli/review.js +44 -0
- package/dist/cli/upload.d.ts +57 -0
- package/dist/cli/upload.js +112 -0
- package/dist/cli-command.d.ts +60 -0
- package/dist/cli-command.js +613 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +182 -0
- package/dist/desktop-authoring-runtime.d.ts +88 -0
- package/dist/desktop-authoring-runtime.js +1602 -0
- package/dist/desktop-sidecar.d.ts +11 -0
- package/dist/desktop-sidecar.js +143 -0
- package/dist/document-dump.d.ts +113 -0
- package/dist/document-dump.js +431 -0
- package/dist/document-graph-extractor.d.ts +125 -0
- package/dist/document-graph-extractor.js +588 -0
- package/dist/document-ingestion-journal.d.ts +68 -0
- package/dist/document-ingestion-journal.js +471 -0
- package/dist/document-ingestion.d.ts +183 -0
- package/dist/document-ingestion.js +976 -0
- package/dist/document-query-path-proof.d.ts +30 -0
- package/dist/document-query-path-proof.js +34 -0
- package/dist/document-query-path-renderer.d.ts +50 -0
- package/dist/document-query-path-renderer.js +75 -0
- package/dist/document-query-proof-paths.d.ts +22 -0
- package/dist/document-query-proof-paths.js +71 -0
- package/dist/document-query.d.ts +97 -0
- package/dist/document-query.js +1106 -0
- package/dist/document-relation-role.d.ts +14 -0
- package/dist/document-relation-role.js +86 -0
- package/dist/document-source.d.ts +107 -0
- package/dist/document-source.js +255 -0
- package/dist/embedding-cache.d.ts +35 -0
- package/dist/embedding-cache.js +317 -0
- package/dist/frozen-review-local-pipeline.d.ts +88 -0
- package/dist/frozen-review-local-pipeline.js +609 -0
- package/dist/frozen-review-source-capture.d.ts +15 -0
- package/dist/frozen-review-source-capture.js +551 -0
- package/dist/frozen-review-wasm-encryptor.d.ts +16 -0
- package/dist/frozen-review-wasm-encryptor.js +72 -0
- package/dist/frozen-review.d.ts +131 -0
- package/dist/frozen-review.js +802 -0
- package/dist/graph-traversal.d.ts +23 -0
- package/dist/graph-traversal.js +100 -0
- package/dist/gui/graph-layout-worker.js +1 -0
- package/dist/gui/graph-layout.wasm +0 -0
- package/dist/gui/graph.css +1 -0
- package/dist/gui/graph.js +76 -0
- package/dist/gui/plane-generation.js +112 -0
- package/dist/gui/plane-generator.js +310 -0
- package/dist/gui/plane-generator_bg.wasm +0 -0
- package/dist/gui/procedural-city.js +595 -0
- package/dist/gui/road-generation.js +129 -0
- package/dist/gui/road-parcels.js +1584 -0
- package/dist/gui/score.css +1 -0
- package/dist/gui/score.js +54 -0
- package/dist/gui/spatial-runtime.js +1231 -0
- package/dist/gui/spatial-templates.js +200 -0
- package/dist/gui/trigger.css +1 -0
- package/dist/gui/trigger.js +142 -0
- package/dist/harness-callback-transport.d.ts +17 -0
- package/dist/harness-callback-transport.js +128 -0
- package/dist/harness-document-ingestion.d.ts +77 -0
- package/dist/harness-document-ingestion.js +343 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +43 -0
- package/dist/ingestion-source-reconciliation.d.ts +88 -0
- package/dist/ingestion-source-reconciliation.js +253 -0
- package/dist/ladybug-runtime.d.ts +117 -0
- package/dist/ladybug-runtime.js +886 -0
- package/dist/local-account-embedding.d.ts +34 -0
- package/dist/local-account-embedding.js +294 -0
- package/dist/local-gallery.d.ts +35 -0
- package/dist/local-gallery.js +227 -0
- package/dist/local-gui-auth.d.ts +96 -0
- package/dist/local-gui-auth.js +703 -0
- package/dist/local-gui-contract.d.ts +53 -0
- package/dist/local-gui-contract.js +5 -0
- package/dist/local-gui-image-assets.d.ts +17 -0
- package/dist/local-gui-image-assets.js +96 -0
- package/dist/local-gui-preview-client.d.ts +3 -0
- package/dist/local-gui-preview-client.js +111 -0
- package/dist/local-gui-score.d.ts +72 -0
- package/dist/local-gui-score.js +184 -0
- package/dist/local-gui-server.d.ts +10 -0
- package/dist/local-gui-server.js +987 -0
- package/dist/local-gui-version.d.ts +17 -0
- package/dist/local-gui-version.js +147 -0
- package/dist/local-gui-workspace.d.ts +14 -0
- package/dist/local-gui-workspace.js +171 -0
- package/dist/local-model-settings.d.ts +28 -0
- package/dist/local-model-settings.js +124 -0
- package/dist/local-preview-assets.d.ts +28 -0
- package/dist/local-preview-assets.js +124 -0
- package/dist/local-preview-bound-resources.d.ts +12 -0
- package/dist/local-preview-bound-resources.js +80 -0
- package/dist/local-preview-message-store.d.ts +63 -0
- package/dist/local-preview-message-store.js +214 -0
- package/dist/local-preview-player-read-models.d.ts +47 -0
- package/dist/local-preview-player-read-models.js +90 -0
- package/dist/local-preview-projections.d.ts +61 -0
- package/dist/local-preview-projections.js +117 -0
- package/dist/local-preview-runtime.d.ts +105 -0
- package/dist/local-preview-runtime.js +553 -0
- package/dist/local-preview-session.d.ts +73 -0
- package/dist/local-preview-session.js +395 -0
- package/dist/local-preview-source.d.ts +40 -0
- package/dist/local-preview-source.js +192 -0
- package/dist/local-preview-view-events.d.ts +101 -0
- package/dist/local-preview-view-events.js +179 -0
- package/dist/local-preview-view-state-sqlite.d.ts +24 -0
- package/dist/local-preview-view-state-sqlite.js +263 -0
- package/dist/local-preview-view-state.d.ts +93 -0
- package/dist/local-preview-view-state.js +108 -0
- package/dist/local-preview-vite-config.d.ts +6 -0
- package/dist/local-preview-vite-config.js +122 -0
- package/dist/local-preview-world-effects.d.ts +9 -0
- package/dist/local-preview-world-effects.js +55 -0
- package/dist/local-preview-worldline-store.d.ts +47 -0
- package/dist/local-preview-worldline-store.js +282 -0
- package/dist/local-preview-worldlines.d.ts +95 -0
- package/dist/local-preview-worldlines.js +136 -0
- package/dist/mcp-async-dispatcher.d.ts +3 -0
- package/dist/mcp-async-dispatcher.js +129 -0
- package/dist/mcp-line-queue.d.ts +14 -0
- package/dist/mcp-line-queue.js +184 -0
- package/dist/mcp-pipe-internal.d.ts +6 -0
- package/dist/mcp-pipe-internal.js +151 -0
- package/dist/mcp-pipe-response.d.ts +14 -0
- package/dist/mcp-pipe-response.js +50 -0
- package/dist/mcp-stdio-response.d.ts +12 -0
- package/dist/mcp-stdio-response.js +27 -0
- package/dist/mcp.d.ts +27 -0
- package/dist/mcp.js +194 -0
- package/dist/prepared-embedding-cache.d.ts +38 -0
- package/dist/prepared-embedding-cache.js +238 -0
- package/dist/preview-browser-adapter.d.ts +53 -0
- package/dist/preview-browser-adapter.js +171 -0
- package/dist/preview-runtime.d.ts +67 -0
- package/dist/preview-runtime.js +460 -0
- package/dist/project-auth-transport.d.ts +27 -0
- package/dist/project-auth-transport.js +121 -0
- package/dist/project-auth.d.ts +51 -0
- package/dist/project-auth.js +108 -0
- package/dist/project-git-capture-recovery.d.ts +16 -0
- package/dist/project-git-capture-recovery.js +347 -0
- package/dist/project-git-cli.d.ts +5 -0
- package/dist/project-git-cli.js +40 -0
- package/dist/project-git-scenario-source.d.ts +10 -0
- package/dist/project-git-scenario-source.js +240 -0
- package/dist/project-git-view-source.d.ts +13 -0
- package/dist/project-git-view-source.js +134 -0
- package/dist/project-git.d.ts +97 -0
- package/dist/project-git.js +656 -0
- package/dist/project-host.d.ts +59 -0
- package/dist/project-host.js +471 -0
- package/dist/project-writer-lease.d.ts +18 -0
- package/dist/project-writer-lease.js +430 -0
- package/dist/public-error.d.ts +7 -0
- package/dist/public-error.js +61 -0
- package/dist/retrieval-benchmark.d.ts +46 -0
- package/dist/retrieval-benchmark.js +58 -0
- package/dist/safe-project-path.d.ts +8 -0
- package/dist/safe-project-path.js +93 -0
- package/dist/scenario-writer.d.ts +32 -0
- package/dist/scenario-writer.js +191 -0
- package/dist/transfer/download.d.ts +159 -0
- package/dist/transfer/download.js +598 -0
- package/dist/transfer/transport.d.ts +26 -0
- package/dist/transfer/transport.js +1 -0
- package/dist/transfer/upload.d.ts +162 -0
- package/dist/transfer/upload.js +354 -0
- package/dist/transfer-types.d.ts +95 -0
- package/dist/transfer-types.js +1 -0
- package/dist/transfer.d.ts +18 -0
- package/dist/transfer.js +273 -0
- package/dist/trigger-runtime.d.ts +121 -0
- package/dist/trigger-runtime.js +153 -0
- package/dist/vendor/wasm-core/asset-hashes.json +5 -0
- package/dist/vendor/wasm-core/wasm_core.d.ts +490 -0
- package/dist/vendor/wasm-core/wasm_core.js +1 -0
- package/dist/vendor/wasm-core/wasm_core_bg.wasm +0 -0
- package/dist/view-watcher.d.ts +9 -0
- package/dist/view-watcher.js +34 -0
- package/package.json +110 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/** 可持久化的空间模板选择;参数是预设的冻结快照,而不是可随意调节的 UI 草稿。 */
|
|
2
|
+
export const SPATIAL_TEMPLATE_VERSION = 1;
|
|
3
|
+
const freeze = (value) => Object.freeze(value);
|
|
4
|
+
/** 每类一个可直接套用的生产预设;可由 Host 另行扩充 library。 */
|
|
5
|
+
export const SPATIAL_TEMPLATE_PRESETS = freeze({
|
|
6
|
+
city: freeze({
|
|
7
|
+
kind: "city",
|
|
8
|
+
id: "city.compact-town",
|
|
9
|
+
revision: 1,
|
|
10
|
+
label: "紧凑城镇",
|
|
11
|
+
parameters: freeze({
|
|
12
|
+
radiusMeters: 480,
|
|
13
|
+
blockSizeMeters: 80,
|
|
14
|
+
roadWidthMeters: 12,
|
|
15
|
+
landUseWeights: freeze({ residential: 56, commercial: 21, industrial: 9, civic: 8, park: 6 }),
|
|
16
|
+
}),
|
|
17
|
+
}),
|
|
18
|
+
parcel: freeze({
|
|
19
|
+
kind: "parcel",
|
|
20
|
+
id: "parcel.fine-grain",
|
|
21
|
+
revision: 1,
|
|
22
|
+
label: "细分街区",
|
|
23
|
+
parameters: freeze({ subdivision: 2, roadParcelMaxFaceAreaMeters: 2_400 }),
|
|
24
|
+
}),
|
|
25
|
+
building: freeze({
|
|
26
|
+
kind: "building",
|
|
27
|
+
id: "building.courtyard-cluster",
|
|
28
|
+
revision: 1,
|
|
29
|
+
label: "庭院组团",
|
|
30
|
+
parameters: freeze({ maxBuildings: 3, fillScale: 0.72 }),
|
|
31
|
+
}),
|
|
32
|
+
interior: freeze({
|
|
33
|
+
kind: "interior",
|
|
34
|
+
id: "interior.compact-corridor",
|
|
35
|
+
revision: 1,
|
|
36
|
+
label: "紧凑走廊",
|
|
37
|
+
parameters: freeze({ roomDensity: 2, corridorRatio: 0.22 }),
|
|
38
|
+
}),
|
|
39
|
+
});
|
|
40
|
+
function isRecord(value) {
|
|
41
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
42
|
+
}
|
|
43
|
+
function exact(value, keys, label) {
|
|
44
|
+
if (!isRecord(value))
|
|
45
|
+
throw new TypeError(`${label} 必须是对象`);
|
|
46
|
+
const actual = Object.keys(value);
|
|
47
|
+
const unknown = actual.filter((key) => !keys.includes(key));
|
|
48
|
+
const missing = keys.filter((key) => !Object.hasOwn(value, key));
|
|
49
|
+
if (unknown.length > 0)
|
|
50
|
+
throw new TypeError(`${label} 包含未知字段:${unknown.join(", ")}`);
|
|
51
|
+
if (missing.length > 0)
|
|
52
|
+
throw new TypeError(`${label} 缺少字段:${missing.join(", ")}`);
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
function presetFor(kind) {
|
|
56
|
+
return SPATIAL_TEMPLATE_PRESETS[kind];
|
|
57
|
+
}
|
|
58
|
+
/** 查找内置模板。用户模板由 Host library 持久化后可用同一 selection shape 套用。 */
|
|
59
|
+
export function getSpatialTemplatePreset(kind, presetId) {
|
|
60
|
+
const preset = presetFor(kind);
|
|
61
|
+
if (preset.id !== presetId)
|
|
62
|
+
throw new TypeError(`${kind} 模板 presetId 不存在:${presetId}`);
|
|
63
|
+
return preset;
|
|
64
|
+
}
|
|
65
|
+
function identifier(value, label) {
|
|
66
|
+
if (typeof value !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(value)) {
|
|
67
|
+
throw new TypeError(`${label} 必须是稳定 identifier`);
|
|
68
|
+
}
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
function revision(value, label) {
|
|
72
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > 1_000_000) {
|
|
73
|
+
throw new RangeError(`${label} 必须是 1..1000000 的整数`);
|
|
74
|
+
}
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
function numberIn(value, label, min, max) {
|
|
78
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < min || value > max) {
|
|
79
|
+
throw new RangeError(`${label} 必须位于 ${min}..${max}`);
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
function cityParameters(value) {
|
|
84
|
+
const source = exact(value, ["radiusMeters", "blockSizeMeters", "roadWidthMeters", "landUseWeights"], "city.parameters");
|
|
85
|
+
const weights = exact(source.landUseWeights, ["residential", "commercial", "industrial", "civic", "park"], "city.parameters.landUseWeights");
|
|
86
|
+
const result = freeze({
|
|
87
|
+
radiusMeters: numberIn(source.radiusMeters, "city.parameters.radiusMeters", 32, 200_000),
|
|
88
|
+
blockSizeMeters: numberIn(source.blockSizeMeters, "city.parameters.blockSizeMeters", 16, 2_000),
|
|
89
|
+
roadWidthMeters: numberIn(source.roadWidthMeters, "city.parameters.roadWidthMeters", 3, 40),
|
|
90
|
+
landUseWeights: freeze({
|
|
91
|
+
residential: numberIn(weights.residential, "city.parameters.landUseWeights.residential", 0, 1_000_000),
|
|
92
|
+
commercial: numberIn(weights.commercial, "city.parameters.landUseWeights.commercial", 0, 1_000_000),
|
|
93
|
+
industrial: numberIn(weights.industrial, "city.parameters.landUseWeights.industrial", 0, 1_000_000),
|
|
94
|
+
civic: numberIn(weights.civic, "city.parameters.landUseWeights.civic", 0, 1_000_000),
|
|
95
|
+
park: numberIn(weights.park, "city.parameters.landUseWeights.park", 0, 1_000_000),
|
|
96
|
+
}),
|
|
97
|
+
});
|
|
98
|
+
if (result.radiusMeters < result.blockSizeMeters * 2 || result.roadWidthMeters > result.blockSizeMeters * 0.45
|
|
99
|
+
|| result.blockSizeMeters - result.roadWidthMeters < 8)
|
|
100
|
+
throw new RangeError("city.parameters 无法形成可用地块");
|
|
101
|
+
if (Object.values(result.landUseWeights).every((weight) => weight === 0))
|
|
102
|
+
throw new RangeError("city.parameters 至少需要一个正用途权重");
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
function parcelParameters(value) {
|
|
106
|
+
const source = exact(value, ["subdivision", "roadParcelMaxFaceAreaMeters"], "parcel.parameters");
|
|
107
|
+
if (source.subdivision !== 1 && source.subdivision !== 2 && source.subdivision !== 3)
|
|
108
|
+
throw new RangeError("parcel.parameters.subdivision 必须为 1、2 或 3");
|
|
109
|
+
return freeze({ subdivision: source.subdivision, roadParcelMaxFaceAreaMeters: numberIn(source.roadParcelMaxFaceAreaMeters, "parcel.parameters.roadParcelMaxFaceAreaMeters", 64, 2_000_000) });
|
|
110
|
+
}
|
|
111
|
+
function buildingParameters(value) {
|
|
112
|
+
const source = exact(value, ["maxBuildings", "fillScale"], "building.parameters");
|
|
113
|
+
if (source.maxBuildings !== 1 && source.maxBuildings !== 2 && source.maxBuildings !== 3 && source.maxBuildings !== 4)
|
|
114
|
+
throw new RangeError("building.parameters.maxBuildings 必须为 1..4 的整数");
|
|
115
|
+
return freeze({ maxBuildings: source.maxBuildings, fillScale: numberIn(source.fillScale, "building.parameters.fillScale", 0.25, 1) });
|
|
116
|
+
}
|
|
117
|
+
function interiorParameters(value) {
|
|
118
|
+
const source = exact(value, ["roomDensity", "corridorRatio"], "interior.parameters");
|
|
119
|
+
if (source.roomDensity !== 1 && source.roomDensity !== 2 && source.roomDensity !== 3)
|
|
120
|
+
throw new RangeError("interior.parameters.roomDensity 必须为 1、2 或 3");
|
|
121
|
+
return freeze({ roomDensity: source.roomDensity, corridorRatio: numberIn(source.corridorRatio, "interior.parameters.corridorRatio", 0.1, 0.35) });
|
|
122
|
+
}
|
|
123
|
+
function validateSelection(kind, value) {
|
|
124
|
+
const selection = exact(value, ["presetId", "revision", "parameters"], `${kind} 模板选择`);
|
|
125
|
+
const parameters = kind === "city" ? cityParameters(selection.parameters)
|
|
126
|
+
: kind === "parcel" ? parcelParameters(selection.parameters)
|
|
127
|
+
: kind === "building" ? buildingParameters(selection.parameters)
|
|
128
|
+
: interiorParameters(selection.parameters);
|
|
129
|
+
return freeze({ presetId: identifier(selection.presetId, `${kind}.presetId`), revision: revision(selection.revision, `${kind}.revision`), parameters });
|
|
130
|
+
}
|
|
131
|
+
function validatePreset(value) {
|
|
132
|
+
const source = exact(value, ["kind", "id", "revision", "label", "parameters"], "SpatialTemplatePresetV1");
|
|
133
|
+
if (source.kind !== "city" && source.kind !== "parcel" && source.kind !== "building" && source.kind !== "interior")
|
|
134
|
+
throw new TypeError("template.kind 非法");
|
|
135
|
+
if (typeof source.label !== "string" || source.label.trim().length === 0 || source.label.trim().length > 128)
|
|
136
|
+
throw new TypeError("template.label 必须是 1..128 字符的文本");
|
|
137
|
+
const selection = validateSelection(source.kind, { presetId: source.id, revision: source.revision, parameters: source.parameters });
|
|
138
|
+
return freeze({ kind: source.kind, id: selection.presetId, revision: selection.revision, label: source.label.trim(), parameters: selection.parameters });
|
|
139
|
+
}
|
|
140
|
+
export function validateSpatialTemplateLibrary(input) {
|
|
141
|
+
const source = exact(input, ["version", "presets"], "SpatialTemplateLibraryV1");
|
|
142
|
+
if (source.version !== SPATIAL_TEMPLATE_VERSION || !Array.isArray(source.presets) || source.presets.length > 128)
|
|
143
|
+
throw new RangeError("templates library version 或 preset 数量非法");
|
|
144
|
+
const presets = source.presets.map(validatePreset);
|
|
145
|
+
const ids = new Set();
|
|
146
|
+
for (const preset of presets) {
|
|
147
|
+
const key = `${preset.kind}:${preset.id}:${preset.revision}`;
|
|
148
|
+
if (ids.has(key))
|
|
149
|
+
throw new TypeError(`模板 revision 重复:${key}`);
|
|
150
|
+
ids.add(key);
|
|
151
|
+
}
|
|
152
|
+
return freeze({ version: SPATIAL_TEMPLATE_VERSION, presets: freeze(presets) });
|
|
153
|
+
}
|
|
154
|
+
/** 严格 decode 旧世界可省略的 templates 字段;一旦出现则不可降级或容忍旧版本。 */
|
|
155
|
+
export function validateSpatialTemplateConfiguration(input) {
|
|
156
|
+
if (!isRecord(input))
|
|
157
|
+
throw new TypeError("SpatialTemplateConfigurationV1 必须是对象");
|
|
158
|
+
const allowed = ["version", "city", "parcel", "building", "interior"];
|
|
159
|
+
const unknown = Object.keys(input).filter((key) => !allowed.includes(key));
|
|
160
|
+
if (unknown.length > 0)
|
|
161
|
+
throw new TypeError(`SpatialTemplateConfigurationV1 包含未知字段:${unknown.join(", ")}`);
|
|
162
|
+
if (!Object.hasOwn(input, "version"))
|
|
163
|
+
throw new TypeError("SpatialTemplateConfigurationV1 缺少字段:version");
|
|
164
|
+
const value = input;
|
|
165
|
+
if (value.version !== SPATIAL_TEMPLATE_VERSION) {
|
|
166
|
+
throw new RangeError(`templates.version 必须为 ${SPATIAL_TEMPLATE_VERSION}`);
|
|
167
|
+
}
|
|
168
|
+
const selected = ["city", "parcel", "building", "interior"].filter((kind) => Object.hasOwn(value, kind));
|
|
169
|
+
if (selected.length === 0)
|
|
170
|
+
throw new TypeError("SpatialTemplateConfigurationV1 至少需要一个 active selection");
|
|
171
|
+
return freeze({
|
|
172
|
+
version: SPATIAL_TEMPLATE_VERSION,
|
|
173
|
+
...(Object.hasOwn(value, "city") ? { city: validateSelection("city", value.city) } : {}),
|
|
174
|
+
...(Object.hasOwn(value, "parcel") ? { parcel: validateSelection("parcel", value.parcel) } : {}),
|
|
175
|
+
...(Object.hasOwn(value, "building") ? { building: validateSelection("building", value.building) } : {}),
|
|
176
|
+
...(Object.hasOwn(value, "interior") ? { interior: validateSelection("interior", value.interior) } : {}),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/** 未选择 parcel 时返回 undefined 以保留 road-parcels 的既有默认;选择后两项参数都实际生效。 */
|
|
180
|
+
export function resolveRoadParcelTemplateSettings(templates) {
|
|
181
|
+
if (templates === undefined)
|
|
182
|
+
return undefined;
|
|
183
|
+
const parcel = validateSpatialTemplateConfiguration(templates).parcel;
|
|
184
|
+
if (parcel === undefined)
|
|
185
|
+
return undefined;
|
|
186
|
+
return freeze({
|
|
187
|
+
// road-parcels 的 minimumArea 为 36;钳制避免合法模板生成非法 settings。
|
|
188
|
+
maxFaceAreaMeters: Math.max(36, parcel.parameters.roadParcelMaxFaceAreaMeters / (parcel.parameters.subdivision ** 2)),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/** 用已发布 preset 生成可保存的完整选择快照,调用端无需复制默认参数。 */
|
|
192
|
+
export function createSpatialTemplateConfiguration(kind, preset = presetFor(kind)) {
|
|
193
|
+
const validated = validatePreset(preset);
|
|
194
|
+
if (validated.kind !== kind)
|
|
195
|
+
throw new TypeError(`template kind 不匹配:${validated.kind} != ${kind}`);
|
|
196
|
+
return validateSpatialTemplateConfiguration({
|
|
197
|
+
version: SPATIAL_TEMPLATE_VERSION,
|
|
198
|
+
[kind]: { presetId: validated.id, revision: validated.revision, parameters: validated.parameters },
|
|
199
|
+
});
|
|
200
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.react-flow{direction:ltr}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1;cursor:-webkit-grab;cursor:grab}.react-flow__pane.selection{cursor:pointer}.react-flow__pane.dragging{cursor:-webkit-grabbing;cursor:grabbing}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow .react-flow__edges{pointer-events:none;overflow:visible}.react-flow__edge-path,.react-flow__connection-path{stroke:#b1b1b7;stroke-width:1;fill:none}.react-flow__edge{pointer-events:visibleStroke;cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;-webkit-animation:dashdraw .5s linear infinite;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;-webkit-animation:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge:focus .react-flow__edge-path,.react-flow__edge:focus-visible .react-flow__edge-path{stroke:#555}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge-textbg{fill:#fff}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;-webkit-animation:dashdraw .5s linear infinite;animation:dashdraw .5s linear infinite}.react-flow__connectionline{z-index:1001}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:-webkit-grab;cursor:grab}.react-flow__node.dragging{cursor:-webkit-grabbing;cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:-webkit-grab;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background:#1a192b;border:1px solid white;border-radius:100%}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:-4px;transform:translate(-50%)}.react-flow__handle-top{left:50%;top:-4px;transform:translate(-50%)}.react-flow__handle-left{top:50%;left:-4px;transform:translateY(-50%)}.react-flow__handle-right{right:-4px;top:50%;transform:translateY(-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.center{left:50%;transform:translate(-50%)}.react-flow__attribution{font-size:10px;background:#ffffff80;padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@-webkit-keyframes dashdraw{0%{stroke-dashoffset:10}}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-default,.react-flow__node-input,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:3px;width:150px;font-size:12px;color:#222;text-align:center;border-width:1px;border-style:solid;border-color:#1a192b;background-color:#fff}.react-flow__node-default.selectable:hover,.react-flow__node-input.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:0 1px 4px 1px #00000014}.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:0 0 0 .5px #1a192b}.react-flow__node-group{background-color:#f0f0f040}.react-flow__nodesselection-rect,.react-flow__selection{background:#0059dc14;border:1px dotted rgba(0,89,220,.8)}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls{box-shadow:0 0 2px 1px #00000014}.react-flow__controls-button{border:none;background:#fefefe;border-bottom:1px solid #eee;box-sizing:content-box;display:flex;justify-content:center;align-items:center;width:16px;height:16px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:5px}.react-flow__controls-button:hover{background:#f4f4f4}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__minimap{background-color:#fff}.react-flow__minimap svg{display:block}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:4px;height:4px;border:1px solid #fff;border-radius:1px;background-color:#3367d9;transform:translate(-50%,-50%)}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:#3367d9;border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.trigger-blueprint{--trigger-bg:var(--bg);--trigger-panel:var(--surface);--trigger-line:var(--line);--trigger-muted:var(--muted);--trigger-text:var(--text);--trigger-accent:var(--accent);--trigger-danger:var(--red);color:var(--trigger-text);display:flex;flex-direction:column;gap:14px;min-height:0}.trigger-blueprint button,.trigger-blueprint input,.trigger-blueprint select{font:inherit}.trigger-blueprint button{border:1px solid var(--trigger-line);border-radius:7px;background:#262626;color:var(--trigger-text);padding:8px 12px;cursor:pointer}.trigger-blueprint button:hover:not(:disabled){border-color:#6a6a6a;background:#2d2d2d}.trigger-blueprint button:disabled{cursor:not-allowed;opacity:.48}.trigger-blueprint button.primary{border-color:var(--trigger-accent);background:var(--trigger-accent);color:#071409;font-weight:700}.trigger-blueprint__toolbar{display:flex;align-items:center;justify-content:space-between;gap:18px}.trigger-blueprint__toolbar p{margin:0 0 3px;color:var(--trigger-accent);font-size:11px;font-weight:800;letter-spacing:.12em;text-transform:uppercase}.trigger-blueprint__toolbar h2{margin:0;font-size:24px}.trigger-blueprint__toolbar span{display:block;margin-top:4px;color:var(--trigger-muted);font-size:12px}.trigger-blueprint__actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end}.trigger-palette{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:10px 12px;border:1px solid var(--trigger-line);border-radius:9px;background:var(--trigger-panel)}.trigger-palette>span{color:var(--trigger-muted);font-size:12px}.trigger-palette .preset{margin-left:auto;border-color:#47704d;color:#bcecc4}.trigger-blueprint__body{display:grid;grid-template-columns:minmax(0,1fr) 300px;min-height:490px;border:1px solid var(--trigger-line);border-radius:10px;overflow:hidden;background:var(--trigger-bg)}.trigger-canvas{height:490px;min-width:0;background:var(--trigger-bg)}.trigger-canvas .react-flow__pane{cursor:grab}.trigger-canvas .react-flow__pane:active{cursor:grabbing}.trigger-canvas .react-flow__node{width:210px;border:1px solid #505050;border-radius:9px;background:#222;box-shadow:0 8px 22px #00000047;padding:0;color:var(--trigger-text)}.trigger-canvas .react-flow__node.selected{border-color:var(--trigger-accent);box-shadow:0 0 0 1px #32d74b3d,0 8px 22px #0000004d}.trigger-canvas .react-flow__handle{width:8px;height:8px;border:2px solid var(--trigger-bg);background:#878787}.trigger-canvas .react-flow__node.selected .react-flow__handle{background:var(--trigger-accent)}.trigger-canvas .react-flow__edge-path{stroke:#7b7b7b;stroke-width:1.7}.trigger-canvas .react-flow__edge.selected .react-flow__edge-path{stroke:var(--trigger-accent)}.trigger-canvas .react-flow__background pattern circle{fill:#3b3b3b}.trigger-canvas .react-flow__controls{border:1px solid var(--trigger-line);box-shadow:none}.trigger-canvas .react-flow__controls-button{border-bottom-color:#444;background:#252525;color:#ddd}.trigger-canvas .react-flow__controls-button svg{fill:currentColor}.trigger-node-card{display:flex;min-height:82px;flex-direction:column;gap:5px;padding:12px 14px;text-align:left;border-left:3px solid #8d8d8d;border-radius:8px}.trigger-node-card--event{border-left-color:#48a7ff}.trigger-node-card--condition{border-left-color:#f0b54a}.trigger-node-card--effect{border-left-color:var(--trigger-accent)}.trigger-node-card--presentation{border-left-color:#b985ff}.trigger-node-card--value{border-left-color:#53d6cf}.trigger-blueprint--canvas .trigger-flow-node--value{border-color:#397f7a}.trigger-blueprint--canvas .trigger-data-edge .react-flow__edge-path{stroke:#53d6cf;stroke-dasharray:5 4}.trigger-blueprint--canvas .trigger-data-edge .react-flow__edge-text{fill:#bcefeb;font-size:10px}.trigger-blueprint--canvas .trigger-data-edge .react-flow__edge-textbg{fill:#252525;fill-opacity:.96}.trigger-node-card__kind{display:flex;align-items:center;gap:6px;color:#bdbdbd;font-size:10px;font-weight:800;letter-spacing:.08em}.trigger-node-card__kind svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:1.7}.trigger-node-card strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px}.trigger-node-card small{overflow:hidden;color:#888;text-overflow:ellipsis;white-space:nowrap}.trigger-node-card em{color:#d9b66d;font-size:10px;font-style:normal}.trigger-inspector{display:flex;flex-direction:column;gap:13px;padding:16px;border-left:1px solid var(--trigger-line);background:var(--trigger-panel);overflow:auto}.trigger-inspector header{display:flex;flex-direction:column;gap:5px;padding-bottom:11px;border-bottom:1px solid var(--trigger-line)}.trigger-inspector header div{display:flex;align-items:baseline;gap:8px}.trigger-inspector header span{color:var(--trigger-accent);font-size:11px;font-weight:800}.trigger-inspector header strong{font-size:16px}.trigger-inspector header code{overflow:hidden;color:#909090;text-overflow:ellipsis;white-space:nowrap;font-size:11px}.trigger-inspector label,.trigger-value-field label,.trigger-simulation label{display:flex;flex-direction:column;gap:6px;color:#ccc;font-size:12px}.trigger-inspector input,.trigger-inspector select,.trigger-simulation input,.trigger-simulation select{min-width:0;border:1px solid var(--trigger-line);border-radius:6px;outline:none;background:var(--trigger-bg);color:#f1f1f1;padding:8px}.trigger-inspector input:focus,.trigger-inspector select:focus,.trigger-simulation input:focus,.trigger-simulation select:focus{border-color:var(--trigger-accent)}.trigger-inspector label small{color:#858585;line-height:1.4}.trigger-inspector .trigger-check{flex-direction:row;align-items:center}.trigger-check input{width:16px;height:16px;accent-color:var(--trigger-accent)}.trigger-value-field{display:grid;grid-template-columns:1fr 1fr;gap:9px}.trigger-limit{border:1px solid #665534;border-radius:7px;background:#29251d;padding:10px;color:#d9c28f}.trigger-limit strong{font-size:12px}.trigger-limit p{margin:5px 0 0;font-size:11px;line-height:1.45}.trigger-advanced{border-top:1px solid #393939;padding-top:9px;color:#999;font-size:11px}.trigger-advanced summary{margin-bottom:9px;cursor:pointer}.trigger-technical{color:#999;font-size:11px}.trigger-technical summary{cursor:pointer}.trigger-technical pre{max-height:230px;overflow:auto;border:1px solid var(--trigger-line);border-radius:6px;background:var(--trigger-bg);padding:9px;color:#b8b8b8;font:11px/1.5 ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre-wrap;word-break:break-word}.trigger-danger{margin-top:auto!important;border-color:#713d43!important;color:#ffadb4!important}.trigger-inspector--empty{justify-content:center;color:#999}.trigger-inspector--empty strong{color:#ddd;font-size:16px}.trigger-inspector--empty p{line-height:1.7}.trigger-validation{border:1px solid var(--trigger-line);border-radius:8px;background:var(--trigger-panel);padding:10px 12px;color:#aaa;font-size:12px}.trigger-validation.is-ok{border-color:#3c6b44;color:#a9eab4}.trigger-validation.is-error{border-color:#713d43;color:#ffb1b7}.trigger-validation strong{display:block;margin-bottom:5px}.trigger-validation ul{margin:5px 0 0;padding-left:20px}.trigger-simulation,.trigger-technical--document{border:1px solid var(--trigger-line);border-radius:8px;background:var(--trigger-panel);padding:11px 13px}.trigger-simulation>summary,.trigger-technical--document>summary{cursor:pointer;font-weight:700}.trigger-simulation__form{display:grid;grid-template-columns:repeat(4,minmax(0,1fr)) auto;align-items:end;gap:9px;margin-top:12px}.trigger-simulation__form button{height:35px}.trigger-muted{margin:9px 0 0;color:#888;font-size:12px}.trigger-result{margin-top:12px;color:#b5eabb;font-size:12px}.trigger-result details{margin-top:7px}.trigger-result pre{max-height:220px;overflow:auto;border:1px solid var(--trigger-line);border-radius:6px;background:var(--trigger-bg);padding:9px;color:#bbb;font:11px/1.5 ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre-wrap}.trigger-empty{display:flex;min-height:430px;flex-direction:column;align-items:center;justify-content:center;border:1px solid var(--trigger-line);border-radius:10px;background:var(--trigger-bg);text-align:center}.trigger-empty strong{font-size:18px}.trigger-empty p{max-width:590px;color:#999;line-height:1.65}.trigger-empty button{border-color:#47704d;color:#bcecc4}@media (max-width:980px){.trigger-blueprint__toolbar{align-items:flex-start;flex-direction:column}.trigger-blueprint__actions{justify-content:flex-start}.trigger-blueprint__body{grid-template-columns:1fr}.trigger-inspector{min-height:260px;border-top:1px solid var(--trigger-line);border-left:0}.trigger-simulation__form{grid-template-columns:1fr 1fr}.trigger-simulation__form button{grid-column:1/-1}.trigger-palette .preset{margin-left:0}}.trigger-blueprint--canvas{position:relative;display:block;width:100%;height:100%;min-height:520px;overflow:hidden;background:var(--trigger-bg)}.trigger-canvas-toolbar{position:absolute;z-index:8;top:0;right:0;left:0;display:flex;align-items:center;gap:14px;height:56px;padding:0 14px;border-bottom:1px solid var(--trigger-line);background:#1c1c1c;box-shadow:0 4px 16px #00000047}.trigger-canvas-title{display:flex;align-items:baseline;gap:9px;white-space:nowrap}.trigger-canvas-title h1{margin:0;font-size:15px}.trigger-canvas-title span{color:#838383;font-size:11px}.trigger-board-tabs{display:flex;min-width:0;align-items:center;gap:3px;overflow:auto}.trigger-board-tabs button{flex:0 0 auto;border-color:transparent;background:transparent;padding:6px 9px;color:#a5a5a5;font-size:12px}.trigger-board-tabs button.active{border-color:#3c6d44;background:#253529;color:#c9f5d0}.trigger-board-tabs button:last-child{border-left-color:#3b3b3b;border-radius:0;margin-left:3px;color:#d0d0d0}.trigger-canvas-actions{display:flex;align-items:center;gap:5px;margin-left:auto}.trigger-canvas-actions button{padding:6px 9px;font-size:12px}.trigger-blueprint--canvas>.trigger-canvas{position:absolute;inset:56px 0 0;height:auto;background:var(--trigger-bg)}.trigger-blueprint--canvas .react-flow__node{width:248px;border-radius:3px;background:var(--trigger-panel);box-shadow:4px 5px #00000052;transition:opacity .12s ease,filter .12s ease}.trigger-blueprint--canvas .trigger-node-card{border-radius:2px}.trigger-blueprint--canvas .react-flow__edge-path{stroke:#9a9a9a;stroke-width:2}.trigger-blueprint--canvas .react-flow__edge.selected .react-flow__edge-path{stroke:var(--trigger-accent);stroke-width:2.4}.trigger-node-ports{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:9px;margin:7px -8px -5px;padding-top:7px;border-top:1px solid #373737}.trigger-node-ports__right{text-align:right}.trigger-ports{display:grid;gap:5px}.trigger-port{display:flex;min-width:0;align-items:center;gap:5px;color:#aaa;font-size:10px;line-height:1}.trigger-ports--output .trigger-port{justify-content:flex-end}.trigger-port small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.trigger-port--control{color:#b9c5c1}.trigger-port--number,.trigger-port--int32,.trigger-port--world_time,.trigger-port--real_timestamp,.trigger-port--duration{color:#ef626c}.trigger-port--boolean{color:#f39a45}.trigger-port--string,.trigger-port--string_list{color:#ec7ab1}.trigger-port--spatial_ref{color:#58c8b7}.trigger-port--object_ref{color:#48a7ff;background:linear-gradient(90deg,#48a7ff 0 50%,#b985ff 50% 100%);border-color:#b985ff}.trigger-port--int32{border-radius:1px}.trigger-port--boolean{border-radius:1px;transform:rotate(45deg)}.trigger-port--string,.trigger-port--string_list{background:transparent}.trigger-port--node-ref{color:#48a7ff;background:transparent;border-color:#48a7ff}.trigger-port--edge-ref{color:#b985ff;background:transparent;border-color:#b985ff}.trigger-port--node_or_edge-ref{color:#48a7ff;background:linear-gradient(90deg,#48a7ff 0 50%,#b985ff 50% 100%);border-color:#b985ff}.trigger-node-ports .react-flow__handle{position:static;display:block;flex:0 0 auto;width:10px;height:10px;margin:0;border:2px solid var(--trigger-panel);transform:none;background:currentColor}.trigger-node-ports .react-flow__handle.trigger-port--string,.trigger-node-ports .react-flow__handle.trigger-port--string_list,.trigger-node-ports .react-flow__handle.trigger-port--node-ref,.trigger-node-ports .react-flow__handle.trigger-port--edge-ref{border-color:currentColor;background:var(--trigger-panel)}.trigger-node-ports .react-flow__handle.trigger-port--object_ref,.trigger-node-ports .react-flow__handle.trigger-port--node_or_edge-ref{border-color:#9073ff;background:linear-gradient(90deg,#48a7ff 0 50%,#b985ff 50% 100%)}.trigger-node-ports .react-flow__handle.trigger-port--boolean{border-radius:1px;transform:rotate(45deg)}.trigger-node-ports .react-flow__handle.connecting,.trigger-node-ports .react-flow__handle.valid{outline:2px solid #d9f7df;outline-offset:2px;filter:brightness(1.35);box-shadow:0 0 10px currentColor}.trigger-blueprint--canvas .react-flow__node.is-incompatible{opacity:.32;filter:saturate(.55)}.trigger-reactflow:has(.react-flow__handle.connectingfrom) .react-flow__node{opacity:.32;filter:saturate(.55)}.trigger-reactflow:has(.react-flow__handle.connectingfrom) .react-flow__node:has(.react-flow__handle.connectingfrom),.trigger-reactflow:has(.react-flow__handle.connectingfrom) .react-flow__node:has(.react-flow__handle.valid){opacity:1;filter:none}.trigger-reactflow:has(.react-flow__handle.connectingfrom) .react-flow__edge{opacity:.2}.trigger-reference-hints{display:flex;align-items:center;gap:5px;margin-top:2px}.trigger-reference-hint{border:1px solid currentColor;border-radius:50%;padding:1px 4px;font-size:9px;line-height:1}.trigger-reference-hint--node{color:#48a7ff}.trigger-reference-hint--edge{color:#b985ff}.trigger-reference-hints small{color:#777;font-size:9px}.trigger-canvas-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:8px;color:#ddd}.trigger-canvas-empty span{color:#858585;font-size:12px}.trigger-context-menu{position:absolute;z-index:30;width:238px;border:1px solid #4b4b4b;background:var(--trigger-panel);padding:5px;box-shadow:8px 10px 28px #00000080}.trigger-context-menu button{display:flex;width:100%;align-items:center;border:0;border-radius:2px;background:transparent;padding:8px 9px;text-align:left;font-size:12px}.trigger-context-menu button:hover{background:#2f3d32}.trigger-context-menu button:focus-visible{outline:1px solid #32d551;outline-offset:-2px;background:#29382c}.trigger-context-menu__entry,.trigger-context-menu__group{gap:8px}.trigger-context-menu__group .trigger-context-menu__chevron{margin-left:auto}.trigger-context-menu__glyph{width:14px;height:14px;flex:0 0 auto;fill:none;stroke:#a8a8a8;stroke-width:1.25}.trigger-context-menu button:hover .trigger-context-menu__glyph,.trigger-context-menu button:focus-visible .trigger-context-menu__glyph{stroke:#d8f5dc}.trigger-context-group{position:relative}.trigger-context-submenu{position:absolute;z-index:31;top:-5px;left:calc(100% + 5px);display:none;width:238px;border:1px solid #4b4b4b;background:var(--trigger-panel);padding:5px;box-shadow:8px 10px 28px #00000080}.trigger-context-group[data-active=true]>.trigger-context-submenu{display:block}.trigger-context-separator{height:1px;margin:4px;background:#3c3c3c}.trigger-context-menu__search{display:flex;align-items:center;gap:7px;margin:2px 3px 7px;border:1px solid #525252;background:#191919;padding:6px 8px}.trigger-context-menu__search:focus-within{border-color:#32d551}.trigger-context-menu__search svg{width:14px;height:14px;fill:none;stroke:#aaa;stroke-width:1.4}.trigger-context-menu__search input{width:100%;min-width:0;border:0;outline:0;background:transparent;color:var(--trigger-text);font:inherit}.trigger-context-menu__search input::placeholder{color:#858585}.trigger-context-search-results{display:flex;max-height:310px;flex-direction:column;overflow:auto}.trigger-context-search-results p{margin:7px 9px;color:#999;font-size:12px}.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;clip-path:inset(50%)}.trigger-context-menu button.danger{color:#ff9da6}.trigger-context-menu button.danger:hover{background:#42272a}.trigger-context-menu--submenu-left .trigger-context-submenu{right:calc(100% + 5px);left:auto}.trigger-context-submenu{max-height:calc(100vh - 72px);overflow-y:auto}.trigger-context-menu__glyph[class*=trigger-operator-icon--],.trigger-context-menu button:hover .trigger-context-menu__glyph[class*=trigger-operator-icon--],.trigger-context-menu button:focus-visible .trigger-context-menu__glyph[class*=trigger-operator-icon--]{stroke:currentColor}.trigger-operator-icon--action{color:#4da3ff}.trigger-operator-icon--read{color:#5fcf89}.trigger-operator-icon--source{color:#f17ead}.trigger-operator-icon--logic{color:#f2a344}.trigger-node-card__kind .trigger-context-menu__glyph{width:13px;height:13px;fill:none;stroke-width:1.7}.trigger-floating-panel{position:absolute;z-index:20;border:1px solid var(--trigger-line);background:var(--trigger-panel);box-shadow:9px 12px 32px #00000080}.trigger-floating-panel>header{display:flex;align-items:center;justify-content:space-between;min-height:40px;padding:0 12px;border-bottom:1px solid var(--trigger-line);background:#252525}.trigger-floating-panel>header button{border:0;background:transparent;padding:5px;color:#aaa;font-size:11px}.trigger-board-manager{top:66px;left:14px;width:330px;padding-bottom:12px}.trigger-board-manager>p{margin:11px 12px;color:#999;font-size:11px;line-height:1.5}.trigger-board-row,.trigger-board-create{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;padding:5px 12px}.trigger-board-row input,.trigger-board-create input,.trigger-board-assignment select{min-width:0;border:1px solid var(--trigger-line);border-radius:3px;background:var(--trigger-bg);color:var(--trigger-text);padding:7px 8px}.trigger-board-row button,.trigger-board-create button{padding:6px 8px;font-size:11px}.trigger-board-row button{border-color:#683b40;color:#ffb1b7}.trigger-node-panel{top:66px;right:14px;bottom:14px;width:310px;overflow:auto}.trigger-node-panel>.trigger-inspector{min-height:calc(100% - 52px);border:0;background:transparent;padding-top:38px}.trigger-panel-close{position:absolute;z-index:2;top:7px;right:8px;border:0!important;background:transparent!important;color:#aaa!important;font-size:17px!important}.trigger-board-assignment{display:flex;flex-direction:column;gap:6px;margin:0 16px 16px;color:#bbb;font-size:12px}.trigger-validation-panel{top:66px;right:14px;width:360px;max-height:calc(100% - 80px);overflow:auto;padding-bottom:12px}.trigger-validation-panel>p,.trigger-validation-panel>ul{margin:12px;color:#aaa;font-size:12px;line-height:1.5}.trigger-validation-panel.is-ok{border-color:#3c6b44}.trigger-validation-panel.is-error{border-color:#713d43}.trigger-validation-panel .trigger-technical{margin:12px}.trigger-simulation-panel{right:14px;bottom:14px;left:14px}.trigger-simulation-panel>.trigger-simulation{border:0;border-radius:0;background:transparent}.trigger-simulation-panel>.trigger-simulation>summary{display:none}.trigger-cross-board-note{position:absolute;z-index:7;bottom:14px;left:14px;border:1px solid var(--trigger-line);background:var(--trigger-panel);padding:7px 10px;color:#aaa;font-size:11px;box-shadow:4px 5px 16px #00000059}.trigger-inspector textarea{min-height:112px;resize:vertical;white-space:pre-wrap}.trigger-spatial-field{display:grid;gap:8px}.trigger-inline-actions{display:flex;flex-wrap:wrap;gap:8px}.trigger-inline-actions button{flex:1 1 auto}@media (max-width:1050px){.trigger-canvas-title span{display:none}.trigger-board-tabs{max-width:38vw}.trigger-canvas-actions button:nth-child(-n+2){display:none}.trigger-node-panel{width:min(340px,88vw)}.trigger-simulation__form{grid-template-columns:1fr 1fr}.trigger-simulation__form button{grid-column:1/-1}}.trigger-node-ports .react-flow__handle.is-compatible{outline:2px solid #d9f7df;outline-offset:2px;filter:brightness(1.35);box-shadow:0 0 10px currentColor}.trigger-reactflow:has(.react-flow__handle.connectingfrom) .react-flow__node:has(.react-flow__handle.is-compatible){opacity:1;filter:none}.trigger-node-ports .react-flow__handle.trigger-port--string,.trigger-node-ports .react-flow__handle.trigger-port--string_list,.trigger-node-ports .react-flow__handle.trigger-port--node-ref,.trigger-node-ports .react-flow__handle.trigger-port--edge-ref{border:2px solid currentColor!important;background:var(--trigger-panel)!important}.trigger-node-ports .react-flow__handle.trigger-port--object_ref,.trigger-node-ports .react-flow__handle.trigger-port--node_or_edge-ref{border:2px solid #9073ff!important;background:linear-gradient(90deg,#48a7ff 0 50%,#b985ff 50% 100%)!important}
|