@things-factory/headless-twin 10.0.12 โ 10.0.13
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/dist-server/engine/canonical-ingest.d.ts +57 -2
- package/dist-server/engine/canonical-ingest.js +43 -2
- package/dist-server/engine/canonical-ingest.js.map +1 -1
- package/dist-server/engine/command-routing.js +1 -1
- package/dist-server/engine/command-routing.js.map +1 -1
- package/dist-server/engine/index.d.ts +3 -0
- package/dist-server/engine/index.js +4 -0
- package/dist-server/engine/index.js.map +1 -1
- package/dist-server/engine/ingest-health.d.ts +335 -0
- package/dist-server/engine/ingest-health.js +434 -0
- package/dist-server/engine/ingest-health.js.map +1 -0
- package/dist-server/engine/integration-coverage.d.ts +76 -0
- package/dist-server/engine/integration-coverage.js +73 -0
- package/dist-server/engine/integration-coverage.js.map +1 -0
- package/dist-server/engine/integration-probes.d.ts +65 -0
- package/dist-server/engine/integration-probes.js +100 -0
- package/dist-server/engine/integration-probes.js.map +1 -0
- package/dist-server/engine/integration-runner.d.ts +45 -0
- package/dist-server/engine/integration-runner.js +59 -0
- package/dist-server/engine/integration-runner.js.map +1 -0
- package/dist-server/engine/integration-target-profile.d.ts +57 -0
- package/dist-server/engine/integration-target-profile.js +79 -0
- package/dist-server/engine/integration-target-profile.js.map +1 -0
- package/dist-server/engine/kpi-fold.d.ts +27 -0
- package/dist-server/engine/kpi-fold.js +47 -4
- package/dist-server/engine/kpi-fold.js.map +1 -1
- package/dist-server/engine/kpi-query.js +128 -14
- package/dist-server/engine/kpi-query.js.map +1 -1
- package/dist-server/engine/live-feed-registry.js +2 -16
- package/dist-server/engine/live-feed-registry.js.map +1 -1
- package/dist-server/engine/load-meter.d.ts +1 -1
- package/dist-server/engine/load-meter.js +12 -3
- package/dist-server/engine/load-meter.js.map +1 -1
- package/dist-server/engine/log.d.ts +18 -0
- package/dist-server/engine/log.js +80 -0
- package/dist-server/engine/log.js.map +1 -0
- package/dist-server/engine/loop-lag.d.ts +54 -0
- package/dist-server/engine/loop-lag.js +87 -0
- package/dist-server/engine/loop-lag.js.map +1 -0
- package/dist-server/engine/model-gap.d.ts +108 -0
- package/dist-server/engine/model-gap.js +95 -0
- package/dist-server/engine/model-gap.js.map +1 -0
- package/dist-server/engine/restart-policy.d.ts +3 -3
- package/dist-server/engine/restart-policy.js +4 -4
- package/dist-server/engine/restart-policy.js.map +1 -1
- package/dist-server/engine/runtime-key.js +1 -1
- package/dist-server/engine/runtime-key.js.map +1 -1
- package/dist-server/engine/stage-path.d.ts +83 -0
- package/dist-server/engine/stage-path.js +118 -0
- package/dist-server/engine/stage-path.js.map +1 -0
- package/dist-server/engine/twin-engine.d.ts +352 -16
- package/dist-server/engine/twin-engine.js +1037 -166
- package/dist-server/engine/twin-engine.js.map +1 -1
- package/dist-server/index.js +34 -2
- package/dist-server/index.js.map +1 -1
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.d.ts +5 -0
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js +58 -0
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js.map +1 -0
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.d.ts +5 -0
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js +55 -0
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js.map +1 -0
- package/dist-server/migrations/index.js +7 -1
- package/dist-server/migrations/index.js.map +1 -1
- package/dist-server/service/index.d.ts +5 -2
- package/dist-server/service/index.js +18 -7
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/reference/discovery-result.d.ts +1 -1
- package/dist-server/service/reference/discovery-result.js +1 -1
- package/dist-server/service/reference/discovery-result.js.map +1 -1
- package/dist-server/service/reference/index.d.ts +4 -1
- package/dist-server/service/reference/index.js +6 -1
- package/dist-server/service/reference/index.js.map +1 -1
- package/dist-server/service/reference/reference-adapter.d.ts +184 -3
- package/dist-server/service/reference/reference-adapter.js +28 -4
- package/dist-server/service/reference/reference-adapter.js.map +1 -1
- package/dist-server/service/reference/reference-assessment.d.ts +68 -0
- package/dist-server/service/reference/reference-assessment.js +136 -0
- package/dist-server/service/reference/reference-assessment.js.map +1 -0
- package/dist-server/service/reference/reference-live.d.ts +12 -1
- package/dist-server/service/reference/reference-live.js +116 -11
- package/dist-server/service/reference/reference-live.js.map +1 -1
- package/dist-server/service/reference/reference-master.d.ts +47 -1
- package/dist-server/service/reference/reference-master.js +34 -4
- package/dist-server/service/reference/reference-master.js.map +1 -1
- package/dist-server/service/reference/reference-probe.d.ts +92 -0
- package/dist-server/service/reference/reference-probe.js +186 -0
- package/dist-server/service/reference/reference-probe.js.map +1 -0
- package/dist-server/service/reference/reference-progress-subscription.d.ts +17 -0
- package/dist-server/service/reference/reference-progress-subscription.js +94 -0
- package/dist-server/service/reference/reference-progress-subscription.js.map +1 -0
- package/dist-server/service/reference/reference-progress.d.ts +38 -0
- package/dist-server/service/reference/reference-progress.js +71 -0
- package/dist-server/service/reference/reference-progress.js.map +1 -0
- package/dist-server/service/reference/reference-resolver.js +210 -43
- package/dist-server/service/reference/reference-resolver.js.map +1 -1
- package/dist-server/service/reference/twin-reference.d.ts +32 -0
- package/dist-server/service/reference/twin-reference.js +10 -0
- package/dist-server/service/reference/twin-reference.js.map +1 -1
- package/dist-server/service/twin-control/twin-control-mutation.js +4 -3
- package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
- package/dist-server/service/twin-event/journal-count.d.ts +21 -0
- package/dist-server/service/twin-event/journal-count.js +26 -0
- package/dist-server/service/twin-event/journal-count.js.map +1 -0
- package/dist-server/service/twin-event/twin-event-keys.d.ts +9 -0
- package/dist-server/service/twin-event/twin-event-keys.js +15 -18
- package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
- package/dist-server/service/twin-event/twin-event-type.d.ts +3 -1
- package/dist-server/service/twin-event/twin-event-type.js +18 -1
- package/dist-server/service/twin-event/twin-event-type.js.map +1 -1
- package/dist-server/service/twin-event/twin-event.d.ts +1 -0
- package/dist-server/service/twin-event/twin-event.js +9 -1
- package/dist-server/service/twin-event/twin-event.js.map +1 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js +2 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
- package/dist-server/service/twin-ingest-window/index.d.ts +5 -0
- package/dist-server/service/twin-ingest-window/index.js +10 -0
- package/dist-server/service/twin-ingest-window/index.js.map +1 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.d.ts +12 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js +123 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js.map +1 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.d.ts +1 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js +51 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js.map +1 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window.d.ts +16 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window.js +108 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window.js.map +1 -0
- package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
- package/dist-server/service/twin-journal/twin-journal-query.js +58 -5
- package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +14 -0
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +72 -2
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.d.ts +1 -0
- package/dist-server/service/twin-metrics/twin-metrics-query.js +78 -3
- package/dist-server/service/twin-metrics/twin-metrics-query.js.map +1 -1
- package/dist-server/service/twin-model/axis-journal-evidence.d.ts +2 -0
- package/dist-server/service/twin-model/axis-journal-evidence.js +89 -0
- package/dist-server/service/twin-model/axis-journal-evidence.js.map +1 -0
- package/dist-server/service/twin-model/epcis-coverage.d.ts +1 -1
- package/dist-server/service/twin-model/epcis-coverage.js +19 -7
- package/dist-server/service/twin-model/epcis-coverage.js.map +1 -1
- package/dist-server/service/twin-model/iec61850-coverage.d.ts +1 -1
- package/dist-server/service/twin-model/iec61850-coverage.js +18 -7
- package/dist-server/service/twin-model/iec61850-coverage.js.map +1 -1
- package/dist-server/service/twin-model/isa95-coverage.d.ts +14 -0
- package/dist-server/service/twin-model/isa95-coverage.js +23 -9
- package/dist-server/service/twin-model/isa95-coverage.js.map +1 -1
- package/dist-server/service/twin-model/item-ref.d.ts +24 -0
- package/dist-server/service/twin-model/item-ref.js +88 -0
- package/dist-server/service/twin-model/item-ref.js.map +1 -0
- package/dist-server/service/twin-model/name-index.d.ts +36 -0
- package/dist-server/service/twin-model/name-index.js +116 -0
- package/dist-server/service/twin-model/name-index.js.map +1 -0
- package/dist-server/service/twin-model/project-structure.js +1 -1
- package/dist-server/service/twin-model/project-structure.js.map +1 -1
- package/dist-server/service/twin-model/status-tally.d.ts +9 -0
- package/dist-server/service/twin-model/status-tally.js +37 -0
- package/dist-server/service/twin-model/status-tally.js.map +1 -0
- package/dist-server/service/twin-model/twin-lineage-query.js +40 -12
- package/dist-server/service/twin-model/twin-lineage-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-item-query.js +38 -39
- package/dist-server/service/twin-model/twin-model-item-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-query.js +156 -4
- package/dist-server/service/twin-model/twin-model-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-tree-query.js +7 -0
- package/dist-server/service/twin-model/twin-model-tree-query.js.map +1 -1
- package/dist-server/service/twin-readiness/index.d.ts +2 -0
- package/dist-server/service/twin-readiness/index.js +6 -0
- package/dist-server/service/twin-readiness/index.js.map +1 -0
- package/dist-server/service/twin-readiness/twin-readiness-query.d.ts +3 -0
- package/dist-server/service/twin-readiness/twin-readiness-query.js +103 -0
- package/dist-server/service/twin-readiness/twin-readiness-query.js.map +1 -0
- package/dist-server/service/twin-space/twin-space-resolver.d.ts +2 -2
- package/dist-server/service/twin-space/twin-space-resolver.js +5 -4
- package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
- package/dist-shared/entity-delta.d.ts +23 -3
- package/dist-shared/entity-delta.js +12 -8
- package/dist-shared/entity-delta.js.map +1 -1
- package/dist-shared/kpi-broadcast.js +1 -1
- package/dist-shared/kpi-broadcast.js.map +1 -1
- package/dist-shared/touched-items.d.ts +7 -0
- package/dist-shared/touched-items.js +80 -0
- package/dist-shared/touched-items.js.map +1 -0
- package/package.json +7 -7
- package/server/engine/canonical-ingest.ts +92 -7
- package/server/engine/command-routing.ts +1 -1
- package/server/engine/index.ts +4 -0
- package/server/engine/ingest-health.ts +704 -0
- package/server/engine/integration-coverage.ts +147 -0
- package/server/engine/integration-probes.ts +144 -0
- package/server/engine/integration-runner.ts +95 -0
- package/server/engine/integration-target-profile.ts +103 -0
- package/server/engine/kpi-fold.ts +72 -4
- package/server/engine/kpi-query.ts +129 -15
- package/server/engine/live-feed-registry.ts +2 -1
- package/server/engine/load-meter.ts +12 -3
- package/server/engine/log.ts +72 -0
- package/server/engine/loop-lag.ts +120 -0
- package/server/engine/model-gap.ts +168 -0
- package/server/engine/restart-policy.ts +4 -4
- package/server/engine/runtime-key.ts +1 -1
- package/server/engine/stage-path.ts +172 -0
- package/server/engine/twin-engine.ts +1135 -162
- package/server/index.ts +35 -2
- package/server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.ts +54 -0
- package/server/migrations/1786200000000-CarryLiveFeedCursor.ts +53 -0
- package/server/migrations/index.ts +7 -1
- package/server/service/index.ts +11 -0
- package/server/service/reference/discovery-result.ts +1 -1
- package/server/service/reference/index.ts +6 -1
- package/server/service/reference/reference-adapter.ts +197 -5
- package/server/service/reference/reference-assessment.ts +215 -0
- package/server/service/reference/reference-live.ts +123 -11
- package/server/service/reference/reference-master.ts +64 -4
- package/server/service/reference/reference-probe.ts +264 -0
- package/server/service/reference/reference-progress-subscription.ts +73 -0
- package/server/service/reference/reference-progress.ts +95 -0
- package/server/service/reference/reference-resolver.ts +200 -12
- package/server/service/reference/twin-reference.ts +39 -1
- package/server/service/twin-control/twin-control-mutation.ts +4 -3
- package/server/service/twin-event/journal-count.ts +53 -0
- package/server/service/twin-event/twin-event-keys.ts +16 -1
- package/server/service/twin-event/twin-event-type.ts +26 -2
- package/server/service/twin-event/twin-event.ts +7 -0
- package/server/service/twin-forecast/twin-forecast-query.ts +2 -1
- package/server/service/twin-ingest-window/index.ts +7 -0
- package/server/service/twin-ingest-window/twin-ingest-window-query.ts +125 -0
- package/server/service/twin-ingest-window/twin-ingest-window-writer.ts +57 -0
- package/server/service/twin-ingest-window/twin-ingest-window.ts +113 -0
- package/server/service/twin-instance/twin-instance.ts +1 -1
- package/server/service/twin-journal/twin-journal-query.ts +59 -5
- package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +77 -3
- package/server/service/twin-metrics/twin-metrics-query.ts +81 -3
- package/server/service/twin-model/axis-journal-evidence.ts +57 -0
- package/server/service/twin-model/epcis-coverage.ts +2 -8
- package/server/service/twin-model/iec61850-coverage.ts +2 -8
- package/server/service/twin-model/isa95-coverage.ts +22 -9
- package/server/service/twin-model/item-ref.ts +80 -0
- package/server/service/twin-model/name-index.ts +94 -0
- package/server/service/twin-model/project-structure.ts +1 -1
- package/server/service/twin-model/status-tally.ts +37 -0
- package/server/service/twin-model/twin-lineage-query.ts +38 -9
- package/server/service/twin-model/twin-model-item-query.ts +26 -27
- package/server/service/twin-model/twin-model-query.ts +155 -4
- package/server/service/twin-model/twin-model-tree-query.ts +7 -0
- package/server/service/twin-readiness/index.ts +3 -0
- package/server/service/twin-readiness/twin-readiness-query.ts +96 -0
- package/server/service/twin-space/twin-space-resolver.ts +5 -4
- package/shared/entity-delta.ts +31 -7
- package/shared/kpi-broadcast.ts +1 -1
- package/shared/touched-items.ts +73 -0
- package/test/axis-journal-evidence.test.ts +71 -0
- package/test/axis-read.test.ts +101 -1
- package/test/boot-resume.test.ts +92 -26
- package/test/broadcast-cost-baseline.test.ts +200 -0
- package/test/broadcast-period.test.ts +58 -0
- package/test/canonical-ingest-vocabularies.test.ts +36 -1
- package/test/canonical-quantity-door.test.ts +61 -0
- package/test/command-routing.test.ts +1 -1
- package/test/declared-location-types.test.ts +89 -0
- package/test/discovery-result.test.ts +1 -1
- package/test/duration-estimators.test.ts +1 -1
- package/test/entity-delta.test.ts +2 -2
- package/test/ingest-bench.test.ts +3 -3
- package/test/ingest-health-engine.test.ts +248 -0
- package/test/ingest-health-wiring.test.ts +119 -0
- package/test/ingest-health.test.ts +306 -0
- package/test/ingest-history.test.ts +247 -0
- package/test/integration-probes.test.ts +103 -0
- package/test/integration-runner.test.ts +95 -0
- package/test/item-ref.test.ts +78 -0
- package/test/journal-read-discipline.test.ts +177 -0
- package/test/journal-retention.test.ts +133 -0
- package/test/journal-sort-axis.test.ts +142 -0
- package/test/journal-write-door.test.ts +110 -0
- package/test/journal-write-trend.test.ts +115 -0
- package/test/kernel-kind-guard.test.ts +4 -4
- package/test/kpi-fold.test.ts +90 -3
- package/test/kpi-query-bench.test.ts +2 -2
- package/test/lineage-survives-restart.test.ts +17 -1
- package/test/live-cursor-wiring.test.ts +87 -0
- package/test/live-feed-registry.test.ts +9 -1
- package/test/live-kernel-facts.test.ts +7 -7
- package/test/live-mirror-parity.test.ts +6 -0
- package/test/load-meter.test.ts +29 -15
- package/test/local-declarations.test.ts +1 -1
- package/test/log-stamp.test.ts +59 -0
- package/test/loop-lag.test.ts +82 -0
- package/test/model-gap.test.ts +153 -0
- package/test/oee-accumulator.test.ts +4 -0
- package/test/operational-vocabulary.test.ts +4 -4
- package/test/read-failure-visible.test.ts +145 -0
- package/test/reference-grounding.test.ts +70 -0
- package/test/resolve-ts-siblings.mjs +52 -0
- package/test/restart-policy.test.ts +7 -7
- package/test/revision-axis.test.ts +93 -0
- package/test/runtime-key.test.ts +2 -2
- package/test/scale-twin-bench.test.ts +2 -2
- package/test/spec-coverage.test.ts +1 -1
- package/test/stage-path.test.ts +95 -0
- package/test/standard-coverage.test.ts +15 -3
- package/test/status-tally.test.ts +55 -0
- package/test/structure-revision-db.test.ts +4 -0
- package/test/tenant-registry-db.test.ts +1 -1
- package/test/time-range.test.ts +152 -0
- package/test/touched-items.test.ts +61 -0
- package/test/twin-event-keys.test.ts +10 -2
- package/test/twin-model-item-db.test.ts +2 -0
- package/test/warm-start-seam.test.ts +4 -0
- package/test/yield-loop.test.ts +57 -2
- package/tsconfig.shared.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"twin-engine.js","sourceRoot":"","sources":["../../server/engine/twin-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * TwinEngine โ operato-twin ์ปค๋ ์ธ์คํด์ค๋ฅผ things-factory ์์์ ํธ์คํ
.\n * integration-base ์ ScenarioEngine ํจํด ๋ฏธ๋ฌ: ๋ฉ๋ชจ๋ฆฌ ์ธ์คํด์ค ๋งต + ๋ฐฑ๊ทธ๋ผ์ด๋ tick + pubsub ์ํ ๋ฐํ.\n *\n * ์ปค๋(zero-dep, ESM+CJS ์ด์ค๋ฐฐํฌ)์ CJS require ๋ก ๋ก๋(Node 20 CommonJS ์๋น โ require(ESM) ํํผ). (vocabulary-guard: allow โ Node ๋ฐํ์ ๋ฒ์ ํ๊ธฐ)\n * ์ปค๋์ ๊ฒฐ์ ์ ๋
ผ๋ฆฌ ์ฐ์ฐ ์ฝ์ด โ ์ด host ๊ฐ ์ ์ก(pubsub)ยท์์(TypeORM)ยท์ค์ผ์ค(tick)ยท๋ณต๊ตฌ(replay)๋ง ์๊ฒ ๋ํ.\n * (์ค๊ณ SoT: operato-twin/design/integration/things-factory-host.md)\n */\n\nimport { pubsub, getRepository, Domain } from '@things-factory/shell'\n/* ์ ๋์ ์๋ฅผ ์กฐ๊ฑด์ SQL ์ด ์๋ค โ ๊ด์ฉ๊ตฌ๋ง ์ด๋ค(์์ SQL ์ 5๊ฐ ๋๋ผ์ด๋ฒ์์ ๊ฐ๋ผ์ง๋ค). */\nimport { And, IsNull, LessThanOrEqual, MoreThan } from 'typeorm'\nimport { cacheService } from '@things-factory/cache-service'\n\nimport type { ReducerCheckpoint } from '@operato/twin-kernel'\nimport type { OeeCheckpoint } from './oee-accumulator.js'\nimport { TwinEvent } from '../service/twin-event/twin-event.js'\nimport { twinEventKeys } from '../service/twin-event/twin-event-keys.js'\nimport { planLiveContinuity, planWarmStart, unwrapState } from './warm-start.js'\nimport { applyDeclarationLayers } from './local-declarations.js'\nimport { isOfDomain, parseRuntimeKey, runtimeKey } from './runtime-key.js'\nimport { routeCommand } from './command-routing.js'\nimport { TwinInstance } from '../service/twin-instance/twin-instance.js'\n/* ์๊ทน์ ์ง์ ์๋ณธ์ด๋ค(ADR-0029) โ ๊ทธ ํ์ ์ฝ๊ณ ์ด๋ค. */\nimport { TwinReference } from '../service/reference/twin-reference.js'\nimport { TwinStructure } from '../service/twin-structure/twin-structure.js'\nimport { TwinSpace } from '../service/twin-space/twin-space.js'\nimport { utcOffsetOf } from '../service/reference/reference-master.js'\nimport { TwinSpaceRepresentation } from '../service/twin-space/twin-space-representation.js'\nimport { TwinSpaceArea } from '../service/twin-space/twin-space-area.js'\nimport { TwinArea } from '../service/twin-space/twin-area.js'\nimport { masterToTwin, type ReferenceMaster } from '../service/reference/reference-master.js'\nimport { resolveIngestSpace } from '../service/reference/ingest-space.js'\nimport { type IngestWarning, describeWarnings, unresolvedReference, projectionFailed, structureAdopted, generationWithoutTimeZone } from '../service/reference/reference-master.js'\nimport { projectStructure } from '../service/twin-model/project-structure.js'\nimport { buildTravelEstimator, chainEstimators } from './travel-estimator.js'\nimport { buildMeasuredEstimator } from './measured-estimator.js'\nimport { buildYieldEstimator } from './measured-yield.js'\nimport { planStimulus, withStimulus } from './declared-stimulus.js'\nimport { readRestartPolicy, type RestartPolicy } from './restart-policy.js'\nimport { describeModelBasis, type ModelBasis } from './model-basis.js'\nimport { computeTwinKpi } from './kpi-query.js'\nimport { createHash } from 'node:crypto'\n\nimport { buildEntityDeltas } from '@things-factory/headless-twin/dist-shared/entity-delta.js'\nimport { fleetLoad, judgeCycle, loadSummary, newLoadMeter, recordFork, recordPhase, slowTickMessage, type LoadMeter, type LoadPhase } from './load-meter.js'\nimport { diffStructures, type StructureDiff } from './structure-diff.js'\nimport { OeeAccumulator, withLiveOee } from './oee-accumulator.js'\nimport { withLiveAttentions } from './live-attentions.js'\nimport { digestAttentions, mergeLensAttentions } from './attention-digest.js'\n\nimport { liveFeedStateOf } from './live-feed-registry.js'\nimport { EMS_PROPERTY } from '@operato/twin-kernel'\nimport type { TwinKernel, TwinModelDef, StructureShift, SubscriptionMessage, TwinRuntime as TwinRuntimeType, CanonicalEnvelope } from '@operato/twin-kernel'\n\n/* ์ปค๋ ๋ฐํ์ ๋ก๋ โ CJS ๋ฒ๋ค(dist-cjs). ํ์
์ ์ import type ๋ก. replay = ์ด๋ฒคํธ์ดโ์ํ ์ฌ๊ตฌ์ฑ(๋ณต๊ตฌยท์๊ฐ์ฌํ). */\nconst { WmsKernel, YmsKernel, MesKernel, EmsKernel, TwinRuntime, StateProjector, replay, replayFrom, replayWithCheckpoint, replaySegments, readBoardLocations, readBoardEquipment, DOMAIN_CATALOG, OP_EVENT, validateScenario } = require('@operato/twin-kernel')\n\nconst KERNELS: Record<string, any> = { wms: WmsKernel, yms: YmsKernel, mes: MesKernel, ems: EmsKernel }\n\n/**\n * ์ข
๋ฅ ๋ฌธ์์ด โ ์ปค๋. **๋ชจ๋ฅด๋ ๊ฐ์ด๋ฉด ๋์ง๋ค.**\n *\n * ์์ ์๋ ํ๋ฅผ ์ฐพ๊ณ ์์ผ๋ฉด WmsKernel ๋ก ๋จ์ด์ก๋ค. `kind` ๋ ๊ฒ์ฆ ์๋ ์์ ๋ฌธ์์ด(`@Arg('kind') kind: string`)\n * ์ด๋ผ ์คํ ํ๋ยท๋์๋ฌธ์ ํ๋๋ก ์ผ๋/์์ฐ ํธ์์ด **์กฐ์ฉํ ์ฐฝ๊ณ ์ปค๋๋ก ๋์๋ค.** ์ค๋ฅ๊ฐ ์์ผ๋ ํ๋ฉด์๋\n * ํธ์์ด ์ ์์ผ๋ก ๋ณด์ด๊ณ , ์์์ ๋๋ ๊ท์น๋ง ๋ค๋ฅธ ๋๋ฉ์ธ์ ๊ฒ์ด๋ค. ์์ธก ๊ฒฝ๋ก๊ฐ ๊ฐ์ฅ ๋์๋ค โ\n * ์ผ๋์ ๋ฏธ๋๋ฅผ ์ฐฝ๊ณ ๊ท์น์ผ๋ก ์คํํด ๋๊ณ ์ซ์๋ง ๋ฌ๋ค.\n *\n * ํ๋ฆฐ ๊ณต์ฅ์ ์กฐ์ฉํ ๋์ฐ๋ ๊ฒ๋ณด๋ค ๋จ์ง ์๋ ํธ์ด ๋ซ๋ค.\n */\nfunction kernelFor(kind: string): any {\n const K = KERNELS[kind]\n if (!K) throw new Error(`unknown twin kind \"${kind}\" โ expected one of ${Object.keys(KERNELS).join(' | ')}`)\n return K\n}\n\n/* ๋ผ์ด๋ธ ์ฒ๋ฆฌ๋ ๊ณ์ธก(๋ชจ๋ํฐ) โ ์ ์
/๋ฐฉ์ก/์ ๋๋ฅ ยท๋ฐฑ๋ก๊ทธ. ์ค ๋๊ธฐ ์ธํฐํ์ด์ค ๋ถํ๋ฅผ ์ฝ๋ ์ผ๊ธ ์งํ. */\ninterface TwinMetrics {\n ingestedTotal: number // ๋์ ์ ์
์ด๋ฒคํธ\n broadcastTotal: number // ๋์ ๋ฐฉ์ก ํ์\n journaledTotal: number // ๋์ ์ ๋ ๊ธฐ๋ก ์ด๋ฒคํธ\n ingestRate: number // ์ต๊ทผ ์ ์
๋ฅ (ev/s)\n broadcastRate: number // ์ต๊ทผ ๋ฐฉ์ก๋ฅ (ํ/s)\n journalRate: number // ์ต๊ทผ ์ ๋๋ฅ (ev/s)\n backlog: number // ๋ง์ง๋ง flush ์ ๋๊ธฐ ์ ๋ ํฌ๊ธฐ(๋ฐฑํ๋ ์
์ ํธ)\n // ์ฐฝ(window) ์ง๊ณ์ฉ ๋ด๋ถ ๋์ \n _accIngest: number\n _accBroadcast: number\n _accJournal: number\n _windowStartMs: number\n}\n\n/*\n * ์ฌ๊ธฐ๋ ์ ์ฑ
์ **์ ์ธ์ด๊ณ ๊ธฐ๋ณธ๊ฐ์ด ์๋ค** โ ์ ์ยทํ์ ์ `engine/restart-policy.ts` ๊ฐ ๋ ๋ค(ADR-0029 ยง2).\n *\n * ์์ ์๋ ์ฌ๊ธฐ์ `DEFAULT_REALITY_MODE = 'sim-experiment'` ๊ฐ ์์๊ณ , ๋ฏธ์ ์ธ์ด ์กฐ์ฉํ **์ ๋ ์ด๊ธฐํ**๋ก\n * ๋จ์ด์ก๋ค. ๊ทธ ๊ด์ฉ์ ๊ฐ์ด ํ๋ ์ด๊ธ๋๋ ์๊ฐ ์ด๋ ฅ์ ์ง์ฐ๋ ๊ธธ์ด ๋๋ค โ ๊ทธ๋์ ์์ด๋ค.\n */\nexport type { RestartPolicy } from './restart-policy.js'\n\n/* ์ธ๋ฉ๋ชจ๋ฆฌ ๋ผ์ด๋ธ ๋ฐํ์ ํ๋(์์ ์ํฐํฐ TwinInstance ์ ๊ตฌ๋ถ). */\ninterface InstanceRuntime {\n /** ๋ถํ ๊ณ๊ธฐํ โ ์์
๋ณ ์์. ์๋ฎฌยท๋ผ์ด๋ธ ๋ชจ๋ ๋ถ๋๋ค(๋๊ฐ ๋ฃจํ๋ฅผ ์ ์ ํ๋์ง ๋ณด๋ ค๋ฉด ๋ ๋ค ํ์ํ๋ค). */\n load?: LoadMeter\n /** ํ์ค ์ถ์ฒ ์ ์ธ(ยง0 ํ๋ ์ โ ). ๋ถํ
๊ฑฐ๋(reset/resume/resync)์ ๊ทผ๊ฑฐ. */\n restartPolicy?: RestartPolicy\n id: string\n domainId: string\n domain?: any // ๋ผ์ด๋ธ ๋ฐ์ธ๋ฉ(data ์ฑ๋)์ฉ Domain ๊ฐ์ฒด(subdomain ํํฐ). start ์ ๋น๋๊ธฐ ํด์.\n runtime?: TwinRuntimeType // sim: ์ปค๋ ๋ฐํ์(tick/subscribe/dispatch). live ๋ projector ์ฌ์ฉ.\n kernel?: any // sim: ForecastTwin(fork/getSnapshot/tick/scenario). live ๋ฏธ์ฌ์ฉ.\n mode?: 'sim' | 'live' // ์ํ ๋๋ผ์ด๋ฒ โ sim=์ปค๋ tick / live=projector ๋ฏธ๋ฌ(face2-inbound-live). ๋ฏธ์ง์ =sim.\n /** ์ด ํธ์์ด ์ ํ์ฅ โ ๊ฐ์ ํ์ฅ์ ํธ์๋ผ๋ฆฌ ์๋ก์ ์ค๋น ์ํ๋ฅผ ์ฝ์ ์ ์๊ฒ ํ๋ ์ด์ . */\n spaceId?: string\n /**\n * live ์ ์ํ ์ ๊ทผ ์ด๋ํฐ โ ์ด์ **๊ด์ธก ๋ชจ๋ ์ปค๋**์ ๊ฐ๋ฆฌํจ๋ค(`kernel` ๊ณผ ๊ฐ์ ๊ฒ).\n * ์ด๋ฆ์ ์๋น์ฒ ํธํ์ผ๋ก ๋จ์๊ณ , P3 ์์ ์ปค๋ ์ดํ๋ก ์ ๋ฆฌํ๋ฉด ์ฌ๋ผ์ง๋ค.\n */\n projector?: any\n oee?: OeeAccumulator // live: OEE ๊ณ์ฐ ์ธต(์ด๋ฒคํธ ๋์ โ equipment payload ๋ณด๊ฐ). sim ์ ์ปค๋์ด ๊ณ์ฐ.\n unsub: () => void\n /**\n * ๋ฐฉ๊ธ ์ธ์
ํ ๋ดํฌ๋ค โ ์ปค๋์ด ๊ทธ๊ฒ์ ์ฌ๋ฐฉ์ถํ ๋ **์ ๋์ ๋ ๋ฒ ์ ์ง ์๊ธฐ** ์ํ ํ์.\n * ๋ผ์ด๋ธ๋ง ์ด๋ค(sim ์ ์ปค๋์ด ์ค์ค๋ก ๋ธ ๊ฒ๋ง ํ๋ฆฐ๋ค). ์ฝํ ์ฐธ์กฐ๋ผ ๋ฐ๋ก ๋น์ธ ๊ฒ์ด ์๋ค.\n */\n applying?: WeakSet<object>\n timer?: any\n /** ์ํฐํฐ๋ณ ๋ง์ง๋ง ๋ฐํ ์๊ทธ๋์ฒ โ ๊ฐ์ด ๋ฐ๋ ์ํฐํฐ๋ง ์ฌ๋ฐํ(๋ฌด๋ณํ ๋ฐ๋ณต push ๋ฐฉ์ง). */\n entitySigs?: Map<string, string>\n /** live ๋ฐฉ์ก ๋ณํฉ(ingest-scale ยง4.4) โ ingest ๋ง๋ค ๋ฐฉ์กํ์ง ์๊ณ dirty ํ์ โ coalescer tick ์ด ์ฃผ๊ธฐ ๋ฐฉ์ก. */\n dirty?: boolean\n /** live ์ ๋ ๊ฒฐ์ โ ingest ์ด๋ฒคํธ๋ฅผ ๋ชจ์๋ค๊ฐ coalescer tick ์์ ๋ฐฐ์น ๊ธฐ๋ก(์ด๋ฒคํธ๋ง๋ค DB write ๊ธ์ง). */\n pendingJournal?: any[]\n /** live ์ ๋ revision ์นด์ดํฐ(sim ์ delta revision ๋์ โ ์๊ฐ์ฌํยทํ์คํ ๋ฆฌ ๋
ธ๋ธ ์ต์ปค). */\n revision?: number\n /** live ์ฒ๋ฆฌ๋ ๊ณ์ธก(๋ชจ๋ํฐ, โฃ-1). */\n metrics?: TwinMetrics\n}\n\n/**\n * ํธ์์ด **์ค์ค๋ก ๋ฉ์ถ ์ด์ ** โ ๋ฌธ์ฅ์ด ์๋๋ผ ์ฝ๋๋ค.\n *\n * ์๋ฒ๊ฐ ๋ง๋ ์์ด ๋ฌธ์ฅ์ ๊ทธ๋๋ก ์ค์ผ๋ฉด ํ๊ตญ์ดยท์ผ๋ณธ์ด ํ๋ฉด์ ๊ทธ ์์ด๊ฐ ๋ฌ๋ค. ์ด ์์คํ
์ ๊ฑฐ์ ๋ฉ์์ง์์\n * ๊ฐ์ ๊ฒฐ๋ก ์ ์ด๋ฅด๋ ๋ค(์ฝ๋+ํ๋ผ๋ฏธํฐ๋ฅผ ๋ด๊ณ ํ๋ฉด์ด ์ฎ๊ธด๋ค). `reason` ๋ง์ ์๋ฌธ ๊ทธ๋๋ก๋ค โ ์ปค๋ยท๋ฐํ์์ด\n * ๋ธ ์ค๋ฅ ๋ฌธ๊ตฌ๋ ์ฎ๊ธธ ์ ์๋ ์ดํ๊ฐ ์๋๊ณ , ์ฎ๊ธฐ๋ ค ๋ค๋ฉด ์์ธ์ ์๋๋ค.\n */\nexport interface StopNote {\n code: 'starved' | 'tick-failed'\n params: Record<string, string | number>\n}\n\nexport class TwinEngine {\n /*\n * ๊ธฐ๋ ์ค์ธ ๋ฐํ์ โ **ํค๋ `runtimeKey(domainId, instanceId)`** ๋ค(`runtime-key.ts` ์ ์ด์ ).\n *\n * ์์ ์ `instanceId` ํ๋๋ก ํค๋ฅผ ์ก์๋ค. ๊ทธ๋ฐ๋ฐ ์ ์ฒด์ฑ์ `(domain, instanceId)` ์ด๊ณ DB ์ ์ผ์ฑ๋\n * ๊ทธ์ชฝ์ด๋ผ, ๋ ํ
๋ํธ๊ฐ ๊ฐ์ id ๋ฅผ ์ฐ๋ฉด(๋ ํผ๋ฐ์ค ๊ฒฝ๋ก๊ฐ ์์ค ์ด๋ฆ์ id ๋ก ์ด๋ค) ํ ์๋ฆฌ๋ฅผ ๋คํ๋ค.\n * **์์ง ๋ฐ์์ ์ด ๋งต์ ์ง์ ์์ธํ์ง ์๋๋ค** โ `owns`ยท`runtime`ยท`kernel` ๊ฐ์ ์ ๊ทผ์๋ฅผ ์ด๋ค.\n */\n static instances: Record<string, InstanceRuntime> = {}\n /** ๋ผ์ด๋ธ ๋ฐํ์์ด ์์ ๋(๋ณต๊ตฌ ํ ๋ฏธ๊ธฐ๋) ์ ๋์์ ์ฌ๊ตฌ์ฑํ ์ํ ์บ์. */\n /** ์์คํํธ ์จ์ โ `instances` ์ **๊ฐ์ ํค**(๊ฒน์น๋ฉด ๋จ์ ์ค๋
์ท์ผ๋ก ์ฌ๊ณ ๊ฐ ์์ธ๋ค). */\n static recovered: Record<string, any> = {}\n static TICK_MS = 1000\n\n /*\n * โโ ๊ตถ๊น ์์ ๋ง (2026-08-14) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์๋ฎฌ ํฑ์ **๋ฉ์ธ ์ด๋ฒคํธ ๋ฃจํ**์์ ๋๋ค. ๊ทธ๋์ ํ ํธ์์ ํฑ์ด ๊ธธ์ด์ง๋ฉด ๊ทธ ์๊ฐ๋งํผ ํธ์คํธ ์ ์ฒด๊ฐ\n * ๋ฉ์ถ๋ค โ HTTPยท๊ตฌ๋
ยท๋ค๋ฅธ ํธ์์ ํฑ๊น์ง. ์ค์ธก์ผ๋ก `order-check` ์ ํฑ ํ๋๊ฐ 34.9์ด์๊ณ , ๊ทธ ์ฌ์ด\n * ๊ตฌ๋
์๊ฐ ์๋ฌด๊ฒ๋ ๋นผ๋ด์ง ๋ชปํด pubsub ์ด ๋์ณ ํ๋ก์ธ์ค๊ฐ ์ฃฝ์๋ค.\n *\n * ๋ฐฉ์ก ๋ฐ๋ณต์ ๊ฑท์ด๋์ง๋ง(`flushLiveBroadcasts` ๋ก ๋ณํฉ) **์ปค๋ ํฑ ์์ฒด๋ ์ฌ์ ํ ๋ฉ์ธ ๋ฃจํ์ ์๋ค.**\n * ๊ทผ๋ณธ ํด๊ฒฐ์ ๋ถ์ฐ์ด๊ณ ๊ทธ๊ฒ์ ์ด์ฐ๋๋ค โ ๊ทธ๋๊น์ง์ ์์ ๋ง์ด ์ด ์
์ด๋ค.\n *\n * ํ์ ์ ์์ฐ(500ms)์ด ์๋๋ผ **๊ตถ๊น ๋ฌธํฑ**์ผ๋ก ๋ฐ๋ก ๋๋ค: ์กฐ๊ธ ๋๋ฆฐ ํธ์์ ๊ณ๊ธฐํ์ด ๋งํ๊ฒ ๋๊ณ \n * (๊ฒฝ๊ณ ), ํธ์คํธ๋ฅผ ๊ตถ๊ธฐ๋ ํธ์๋ง ๋ฉ์ถ๋ค. ํ ๋ฒ์ผ๋ก ๋ฉ์ถ์ง ์๋๋ค โ ์์คํํธ ์งํ์ ์ฒซ ํฑ์ ์๋\n * ๋ฌด๊ฒ๋ค(๋ณต๊ตฌํ ์ํ๋ฅผ ์ฒ์ ์ ๋๋ค). **์ฐ์**์ผ๋ก ์ด์ด์ง ๋๊ฐ ๊ตฌ์กฐ์ ์ผ๋ก ๋๋ฆฐ ๊ฒ์ด๋ค.\n */\n /** ๊ตถ๊น ๋ฌธํฑ โ ํฑ ๊ฐ๊ฒฉ์ ๋ฐฐ์(1์ด ๊ฐ๊ฒฉ์ด๋ฉด 5์ด). ์ด ์๊ฐ๋งํผ ํธ์คํธ๊ฐ ๋ฉ์ถ๋ค. */\n static STARVE_FACTOR = 5\n /** ์ฐ์ ๋ช ๋ฒ์ด๋ฉด ๋ฉ์ถ๋ โ 3๋ฒ์ด๋ฉด 15์ด๋ฅผ ๊ตถ๊ธด ์
์ด๊ณ , ๊ทธ๊ฑด ์ฐ์ฐ์ด ์๋๋ค. */\n static STARVE_STREAK = 3\n private static starveStreak = new Map<string, number>()\n /**\n * ์ ๋ฉ์ท๋ โ **ํ๋ฉด์ด ๊ทธ๋๋ก ๋งํ ์ ์๊ฒ.** ์ค์ค๋ก ๋ฉ์ถ ํธ์์ด ์ด์ ์์ด ใ์ ์งใ๋ก๋ง ๋ณด์ด๋ฉด\n * ์ฌ๋์ ์๊ธฐ๊ฐ ๋ฉ์ถ ์ค ์๋ค. ๋ฉ๋ชจ๋ฆฌ์๋ง ๋๋ค(์ฌ๊ธฐ๋ํ๋ฉด ์ฌ๋ผ์ง๋ค โ ๊ทธ๋๋ ใ๋ชจ๋ฅธ๋คใ๊ฐ ์ฌ์ค์ด๋ค).\n */\n private static stopNotes = new Map<string, StopNote>()\n\n /* ์ต์ ์ค๋
์ท ์์(warm-start) โ ์ฌ๊ธฐ๋ ์ ์ ๋ fold-from-0 replay ๋์ ๋ง์ง๋ง ๋ผ์ด๋ธ ์ค๋
์ท์ผ๋ก ๋ณต์.\n * ํ๋ ์์ํฌ ๊ณตํต cache-service(@things-factory/cache-service) ์ฌ์ฌ์ฉ(์ฌ๋ฐ๋ช
๊ธ์ง, framework-leverage ยง4).\n * ์ ๋์ ๊ทธ๋๋ก ์ง์ค(์๊ฐ์ฌํ/history replay ๋ฌด๋ณ๊ฒฝ) โ ์บ์๋ display-only ์์คํํธ ์ต์ ํ. */\n static SNAPSHOT_CACHE_ID = 'twin-snapshot'\n /*\n * โโ ์ฌ๊ฐ์ **์ฌ์ฌ** โ ๊ณผ๊ฑฐ๋ฅผ ๋ฌผ์์ ๋ ๋ชฉํ ์ง์ ์์ ์ ๊ธฐ ์ํด (2026-08-18) โโ\n *\n * ์ต์ ์ฌ๊ฐ์ ํ๋๋ก๋ ์๊ฐ์ฌํ์ ๋์ธ ์ ์๋ค: ๊ทธ๊ฒ์ ์ธ์ ๋ ๋ชฉํ๋ณด๋ค **๋ค**์ ์๋ค. ๊ทธ๋์ ์ง์ ์\n * ์ฌ๋ฌ ๊ฐ ๋จ๊ธด๋ค. ๋ค๋ง ๊ทธ๊ฒ๋ค์ ๊ฐ๊ฐ ์ํ ์ ์ฒด๋ฅผ ๋ค๊ณ ์์ด ๋ฌด๊ฒ๋ค โ ํ ํ์ ๋ชฐ์ ๋ฃ์ผ๋ฉด ๊ฑฐ๋ํ\n * JSON ์ด ๋๋ฏ๋ก **์ง์ ๋ง๋ค ๋ฐ๋ก ๋๊ณ ์์ธ์ ๋๋ค**(cache-service ๋ ํด์ ํค ์กฐํ๋ผ ์ด๊ฑฐ๊ฐ ์ ๋๋ค).\n *\n * ๊ฐ๊ฒฉ์ ๋ฆฌ๋น์ ๋๊ธ์ผ๋ก ์ก๋๋ค(`CHAIN_STRIDE`): ๋๊ธ์ ๋์ ๋๋ง ํ ์ง์ ์ ๋จ๊ธฐ๋ฏ๋ก, ์ ๋์ด ๋น ๋ฅด๊ฒ\n * ์๋ผ๋ ํธ์์์๋ ์ง์ ์๊ฐ ํญ๋ฐํ์ง ์๋๋ค. ์ค๋๋ ๊ฒ๋ถํฐ ๋ฒ๋ฆฌ๊ณ ์ต๊ทผ `CHAIN_KEEP` ๊ฐ๋ง ๋ ๋ค โ\n * ๊ณผ๊ฑฐ๋ก ๊น์ด ๊ฐ์๋ก ์ง์ ์ด ์์ด 0๋ถํฐ ์ ๋ ๊ฒ์ **์๋ ค์ง ํ๊ณ**๋ค(๋ฌดํ ๋ณด๊ด๋ณด๋ค ์ ์งํ๋ค).\n */\n static CHAIN_CACHE_ID = 'twin-fold-chain'\n static CHAIN_INDEX_CACHE_ID = 'twin-fold-chain-index'\n static CHAIN_STRIDE = 5000 // ๋ฆฌ๋น์ ๋๊ธ โ ์ด ๊ฐ๊ฒฉ์ ๋์ ๋๋ง ํ ์ง์ ์ ๋จ๊ธด๋ค\n static CHAIN_KEEP = 5 // ์ต๊ทผ ๋ช ์ง์ ์ ๋ค๊ณ ์๋(๊ทธ๋ณด๋ค ๊ณผ๊ฑฐ๋ 0๋ถํฐ ์ ๋๋ค)\n static SNAPSHOT_TTL_S = 7 * 24 * 3600 // 7์ผ โ ์ ์ ๋ค์ดํ์ ์์กด, ๋ง๋ฃ ์ ์ ๋ replay ํด๋ฐฑ\n static CHECKPOINT_MS = 20000 // ์ฒดํฌํฌ์ธํธ ์ฃผ๊ธฐ(ํซ ๋ธ๋ก๋์บ์คํธ ๊ฒฝ๋ก์ ๋ถ๋ฆฌ, O(state) ์ค๋กํ)\n private static checkpointTimer?: any\n\n /** ์ต์ ์ค๋
์ท์ cache-service ์ ์ฒดํฌํฌ์ธํธ(๋๋ฉ์ธ+instanceId ํค). display-onlyยท๋น์ฐจ๋จยท์ค๋ฅํก์. */\n static async persistSnapshot(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[runtimeKey(domainId, instanceId)]\n if (!inst) return\n /*\n * **๋ดํฌ๊ฐ ์๋๋ผ ์ํ๋ฅผ ์ ์ฅํ๋ค.** `snapshot()` ์ ์๋ฎฌ์์ `runtime.resync()` ๋ดํฌ๋ฅผ ์ฃผ๋๋ฐ,\n * ๊ทธ๊ฒ์ ๋ค์ `{revision, state}` ๋ก ๊ฐ์ธ ๋ฃ์ด ์๋ค โ ๊บผ๋ธ ๊ฐ์ ์ถ์ด ํ๋๋ ์์ด ์์คํํธ๊ฐ\n * ์กฐ์ฉํ ๋์ด๊ฐ๋ค(์ ๋์ ์์ฒ ๊ฑด์ด ์์ด๋ ํธ์์ด ๋น ์ฑ๋ก ๋ด๋ค).\n */\n const state = unwrapState(this.snapshot(domainId, instanceId))\n if (!state) return\n const revision = inst.revision ?? state.revision ?? 0\n /* ๊ตฌ์กฐ ๋ฆฌ๋น์ ๋ ํจ๊ป โ ์ฝ๋ ์ชฝ์ด \"์ด ์ํ๊ฐ ์ง๊ธ์ ๊ณต์ฅ์ธ๊ฐ\" ๋ฅผ ๊ฐ๋ฆด ์ ์์ด์ผ ํ๋ค. */\n const { structureRev } = await this.tipOf(domainId, instanceId).catch(() => ({ structureRev: null }) as any)\n await cacheService.setInCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId }, { revision, state, structureRev }, this.SNAPSHOT_TTL_S)\n }\n\n /**\n * ์ ๊ธฐ์ **์ฌ๊ฐ์ ** โ ๋ฆฌ๋์ ๋ด๋ถ ์ํ ์ ๋ถ + ๊ฐ๋ ๋์ ๊ธฐ.\n *\n * ์ค๋
์ท(`state`)์ ์๋น์ฒ๊ฐ ๋ณด๋ ๊ฐ์ด๋ผ ์ด์ด ์ ๊ธฐ์ ์จ์์ด ๋์ง ๋ชปํ๋ค(๋ณด๋ฅ๋ ๋ด๊นยท์งํฉยท๋ฐ์ ๋ชป ํ\n * ์ฌ๊ฑด ์ง๊ณ๊ฐ ์๋ค โ ๊ทธ ์ํ๋ก ๋ค๋ฅผ ์ ์ผ๋ฉด 0๋ถํฐ ์ ์ ๊ฒฐ๊ณผ์ ์กฐ์ฉํ ๋ฌ๋ผ์ง๋ค). ๊ทธ๋์ ์จ์์ ๋ฐ๋ก ๋ ๋ค.\n */\n private static readonly FOLD_NOTE = 'reducer + oee checkpoint โ the seed for folding only the tail'\n\n /** ์ฒดํฌํฌ์ธํธ๋ ์ต์ ์ค๋
์ท ๋ก๋(์์ผ๋ฉด null). getFromCache ๋ CacheStore ์ํฐํฐ๋ฅผ ๋ฐํ โ ํ์ด๋ก๋๋ .value. */\n static async loadSnapshot(\n domainId: string,\n instanceId: string\n ): Promise<{ revision: number; state: any; structureRev?: number | null; fold?: { reducer: ReducerCheckpoint; oee: OeeCheckpoint } } | null> {\n const entry = await cacheService.getFromCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId })\n return (entry as any)?.value ?? null\n }\n\n /**\n * ์ ์ ์ํ๋ฅผ ์ค๋
์ท์ผ๋ก ๋จ๊ธด๋ค โ **๋ผ์ด๋ธ๊ฐ ์๋์ด๋.**\n *\n * `persistSnapshot` ์ ๊ธฐ๋ ์ค์ธ ์ธ์คํด์ค์์๋ง ๋ฌ๋ค(๋ฉ๋ชจ๋ฆฌ๊ฐ ์ง์ค์ด๋ฏ๋ก ์ณ๋ค). ๊ทธ๋ฐ๋ฐ **๋ฉ์ถ**\n * ํธ์์ ์กฐํํ ๋๋ง๋ค ์ ๋์ ์ ๋ ๋ค์ ์ ๊ณ ์์๋ค(23,731๊ฑด์ง๋ฆฌ ํธ์์์ 4.6์ด). ๊ทธ ํด๋์ ๊ฒฐ๊ณผ๋ฅผ\n * ๋จ๊ฒจ ๋๋ฉด **์ฒ์ ํ ๋ฒ๋ง ๋๋ฆฌ๋ค.**\n *\n * `structureRev` ๋ฅผ ํจ๊ป ์ ๋๋ค: ์ด๋ฒคํธ๊ฐ ํ๋๋ ์ ๋์ด๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์์น์ฐ๋ฉด(์ฌํ๋ก๋น์ ๋) ๊ทธ\n * ์ํ๋ ๋ก์ ๊ฒ์ด๋ค. ๋ฆฌ๋น์ ๋ง ๋ณด๋ฉด ์ ์ค๋น๊ฐ ์๋ ์ ์ํ๋ฅผ \"์ง๊ธ\" ์ผ๋ก ๋ด๊ฒ ๋๋ค.\n */\n static async saveFoldedSnapshot(\n domainId: string,\n instanceId: string,\n value: { revision: number; state: any; structureRev?: number | null; fold?: { reducer: ReducerCheckpoint; oee: OeeCheckpoint } }\n ): Promise<void> {\n if (!value?.state) return\n await cacheService\n .setInCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId }, value, this.SNAPSHOT_TTL_S)\n .catch((err: any) => console.error(`[twin-engine] snapshot save fail \"${instanceId}\"`, err?.message ?? err))\n }\n\n\n /** ์ฌ์ฌ ์์ธ โ ์ด๋ค ๋ฆฌ๋น์ ์ง์ ์ ๋ค๊ณ ์๋(์ต์ ์ ์๋, ์ค๋ฆ์ฐจ์). */\n private static async chainIndex(domainId: string, instanceId: string): Promise<number[]> {\n const entry = await cacheService.getFromCache(this.CHAIN_INDEX_CACHE_ID, { domainId, instanceId }).catch(() => null)\n const revs = (entry as any)?.value?.revisions\n return Array.isArray(revs) ? revs.filter((r: any) => Number.isFinite(r)).sort((a: number, b: number) => a - b) : []\n }\n\n /**\n * ๋ชฉํ ์ด์ ์ **๊ฐ์ฅ ๊ฐ๊น์ด ์ง์ **์ ๊ณ ๋ฅธ๋ค โ ์์ผ๋ฉด `null`(0๋ถํฐ ์ ๋๋ค).\n *\n * ์๊ฐ์ผ๋ก ๋ฌผ์์ผ๋ฉด ๊ทธ ์ง์ ์ ๋ง์ง๋ง ์ฌ์ค ์๊ฐ์ด ๋ชฉํ ์ด๋ด์ฌ์ผ ํ๋ค(๋ฆฌ๋น์ ๋ง ๋ณด๋ฉด ๋ชฉํ๋ณด๋ค ๋ค์\n * ์ฌ์ค์ด ์จ์์ ์์ธ๋ค). ๊ตฌ์กฐ๊ฐ ๋ฐ๋ ํธ์์์๋ ์ฐ์ง ์๋๋ค โ ๋ง๋๋ฅผ ๊ฑด๋๋ด ์จ์์ ๊ทธ ๊ฒฝ๊ณ์\n * ํ์ ์ ์๋๋ค(๊ทธ ๊ฒฝ์ฐ๋ 0๋ถํฐ ์ ๋ ๊ฒ์ด ์ณ๋ค).\n */\n private static async chainSeedFor(\n domainId: string,\n instanceId: string,\n target: { revision?: number; timeMs?: number }\n ): Promise<{ revision: number; eventTime?: string; structureRev?: number | null; fold?: { reducer: ReducerCheckpoint; oee: OeeCheckpoint } } | null> {\n const revs = await this.chainIndex(domainId, instanceId)\n if (!revs.length) return null\n for (const revision of [...revs].reverse()) {\n if (target.revision != null && revision > target.revision) continue\n const entry = await cacheService.getFromCache(this.CHAIN_CACHE_ID, { domainId, instanceId, revision }).catch(() => null)\n const value = (entry as any)?.value\n if (!value?.fold?.reducer) continue\n if (target.timeMs != null) {\n const t = value.eventTime ? Date.parse(String(value.eventTime)) : NaN\n /* ์๊ฐ์ ๋ชจ๋ฅด๋ ์ง์ ์ ์ฐ์ง ์๋๋ค โ ๋ชฉํ ์ด๋ด์ธ์ง ๊ฐ๋ฆด ์ ์๋ค(์ง์ํ์ง ์๋๋ค). */\n if (!Number.isFinite(t) || t > target.timeMs) continue\n }\n return value\n }\n return null\n }\n\n /** ๋๊ธ์ ๋์์ผ๋ฉด ํ ์ง์ ์ ๋จ๊ธด๋ค โ ์ค๋๋ ๊ฒ์ ๋ฒ๋ฆฐ๋ค(์์ธ๋ ํจ๊ป ์ค์ธ๋ค). */\n private static async keepChainPoint(\n domainId: string,\n instanceId: string,\n /*\n * **๋ณด๊ธฐ(state)๋ ๋ด์ง ์๋๋ค** (2026-08-18 ์ค์ธก์ผ๋ก ๊ณ ์นจ).\n *\n * ์ฒ์์๋ ์ํ๊น์ง ๋ด์๋๋ ์ง์ ํ๋๊ฐ **11.4 MB** ์๋ค(27๋ง ๊ฑด ํธ์). ์ฌ์ฌ์ด ํ์ํ ๊ฒ์ ์จ์\n * (์ฌ๊ฐ์ )๋ฟ์ด๊ณ , ์๋น์ฒ๊ฐ ๋ณด๋ ๊ฐ์ ๊ทธ ์จ์์์ ๋ค์ ๋ง๋ค์ด์ง๋ค โ ๊ฐ์ ์ฌ์ค์ ๋ ๋ฒ ์ ์ฅํ์ง ์๋๋ค.\n */\n value: { revision: number; eventTime?: string; structureRev?: number | null; fold: { reducer: ReducerCheckpoint; oee: OeeCheckpoint } }\n ): Promise<void> {\n const revs = await this.chainIndex(domainId, instanceId)\n const newest = revs.length ? revs[revs.length - 1] : -Infinity\n if (value.revision - newest < this.CHAIN_STRIDE) return // ์์ง ๋๊ธ์ ๋์ง ์์๋ค\n const next = [...revs, value.revision].slice(-this.CHAIN_KEEP)\n const dropped = revs.filter(r => !next.includes(r))\n await cacheService.setInCache(this.CHAIN_CACHE_ID, { domainId, instanceId, revision: value.revision }, value, this.SNAPSHOT_TTL_S)\n await cacheService.setInCache(this.CHAIN_INDEX_CACHE_ID, { domainId, instanceId }, { revisions: next }, this.SNAPSHOT_TTL_S)\n /*\n * ๋ฒ๋ฆฐ ์ง์ ์ **์์ธ์์๋ง** ๋น ์ง๋ค โ ๊ณต์ฉ ์บ์์ ์ญ์ API ๊ฐ ์๋ค(`ICacheService` ๋ getยทsetยท\n * clearStaleCache ๋ฟ์ด๋ค). ๊ทธ๋์ ๊ฐ์ TTL(7์ผ)๊น์ง ๋จ๋๋ค: ์๋ฌด๋ ๋ฟ์ง ๋ชปํ์ง๋ง ์๋ฆฌ๋ ์ฐจ์งํ๋ค.\n * ์ง๊ธ ๊ท๋ชจ์์ ๊ฐ๋นํ ์ ์๋ ๋ญ๋น์ด๊ณ , ๊ณต์ฉ ๋ชจ๋์ ์ญ์ ๋ฅผ ์ฌ๋ ๊ฒ์ ๋ค๋ฅธ ์๋น์ฒ๊น์ง ํจ๊ป ๋ณผ\n * ์ผ์ด๋ผ ์ฌ๊ธฐ์ ๋ชฐ๋ ํ์ง ์๋๋ค โ **์๋ ค์ง ํ๊ณ๋ก ์ ์ด ๋๋ค.**\n */\n if (dropped.length) console.info(`[twin-engine] \"${instanceId}\" fold chain dropped ${dropped.join(', ')} from the index (values expire with the cache TTL).`)\n }\n\n /** ์ด ํธ์ ์ ๋์ ๋ ๋ฆฌ๋น์ ยท ์ต์ ๊ตฌ์กฐ ๋ฆฌ๋น์ โ ์ค๋
์ท์ด ์ง๊ธ์ ์ฌ์ค์ธ์ง ๊ฐ๋ฆฌ๋ ๋ ๊ฐ. */\n private static async tipOf(domainId: string, instanceId: string): Promise<{ revision: number; structureRev: number | null }> {\n const [tip, newest] = await Promise.all([\n getRepository(TwinEvent).findOne({ where: { domain: { id: domainId }, instanceId }, order: { revision: 'DESC' } }),\n getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n ])\n return { revision: tip?.revision ?? 0, structureRev: newest?.rev ?? null }\n }\n\n /** ์ฒดํฌํฌ์ธํธ ๋ฃจํ ๊ธฐ๋(1ํ) โ ๋ผ์ด๋ธ ์ธ์คํด์ค๋ค์ ์ต์ ์ค๋
์ท์ ์ฃผ๊ธฐ ์์. */\n static startCheckpointLoop(): void {\n if (this.checkpointTimer) return\n this.checkpointTimer = setInterval(() => {\n for (const [key, inst] of Object.entries(this.instances)) {\n const { instanceId } = parseRuntimeKey(key)\n this.persistSnapshot(inst.domainId, instanceId).catch(err =>\n console.error(`[twin-engine] snapshot checkpoint fail \"${instanceId}\"`, err?.message ?? err)\n )\n }\n }, this.CHECKPOINT_MS)\n if (typeof this.checkpointTimer?.unref === 'function') this.checkpointTimer.unref()\n }\n\n /**\n * ๋ถํ
ํ
โ DB ์ status='running' ์ผ๋ก ๋จ์ ์ธ์คํด์ค๋ฅผ ์ ๋์์ ์ํ ์ฌ๊ตฌ์ฑ(DBโreplay).\n * ๋ผ์ด๋ธ tick ์ฌ๊ฐ(sim ๊ฒฐ์ ์ re-run / live ์ธ์ ์คํธ ์ง์)๋ ํ์. ์ฌ๊ธฐ์ ์ํ ๋ณต์ + ๋
ธ์ถ.\n */\n static async bootstrap(): Promise<void> {\n try {\n const repo = getRepository(TwinInstance)\n const rows = await repo.find({ where: { status: 'running' } })\n for (const row of rows) {\n if (!row.domainId || !row.instanceId) continue\n // ์์คํํธ: ์บ์๋ ์ต์ ์ค๋
์ท ์ฐ์ (O(1) + attentions/OEE ๋ฑ ๋ผ์ด๋ธ ํ์์ํ ๋ณด์กด).\n // ์์ผ๋ฉด ์ ๋ fold-from-0 replay(์ง์ค ํด๋ฐฑ โ replay ๋ ๋ผ์ด๋ธ ํ์์ํ๋ฅผ ๋ชป ๋ด์ผ๋ฏ๋ก ์บ์๊ฐ ๋ ์ถฉ์ค).\n const cached = await this.loadSnapshot(row.domainId, row.instanceId).catch(() => null)\n if (cached?.state) {\n /* ์์ ์ ๊ฒนํฌ์ฅ์ผ๋ก ์ ์ฅ๋ ๊ฐ์ด ๋จ์ ์์ ์ ์๋ค โ ์ฝ๋ ์ชฝ์์๋ ๋ฒ๊ธด๋ค(ํ ๋ฒ์ ๋ฐ๋์ ๋ง๋๋ค). */\n this.recovered[runtimeKey(row.domainId, row.instanceId)] = { revision: cached.revision, state: unwrapState(cached.state) }\n /*\n * **ใ์์คํํธํ๋คใ๊ณ ๋งํ์ง ์๋๋ค** โ ์ฌ๊ธฐ์๋ ์ํ๋ฅผ **์ฐพ์ ๋ ๊ฒ**๋ฟ์ด๋ค.\n *\n * ์ค์ ์ฃผ์
์ ๊ธฐ๋ ๋ ์ผ์ด๋๊ณ (`warmStart` ๊ฐ ๊ทธ๋ ๋ฌด์์ ์ฌ์๋์ง ๋งํ๋ค), ๋ฏธ๋ฌ(live) ํธ์์\n * ๊ทธ ์จ์์ ์์ ์ฐ์ง ์๋๋ค(`startLive` ๊ฐ ๋ฒ๋ฆฐ๋ค). ๊ทธ๋ฐ๋ฐ ์ด ์ค์ด ใwarm-startedใ๋ผ๊ณ ๋งํด\n * ๋ก๊ทธ๋ง ์ฝ์ผ๋ฉด ์ฌ๊ธด ์ค ์๊ฒ ๋๋ค โ ์ค์ ๋ก ๊ทธ๋ ๊ฒ ์ฝ๊ณ ์ฌ๊ธฐ๋ ๋ค ์ง์์๊ฐ์ด ์ฌ๋ผ์ง ๊ฒ์\n * ๋ฐ์ดํฐ ๋ฌธ์ ๋ก ์ค์งํ ๋ปํ๋ค.\n */\n console.log(`[twin-engine] found cached state for \"${row.instanceId}\" โ revision ${cached.revision} (seeded at start).`)\n continue\n }\n const state = await this.recover(row.domainId, row.instanceId).catch(() => null)\n if (state) {\n this.recovered[runtimeKey(row.domainId, row.instanceId)] = { revision: state.revision, state }\n console.log(`[twin-engine] recovered \"${row.instanceId}\" from journal โ revision ${state.revision}.`)\n }\n }\n /* ์ํ๋ง ๋์ฐพ๋ ๊ฒ์ผ๋ก๋ **๋๋ ํธ์์ด ๋์ง ์๋๋ค** โ ๋ฐํ์๊น์ง ๋์ด๋ฆฐ๋ค(์๋). */\n for (const row of rows) await this.resumeRow(row)\n this.startCheckpointLoop() // ์ดํ ๊ธฐ๋๋๋ ๋ผ์ด๋ธ ์ธ์คํด์ค์ ์ต์ ์ค๋
์ท์ ์ฃผ๊ธฐ ์์\n } catch (err) {\n console.error('[twin-engine] recovery scan failed', err)\n }\n }\n\n /**\n * ๋ถํ
๋ **๋๋ ํธ์์ ์ค์ ๋ก ๋์ด๋ฆฐ๋ค** โ ใ๋๋ ์คใ์ด ์ฌ์ค์ด ๋๊ฒ.\n *\n * โโ ๋ฌด์์ด ๊ฑฐ์ง๋ง์ด์๋ (2026-08-14) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * `bootstrap()` ์ ์ํ๋ง ๋์ฐพ์ `recovered` ์ ๋ด์๊ณ , ์ปค๋์ ์ธ์ฐ๋ ๊ฒ์ **๋ช
์ mutation ๋ฟ**์ด์๋ค\n * (์ด ํ์ผ ์์ชฝ ์ฃผ์์ด ใํฅํใ๋ผ๊ณ ์ ์ด ๋ ๊ทธ ์๋ฆฌ๋ค). ๊ทธ๋์ ์๋ฒ๋ฅผ ํ ๋ฒ ์ฌ๊ธฐ๋ํ๋ฉด ๋ฑ๋ก๋ถ๋\n * `running` ์ด๋ผ ๋งํ๋๋ฐ **์๋ฌด ์ปค๋๋ ๋์ง ์์๋ค** โ ํ๋ฉด์ ๋๋ ํธ์์, ์ค์ ๋ก๋ ๋ฉ์ถ ํธ์์.\n * ๋ฏธ๋ฌ ํธ์์์๋ ๋ ๋์๋ค: ๊ณ์ธก์ด ์กฐ์ฉํ ๋๊ธฐ๊ณ , ์ฌ๋์ ใ๊ฐ์ด ์ ๋ณํ๋คใ๋ก ์๊ฒ ๋๋ค.\n *\n * โโ ๋ชจ๋๋ฅผ ์ง์ด๋ด์ง ์๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๋ฏธ๋ฌ์๋ ํธ์์ ์๋ฎฌ๋ก ๋์ด๋ฆฌ๋ฉด **์๋ ์์ง์์ ๋ง๋ค์ด ๋ธ๋ค**(๊ด์ธก ํธ์์ด ์ค์ค๋ก ๋ฌผ๊ฑด์ ์ฎ๊ธด๋ค).\n * ๊ทธ๋์ ์ ์ธ๋ `restartPolicy` ๊ทธ๋๋ก ๋์ด๋ฆฐ๋ค โ ๋ฏธ๋ฌ๋ ๊ด์ธก ๊ตฌ๋์ผ๋ก, ์๋ฎฌ์ ์๋ฎฌ๋ก.\n *\n * โโ ๋์ด๋ฆด ์ ์์ผ๋ฉด ๊ทธ๋ ๊ฒ ์ ๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์คํจ๋ฅผ ์ผํค๋ฉด ๋ฑ๋ก๋ถ๊ฐ ๊ณ์ `running` ์ด๋ผ ๋งํ๋ค โ ์ฐ๋ฆฌ๊ฐ ๊ณ ์น๋ ค๋ ๊ทธ ๊ฑฐ์ง๋ง์ด๋ค. ๊ทธ๋์ ์คํจํ\n * ํ์ `stopped` ๋ก ์ ๊ณ ์ด์ ๋ฅผ ๋จ๊ธด๋ค. ใ๋ฉ์ท๋คใ๋ ์ฌ์ค์ด๊ณ , ใ๋๋ ์คใ์ ์ฌ์ค์ด ์๋์๋ค.\n */\n private static async resumeRow(row: TwinInstance): Promise<void> {\n const { domainId, instanceId } = row\n if (!domainId || !instanceId) return\n if (this.instances[runtimeKey(domainId, instanceId)]) return // ์ด๋ฏธ ์ธ์์ก๋ค(๋ฐ๋ชจ ์๋ ๋ฑ)\n\n /*\n * ๋ฒค์น ์ฌ๋ณธ์ ๋์ด๋ฆฌ์ง ์๋๋ค โ ๊ทธ๊ฒ์ **๋๊ตฐ๊ฐ ์ง์ผ๋ณด๋ ์คํ**์ด๊ณ , ๋ฌด์ธ์ผ๋ก ๋์ด์๋๋ฉด ํธ์คํธ๋ฅผ\n * ๊ทธ๋๋ก ๋๋ค๊ธด๋ค(๊ฒฉ๋ฆฌ ์ฌ๋ณธ์ ๋ป์ ใ์ด์๊ณผ ์์ด์ง ์๋๋คใ์ด์ง ใ์์ํ ๋๋คใ๊ฐ ์๋๋ค).\n * ์คํ์ ์ฌ๊ธฐ๋์ ๋๊ธฐ์ง ๋ชปํ์ผ๋ฏ๋ก ๋ฑ๋ก๋ถ๋ ๊ทธ๋ ๊ฒ ์ ๋๋ค.\n */\n if (row.purpose === 'bench') {\n await this.markStopped(row, 'bench copy โ an experiment does not survive a restart unattended')\n return\n }\n\n try {\n if (row.restartPolicy === 'resync') {\n if (!row.model) throw new Error('no model')\n /* ์๊ฐ ๊ธฐ์ค์ **๊ณต๊ฐ**์ด ๊ฐ๋๋ค โ ๊ต๋์ HH:MM ์ ์ด๋ ๊ธฐ์ค์ผ๋ก ์ฝ๋(๋ผ์ด๋ธ ๊ธฐ๋๊ณผ ๊ฐ์ ๊ท์น). */\n this.startLive(instanceId, domainId, row.kind, await this.withSpaceTimeBase(row.model as TwinModelDef, domainId))\n /* ๊ณ์ธก์ ๋๋ฅด๋ ํผ๋๋ ์ปค๋ฅํฐ์ ๊ฒ์ด๋ค โ ๋ ํผ๋ฐ์ค ๊ณ์ธต์ด ๋ถํ
ํ
์์ ๋ค์ ๋ถ์ธ๋ค\n (`resumeReferenceLiveFeeds`). ์ฌ๊ธฐ์ ์ด๋ํฐ๋ฅผ ์๋ ๊ฒ์ ๊ณ์ธต์ ๊ฑฐ๊พธ๋ก ์๋ ๊ฒ์ด๋ค. */\n console.log(`[twin-engine] resumed mirror \"${instanceId}\" โ feed reattach is the reference layer's job.`)\n } else {\n await this.startFromRegistry(domainId, instanceId)\n console.log(`[twin-engine] resumed ${row.restartPolicy} \"${instanceId}\".`)\n }\n } catch (err: any) {\n await this.markStopped(row, err?.message ?? 'resume failed')\n }\n }\n\n /** ๋์ด๋ฆฌ์ง ๋ชปํ ํ์ ์ ์งํ๊ฒ ์ ๋๋ค โ ใ๋๋ ์คใ์ด๋ผ ๋งํ๋ ์ฑ๋ก ๋์ง ์๋๋ค. */\n private static async markStopped(row: TwinInstance, why: string): Promise<void> {\n console.warn(`[twin-engine] \"${row.instanceId}\" not resumed (${why}) โ registry says stopped now.`)\n try {\n await getRepository(TwinInstance).update({ id: row.id }, { status: 'stopped' })\n } catch (e: any) {\n console.error(`[twin-engine] could not mark \"${row.instanceId}\" stopped โ registry now lies about it.`, e?.message)\n }\n }\n\n /**\n * ์์คํํธ โ ๊ธฐ๋ํ๋ ์ปค๋์ **์ง์ ๊ด์ธก ์ํ**๋ฅผ ์ฃผ์
ํ๋ค.\n *\n * โโ ์ ํ์ํ๊ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * `loadTwinModel` ๋ **๊ตฌ์กฐ๋ง** ์ฃ๋๋ค(์๋ฆฌยท์ค๋น). ์ํ(๋ฌด์์ด ์ด๋์ ์ผ๋ง๋)๋ ์๋ค. ๊ทธ๋์ ์ฌ๊ธฐ๋ํ\n * ํธ์์ ์ ๋์ ์
๊ณ 540๊ฑด์ด ๋จ์ ์์ด๋ ์ฌ๊ณ ๊ฐ 0 ์ด์๊ณ , ํ๋ฉด์ \"๋ณด์ ์ค์ธ ๊ฒ์ด ์์ต๋๋ค\" ๋ผ๊ณ \n * ๋งํ๋ค โ ์๋ ์ฌ๊ณ ๋ฅผ ์๋ค๊ณ ํ๋ ์
์ด๋ค(2026-07-31 hatiolab-wms ์ค์ธก์ผ๋ก ํ์ธ).\n * `bootstrap()` ์ด ์ด๋ฏธ ์ฒดํฌํฌ์ธํธ ์บ์(์์ผ๋ฉด ์ ๋ replay)๋ก ์ํ๋ฅผ ๋ณต๊ตฌํด `recovered` ์ ๋ด์ ๋๋๋ฐ,\n * ๊ธฐ๋ ์๊ฐ ๊ทธ๊ฑธ **๋ฒ๋ฆฌ๊ณ ** ์์๋ค. ๋ฐ๋ง ์ฐ๊ฒฐ๋ผ ์๋ ์ฅ์น๋ฅผ ์๋๋ค.\n *\n * โโ ๋ฐ์ชฝ์ด๋ ๋ณต๊ตฌ๋ฅผ ๋ง๋ฌด๋ฆฌํ๋ค (2026-08-05) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ฌ๊ณ ๋ ์ด์๋ฌ๋๋ฐ **์งํ ์ค ์ฃผ๋ฌธ์ด ํต์งธ๋ก ์ฌ๋ผ์ง** ํ๋ฉด์ด ๋จ์ ์์๋ค. ์จ์์ด ์๋ฆฌยท๋ฌผํยท์ค๋น\n * ์
๋ง ๋๊ฒผ๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ ๊ทผ๊ฑฐ๋ \"์ค๋
์ท ์ค๋์ progress ๋ฐ์ ์๋ค\" ์๊ณ , ๊ทธ๋๋ ๋ง์๋ค โ\n * ๊ทธ๋ฌ๋ ์ปค๋ `OrderState` ๊ฐ ์๊ฐ(`requested`ยท`fulfilled`ยท`lines`)์ ๋์ฐพ์ ๋ค์๋ ์ด ์๋ฆฌ๋ง\n * ๊ทธ๋๋ก ๋จ์๋ค. ์ค๋ฅ๋ฅผ ๋ด์ง ์๋ ์ข
๋ฅ๋ผ ์ค๋ ๋ฒํ
ผ๋ค.\n *\n * ์ง๊ธ์ **๊ด์ธก ์ค๋
์ท ์ ์ฒด**๋ฅผ ๋๊ธด๋ค(์ค๋ยท์์
ยท์ฌ๋ยท์์ฐ ํฌํจ). ์๋ฎฌ์ ์ปค๋ `snapshot()`,\n * ๋ผ์ด๋ธ๋ `StateProjector` ๊ฐ ๊ทธ ์ผ๊ณฑ ์ถ์ ๋ชจ๋ ๋ด๋๋ค. ๋ฌด์์ ์ฌ์ ์ ์๋์ง ํ์ ํ๋ ๊ท์น\n * (์ดํ ์๋ฃ ์ค๋ ์ ์ธยท๊ณ ์ ์์
์ ์ธ)์ ์ปค๋์ ์๊ณ , ํธ์คํธ๊ฐ ๋ฏธ๋ฆฌ ๊ณจ๋ผ๋ด์ง ์๋๋ค.\n *\n * โโ ๋จ์ ํ๊ณ๋ ์จ๊ธฐ์ง ์๊ณ ์ผ๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ยท ์๊ฐ์ด ์๋ ์ค๋(progress ๋ง ์๋ ๊ฒ)๋ ๋จ์ ์๋์ ์ ์ ์์ด ์ฃผ์
ํ์ง ์๋๋ค. **์ง์ด๋ด์ง ์๋\n * ๋์ ๋ช ๊ฑด์ธ์ง ๋งํ๋ค** โ ์ธ์ง ์์ผ๋ฉด \"์ฃผ๋ฌธ์ด ์๋ค\" ์ \"์ฃผ๋ฌธ์ ๋ชป ์ฌ์๋ค\" ๊ฐ ํ๋ฉด์์ ๊ฐ์์ง๋ค.\n * ยท ์งํ ์ค ๊ฐ๋ณ ์์
์ ๋ด๋ถ ์ํ๋ ๊ด์ธก๋ง์ผ๋ก ์์ ํ ๋ณต์๋์ง ์๋๋ค(์ปค๋์ด ๋ช
์ํ ํ๊ณ, ์ฌ๊ณํ์ ๋งก๊น).\n *\n * โโ ๋ฒค์น๋ ์๋ํ์ง ์๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๋ถํ ๋ฒค์น๋ **์ ์์์์ ์ฉ๋์ ์ฌ๋ ๊ฒ**์ด ๋ชฉ์ ์ด๋ผ ํ์ฌ ์ํ๋ฅผ ์ฃผ์
ํ๋ฉด ์ธก์ ์ด ์ค์ผ๋๋ค.\n */\n private static warmStart(domainId: string, id: string, kernel: TwinKernel, purpose?: string): void {\n const hydrate = (kernel as any).hydrateObserved\n const plan = planWarmStart(this.recovered[runtimeKey(domainId, id)]?.state, purpose, typeof hydrate === 'function')\n\n if (plan.action === 'skip') {\n if (plan.reason === 'bench') {\n console.log(`[twin-engine] \"${id}\" is a bench twin โ starting empty on purpose (seeding would skew the measurement).`)\n } else if (plan.reason === 'unsupported') {\n console.warn(\n `[twin-engine] kernel for \"${id}\" cannot be warm-started (no hydrateObserved) โ it starts with structure only, so held stock will read as zero.`\n )\n }\n return\n }\n\n hydrate.call(kernel, plan.seed)\n const restored = [\n `${plan.itemCount} item(s)`,\n `${plan.equipmentCount} equipment`,\n `${plan.orderCount} open order(s)`,\n `${plan.taskCount} task(s)`,\n ...(plan.personCount ? [`${plan.personCount} person(s)`] : []),\n ...(plan.assetCount ? [`${plan.assetCount} asset(s)`] : []),\n /* ํ์ธํด ๋ ์ ํธ๋ฅผ ์ด์ด๋ฐ์๋ค๋ ์ฌ์ค๋ ๋งํ๋ค โ ์์ผ๋ฉด ํ์ธ ์ฒ๋ฆฌ๊ฐ ๋ค์ ๋นจ๊ฐ์ง๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค. */\n ...(plan.ackedCount ? [`${plan.ackedCount} acknowledged attention(s)`] : []),\n /* ใ์ธ์ ๋ถํฐ์ธ๊ฐใ๋ ๋งํ๋ค โ ์์ผ๋ฉด ์ง์๋ ์กฐ๊ฑด์ด ๋ชจ๋ ใ๋ฐฉ๊ธใ์ผ๋ก ๋ณด์ธ๋ค. */\n ...(plan.attentionSinceCount ? [`${plan.attentionSinceCount} attention start time(s)`] : [])\n ].join(', ')\n console.log(`[twin-engine] warm-started \"${id}\" โ restored ${restored}.`)\n /* ๋บ ๊ฒ์ ์กฐ์ฉํ ๋๊ธฐ์ง ์๋๋ค โ ์ง์ด๋ด์ง ์์๋ค๋ ์ฌ์ค ์์ฒด๋ฅผ ๋งํด์ผ ํ๋ฉด์ ๋น์นธ์ด ์ฝํ๋ค. */\n if (plan.ordersWithoutDemand > 0) {\n console.warn(\n `[twin-engine] \"${id}\": ${plan.ordersWithoutDemand} order(s) could not be restored โ they carry progress only, ` +\n 'with no requested/fulfilled counts, so the remaining demand is unknown. They are left out rather than guessed.'\n )\n }\n }\n\n /** ํธ์ ์ธ์คํด์ค ์์ โ ์ปค๋ ์์ฑ + ๋ชจ๋ธ ๋ก๋ + ์ง์ ์ํ ์์คํํธ + State ์คํธ๋ฆผ ๋ธ๋ฆฌ์ง + ์์ปค tick + ๋ ์ง์คํธ๋ฆฌ ์์. */\n /**\n * ๊ณต์ ๋ช
์ธ๋ฅผ ์ปค๋์ ์ฃ๋๋ค โ **์๋ฎฌ๋ ์ด์
์ ์๊ฐ์ ๋ฐ์ดํฐ๊ฐ ๋งํ๊ฒ ํ๋ ๋ง์ง๋ง ํ ์นธ.**\n *\n * `model.operations`(๋ง์คํฐ ์ธ์ ์คํธ๊ฐ ํต๊ณผ์ํจ ISA-95 OperationsSegment ๋ช
์ธ)๋ฅผ ์ปค๋์ด ์๋นํ๋ค.\n * ์์ผ๋ฉด ์ปค๋ ๊ธฐ๋ณธ ์์๋ก ๊ตด๋ฌ๊ฐ๊ณ , ์ปค๋ `specCoverage()` ๊ฐ ๋ฌด์์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ผ๋์ง ๋ณด๊ณ ํ๋ค.\n *\n * ์ปค๋์ด ์์ง ์ด API ๋ฅผ ๊ฐ์ง ์์ ๋ฒ์ ์ด๋ฉด(๋ฐํ ์ด์ ) **์กฐ์ฉํ ๋์ด๊ฐ์ง ์๊ณ ๊ฒฝ๊ณ ํ๋ค** โ ๋ช
์ธ๋ฅผ\n * ์ ์ธํ๋๋ฐ ๋ฐ์๋์ง ์๋ ์ํ๋ฅผ ๋ชจ๋ฅด๊ณ ์ง๋๊ฐ๋ฉด, ์์ธก์ด ์์๋ก ๋์๊ฐ ๊ฒ์ ์๋ฌด๋ ์ ์ ์๋ค.\n */\n private static applyOperations(kernel: any, model: any, id: string): void {\n /*\n * ํ์ฅ์ด ์ ํ ๊ณต์ ์๊ฐ โ ๋ช
์ธ ํ๊ณผ **๋ฐ๋ก** ์ฃ๋๋ค(`declareDurations`).\n *\n * ํ์ด ์๋ ์ข
๋ฅ์๋ ์๊ฐ์ ์ค ์ ์์ด์ผ ํ๋ค: ์ค์ธก์ผ๋ก ์ฐฝ๊ณ ยท์ผ๋ ํธ์์๋ ๊ณต์ ๋ช
์ธ ํ์ด 0๊ฐ์๊ณ ,\n * ๊ทธ ํธ์๋ค์ ์๊ฐ์ ์ ๋ถ ์ปค๋ ์์์์ ์๋ค. ํ์ ์ง์ด ๋ง๋๋ ๊ธธ์ ๋ง์๋ค(`label`ยท`intent` ๋ฅผ\n * ์ง์ด๋ด๋ฉด ๋ฅ๋ ฅ ๊ณ์ฐ๊น์ง ์ค์ผ๋๋ค) โ ๊ทธ๋์ ์๊ฐ๋ง ๋ฐ๋ ์ฐฝ๊ตฌ๊ฐ ์ปค๋์ ์๋ค.\n */\n const declared = model?.localDurations as Record<string, string> | undefined\n if (declared && Object.keys(declared).length) {\n if (typeof kernel?.declareDurations !== 'function') {\n console.warn(\n `[twin-engine] \"${id}\": this facility declared ${Object.keys(declared).length} operation duration(s) but the kernel cannot consume them ` +\n '(declareDurations missing โ kernel needs publishing). The simulation keeps running on built-in constants, and specCoverage() will keep reporting \"default\".'\n )\n } else {\n try {\n kernel.declareDurations(declared)\n } catch (err: any) {\n /* ์ปค๋์ด ๊ฑฐ์ ํ ๊ฐ์ ์กฐ์ฉํ ๋๊ธฐ์ง ์๋๋ค โ ํ๋ฉด์ ใ๋ฃ์์ต๋๋คใ๋ผ๊ณ ๋งํ ๊ฐ์ด๋ค. */\n console.warn(`[twin-engine] \"${id}\": declared operation duration rejected by the kernel โ ${err?.message ?? err}`)\n }\n }\n }\n /* ๊ณต์ ๋ชจ์(์์จยท์
์
)๋ ๊ฐ์ ๊ท์จ๋ก ์ฃ๋๋ค โ ์ปค๋์ด ๊ทธ ์ฐฝ๊ตฌ๋ฅผ ๊ฐ์ง ์์ผ๋ฉด ๊ทธ ์ฌ์ค์ ๋งํ๋ค. */\n const params = model?.localParams as Record<string, Record<string, string>> | undefined\n if (params && Object.keys(params).length) {\n if (typeof kernel?.declareParameters !== 'function') {\n console.warn(\n `[twin-engine] \"${id}\": this facility declared operation parameters for ${Object.keys(params).length} operation(s) but the kernel cannot consume them ` +\n '(declareParameters missing โ kernel needs publishing). Yield and setup keep running on built-in constants.'\n )\n } else {\n try {\n kernel.declareParameters(params)\n } catch (err: any) {\n console.warn(`[twin-engine] \"${id}\": declared operation parameter rejected by the kernel โ ${err?.message ?? err}`)\n }\n }\n }\n const ops = model?.operations\n if (!ops?.length) return\n if (typeof kernel?.loadOperations !== 'function') {\n console.warn(`[twin-engine] \"${id}\": model declares ${ops.length} operation spec(s) but the kernel cannot consume them (loadOperations missing โ kernel needs publishing). Simulation will use built-in default durations.`)\n return\n }\n kernel.loadOperations(ops)\n }\n\n /**\n * ์์์๊ฐ ์ถ์ ๊ธฐ ์ฃผ์
โ **์์๋ฅผ ๋ฐ์ดํฐ๋ก ๋ฐ๊พธ๋ ๋ ๋ฒ์งธยท์ธ ๋ฒ์งธ ์ธต.**\n *\n * ์ปค๋ `durationOf` ์ ์ฐ์ ์์๋ ์ถ์ ๊ธฐ > ๋ช
์ธ > ์์๋ค. ๊ทธ ์ถ์ ๊ธฐ ์๋ฆฌ์ ๋ ๊ฐ์ง๋ฅผ ์ฌ์ฌ๋ก ๋ฃ๋๋ค:\n * โ **์ค์ธก**(์ ๋์ ์์
์ข
๋ฅ๋ณ ์์
์๊ฐ p50) โ ๊ทธ ํ์ฅ์์ ์ค์ ๋ก ์ผ๋ง ๊ฑธ๋ ธ๋. ๊ฐ์ฅ ๊ฐํ ๊ทผ๊ฑฐ.\n * โก **๊ฑฐ๋ฆฌ ร ์๋**(model.layout + ์ค๋น ์๋ ์์ฑ) โ ์ด๋์ ๊ฑฐ๋ฆฌ์ ๋น๋กํ๋ค. ์ปค๋์ ์ขํ๋ฅผ ๋ชจ๋ฅด๋ฏ๋ก\n * ํธ์คํธ๊ฐ ๊ณ์ฐํด ๋ฃ๋๋ค.\n * ๋ ๋ค ๋ชป ๋ง๋ค๋ฉด ์ฃผ์
ํ์ง ์๋๋ค โ ์ปค๋์ด ๋ช
์ธยท์์๋ก ๊ตด๋ฌ๊ฐ๊ณ `specCoverage()` ๊ฐ ๊ทธ ์ฌ์ค์ ๋จ๊ธด๋ค.\n *\n * ์ค์ธก์ DB ์กฐํ๋ผ ๋น๋๊ธฐ๋ค. ๊ทธ๋์ ์ด ํจ์๋ **await ํ์ง ์๋ ์ชฝ์์๋ ์์ **ํ๋๋ก ์คํจ๋ฅผ ์ผํค๋,\n * ๋ฌด์์ ์ ๋ชป ๋ฃ์๋์ง๋ ๋ก๊ทธ๋ก ๋จ๊ธด๋ค(์กฐ์ฉํ ๋ฌดํจํ ๊ธ์ง).\n */\n static async installEstimators(kernel: any, domainId: string, instanceId: string, model: any): Promise<void> {\n if (!kernel || typeof kernel !== 'object') return\n const travel = buildTravelEstimator({ layout: model?.layout, equipment: model?.equipment, unit: model?.unit })\n const measured = await this.measuredEstimator(domainId, instanceId)\n const chained = chainEstimators([measured?.estimator, travel.estimator])\n if (!chained) {\n /* ์ ๋ชป ๋ฃ์๋์ง ํ ๋ฒ๋ง ์๋ฆฐ๋ค โ ์ด๋์๊ฐ์ด ์์๋ก ๋จ์ ์ด์ ๋ฅผ ๋ชจ๋ฅด๊ณ ์ง๋๊ฐ์ง ์๊ฒ. */\n if (travel.reasons.length) console.warn(`[twin-engine] \"${instanceId}\": no duration estimator installed โ ${travel.reasons.join('; ')}`)\n return\n }\n kernel.durationEstimator = chained\n /*\n * **์ํ๋ฅ ๋ ์ด๋ ฅ์์ ๋ฐฐ์ด๋ค** (2026-08-19) โ ์์์ ๊ฐ์ ์๋ฆฌ์์ ๋ถ์ธ๋ค.\n *\n * ์ปค๋์ด ๊ทธ ์์์ ๊ฐ์ง ์์ ๋ฒ์ ์ด๋ฉด(๋ฐํ ์ด์ ) ์กฐ์ฉํ ๋์ด๊ฐ์ง ์๊ณ ๋งํ๋ค: ์์จ์ด ์์๋ก ๋จ์\n * ์ด์ ๋ฅผ ๋ชจ๋ฅด๊ณ ์ง๋๊ฐ๋ฉด, ํ๋ฉด์ ๋ถ๋ ํ์ ์ด ๊ทธ ํ์ฅ์ ์ฌ์ค์ด ์๋๋ผ ์ฐ๋ฆฌ ์์์ ๊ฒฐ๊ณผ๋ค.\n */\n const yields = await this.measuredYield(domainId, instanceId)\n if (yields?.estimator) {\n if (typeof kernel.yieldOf !== 'function') {\n console.warn(\n `[twin-engine] \"${instanceId}\": learned yield for ${Object.keys(yields.learned).length} operation kind(s) but the kernel cannot consume it ` +\n '(yieldOf missing โ kernel needs publishing). Yield keeps running on the declared value or the built-in constant.'\n )\n } else {\n kernel.yieldEstimator = yields.estimator\n console.log(\n `[twin-engine] \"${instanceId}\": measured yield installed โ ${Object.entries(yields.learned)\n .map(([k, v]) => `${k}=${Math.round(v * 1000) / 10}%(${yields.samples[k].good + yields.samples[k].scrap}๊ฑด)`)\n .join(', ')}${yields.skipped.length ? ` ยท ํ๋ณธ ๋ถ์กฑ์ผ๋ก ๋บ ์ข
๋ฅ: ${yields.skipped.map(s => `${s.kind}(${s.judged})`).join(', ')}` : ''}`\n )\n }\n } else if (yields?.skipped.length) {\n /* ๋ฐฐ์ด ๊ฒ์ด ์๊ณ ๋ฒ๋ฆฐ ๊ฒ๋ง ์์ผ๋ฉด ๊ทธ ์ฌ์ค๋ ๋งํ๋ค โ ใ์ด๋ ฅ์ด ์๋คใ์ ใํ๋ณธ์ด ๋ชจ์๋ผ๋คใ๋ ๋ค๋ฅด๋ค. */\n console.log(\n `[twin-engine] \"${instanceId}\": no measured yield yet โ samples below ${yields.minSamples}: ${yields.skipped\n .map(s => `${s.kind}(${s.judged})`)\n .join(', ')}`\n )\n }\n const learned = Object.keys(measured?.learned ?? {})\n const spread = Object.keys(measured?.spreads ?? {})\n console.log(\n `[twin-engine] \"${instanceId}\": duration estimator installed โ measured kinds: ${learned.length ? learned.join(',') : 'none'}` +\n ` (with observed spread: ${spread.length ? spread.join(',') : 'none'})` +\n `${travel.estimator ? `, travel from distance (speeds: ${Object.keys(travel.speedsByKind).join(',')})` : `, travel not derived (${travel.reasons.join('; ')})`}`\n )\n }\n\n /**\n * ์ค์ธก ์ถ์ ๊ธฐ โ **์์ธก ์์ฒญ๋ง๋ค ์ ๋์ ๋ค์ ์ ์ง ์๋๋ค.**\n *\n * ์์ธก ์ปค๋์ ์์ฒญ๋ง๋ค ์๋ก ์ธ์์ง๊ณ (๋ฏธ๋ฌ ์์ธกยท๋ฐฑํ
์คํธ), ํ๋ฉด์ ์๊ฐ์ ๊ธ์ผ๋ฉด ๊ณ์ ์ฌ์์ธกํ๋ค.\n * ๊ฑฐ๊ธฐ์ KPI ์กฐํ๋ฅผ ๊ทธ๋๋ก ๋ฌ๋ฉด ์์ฒญ๋น ์ ๋ ์ค์บ์ด ํ๋์ฉ ๋ถ๋๋ค โ ์ค์ธก์ ๋ถ ๋จ์๋ก ๋ฐ๋์ง ์์ผ๋ฏ๋ก\n * ์งง์ TTL ๋ก ์ฌ์ฌ์ฉํ๋ค. ์บ์๋ ์ธ์คํด์ค๋ณ์ด๊ณ , ๋ง๋ฃ ์ ์๋ ๊ฐ์ ๊ฐ์ ์ด๋ค(์์ธก ๊ฐ ์ผ๊ด์ฑ๋ ์ป๋๋ค).\n */\n private static measuredCache = new Map<\n string,\n {\n at: number\n value: ReturnType<typeof buildMeasuredEstimator> | undefined\n /** ๊ฐ์ ํด๋์์ ๋์จ ์ํ๋ฅ โ **์ ๋์ ๋ ๋ฒ ์ ์ง ์๋๋ค**(์์์ ์์จ์ ๊ฐ์ ์ฐฝ์ ๊ฐ์ ์ฌ์ค์ด๋ค). */\n yields?: ReturnType<typeof buildYieldEstimator>\n }\n >()\n private static readonly MEASURED_TTL_MS = 60_000\n /**\n * ์บ์ ํญ๋ชฉ ์ํ โ **๋ผ์ดํ์ฌ์ดํด์ด ๋์น ๊ฒ๊น์ง ๋ง๋ ๋ ๋ฒ์งธ ๋ฐฉ์ด.**\n *\n * ์ง์์ `forgetInstance` ๊ฐ ํ๋ค(๊ทธ๊ฒ์ด ์ฒซ ๋ฒ์งธ ๋ฐฉ์ด์ด๊ณ ์ ํํ ์ชฝ์ด๋ค). ๊ทธ๋ฐ๋ฐ ํธ์์ด ์ฐ๋ฆฌ API ๋ฅผ\n * ์ง๋์ง ์๊ณ ์ฌ๋ผ์ง๋ ๊ธธ์ด ์๋ค: ๋๋ฉ์ธ(ํ
๋ํธ)์งธ๋ก ์ง์์ง๊ฑฐ๋ DB ๋ฅผ ์ง์ ์๋๋ ๊ฒฝ์ฐ๋ค. ๊ทธ๋\n * ๋จ์ ํญ๋ชฉ์ ์ง์ธ ์ฃผ์ธ์ด ์์ผ๋ฏ๋ก ์ํ์ด ํ์ํ๋ค.\n *\n * ๋์น๋ฉด **๊ฐ์ฅ ์ค๋ ์๋์ง ์์ ๊ฒ**๋ถํฐ ๋ฒ๋ฆฐ๋ค(Map ์ ์ฝ์
์์๊ฐ ๊ณง ๊ทธ ์์๋ค โ ๊ฐ์ ์ธ ๋๋ง๋ค\n * ๋ค์ ๋ฃ์ผ๋ฏ๋ก). ๋ฒ๋ฆฌ๋ ๊ฒ์ด ์ํด๊ฐ ์๋ ์ด์ : ์ด ๊ฐ์ ์บ์์ด๊ณ , ์์ผ๋ฉด ๋ค์ ๊ณ์ฐํ๋ค.\n *\n * ์๋ฅผ ํฌ๊ฒ ์ก๋๋ค โ ํธ์ ๊ท๋ชจ๋ ๋ ํฌ๊ณ , ํญ๋ชฉ ํ๋๋ ์์
์ข
๋ฅ๋ณ ์์ ๋ช ์ค์ด๋ค. ์ํ์ด ์์ผ๋ฉด\n * ์ ์ ๊ท๋ชจ์์ ์๋ก ๋ฐ์ด๋ด๋ฉฐ ์บ์๊ฐ ๋ฌด์๋ฏธํด์ง๋ค(๊ทธ๊ฒ ๋ ๋์๋ค: ์กฐ์ฉํ ๋๋ ค์ง๋ค).\n */\n private static readonly MEASURED_MAX = 5_000\n\n /** ์ด ํธ์์ด ์ด๋ ฅ์์ ๋ฐฐ์ด ์ํ๋ฅ โ ์์์ **๊ฐ์ ํด๋ยท๊ฐ์ ์บ์**์์ ์จ๋ค(์ ๋์ ๋ ๋ฒ ์ ์ง ์๋๋ค). */\n private static async measuredYield(domainId: string, instanceId: string) {\n await this.measuredEstimator(domainId, instanceId)\n return this.measuredCache.get(runtimeKey(domainId, instanceId))?.yields\n }\n\n private static async measuredEstimator(domainId: string, instanceId: string) {\n /* ํค๋ `runtimeKey` ํ๋๋ก โ ์์ผ๋ก ์กฐ๋ฆฝํ๋ฉด ์ง์ฐ๋ ์ชฝ๊ณผ ์ด๊ธ๋ ๋ชป ์ง์ฐ๋ ํญ๋ชฉ์ด ์๊ธด๋ค. */\n const key = runtimeKey(domainId, instanceId)\n const hit = this.measuredCache.get(key)\n if (hit && Date.now() - hit.at < this.MEASURED_TTL_MS) return hit.value\n let value: ReturnType<typeof buildMeasuredEstimator> | undefined\n let yields: ReturnType<typeof buildYieldEstimator> | undefined\n try {\n /* ์์
์ข
๋ฅ๋ณ ์ค์ธก โ ์ฐฝ์ ๋๋ํ(ํ๋ฃจ) ๋๊ณ ํ๋ณธ์ด ๋ชจ์๋ ์ข
๋ฅ๋ ์ถ์ ๊ธฐ๊ฐ ์ค์ค๋ก ๋บ๋ค. */\n const kpi: any = await computeTwinKpi({ domainId, instanceId, windowMinutes: 24 * 60, groupBy: 'taskKind' })\n value = buildMeasuredEstimator(kpi?.groups?.items, {})\n /* ๊ฐ์ ๊ทธ๋ฃน์์ ์ํ๋ฅ ๋ ๋ฐฐ์ด๋ค โ ํ ๋ฒ ์ ์ ์ ๋์ ๋์ด ๋๋ ์ด๋ค. */\n yields = buildYieldEstimator(kpi?.groups?.items, {})\n } catch (err) {\n console.warn(`[twin-engine] \"${instanceId}\": measured duration lookup failed โ falling back to declared/default durations.`, (err as any)?.message)\n }\n /* ๋ค์ ๋ฃ์ด **์ต๊ทผ ์ด ๊ฒ**์ผ๋ก ๋ง๋ ๋ค โ ์ฝ์
์์๊ฐ ๊ณง ๋ฒ๋ฆด ์์์ด๋ฏ๋ก ์ด ํ ์ค์ด LRU ๋ฅผ ๋ง๋ ๋ค. */\n this.measuredCache.delete(key)\n this.measuredCache.set(key, { at: Date.now(), value, yields })\n if (this.measuredCache.size > this.MEASURED_MAX) {\n const oldest = this.measuredCache.keys().next()\n if (!oldest.done) this.measuredCache.delete(oldest.value)\n }\n return value\n }\n\n /**\n * **์๋ณธ์ด ์ ์ธํ ์๊ทน์ ์ฃ๋๋ค** โ ์ฌ๊ธฐ๋ํด๋ ์ด์ ์๊ฒ (2026-08-19).\n *\n * โโ ๋ฌด์์ด ๋ฌ๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๋ฐ๋ชจ์ ์๋๋ฆฌ์ค๋ ์๋ ์ฝ๋๊ฐ ๋ฉ๋ชจ๋ฆฌ์๋ง ์ค์๋ค. ๊ทธ๋์ ํธ์์ ์ฌ๊ธฐ๋ํ๋ฉด ์๊ทน์ด ์ฌ๋ผ์ง๊ณ ๊ตฌ์กฐ๋ง\n * ์ ์๋ ํธ์์ด ๋จ์๋ค(์์
0ยท์ค๋ 0) โ ใ์ด์ ์๋ ๋ฐ๋ชจใ๊ฐ **์ฒซ ์ฌ๊ธฐ๋๊น์ง๋ง** ์ด์๋ค.\n *\n * ์๊ทน์ ์ง์ **์๋ณธ**์ด๋ค(`TwinReference.connectionConfig.scenario`, ADR-0029 ยท\n * `plans/simulator-as-source.md` ยง4): ๋ฌด์์ด ๋ค์ด์ค๊ณ ๋ฌด์จ ์ฃผ๋ฌธ์ด ๋๋์ง๋ ์๋ฎฌ๋ ์ดํฐ๊ฐ ์ ํ๋ ์ฌ์ค์ด๊ณ \n * ํธ์์ ๋ฐ์ํ๋ค. ํธ์์ ์ ์ถ์ ๋ง๋ค๋ฉด ADR-0029 ๊ฐ ๊ฑท์ด๋ด์ผ ํ ํ๋ฉด์ด ํ๋ ๋์ด๋๋ค.\n *\n * ํ์ ์ ์์ ํจ์๊ฐ ํ๋ค(`planStimulus`) โ ๋ฏธ๋ฌ์ ์ฃ์ง ์๊ณ , ๊ฒ์ฌ๋ฅผ ํต๊ณผํ์ง ๋ชปํ ์ ์ธ์ ํ์ฐ์ง ์๊ณ \n * (๊ทธ ์ด๋ ฅ์ด ์๋ค: ์๋ชป๋ ์ ์ธ ํ๋๊ฐ ๋ค์ ํฑ์์ ์๋ฒ๋ฅผ ๋ด๋ ธ๋ค), ๋ชป ์ค์ ์ด์ ๋ **๋งํ๋ค.**\n */\n private static async installStimulus(domainId: string, instanceId: string, inst: InstanceRuntime): Promise<void> {\n let config: any\n try {\n const ref = await getRepository(TwinReference).findOne({ where: { domain: { id: domainId }, source: instanceId } })\n config = ref?.connectionConfig\n } catch (err: any) {\n console.warn(`[twin-engine] \"${instanceId}\": could not read the declared stimulus โ ${err?.message ?? err}`)\n return\n }\n const plan = planStimulus(config, { hasScenarioEngine: !!inst.runtime?.scenario, mode: inst.mode }, validateScenario as any)\n if (plan.action === 'skip') {\n /* ์ ์ธ์ด ์๋ ๊ฒ์ ์ ์์ด๋ฏ๋ก ์กฐ์ฉํ ์ง๋๋ค. ๋๋จธ์ง ์
์ **๋งํ๋ค** โ ์ ์ธํ๋๋ฐ ์ ์ค๋ฆฐ ์ํ๋ค. */\n if (plan.reason !== 'none') {\n console.warn(\n `[twin-engine] \"${instanceId}\": a stimulus is declared on its source but was not loaded (${plan.reason}${plan.detail ? `: ${plan.detail}` : ''}).` +\n (plan.reason === 'observed' ? ' This twin runs on observation โ we do not manufacture arrivals for it.' : '')\n )\n }\n return\n }\n try {\n inst.runtime!.scenario.load(plan.scenario)\n inst.runtime!.scenario.start()\n const kinds = (plan.scenario.generators ?? []).map((g: any) => g?.kind).filter(Boolean)\n console.log(`[twin-engine] \"${instanceId}\": stimulus from its source started โ ${kinds.length ? kinds.join(', ') : 'no generators'}.`)\n } catch (err: any) {\n console.warn(`[twin-engine] \"${instanceId}\": the declared stimulus was rejected at load โ ${err?.message ?? err}`)\n }\n }\n\n /**\n * ์๊ทน์ **์๋ณธ์ ์ ์ธํ๋ค** โ ํ๋ก๋น์ ๋ยท๋ฐ๋ชจ ์๋๊ฐ ๋ถ๋ฅด๋ ๋ฌธ.\n *\n * ํธ์์ด ์๋๋ผ ์๋ณธ์ ์ ๋ ์ด์ ๋ ์์ ๊ฐ๋ค(ADR-0029). ์๋ณธ ํ์ด ์์ผ๋ฉด ๋ง๋ค์ง ์๋๋ค โ ์ด๋ค ์๋ณธ์์\n * ์จ ํธ์์ธ์ง ๋ชจ๋ฅด๋ ์ฑ ์๊ทน์ ์ง์ด ๋ถ์ด๋ฉด, ๊ทธ ์๊ทน์ด ์ด๋์ ์๋์ง ์๋ฌด๋ ๋์ง์ ์ ์๋ค.\n */\n static async declareStimulus(domainId: string, instanceId: string, scenario: any): Promise<boolean> {\n const repo = getRepository(TwinReference)\n const ref = await repo.findOne({ where: { domain: { id: domainId }, source: instanceId } })\n if (!ref) {\n console.warn(`[twin-engine] \"${instanceId}\": no source reference โ a stimulus has nowhere to be declared.`)\n return false\n }\n ref.connectionConfig = withStimulus(ref.connectionConfig, scenario)\n await repo.save(ref)\n return true\n }\n\n /**\n * ์ด ํธ์์ด **์ด๋ ฅ์์ ์๊ฐ์ ๋ฐฐ์ด ์์
์ข
๋ฅ๋ค** โ ์ฌ๊ธฐ๋์๋ ๋จ๋ ๊ทผ๊ฑฐ.\n *\n * โโ ์ ํ์ํ๊ฐ (2026-08-18 ์ค์ธก) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ปค๋์ ์๊ธฐ๋ณด๊ณ (`specCoverage()`)๋ **์์
์ด ์๋ก ์๊ธธ ๋** ์ฑ์์ง๋ค. ๊ทธ๋์ ์ฌ๊ธฐ๋ ์งํ์๋ ์ด๋ ฅ์ด\n * ํ๋ถํ ํธ์์์๋ ๋ชฉ๋ก์ด ๋น๊ณ , ใ์ด ํธ์์ด ๋ฌด์จ ๊ณต์ ์ ๋๋ฆฌ๋ใ ํ๋ฉด์ด ๋น์นธ์ด ๋๋ค โ ๊ฐ์ ์ฑ์ธ ๊ณณ์\n * ๋ณด์ฌ์ผ ํ๋ ํ๋ฉด์ด ์ ์ ๊ทธ๋ ์๋ฌด ๋ง๋ ๋ชป ํ๋ค.\n *\n * ๊ทธ ๋น์นธ์ ์ด๋ ฅ๋ก ๋ฉ์ด๋ค: ์ ๋์์ ๋ฐฐ์ด ์ข
๋ฅ๋ **์ถ์ ๊ธฐ๊ฐ ์ด๋ฏธ ๋ตํ ์ ์๋ ์ข
๋ฅ**์ด๋ฏ๋ก, ์ง์ด๋ด๋\n * ๊ฒ์ด ์๋๋ผ ์๋ ์ฌ์ค์ ๊บผ๋ด๋ ๊ฒ์ด๋ค. ๊ฐ์ ์บ์(60์ด)๋ฅผ ์ฐ๋ฏ๋ก ์กฐํ๋ง๋ค ์ ๋์ ๋ค์ ์ ์ง ์๋๋ค.\n */\n static async measuredOperationKinds(domainId: string, instanceId: string): Promise<string[]> {\n const measured = await this.measuredEstimator(domainId, instanceId)\n return Object.keys((measured as any)?.learned ?? {})\n }\n\n /**\n * ์ง๊ธ ์ด ํธ์์ด ์ด๋ค ๋ชจ๋ธ๋ก ๊ตด๋ฌ๊ฐ๋๊ฐ โ ์์ธก ์ถ๋ ฅ ๋ณด์ ์ด **์๊ธฐ๊ฐ ๋ฐฐ์ด ๋ชจ๋ธ**์๋ง ์ ์ฉ๋๋๋ก\n * ๋น๊ตํ๋ ์ง๋ฌธ. ์ฌ๋ฃ๋ ํธ์คํธ๊ฐ ์๋ ๊ฒ(์ค์ธกยท์๋ยท์ ์ธ ๋ช
์ธ)์ด๋ผ ์ปค๋ ๋ฐํ ์ํ์ ๋ฌด๊ดํ๋ค.\n * ์คํจํ๋ฉด undefined โ ๊ทธ๋๋ ๋น๊ต๋ฅผ ํ์ง ์๋๋ค(๋ชจ๋ฅด๋ ๊ฒ์ ๊ทผ๊ฑฐ๋ก ๋ณด์ ์ ๋์ง ์๋๋ค).\n */\n static async modelBasis(domainId: string, instanceId: string): Promise<ModelBasis | undefined> {\n try {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n const model: any = reg?.model\n const measured = await this.measuredEstimator(domainId, instanceId)\n const travel = buildTravelEstimator({ layout: model?.layout, equipment: model?.equipment, unit: model?.unit })\n return { measured: measured?.learned, speeds: travel.speedsByKind, declared: model?.operations }\n } catch {\n return undefined\n }\n }\n\n /**\n * **์ด ํธ์์ด ํ๋ฃจ ๋ช ๋๋ฅผ ๋ผ ์ ์๋๊ฐ** โ ์คํํด ๋ณด์ง ์๊ณ ๋ตํ๋ค.\n *\n * ๊ณ์ฐ์ ์ปค๋์ด ์๊ธฐ ์ํ์์ ํ๋ค(`kernel.capacity`). ์ฌ๊ธฐ์ ํ๋ ์ผ์ **๊ธฐ์ค ์ฃผ๋ฅผ ์ ํด ์ฃผ๋\n * ๊ฒ**๋ฟ์ด๋ค: ๊ณตํด์ผ์ด ์๋ ํ์์ฃผ์ฌ์ผ ํ๋ค โ ๊ณตํด์ผ์ ์ฐ๊ฐ ๊ฐ์ฉ๋์ ๋ฐ๋ก ๊น์ง, ์ด ๊ณต์ฅ์ ํ์์\n * ์ํ์ ์ ํ์ง ์๋๋ค. ์ปค๋์ด ์์๋ก ๊ณ ๋ฅด๊ฒ ๋๋ฉด ๊ทธ ์ฃผ์ ๊ณตํด์ผ์ด ๋ผ์์ ๋ ์ํ์ด ์กฐ์ฉํ ๋ฎ์์ง๋ค.\n *\n * ํธ์์ด ๊ธฐ๋ ์ค์ด ์๋๋ฉด `undefined` ๋ค โ 0 ์ด ์๋๋ค. ๊ธฐ๋ํ์ง ์์ ํธ์์ ์ํ์ 0 ์ด๋ผ๊ณ ๋ตํ๋ฉด ํ๋ฉด์\n * \"์ด ๊ณต์ฅ์ ์๋ฌด๊ฒ๋ ๋ชป ๋ง๋ ๋ค\" ๊ณ ๋งํ๋ค.\n */\n static async capacity(\n domainId: string,\n target: { instanceId?: string; spaceId?: string },\n unitsPerDay: number,\n sampleWeekStartMs: number\n ): Promise<{ instanceId: string; kind?: string; analysis?: any; reason?: 'not-running' | 'no-operations' }[]> {\n /* ๋์์ **๋ฑ๋ก๋ถ**๊ฐ ์ ํ๋ค โ ๊ธฐ๋ ์ค์ธ ๋ฐํ์๋ง ํ์ผ๋ฉด \"์ ๋ ์์ด์ ์ ๋ณด์ด๋ ๊ฒ\" ๊ณผ \"์๋ ๊ฒ\" ์ด\n ๊ตฌ๋ณ๋์ง ์๋๋ค. ํ๋ฉด์ ๊ทธ ๋์ ๋ค๋ฅด๊ฒ ๋งํด์ผ ํ๋ค. */\n const where: any = { domain: { id: domainId } }\n if (target.instanceId) where.instanceId = target.instanceId\n else where.spaceId = target.spaceId\n const registered = await getRepository(TwinInstance).find({ where })\n\n return registered.map(reg => {\n const rt = this.instances[runtimeKey(domainId, reg.instanceId)]\n const kernel: any = rt?.kernel // ํค์ ๋๋ฉ์ธ์ด ์์ผ๋ฏ๋ก ๋จ์ ๋ฐํ์์ ์ง์ ์ ์๋ค\n if (typeof kernel?.capacity !== 'function') return { instanceId: reg.instanceId, kind: reg.kind, reason: 'not-running' as const }\n\n const analysis = kernel.capacity({ unitsPerDay, sampleWeekStartMs })\n /* ๊ณต์ ์ ์ ์ธํ์ง ์์ ํธ์(๋๊ฐ YMSยทWMS)์ **ํ์ ๋์์ด ์๋๋ค.** 0 ์ผ๋ก ์ฑ์ ๋ฃ์ผ๋ฉด\n \"์ผ๋๊ฐ ๋ณ๋ชฉ\" ์ด๋ผ๋ ์๋ ์ฌ์ค์ด ์๊ธด๋ค โ ์ด ๊ฒ์ด ์๋ค๊ณ ๋งํ๋ค. */\n if (!analysis?.operations?.length) return { instanceId: reg.instanceId, kind: reg.kind, reason: 'no-operations' as const }\n return { instanceId: reg.instanceId, kind: reg.kind, analysis }\n })\n }\n\n /**\n * **์์ฐ ๋ฅ๋ ฅ ๋ณด๊ณ ์** โ ISA-95 Part 4 `OperationsCapability`. ๊ตฌ๊ฐ์ ์์ ์ข
๋ฅ๋ก ๊ตฌ๋ถํ๋ค\n * (์ฝ์ ยท๊ฐ์ฉยท๋ฌ์ฑ๋ถ๊ฐ). ์ฉ๋(`capacity`)์ ๋น์จ์ ๋ด๊ณ ์ด๊ฒ์ **๊ตฌ๊ฐ์ ์**์ ๋ธ๋ค.\n *\n * ๋์ ์ ์ ยท๊ฑฐ์ ์ฌ์ ๋ `capacity` ์ **๊ฐ์ ๊ท์จ**์ด๋ค: ๋ฑ๋ก๋ถ๊ฐ ๋์์ ์ ํ๊ณ (์ ๊ธฐ๋ ์ค์ธ ๊ฒ๊ณผ\n * ์๋ ๊ฒ์ ๊ตฌ๋ณํ๋ค), ๊ณต์ ์ ์ ์ธํ์ง ์์ ํธ์์ ํ์ ๋์์ด ์๋๋ผ๊ณ ๋งํ๋ค(0 ์ผ๋ก ์ฑ์ฐ๋ฉด\n * \"์ผ๋๊ฐ ๋ณ๋ชฉ\" ์ด๋ผ๋ ์๋ ์ฌ์ค์ด ์๊ธด๋ค).\n */\n static async operationsCapability(\n domainId: string,\n target: { instanceId?: string; spaceId?: string },\n unitsPerDay: number,\n sampleWeekStartMs: number,\n window: { fromTime: string; toTime: string }\n ): Promise<{ instanceId: string; kind?: string; report?: any; reason?: 'not-running' | 'no-operations' }[]> {\n const where: any = { domain: { id: domainId } }\n if (target.instanceId) where.instanceId = target.instanceId\n else where.spaceId = target.spaceId\n const registered = await getRepository(TwinInstance).find({ where })\n\n return registered.map(reg => {\n const rt = this.instances[runtimeKey(domainId, reg.instanceId)]\n const kernel: any = rt?.kernel\n if (typeof kernel?.operationsCapability !== 'function') {\n return { instanceId: reg.instanceId, kind: reg.kind, reason: 'not-running' as const }\n }\n const report = kernel.operationsCapability({ unitsPerDay, sampleWeekStartMs, window })\n if (!report?.perOperation?.length) return { instanceId: reg.instanceId, kind: reg.kind, reason: 'no-operations' as const }\n return { instanceId: reg.instanceId, kind: reg.kind, report }\n })\n }\n\n /**\n * ๋ฏธ๋ฌ ๊ธฐ๋์ ์ฐ์์ฑ ์จ์ โ ์ด์ด๋ฐ์ ๊ฒ์ **๋งํ๋ค**(์กฐ์ฉํ ์์ง ์๋๋ค).\n *\n * ์ปค๋์ด ๊ทธ ๋ฌธ์ ์ด์ด ๋์ง ์์์ผ๋ฉด ๊ทธ ์ฌ์ค๋ ๋งํ๋ค: ๊ทธ ํธ์์ ์ฌ๊ธฐ๋๋ง๋ค ์ด๋ฆฐ ๊ตฌ๊ฐ์ ์๋๋ค.\n */\n private static seedLiveContinuity(domainId: string, id: string, kernel: any): void {\n const cached = this.recovered[runtimeKey(domainId, id)]?.state\n if (!cached) return\n const plan = planLiveContinuity(cached)\n if (!plan.ackedCount && !plan.attentionSinceCount && !plan.energy) return\n if (typeof kernel.hydrateContinuity !== 'function') {\n console.warn(\n `[twin-engine] kernel for \"${id}\" cannot carry continuity (no hydrateContinuity) โ the open demand window, ` +\n 'its peak and the attention start times are lost on every restart.'\n )\n return\n }\n try {\n kernel.hydrateContinuity(plan.seed)\n } catch (err: any) {\n /* ์ด์ด๋ฐ๊ธฐ๊ฐ ์คํจํด๋ ๋ฏธ๋ฌ๋ ๋์์ผ ํ๋ค โ ๋ค๋ง ๋ฌด์์ ์์๋์ง ๋งํ๋ค. */\n console.warn(`[twin-engine] continuity seed failed for \"${id}\" โ starting without it: ${err?.message ?? err}`)\n return\n }\n const carried = [\n ...(plan.energy ? ['energy accumulation (open window, totalizer baselines, peak)'] : []),\n ...(plan.ackedCount ? [`${plan.ackedCount} acknowledged attention(s)`] : []),\n ...(plan.attentionSinceCount ? [`${plan.attentionSinceCount} attention start time(s)`] : [])\n ].join(', ')\n console.log(`[twin-engine] mirror \"${id}\" carried over ${carried} โ observation axes come from the source.`)\n }\n\n static start(id: string, domainId: string, kind: string, model: TwinModelDef, restartPolicy?: RestartPolicy, purpose?: string, resumeFrom?: number): InstanceRuntime {\n const key = runtimeKey(domainId, id)\n if (this.instances[key]) return this.instances[key]\n\n const Kernel = kernelFor(kind)\n const kernel: TwinKernel = new Kernel(domainId, undefined, this.productionSpecOf(model))\n kernel.loadTwinModel(model) // ๊ตฌ์กฐ๋ง. ์ํ๋ ์๋ ์์คํํธ๊ฐ ์ฃผ์
ํ๋ค.\n this.applyOperations(kernel, model, id) // ์๊ฐยท์์จ ๋ช
์ธ(์์ผ๋ฉด) โ ์์ผ๋ฉด ์ปค๋ ๊ธฐ๋ณธ๊ฐ\n /* ์ถ์ ๊ธฐ๋ DB ์กฐํ๋ฅผ ํฌํจํด ๋น๋๊ธฐ โ ๊ธฐ๋์ ๋ง์ง ์๊ณ ๋ถ๋๋ค(๋ถ๊ธฐ ์ ์์
์ ๋ช
์ธยท์์๋ก ์ฐ์ถ). */\n this.installEstimators(kernel, domainId, id, model).catch(err => console.warn('[twin-engine] estimator install failed', err?.message))\n this.warmStart(domainId, id, kernel, purpose)\n /*\n * **๋ฒํธ๋ฅผ ์ด์ด ์ผ๋ค** โ ์ ๋์ ์ด๋ฏธ ์๋ ๋ฒํธ์ ๊ฒน์น์ง ์๊ฒ.\n *\n * ์ ๋์ด ๋น์ด ์์ผ๋ฉด(0) ์๋ฌด ์ผ๋ ์ ํ๋ค. ๋น์ด ์์ง ์์๋ฐ 0๋ถํฐ ๋ค์ ์ธ๋ฉด ๊ฐ์ ํธ์์ ๊ฐ์\n * ๋ฆฌ๋น์ ์ด ๋ ์๊ธฐ๊ณ , ์ฌ์ ์์๊ฐ ๋ค์์ด๋ฉฐ, ์๊ฐ์ฌํ์ด ์๋ฑํ ์์ ์ ๋ตํ๋ค โ ์ค๋ฅ๋ ์ ๋๋ค.\n */\n if (resumeFrom && typeof (kernel as any).resumeRevision === 'function') (kernel as any).resumeRevision(resumeFrom)\n /*\n * โโ ์ด ํธ์์ ์๊ณ๋ฅผ **์ง๊ธ**์ ๋ง์ถ๋ค (2026-08-15) โโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ปค๋์ ๊ธฐ๋ณธ ๊ธฐ์ค์ ์ ์์(2026-01-01)๋ค. ๊ทธ๋๋ก ๋๋ฉด ์๋ฎฌ ํธ์์ ์ ๋ ์๊ฐ์ด **์ฌ๊ธฐ๋๋ง๋ค\n * ๋๊ฐ๊ฒจ** ๋ฉฐ์น ์น ์ฌ๊ฑด์ด ์ ๋ถ ๊ฐ์ ๋ถ์ ๋ชฐ๋ฆฐ๋ค โ ใ์ธ์ ์์๋ ์ผ์ธ๊ฐใ๋ฅผ ๋์ง์ ์ ์๊ณ ,\n * ์ค ์๊ฐ์ผ๋ก ์ฐฝ์ ์๋ฅด๋ ์ฑ๊ณผยท์ด๋ ฅ ์ง์์๋ ๊ทธ ํธ์์ด ์์ ๋ณด์ด์ง ์๋๋ค.\n *\n * ์ฌ๊ธฐ๋ํ๋ฉด ๊ทธ๋งํผ ์๊ณ๊ฐ ์์ผ๋ก ๋ฐ๋๋ฐ, ๊ทธ๊ฒ์ด ์ฌ์ค์ด๋ค: ๊ทธ ์ฌ์ด ์ด ํธ์์ ๋์ง ์์๊ณ \n * ์ ๋์ ๋น ๊ตฌ๊ฐ์ด ๊ทธ ์ฌ์ค์ ๋งํ๋ค.\n */\n kernel.setClockOrigin?.(Date.now())\n const runtime: TwinRuntimeType = new TwinRuntime(kernel)\n\n /* subscribe ๋ RuntimeSubscription({ unsubscribe() }) ๋ฐํ โ () => void ๋ก ๊ฐ์. */\n /*\n * **๋ชจ๋๋ฅผ ์ ์ด ๋๋ค** (2026-08-18 ์ค์ธก์ผ๋ก ๊ณ ์นจ).\n *\n * ์๋ฎฌ ๊ฒฝ๋ก๋ `mode` ๋ฅผ ๋น์ ๋์๊ณ (ใ๋ฏธ์ง์ =simใ์ด๋ผ๋ ๊ท์ฝ์ ๊ธฐ๋), ๋ผ์ด๋ธ๋ง ์ ์๋ค. ๊ทธ๋์\n * `modeOf()` ๊ฐ **๋๋ ์๋ฎฌ๋ ์ด์
์ undefined** ๋ฅผ ๋ตํ๊ณ , ์ ์ธยท์ฒ ํ์ ๋ต์ด ใ์ ์ฅํ๋คใ๋ก ๋๊ฐ๋ค โ\n * ์ค์ ๋ก๋ ๋๋ ์ปค๋์ด ์ ์๋ฅผ ๊ทธ๋๋ก ์ฐ๊ณ ์ฌ๊ธฐ๋ ๋ ๋ฐ๋๋ฐ, ๊ทธ ์ฌ์ค์ด ๋ต์์ ์ฌ๋ผ์ง ๊ฒ์ด๋ค.\n * ๊ท์ฝ์ ๊ธฐ๋๋ ๋์ ์ฌ์ค์ ์ ๋๋ค: ใ๋๊ณ ์๋ใ๋ฅผ ๋ฌป๋ ์ชฝ์ด ๊ทธ ๋ต์ ๋ฐ์์ผ ํ๋ค.\n */\n const inst: InstanceRuntime = {\n id,\n domainId,\n mode: 'sim',\n runtime,\n kernel,\n /* ์ ์ฑ
์ ๋ถ๋ฅด๋ ์ชฝ์ด ์ ์ธํ๋ค โ ์ฌ๊ธฐ์ ๊ณ ๋ฅด๋ฉด ๊ฐ์ ํธ์์ด ๋ถ๋ฅด๋ ์๋ฆฌ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ฌ๊ธฐ๋ํ๋ค. */\n restartPolicy: readRestartPolicy(restartPolicy, `start(\"${id}\")`),\n spaceId: (model as any)?.spaceId,\n unsub: () => {}\n }\n this.instances[key] = inst\n /* ๋ค์ ์ธ์ ์ผ๋ฏ๋ก ์ง๋ ์ ์ง ์ด์ ๋ ์ฌ์ค์ด ์๋๋ค โ ๋จ๊ฒจ ๋๋ฉด ๋๋ ํธ์์ด ใ๊ตถ๊ฒจ์ ๋ฉ์ท๋คใ๊ณ ๋งํ๋ค. */\n this.stopNotes.delete(key)\n delete this.recovered[key] // ์์คํํธ๋ก ์ปค๋์ ์ฎ๊ฒจ ์ฌ์๋ค โ ์ด์ ๋ผ์ด๋ธ๊ฐ ์ง์ค์ด๋ค.\n /* ์๋ณธ์ด ์ ์ธํ ์๊ทน โ ๊ธฐ๋์ ๋ง์ง ์๋๋ค(์ถ์ ๊ธฐ์ ๊ฐ์ ๊ท์จ). ๋ชป ์ค์์ผ๋ฉด ๊ทธ ์ฌ์ค์ ๋งํ๋ค. */\n this.installStimulus(domainId, id, inst).catch(err => console.warn(`[twin-engine] \"${id}\": stimulus install failed โ ${err?.message ?? err}`))\n\n /* ๋ผ์ด๋ธ ๋ฐ์ธ๋ฉ(P3): data ์ฑ๋ ํํฐ๊ฐ subdomain ์ ๋ณด๋ฏ๋ก Domain ๊ฐ์ฒด๋ฅผ 1ํ ํด์ํด ๋๋ค. */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n\n /* State ์ฑ๋: runtime.subscribe(snapshotโdeltaโclock) โ pubsub ๋ฐฉ์ก(๊ตฌ๋
๋ฆฌ์กธ๋ฒ๊ฐ instanceId ํํฐ). */\n const sub = runtime.subscribe((msg: SubscriptionMessage) => {\n this.publishGuarded(\n 'twin-state',\n { twinState: { instanceId: id, kind: msg.kind, revision: (msg as any).revision, payload: msg } },\n `twin-state:${id}`\n )\n /* ์์ + ๋ผ์ด๋ธ ๋ฐ์ธ๋ฉ ๋ธ๋ฆฌ์ง: delta ๋ง๋ค ์ ๋ ์ ์ฅ + ์ํฐํฐ๋ณ data(tag:) publish โ ๋ณด๋ ์ปดํฌ๋ํธ ๋ผ์ด๋ธ. */\n if (msg.kind === 'delta') {\n this.persist(domainId, id, msg).catch(err => console.error('twin persist fail', err))\n /*\n * โโ ๋ฐฉ์ก์ **๋ชจ์์** ํ ๋ฒ (2026-08-14 ์ค์ธก์ผ๋ก ์ก์) โโโโโโโโโโโโโโโโโโโโ\n * ์ฌ๊ธฐ์ ๊ณง๋ฐ๋ก ๋ฐฉ์กํ๊ณ ์์๋ค. ๊ทธ๋ฐ๋ฐ ์ปค๋์ ํ ๋ฒ์ tick ์์ ์ฌ์ค์ **์ฌ๋ฌ ๊ฐ** ๋ธ๋ค\n * (์์ฝยท๋ฐฐ์นยท์๋ฃโฆ). ๊ทธ๋์ tick ํ๋๊ฐ ์ ์ํ ํฌ์์ ์๋ฐฑ ๋ฒ ๋ฐ๋ณตํ๋ค โ `order-check`\n * ํธ์์์ **ํฑ ํ๋๊ฐ 35์ด**๋ฅผ ๋จน๊ณ (๋จ๊ณ ํฉ์ 32ms ์๋ค: ์๊ฐ์ ๋ฐ๋ณต ํ์์ ์์๋ค) ๊ทธ\n * 35์ด ๋์ ์ด๋ฒคํธ ๋ฃจํ๊ฐ ๋งํ ๊ตฌ๋
์๊ฐ ์๋ฌด๊ฒ๋ ๋นผ๋ด์ง ๋ชปํ๋ค. ๋ฐ๋ฆฐ push ๊ฐ 1024๋ฅผ ๋๋\n * ์๊ฐ pubsub ์ด ๋์ง๊ณ , ๊ทธ ์์ธ๊ฐ ํ์ด๋จธ ์ฝ๋ฐฑ์ ํ๊ณ ์ฌ๋ผ์ **ํธ์คํธ๊ฐ ์ฃฝ์๋ค.**\n *\n * ๋ผ์ด๋ธ๋ ์ด๋ฏธ dirty ํ์ + ์ฃผ๊ธฐ flush ๋ก ์ด ๋ฌธ์ ๋ฅผ ํ์ด ๋์๋ค(BROADCAST_COALESCE_MS).\n * ์๋ฎฌ๋ง ๊ทธ ๊ท์จ ๋ฐ์ ์์๋ค โ ๊ฐ์ ๊ท์จ๋ก ๋ค์ธ๋ค(์ต์ -์ํ ์ฑ๋์ด๋ผ ์ค๊ฐ ์ํ๋ฅผ ๋ชจ๋\n * ๋ณด๋ผ ์ด์ ๊ฐ ์๋ค: 200ms ๋ง๋ค ๋ง์ง๋ง ๊ฒ ํ๋๋ฉด ํ๋ฉด์ ๊ฐ๋ค).\n */\n inst.dirty = true\n this.ensureBroadcastCoalescer()\n }\n })\n inst.unsub = () => sub.unsubscribe()\n\n /* ๋ณต๊ตฌ ์ต์ปค: ๋ ์ง์คํธ๋ฆฌ์ model/kind/status/restartPolicy ์์(์ฌ๋ถํ
์ ์ด๊ฒ ์์ด์ผ replayยท์ ์ธ ๊ฑฐ๋ ๊ฐ๋ฅ). */\n this.register(domainId, id, kind, model, 'running', inst.restartPolicy).catch(err => console.error('twin register fail', err))\n\n /* ์์ปค tick โ ์ค์ผ๋ ํค์ setInterval(๋ฉ์ธ ๋ฃจํ). ๊ธด ์๋ฎฌ ์คํ-๋ฃจํ(worker thread)๋ ์ค์ผ์ผ ํ๋๋(ํฅํ, ยงhost ๊ฒฝ๊ณ). */\n inst.timer = setInterval(() => this.tickGuarded(domainId, id, runtime), this.TICK_MS)\n return inst\n }\n\n /**\n * live-๋ชจ๋ ๊ธฐ๋ โ **๊ด์ธก ๋ชจ๋ ์ปค๋**๋ก ์ค ์ด๋ฒคํธ๋ฅผ ๋ฏธ๋ฌํ๋ค(ํตํฉ P2).\n *\n * ์์ ์๋ `StateProjector` ๋ฅผ ์ธ์ ๋ค. ๊ทธ๋์ ๋ผ์ด๋ธ์๋ **์ปค๋์ด ์์๊ณ **, ๊ทธ ํ๋ ๋๋ฌธ์ ์ฐํ๊ฐ\n * ์ค์ค์ด ์๊ฒผ๋ค: ์์ธกํ๋ ค๋ฉด ์์ ์ปค๋์ ์ธ์์ผ ํ๊ณ (`buildForecastKernel`), ์ฃผ๋ชฉ ์ ํธ๋ฅผ ํธ์คํธ๊ฐ\n * ๋ง๋ถ์ฌ์ผ ํ๊ณ (`withLiveAttentions`), AI ์์ธก ๋๊ตฌ๋ ๋ฏธ๋ฌ์์ \"์ฐพ์ ์ ์๋ค\" ๋ก ๋๋ฌ๋ค.\n *\n * ์ด์ ๋ผ์ด๋ธ ์ธ์คํด์ค๋ **์ปค๋์ด๋ค.** ๊ฐ์ ๊ท์น(`ObservedReducer`)์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์ ๊ณ , ์ฃผ๋ชฉ ์ ํธ๋ฅผ\n * ์ค์ค๋ก ๋ด๊ณ , ๊ทธ ์๋ฆฌ์์ `fork` ํด ์์ธกํ๋ค. ๊ตฌ๋๋ง ๋ค๋ฅด๋ค โ sim ์ `tick`, live ๋ `apply`.\n *\n * ์ค ์ด๋ฒคํธ์ = reference ์ด๋ํฐ openLiveFeed โ face2-adapter.ingest โ CanonicalEnvelope โ ingestLive().\n */\n /**\n * ๋ชจ๋ธ์ด ์ค์ **์์ฐ ์ ์**(๋ ์ํผยท๋ผ์ฐํธยท๋ฐ์ธ๋ฉ)๋ฅผ ๊บผ๋ธ๋ค โ ์ปค๋์ ์ ์-๊ตฌ๋ ๋ชจ๋ ์
๊ตฌ.\n *\n * โโ ์์ ๋ ๋ฌด์์ด ์ผ์ด๋ฌ๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ปค๋์๋ ์ ์-๊ตฌ๋ MES ๊ฒฝ๋ก๊ฐ ์๋๋ฐ **ํธ์คํธ๊ฐ ๊ทธ๊ฒ์ ํ ๋ฒ๋ ๋๊ธฐ์ง ์์๋ค.** ๊ทธ๋์ ๋ชจ๋ MES\n * ํธ์์ด **ํ๋์ฝ๋ฉ๋ ๋ ๊ฑฐ์ ํ๋ฆ**์ผ๋ก ๋์๋ค โ ํ์ฅ ๋ ์ํผ๋ฅผ ์๋ฌด๋ฆฌ ์ ์ฑ๊ป ์ ์ด๋ ์ปค๋์ ๊ทธ๊ฒ์\n * ๋ณด์ง ๋ชปํ๊ณ ํ ์ด ๋ถํ์ผ๋ก ํ ์ด ์ ํ์ ๋ง๋ค์๋ค. ์ ์ธ๊ณผ ์คํ์ด ๊ฐ๋ผ์ ธ ์๋ ์๋ฆฌ๋ค.\n *\n * ๋ชจ๋ธ์ ์์ผ๋ฉด `undefined` โ ๋ ๊ฑฐ์ ๊ฒฝ๋ก ๊ทธ๋๋ก๋ค(๊ธฐ์กด ํธ์์ ๊ฑฐ๋์ ๋ฐ๊พธ์ง ์๋๋ค).\n */\n /**\n * ์์ฐ ์ ์ธ์ ๊บผ๋ธ๋ค โ ์ปค๋ ์์ฑ์์ ๋๊ธด๋ค.\n *\n * **์ ์ด๋ฆ(`mesSpec`)์ ์ฝ์ง ์๋๋ค.** ๊ทธ๊ฒ์ ๊ณ์ฝ์ ์ ์ธ์กฐ์ฐจ ์๋ ํ๋์๊ณ (MES ์ปค๋ ์์ฑ์ ์ธ์\n * ์ด๋ฆ์ด ๊ทธ๋๋ก ๊ตณ์ ๊ฒ), ์ผ๋ฐ ๊ธฐ์ ์ ํ ์์คํ
์ด๋ฆ์ด ๋ถ์ด ์์๊ธฐ ๋๋ฌธ์ ์ฐฝ๊ณ ํธ์์ด ์ด ์๋ฆฌ๋ฅผ\n * ์ฐ์ง ๋ชปํ๋ค. ๋ณ๋ช
์ผ๋ก ๋จ๊ฒจ ๋๋ฉด ๊ทธ ํผ๋์ด ๊ณ์๋๋ฏ๋ก ํ๋๋ก ํต์ผํ๋ค.\n *\n * ์ ์ด๋ฆ๋ง ๊ฐ์ง ๋ชจ๋ธ์ด ์์ผ๋ฉด **์กฐ์ฉํ ์์ฐ ์ ์ธ์ ์๋ ๋์ ๋ถ๋ช
ํ ๋ฉ์ถ๋ค** โ ๊ทธ ํธ์์ ๊ณต์ ์ด\n * ์๋ ์ฑ๋ก ๋๊ฒ ๋๊ณ (๋ผ์ธ์ด ์ ์๋ ์ฐฝ๊ณ ), ์์ธ์ ์ฐพ๊ธฐ ์ด๋ ต๋ค.\n */\n private static productionSpecOf(model: TwinModelDef | undefined): any {\n const legacy = (model as any)?.mesSpec\n if (legacy && !(model as any)?.productionSpec) {\n throw new Error(\n 'the twin model carries the retired `mesSpec` field โ rename it to `productionSpec` ' +\n '(same shape; the name was tied to one kernel while the declaration is ISA-95 operations + BOM)'\n )\n }\n return (model as any)?.productionSpec\n }\n\n /**\n * ํ์ฅ(๊ณต๊ฐ)์ **์๊ฐ ๊ธฐ์ค**์ ๋ชจ๋ธ์ ์น๋๋ค โ ์ปค๋์ด ๊ต๋์ `HH:MM` ์ ์ฝ์ ๊ธฐ์ค.\n *\n * **ํ
๋ํธ๊ฐ ์๋๋ผ ๊ณต๊ฐ์ด ๊ถ์๋ค.** ํ ํ
๋ํธ๊ฐ Rosarito(ํํ์)์ ํ๊ตญ ๊ณต์ฅ์ ํจ๊ป ๊ฐ์ง ์ ์๊ณ ,\n * ํ
๋ํธ ๋จ์(`Domain.timezone`)๋ก ๋๋ฉด ๋ ์ค ํ๋๋ ๋ฐ๋์ ํ๋ฆฐ๋ค. ๊ทธ๋์ ์ธ์คํด์ค๊ฐ ์ฐ๊ฒฐ๋ ๊ณต๊ฐ์\n * `timezone` ์ ์ฝ๋๋ค. ๊ณต๊ฐ์ด ๋งํ์ง ์์ผ๋ฉด **ํ
๋ํธ๋ก ๋ด๋ ค๊ฐ์ง ์๋๋ค** โ ์๋ชป๋ ์
์๋ก ๋ตํ๋ ๊ฒ์ด\n * ๋ชจ๋ฅด๋ ๊ฒ๋ณด๋ค ๋์๋ค(๊ทธ๋๋ ์ปค๋์ด UTC ๋ก ์ฝ๊ณ , ๊ทธ ๊ธฐ๋ณธ๊ฐ์ ๊ณ์ฝ์ ๋ฐํ์ ธ ์๋ค).\n *\n * ์ปค๋์ zero-dep ์ด๋ผ ์๊ฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ฐ์ง ์์ผ๋ฏ๋ก **๋ถ ์คํ์
**์ผ๋ก ํ์ด ๋๊ธด๋ค. ๊ทธ ๊ฐ์\n * ์ง๊ธ ๊ณ์ ์ ๊ฒ์ด๋ค(์ผ๊ด์ ์ฝ์๊ฐ) โ ๊ณ์ ์ ๋๋ ๊ธด ์์ธก์ ํ ์๊ฐ ์ด๊ธ๋๋ค(๊ณ์ฝ์ ๋ช
์).\n */\n static async withSpaceTimeBase(model: TwinModelDef, domainId: string, spaceId?: string): Promise<TwinModelDef> {\n const sid = spaceId ?? (model as any)?.spaceId\n if (!sid) return model\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId: sid } }).catch(() => null)\n const offset = utcOffsetOf(space?.timezone)\n if (offset === undefined) {\n if (space?.timezone) console.warn(`[twin-engine] space \"${sid}\" declares time zone \"${space.timezone}\" but it is not a known IANA zone โ times will be read as UTC.`)\n return model\n }\n return { ...model, utcOffsetMinutes: offset }\n }\n\n static startLive(id: string, domainId: string, kind: string, model: TwinModelDef): InstanceRuntime {\n const key = runtimeKey(domainId, id)\n if (this.instances[key]) return this.instances[key]\n const Kernel = kernelFor(kind)\n const kernel: any = new Kernel(domainId, undefined, this.productionSpecOf(model))\n kernel.loadTwinModel(model)\n /* **์ธ์ฐ๋ ์ชฝ์ด ์๋ ์ฌ์ค์ ์ธ์ธ ๋ ๋งํ๋ค.** ์์ ์๋ ์ฒซ ์ด๋ฒคํธ๊ฐ ๋์ฐฉํด์ผ ์ปค๋์ด ์ค์ค๋ก๋ฅผ\n ๊ด์ธก ๊ตฌ๋์ผ๋ก ์ฌ๊ฒผ๊ณ , ๊ทธ๋์ ์์ง ์๋ฌด๊ฒ๋ ๋ชป ๋ฐ์ ๋ฏธ๋ฌ๋ ์๋ฎฌ๋ ์ด์
์ทจ๊ธ์ ๋ฐ์๋ค. */\n kernel.observe?.()\n this.applyOperations(kernel, model, id) // ๋ช
์ธ๋ ๋ผ์ด๋ธ์๋ ์ค๋ฆฐ๋ค(์์ธก ์๊ฒฉ์ด sim ๊ณผ ๊ฐ์์ง๋ค)\n /* `projector` ํ๋๋ ์ ์ด๋ฆ์ผ๋ก ๋จ๊ธด๋ค โ ์๋น์ฒ๊ฐ `snapshot()` ์ ๋ถ๋ฅด๋ฏ๋ก ์์ ์ด๋ํฐ๋ก ์๋๋ค.\n * (P3 ์์ ์๋น์ฒ๋ฅผ ์ปค๋ ์ดํ๋ก ๋ฐ๊พธ๋ฉด ์ฌ๋ผ์ง๋ค.) */\n const projector = { apply: (e: CanonicalEnvelope) => kernel.apply(e), snapshot: () => kernel.getSnapshot() }\n const inst: InstanceRuntime = { id, domainId, mode: 'live', restartPolicy: 'resync', kernel, projector, oee: new OeeAccumulator(), spaceId: (model as any)?.spaceId, unsub: () => {} }\n /*\n * โโ ์ปค๋์ด **ํ์ ์ผ๋ก ๋ธ ์ฌ์ค**๋ ์ ๋์ ๋จ๋๋ค (2026-08-14 ์ค์ธก์ผ๋ก ์ก์) โโโโ\n *\n * ๋ผ์ด๋ธ๋ ์ธ์
๋ดํฌ๋ง ์ ๋์ ์ ๊ณ ์์๋ค(`ingestLive`). ๊ทธ๋ฐ๋ฐ ์ปค๋์ ๊ด์ธก์ ์ ๋ค๊ฐ **์๊ธฐ ์ฌ์ค**์\n * ๋ธ๋ค โ ์๋์ง์ ์์ ๊ตฌ๊ฐ ๋ง๊ฐยทํผํฌ ๊ฒฝ์ ยท๊ฐ์ถ ์ ์์ด ๊ทธ๋ ๋ค(`emitOp`). ๊ทธ๊ฒ์ ๊ตฌ๋
ํ๋ ๊ณณ์ด\n * ์์ด์ ๊ทธ ์ฌ์ค๋ค์ด **์ปค๋ ์์์ ์ฌ๋ผ์ก๋ค**: ํ๋ณธ 48๊ฑด์ด ์ ๋์ ์์๋๋ฐ ๊ตฌ๊ฐ ๋ง๊ฐ์ 0๊ฑด์ด์๊ณ ,\n * ์ ๋์ ์ฝ๋ ์ฑ๊ณผ ํ๋ฉด์ ์ ๋ ฅ ํ์ผ์ ์์ํ ๋์ค์ง ์์๋ค.\n *\n * sim ์ `runtime.subscribe` ๋ก ๊ฐ์ ์ผ์ ํ๋ค โ ๋ผ์ด๋ธ์๋ง ๊ทธ ๋ฐฐ์ ์ด ์์๋ค.\n *\n * **์ธ์
์ ์ฌ๋ฐฉ์ถ์ ๊ฑธ๋ฌ๋ธ๋ค**: `apply()` ๋ ๋ฐ์ ๋ดํฌ๋ฅผ ๊ตฌ๋
์์๊ฒ ๊ทธ๋๋ก ํ๋ฆฐ๋ค(ํธ์คํธ๊ฐ ๋ ๋ชจ๋์์\n * ๊ฐ์ ๋ฐฐ์ ์ ์ฐ๊ฒ ํ๋ ค๊ณ ). ๊ทธ๊ฒ๊น์ง ์ ์ผ๋ฉด ์ธ์
์ด ์ ๋์ ๋ ๋ฒ ๋ค์ด๊ฐ๋ค โ ๊ทธ๋์ ๋ฐฉ๊ธ ๋ฃ์ ๊ฒ๊ณผ\n * **๊ฐ์ ๊ฐ์ฒด**์ธ์ง ๋ณด๊ณ ๊ฑด๋๋ด๋ค(id ๋น๊ต๋ ์ด๋ํฐ๊ฐ id ๋ฅผ ์ด๋ป๊ฒ ๋ง๋๋์ง์ ๊ธฐ๋๊ฒ ๋์ด ์ฝํ๋ค).\n */\n const applying = new WeakSet<object>()\n inst.applying = applying\n inst.unsub = kernel.onEvent?.((e: CanonicalEnvelope) => {\n if (e && typeof e === 'object' && applying.has(e as object)) return // ์ธ์
์ ์ฌ๋ฐฉ์ถ โ ์ ๋์ ์ธ์
์์ ํ ๋ฒ๋ง\n ;(inst.pendingJournal ?? (inst.pendingJournal = [])).push(e)\n /* ์ปค๋์ด ๋ธ ์ฌ์ค๋ ์ํ๋ฅผ ๋ฐ๊พผ๋ค(ํผํฌยท๋ง๊ฐ) โ ๋ค์ ๋ฐฉ์ก ์ฃผ๊ธฐ์ ์ค๋ฆฐ๋ค. */\n inst.dirty = true\n this.ensureBroadcastCoalescer()\n }) ?? (() => {})\n /* ์ถ์ ๊ธฐ(์ค์ธกยท๊ฑฐ๋ฆฌ)๋ ๋ผ์ด๋ธ์ ๋ถ์ธ๋ค โ ์์ธก์ด ์์๋ก ๊ณ์ฐ๋์ง ์๊ฒ. ๊ธฐ๋์ ๋ง์ง ์๋๋ค. */\n this.installEstimators(kernel, domainId, id, model).catch(err => console.warn('[twin-engine] estimator install failed', err?.message))\n inst.metrics = { ingestedTotal: 0, broadcastTotal: 0, journaledTotal: 0, ingestRate: 0, broadcastRate: 0, journalRate: 0, backlog: 0, _accIngest: 0, _accBroadcast: 0, _accJournal: 0, _windowStartMs: Date.now() }\n this.instances[key] = inst\n /* ๋ฏธ๋ฌ์๋ ๋ถ๋ฅธ๋ค โ ์ ์ธ์ด ์์ผ๋ฉด ใ๋ฏธ๋ฌ์๋ ์ฃ์ง ์๋๋คใ๊ณ ๋งํด์ผ ํ๋ค(์กฐ์ฉํ ๋ฌด์ ๊ธ์ง). */\n this.installStimulus(domainId, id, inst).catch(err => console.warn(`[twin-engine] \"${id}\": stimulus check failed โ ${err?.message ?? err}`))\n /*\n * **์์ฒ์ด ๋ํ์ด ์ฃผ์ง ์๋ ๊ฒ๋ง ์๋๋ค** (2026-08-18 ์ค์ธก์ผ๋ก ๋ถ์).\n *\n * ๋ฏธ๋ฌ๋ ์ค๋ซ๋์ ์๋ฌด๊ฒ๋ ์ด์ด๋ฐ์ง ์์๋ค โ ์ง์ค์ด ์์ฒ์ ์์ผ๋ ์ณ์ ํ๋จ์ด์์ง๋ง, ์์ฒ์ด **์ ์ด์\n * ๋ค์ ๋งํด ์ฃผ์ง ์๋ ์ถ**๊น์ง ํจ๊ป ๋ฒ๋ ธ๋ค: ์ด๋ฆฐ 15๋ถ ๊ตฌ๊ฐ์ ๋์ ยท์ ์ฐ ๊ธฐ์ค์ ยท๊ด์ธก ์ดํ ์ต๋, ๊ทธ๋ฆฌ๊ณ \n * ํ์ธํด ๋ ์ ํธ์ ์กฐ๊ฑด์ด ์ธ์ ๋ถํฐ์ธ์ง. ๊ทธ๋์ ์ฌ๊ธฐ๋ํ๋ฉด ์ค๋ฅ ์์ด ๊ฐ์ด ์์์ก๋ค(๊ทธ ๊ตฌ๊ฐ์ ์ ๋ ฅ๋๊ณผ\n * ํผํฌ๊ฐ ๋ถํ
์ดํ๋ก๋ง ์กํ๊ณ , ์ธ ์๊ฐ์งธ ์ง์๋ ๊ฒฝ๋ณด๊ฐ ใ0์ด์งธใ๊ฐ ๋๋ค โ ์๊ธ์ด ๊ฑธ๋ฆฐ ์๋ค).\n *\n * ๊ด์ธก ์ถ(์ฌ๊ณ ยท์์นยท์ค๋น)์ **์ฌ์ ํ ์ฌ์ง ์๋๋ค** โ ๋ค์ ๊ณ์ธก์ด ์ ์ ํ๊ณ , ์ฌ์ผ๋ฉด ๋ ๋ ๋ฌผ๊ฑด์ด\n * ๋์ด์๋๋ค. ๋ฌด์์ ๋๊ธธ์ง๋ `planLiveContinuity` ๊ฐ ๊ณ ๋ฅด๊ณ , ์ด๋ป๊ฒ ํก์ํ ์ง๋ ์ปค๋์ด ์ ํ๋ค.\n */\n this.seedLiveContinuity(domainId, id, kernel)\n delete this.recovered[key]\n /* ๋ผ์ด๋ธ ๋ฐ์ธ๋ฉ(data ์ฑ๋) subdomain ํํฐ์ฉ Domain 1ํ ํด์(sim ๊ณผ ๋์ผ). */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n /* ์ ๋ revision ์นด์ดํฐ ์๋ โ ๊ธฐ์กด ์ ๋ ์ต๋์น์์ ์ด์ด๋ถ์(์ฌ๊ธฐ๋ ์ revision ์ถฉ๋ ๋ฐฉ์ง). ์ดํ ์ธ๋ฉ๋ชจ๋ฆฌ ์ฆ๊ฐ. */\n getRepository(TwinEvent)\n .findOne({ where: { domain: { id: domainId }, instanceId: id }, order: { revision: 'DESC' } })\n .then(top => (inst.revision = top?.revision ?? 0))\n .catch(() => (inst.revision = 0))\n this.register(domainId, id, kind, model, 'running', 'resync').catch(err => console.error('twin register fail', err))\n return inst\n }\n\n /**\n * live ์ด๋ฒคํธ ์ธ์ ์คํธ โ projector ๊ตฌ๋ + data(tag) ๋ฐฉ์ก(ํ๋ฃจํ์ ์ธ๋ฐ์ด๋ ๋์ฐฉ ์ง์ , command-routing ยง8.2).\n * reference ์ด๋ํฐ๊ฐ ๋ธ records โ ์ปค๋ face2-adapter.ingest โ CanonicalEnvelope ๋ฅผ ์ฌ๊ธฐ๋ก ๋ฐ์ด๋ฃ๋๋ค.\n * (State ์ฑ๋ ๋ธํ/์ ๋ ๊ฒฐ์ ์ ํ์ โ ์ค์ผ๋ ํค์ data(tag) ๋ฏธ๋ฌ ์ค์ฌ.)\n */\n static ingestLive(domainId: string, id: string, envelopes: CanonicalEnvelope[]): void {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (inst?.mode !== 'live' || !inst.projector) return\n const tIngest = performance.now()\n /* ์ธ์
๋ดํฌ๋ฅผ ํ์ํด ๋๊ณ ๋ฃ๋๋ค โ ์ปค๋์ด ๊ทธ๊ฒ์ ์ฌ๋ฐฉ์ถํด๋ ์ ๋์ ๋ ๋ฒ ์ ํ์ง ์๊ฒ(์ ๊ตฌ๋
์ฃผ์). */\n for (const e of envelopes) {\n if (e && typeof e === 'object') inst.applying?.add(e as object)\n inst.projector.apply(e)\n inst.oee?.apply(e) // ๊ด์ธก(projector) + ๊ณ์ฐ(OEE ๋์ )\n }\n recordPhase(inst.load ?? (inst.load = newLoadMeter()), 'ingest', performance.now() - tIngest)\n // ์ ๋ ๊ฒฐ์ (๋ผ์ด๋ธ๋ sim ์ฒ๋ผ ์ด๋ฒคํธ ์์) โ ๋จ ์ด๋ฒคํธ๋ง๋ค DB write ํ๋ฉด ๋ถํํญ๋ฐ์ด๋ผ ๋ชจ์๋๋ค๊ฐ\n // coalescer tick ์์ ๋ฐฐ์น ๊ธฐ๋ก(๋ฐฉ์ก๊ณผ ๋์ผ ์ฃผ๊ธฐ). ํ์คํ ๋ฆฌ ๋
ธ๋ธยทํ์๋ผ์ธยท๋น์ฆ๋์ค ์์ฅ์ด ์ด ์ ๋์ ์ฝ๋๋ค.\n ;(inst.pendingJournal ?? (inst.pendingJournal = [])).push(...envelopes)\n if (inst.metrics) { inst.metrics.ingestedTotal += envelopes.length; inst.metrics._accIngest += envelopes.length } // ๊ณ์ธก(โฃ-1)\n // ๋ฐฉ์ก ๋ณํฉ(ingest-scale ยง1.1/ยง4.4) โ apply ๋ O(1)ยท์ธ๋ค. ๊ทธ๋ฌ๋ ๋ฐฉ์ก(snapshot O(state))์ ๋น์ธ(๋๊ท๋ชจ 5ms+)\n // ์ด๋ฒคํธ๋ง๋ค ๋ฐฉ์กํ๋ฉด ํญ๋ฐ โ dirty ๋ง ์ฐ๊ณ coalescer tick ์ด ์ฃผ๊ธฐ ๋ฐฉ์ก(๋ฐฉ์ก๋ฅ โ ์ธ์ ์คํธ๋ฅ ).\n inst.dirty = true\n this.ensureBroadcastCoalescer()\n }\n\n /**\n * ๊ตฌ๊ฐ ์ฑ๊ณผ ๋ฐฉ์ก์ **์์ด๋ค**(2026-08-06). ์นด๋๊ฐ `twinKpi` ๋ฅผ ์ง์ ๋ฌป๋๋ค.\n *\n * ์: ์นด๋๋ฅผ ์ฌ๋ฌ ๋จ๊ณ(๊ณต๊ฐยทํธ์ยท๊ตฌ์ญยท์๋ฆฌยท์ค๋น)์ ๋ถ์ด๋ ค๋ฉด ๋ฐฉ์ก์ผ๋ก๋ ํ๊ทธ๊ฐ ํธ์๋น 1,200๊ฐ๊ฐ ๋๊ณ ,\n * **๋ชจ๋ธ์ ์นด๋๋ฅผ ํ๋๋ ์ ๋์๋** 30์ด๋ง๋ค ํธ์๋ง๋ค ์ ๋์ ์ ์๋ค. ์ง์๋ก ๋ฐ๊พธ๋ ๋ณด๊ณ ์๋ ์นด๋\n * ์๋งํผ๋ง ๋ค๊ณ , ๊ฐ์ (๋์ยท์ฐฝยท์ถ) ์ ํด๋ผ์ด์ธํธ๊ฐ ํ๋๋ก ํฉ์น๋ค.\n *\n * ๋ค์ผ๋ก ์ง์๋ง ํ ์ ์๋ ๊ฒ์ด ๋ ์๊ฒผ๋ค โ **๊ณผ๊ฑฐ ์๊ฐ**(`toTime`)๊ณผ **๊ณต๊ฐ ๋จ์ ํฉ์ฐ**(์ฌ๋ฌ ํธ์์\n * ํ ๋ฒ์ ์ ๊ธฐ). ๋ฐฉ์ก ๋ฃจํ๋ ํธ์๋ณ์ด๋ผ ๋ ๋ค ๋ชป ํ๋ค.\n *\n * ์ถ์ ๋๋ ๋ ํด๋ ๋น์ฉ์ด ๊ฐ๋ค๋ ์ค์ธก์ด ๊ทผ๊ฑฐ๋ค(`test/kpi-query-bench.test.ts`).\n */\n /** ๋ฐฉ์ก ๋ณํฉ ์ฃผ๊ธฐ(ms) โ ๋ฐฉ์ก๋ฅ ์ํ. ์ธ์ ์คํธ๊ฐ ์๋ฌด๋ฆฌ ๋นจ๋ผ๋ ์ด ์ฃผ๊ธฐ๋ก๋ง ๋ฐฉ์ก. */\n static BROADCAST_COALESCE_MS = 200\n private static broadcastTimer?: any\n\n /** live ๋ฐฉ์ก coalescer โ dirty ์ธ live ์ธ์คํด์ค๋ง ์ฃผ๊ธฐ์ ์ผ๋ก 1ํ ๋ฐฉ์ก(entitySigs ๋ก ๋ณ๊ฒฝ ์ํฐํฐ๋ง). */\n private static ensureBroadcastCoalescer(): void {\n if (this.broadcastTimer) return\n this.broadcastTimer = setInterval(() => this.flushLiveBroadcasts(), this.BROADCAST_COALESCE_MS)\n if (typeof this.broadcastTimer.unref === 'function') this.broadcastTimer.unref() // ์ข
๋ฃ ๋น์ฐจ๋จ\n }\n\n /**\n * dirty ์ธ์คํด์ค ๋ฐฉ์ก flush(์ฃผ๊ธฐ tick ๋๋ ๋ช
์ ํธ์ถ) โ **์๋ฎฌ๊ณผ ๋ผ์ด๋ธ ๋ ๋ค.**\n *\n * ์์ ์๋ ๋ผ์ด๋ธ๋ง ๋ดค๋ค(`mode !== 'live'` ๋ฉด ๊ฑด๋๋). ์๋ฎฌ์ delta ๋ง๋ค ๊ณง๋ฐ๋ก ๋ฐฉ์กํ๊ณ , ๊ทธ๊ฒ์ด\n * ํ tick ์์ ์๋ฐฑ ๋ฒ ๋ฐ๋ณต๋๋ฉฐ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ๋ง์๋ค(์ `start()` ์ฃผ์์ 35์ด ํฑ). ๋ฐฉ์ก์ ๋ชจ์ผ๋\n * ๊ท์จ์ ๋ชจ๋์ ์ฑ์ง์ด ์๋๋ผ **์ฑ๋์ ์ฑ์ง**์ด๋ค โ ์ต์ -์ํ ์ฑ๋์ด๋ฉด ์ค๊ฐ ์ํ๋ ๋ณด๋ผ ๊ฐ์ด ์๋ค.\n */\n static flushLiveBroadcasts(): void {\n const now = Date.now()\n for (const inst of Object.values(this.instances)) {\n const isLive = inst.mode === 'live'\n // ์ฒ๋ฆฌ๋ ๊ณ์ธก(โฃ-1) โ ์ฐฝ(โฅ1s)๋ง๋ค ์ ์
/๋ฐฉ์ก/์ ๋๋ฅ ๊ฐฑ์ . dirty ๋ฌด๊ด(์ ํด๋ฉด 0์ผ๋ก ์๋ ด). ๋ถํ๋ฅผ ์ฝ๋ ์ ํธ.\n const m = isLive ? inst.metrics : undefined\n if (m) {\n const dt = (now - m._windowStartMs) / 1000\n if (dt >= 1) {\n m.ingestRate = Math.round(m._accIngest / dt)\n m.broadcastRate = Math.round((m._accBroadcast / dt) * 10) / 10\n m.journalRate = Math.round(m._accJournal / dt)\n m._accIngest = 0; m._accBroadcast = 0; m._accJournal = 0; m._windowStartMs = now\n }\n }\n if (!inst.dirty) continue\n inst.dirty = false\n // โ ์ํฐํฐ data(tag) ๋ฐฉ์ก โ ๋ณด๋ ์ปดํฌ๋ํธ ๋ผ์ด๋ธ ๋ ๋.\n this.publishEntityData(inst)\n if (m) { m.broadcastTotal++; m._accBroadcast++ }\n /* ์๋ฎฌ์ ์ ๋ยทstate ์ฑ๋์ ์๊ธฐ ์ฝ๋ฐฑ์ด delta ๋ง๋ค ์ฒ๋ฆฌํ๋ค(์ฌ์ค์ ํ๋๋ ๋น ๋จ๋ฆฌ์ง ์๋๋ค).\n ์ฌ๊ธฐ์ ๋ชจ์ผ๋ ๊ฒ์ **์ํฐํฐ ๋ฐฉ์ก**๋ฟ์ด๋ค โ ํ๋ฉด์ด ์ฝ๋ ์ต์ -์ํ ์ฑ๋. */\n if (!isLive) continue\n // โข ์ ๋ ๋ฐฐ์น ๊ธฐ๋ก โ ๋ชจ์๋ ์ด๋ฒคํธ์ revision ๋ถ์ฌํด ๋ฒํฌ ์ ์ฅ(์ด๋ฒคํธ๋ง๋ค write ์๋).\n // revision ์นด์ดํฐ๋ ์ธ๋ฉ๋ชจ๋ฆฌ(startLive ์์ ์ ๋ high-water ๋ก 1ํ ์๋) โ tick ๋ง๋ค DB ์ง์ ์์.\n const batch = inst.pendingJournal\n if (batch?.length && inst.revision != null) {\n inst.pendingJournal = []\n const start = inst.revision\n inst.revision = start + batch.length\n if (m) { m.journaledTotal += batch.length; m._accJournal += batch.length; m.backlog = batch.length }\n const tJournal = performance.now()\n this.persistBatch(inst.domainId, inst.id, batch, start)\n .then(() => recordPhase(inst.load ?? (inst.load = newLoadMeter()), 'journal', performance.now() - tJournal))\n .catch(err => console.error('twin live journal fail', err))\n }\n // โก State ์ฑ๋ ๋ฐฉ์ก โ \"๋ฐ๋์๋ค\"๋ ๊ฐ๋ฒผ์ด ์ ํธ๋ง(kind+revision). ๋งต ๊ตฌ๋
(subscribeTwinState)์ ์ด ์ ํธ์\n // scheduleRefresh(250ms ๋๋ฐ์ด์ค)โpollLive ๋ก ๋๋ฌผ์ด๋ด. ์ค๋
์ท(O(state))์ ๋ณด๋ ์ฌ๋์ด ๋ฌผ์ ๋๋ง 1ํ ๊ณ์ฐ.\n // (์ฌ๊ธฐ์ payload ๋ก ์ค๋
์ท์ ์ค์ผ๋ฉด ์๋ฌด๋ ์ ์ฝ๋๋ฐ tick ๋ง๋ค ํต์งธ๋ก ๋ ์ ์์ ๋ญ๋น โ ์ ํธ๋ง ๋ณด๋ธ๋ค.)\n this.publishGuarded(\n 'twin-state',\n { twinState: { instanceId: inst.id, kind: 'delta', revision: inst.revision ?? 0 } },\n `twin-state:${inst.id}`\n )\n }\n /* ๋๊ณ ์๋ ์ธ์คํด์ค๊ฐ ํ๋๋ ์์ผ๋ฉด tick ์ ๋ฉ์ถ๋ค(์์ ์ ใ๋ผ์ด๋ธ๊ฐ ์์ผ๋ฉดใ์ด์๋๋ฐ, ์ด์ \n ์๋ฎฌ๋ ์ด flush ์ ๊ธฐ๋๋ฏ๋ก ๊ทธ ์กฐ๊ฑด์ด๋ฉด ์๋ฎฌ ๋ฐฉ์ก์ด ๋ฉ์ถ ์ฑ ๋จ๋๋ค). */\n if (!Object.keys(this.instances).length && this.broadcastTimer) {\n clearInterval(this.broadcastTimer)\n this.broadcastTimer = undefined\n }\n }\n\n /**\n * ์ ๋ ํ ํ ์ค โ **๊ธฐ๋ก ๊ฒฝ๋ก๊ฐ ๋์ด๋ผ(๋ผ์ด๋ธ ๋ฒํฌยท์ฌ ๋จ๊ฑด) ํ ๋ชจ์์ ๋ฐ๋์ ํ ๊ณณ์์ ๋ง๋ ๋ค.**\n * ๋ ๊ณณ์ ๊ฐ์ ์ ์ผ๋ฉด ์น๊ฒฉ ๊ฒ์ ํค๊ฐ ํ์ชฝ์๋ง ์ฑ์์ง๊ณ , ๋ฐ์ฏค ๋น ์์ธ์ \"์ ๋์๋ ์๋๋ฐ\n * ๊ฒ์์ผ๋ก๋ ์ ๋์ค๋ ์ด๋ฒคํธ\" ๋ฅผ ๋ง๋ ๋ค โ ์ ๋์์ ๊ฐ์ฅ ๋์ ์ข
๋ฅ์ ๊ฒฐํจ์ด๋ค.\n */\n /** ์ ๋์ ์๊ฐ ์ถ์ ๋ ์ง๋ค โ ๋ชป ์ฝ๋ ๊ฐ์ ๋น์ด๋ค(0 ์ด๋ ์ง๊ธ์ผ๋ก ์์ฅํ์ง ์๋๋ค). */\n private static toEventTimeValue(v: any): Date | undefined {\n if (v instanceof Date) return v\n const t = typeof v === 'string' ? Date.parse(v) : NaN\n return Number.isNaN(t) ? undefined : new Date(t)\n }\n\n private static journalRow(repo: any, domainId: string, instanceId: string, e: any, revision: number, structureRev?: number) {\n return repo.create({\n domain: { id: domainId } as any,\n instanceId,\n eventType: e?.eventType,\n /* ์ปค๋์ด ์ปค๋งจ๋์์ ์ด์ด ์ค ๊ฐ โ ์ด๊ฒ์ด ๊ฐ์ฌ ๊ธฐ๋ก๊ณผ ์ ๋์ ์๋ ๋ค๋ฆฌ๋ค. */\n correlationId: e?.correlationId,\n revision,\n /* **์ด ์ฌ์ค์ด ์ผ์ด๋ ๊ณต์ฅ**์ ํจ๊ป ์ฐ๋๋ค โ ์ด๊ฒ์ด ์์ผ๋ฉด ๋์ค์ ๊ตฌ์กฐ๊ฐ ๋ฐ๋์์ ๋ ์ด ํ์\n ์ ๊ณต์ฅ์ ๋๊ณ ์ ๊ฒ ๋๊ณ , ๊ทธ๋ ์๋ ์ค๋น์์ ์ผ์ด ์์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค. */\n ...(structureRev === undefined ? {} : { structureRev }),\n /* ์ปค๋์ ISO ๋ฌธ์์ด์ ์ค๋ค. ์ปฌ๋ผ์ ๋ ์ง๋ค โ **์ฌ๊ธฐ์ ์ฎ๊ธด๋ค.** ๋ฌธ์์ด์ ๊ทธ๋๋ก ๋ฃ์ผ๋ฉด\n ๋๋ผ์ด๋ฒ๊ฐ ์ ํ์์ผ๋ก ์ ๊ทํํ์ง ์์, ๋์ค์ ๋ ์ง๋ก ๊ฑฐ๋ ์ง์์ ์ ๊ฑธ๋ฆฐ๋ค. */\n eventTime: this.toEventTimeValue(e?.eventTime),\n ...twinEventKeys(e),\n payload: e\n })\n }\n\n /**\n * ์ด ํธ์์ด ์ง๊ธ ์ด๋ ๊ตฌ์กฐ๋ก ๋๋๊ฐ โ ์ด๋ฒคํธ์ ์ฐ์ ๋ฒํธ. ํ ๋ฒ ์ฝ๊ณ ์บ์ํ๋ค(์ฐ๊ธฐ๋ง๋ค ์กฐํ ๊ธ์ง).\n *\n * ์์ผ๋ฉด `undefined` ๋ค โ 0 ์ด ์๋๋ค. ๊ตฌ์กฐ ๋ฆฌ๋น์ ์ด ์๊ธฐ๊ธฐ ์ ์ ๋ง๋ค์ด์ง ํธ์์ ์์ง ๋ฆฌ๋น์ ์ด\n * ์๊ณ , ๊ทธ ์ฌ์ค์ 0 ์ด๋ผ๋ **์ ํจํด ๋ณด์ด๋ ๋ฒํธ**๋ก ์์ฅํ๋ฉด ์ ๋๋ค.\n */\n private static structureRevCache: Record<string, number> = {}\n static async structureRevOf(domainId: string, instanceId: string): Promise<number | undefined> {\n const key = runtimeKey(domainId, instanceId)\n const cached = this.structureRevCache[key]\n if (cached !== undefined) return cached\n const latest = await getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n if (latest) this.structureRevCache[key] = latest.rev\n return latest?.rev\n }\n\n /** live ์ ๋ ๋ฐฐ์น ๊ธฐ๋ก โ ๋ชจ์๋ CanonicalEnvelope ๋ค์ startRevision+1.. ์ ๋ถ์ฌํด ๋ฒํฌ ์ ์ฅ(coalescer tick ๋น 1ํ). */\n static async persistBatch(domainId: string, instanceId: string, envelopes: any[], startRevision: number): Promise<void> {\n const repo = getRepository(TwinEvent)\n const structureRev = await this.structureRevOf(domainId, instanceId)\n const rows = envelopes.map((e, i) => this.journalRow(repo, domainId, instanceId, e, startRevision + i + 1, structureRev))\n await repo.save(rows, { chunk: 500 })\n }\n\n /** ๋ ์ง์คํธ๋ฆฌ upsert(๋๋ฉ์ธ+instanceId ์ ๋ํฌ). status ์ธ์๋ก provision(stopped)/start(running) ๊ณต์ฉ. */\n static async register(\n domainId: string,\n instanceId: string,\n kind: string,\n model: TwinModelDef,\n status: 'running' | 'stopped' = 'running',\n restartPolicy?: RestartPolicy,\n origin?: any,\n /*\n * ์ฌ๋์ด ๋ถ๋ฅด๋ ์ด๋ฆ๊ณผ **๋๊ฐ ํ๋** โ ์
๋ฌดํค๋ฅผ ๋๋ ๋ ๋๊ฐ๋ก ์ด๋ฆ์ ํจ๊ป ์ค์ด์ผ ํ๋ค.\n * ์ฌ๋ ์๋ ๊ฒฝ๋ก(๋ถํ
์๋ ํ๋ก๋น์ ๋ยท๋ณต๊ตฌ)๋ `actor` ๋ฅผ ์ฃผ์ง ์๋๋ค โ ์๋ฌด ์ฌ์ฉ์๋ฅผ ์ ์ผ๋ฉด\n * ๊ฐ์ฌ ๊ธฐ๋ก์ด ๊ฑฐ์ง์ด ๋๋ค.\n */\n meta?: { name?: string; description?: string; actor?: { id: string } }\n ): Promise<void> {\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n await repo.save(\n repo.create({\n ...(existing ?? {}),\n domain: { id: domainId } as any,\n instanceId,\n kind,\n model,\n // ์ธ์คํด์คโ๊ณต๊ฐ 1๊ธ ๋งํฌ(space #3) โ model.spaceId/areaId ๋ฅผ ์ปฌ๋ผ์ผ๋ก ์น๊ฒฉ(dual-write). model JSON ๋ ์ ์ง(์ปค๋ยท๋ณต๊ตฌ์ฉ).\n spaceId: (model as any)?.spaceId ?? existing?.spaceId,\n areaId: (model as any)?.areaId ?? existing?.areaId,\n /* ์ฌ๊ธฐ๋ ์ ์ฑ
(ADR-0029 ยง2) โ ๋ช
์๊ฐ ์ฐ์ , ์์ผ๋ฉด ๊ธฐ์กด๊ฐ ๋ณด์กด(์ฌํ๋ก๋น์ ์ด ์ ์ธ์ ์ง์ฐ์ง ์๊ฒ).\n **๋ ๋ค ์์ผ๋ฉด ๋์ง๋ค**: ์์ ์๋ ์ฌ๊ธฐ์ ๊ธฐ๋ณธ๊ฐ์ ๊ฐ์ธํ๋๋ฐ, ๊ทธ ๊ธฐ๋ณธ๊ฐ์ด ใ์ ๋ ์ด๊ธฐํใ๋ผ์\n ์ ์ธ์ ๋น ๋จ๋ฆฐ ํ๋ก๋น์ ๋์ด ์กฐ์ฉํ ์ด๋ ฅ์ ์ง์ฐ๋ ํธ์์ ๋ง๋ค์๋ค. ์ ์ธ์ ๋ถ๋ฅด๋ ์ชฝ์ ๋ชซ์ด๋ค. */\n restartPolicy:\n restartPolicy ??\n readRestartPolicy(\n existing?.restartPolicy,\n `register(\"${instanceId}\") did not declare a restart policy and the stored row has none`\n ),\n /* ์ฉ๋๋ ๊ฐ์ธํ๋ค. ๋ฒค์น๋ก ๋ค์ง๋ ๊ฒ์ `setPurpose` ํ๋๋ฟ์ด๋ฏ๋ก ๊ธฐ์กด๊ฐ์ ๋ฐ๋์ ๋ณด์กดํ๋ค\n โ ์ฌ๊ธฐ์ ๋ฎ์ผ๋ฉด ์ฌํ๋ก๋น์ ์ด ๋ฒค์น ์ฌ๋ณธ์ ์ด์ ํธ์์ผ๋ก ๋๋๋ฆฐ๋ค. */\n purpose: existing?.purpose ?? 'operational',\n /* **๋ค์ ์ฝ๋ ๋ฐฉ๋ฒ**์ ๊ฐ์ธํ๋ค. ๋ช
์๊ฐ ์ฐ์ , ์์ผ๋ฉด ๊ธฐ์กด๊ฐ ๋ณด์กด โ ์์ฒ์ ๋ชจ๋ฅด๋ ํธ์ถ์ด\n ํ ๋ฒ ์ง๋๊ฐ๋ฉด์ ์ด๋ฏธ ์๋ ๊ฒ์ ์ง์ ๋ฒ๋ฆฌ๋ฉด, ๊ทธ ํธ์์ ๋ค์ ์ฝ์ ์ ์๋ ํธ์์ด ๋๋ค. */\n origin: origin ?? existing?.origin ?? null,\n /* ์ด๋ฆ์ **๋ฎ์ง ์๊ณ ์ฑ์ด๋ค** โ ์ฌ์ฉ์๊ฐ ๊ณ ์น ์ด๋ฆ์ ์ฌํ๋ก๋น์ ์ด ๋๋๋ฆฌ๋ฉด ์ ๋๋ค. */\n name: existing?.name ?? meta?.name ?? null,\n description: existing?.description ?? meta?.description ?? null,\n /* ๋ง๋ ์ฌ๋์ ์ฒ์ ํ ๋ฒ๋ง. ๊ณ ์น ์ฌ๋์ ์ฌ๋์ด ํ ๊ฒฝ์ฐ์๋ง ๊ฐฑ์ ํ๋ค. */\n ...(existing ? {} : meta?.actor ? { creator: { id: meta.actor.id } as any } : {}),\n ...(meta?.actor ? { updater: { id: meta.actor.id } as any } : {}),\n status\n })\n )\n }\n\n /**\n * ๋ผ์ด๋ธ ๊ตฌ์กฐ ๋ณ์ด(resource.add ๋ฑ)๋ฅผ ์ ์ฅ๋ model ์ ๋ฐ์ โ ๋ฐํ์ ์ปค๋์ ๋ฌด๋ฒ๋ฅผ registry model.equipment ์ ๋๊ธฐ.\n * ์ด๊ฒ ์์ผ๋ฉด ๋ฐํ์์ ์ถ๊ฐ๋ผ๋(์ํยท์ ๋์ ๋ฐ์) ์ ์ฅ model ๋ ์๋ณธ์ด๋ผ ํ๋ก๋น์ ๋ ํธ์ง๊ธฐยท์ฌ๊ธฐ๋(loadTwinModel)์ด\n * ์ถ๊ฐ๋ถ์ ์๋๋ค. ๊ธฐ์กด model.equipment ํญ๋ชฉ์ ๋ณด์กด(homeLocation ์ ์ง)ํ๊ณ ์ id ๋ง append(์ถ๊ฐ ์์ location=homeLocation).\n * ์ขํ(layout)๋ง ๋ค๋ฃจ๋ register ์ ๋ฌ๋ฆฌ equipment ์งํฉ์ ๊ฐฑ์ ํ๋, ์ฌํ๋ก๋น์ (purge)์ด ์๋๋ผ in-place ๊ฐฑ์ ์ด๋ผ\n * ์ ๋์ ๋ณด์กด๋๋ค(์ถ๊ฐ๋ ์ด๋ฏธ equipment ๋ธํ๋ก ์ ๋๋จ โ replay ๋ id-keyed upsert ๋ผ ์ด์ค๊ณ์ฐ ์์).\n */\n static async syncBoardEquipment(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[runtimeKey(domainId, instanceId)]\n const snap = inst?.kernel?.getSnapshot?.()\n if (!snap?.equipment) return\n const repo = getRepository(TwinInstance)\n const reg = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.model) return\n const model = reg.model as TwinModelDef\n const known = new Set((model.equipment ?? []).map(m => m.id))\n const added = snap.equipment\n .filter((m: any) => !known.has(m.id))\n .map((m: any) => ({ id: m.id, kind: m.kind, homeLocation: m.location }))\n if (!added.length) return\n model.equipment = [...(model.equipment ?? []), ...added]\n reg.model = model\n await repo.save(reg)\n }\n\n /**\n * ํ๋ก๋น์ ๋ โ ๋ ์ง์คํธ๋ฆฌ์ ๊ตฌ์กฐ(model)๋ฅผ ๋ฑ๋ก๋ง ํ๊ณ ๊ธฐ๋ํ์ง ์์(status='stopped').\n * ์ฌํ๋ก๋น์ ์ ๊ตฌ์กฐ ์๊ทธ๋์ฒ๊ฐ ๋ฐ๋๋ฉด(๋
ธ๋ยท๋ฌด๋ฒ ์งํฉ/์์ฑ ๋ณ๊ฒฝ) ๊ธฐ์กด ์ ๋์ purge ํ๋ค(ADR-0015):\n * model ๋ replay ์ ๋ง์คํฐ๋ผ ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ฉด ๊ณผ๊ฑฐ ์ด๋ฒคํธ์ ์ ์ ๊ฐ ๊นจ์ง๋ค. ์ขํ(layout)๋ง ๋ฐ๋๋ฉด ์ ๋ ๋ณด์กด.\n */\n /**\n * ์คํ ์ค์ด๋ฉด ๊ตฌ์กฐ๋ฅผ ๊ต์ฒดํ์ง ์๋๋ค โ **ํ์ ๋ฌธ์ฅ์ ํ ๊ณณ์ ๋๋ค.**\n *\n * ์ธ์ ์คํธ๋ ์ ๋ ๊ต์ฒด๋ผ, ์ด๋ฒคํธ๋ฅผ ์ ๊ณ ์๋ ์ปค๋ ๋ฐ์์ ๋ฐ๋ฅ์ ๋ฐ๊พธ๋ ์
์ด ๋๋ค. ์ง๊ธ์ ๊ฑฐ์ ์ด\n * ์ ์ผํ ๋ต์ด์ง๋ง ์ต์ข
ํ์ ์๋๋ค(`adoptStructure` ๋ฐฐ์ ). ๋ ๊ณณ์์ ๊ฐ์ ๋ฌธ์ฅ์ผ๋ก ๊ฑฐ์ ํด์ผ\n * ๋์ค์ ์ด ๊ท์น์ ๊ฑท์ด๋ผ ๋ ๊ฑท์ด๋ผ ๊ฒ์ด ํ๋๋ก ๋ณด์ธ๋ค.\n */\n private static assertNotRunning(domainId: string, instanceId: string): void {\n if (!this.instances[runtimeKey(domainId, instanceId)]) return\n /*\n * **๊ฑฐ์ ๋ ๋ฒ์ญ๋ผ์ผ ํ๋ค.** ์ด ๋ฌธ์ฅ์ ๋์ ธ์ ธ์ ๋ฆฌ์กธ๋ฒ์ `catch` ๋ฅผ ์ง๋ ํ๋ฉด ํ ์คํธ์ ๊ทธ๋๋ก\n * ๋ด๋ค โ ๋ค์ฏ ์ธ์ด ์ ํ์์ ์์ด ํ ์ค์ด ์ฌ์ฉ์์๊ฒ ๋ณด์๋ค(2026-08-14 ์ค์ธก).\n *\n * ๊ทธ๋์ ์ฝ๋์ ํ๋ผ๋ฏธํฐ๋ฅผ ์์ธ์ ์ค์ด ๋ณด๋ธ๋ค(`ImportSpaceRefusal` ๊ณผ ๊ฐ์ ๊ท์ฝ: ์์ด ๋ฌธ์ฅ์\n * canonical ์ด๊ณ ๋ก๊ทธยทํด๋ฐฑ์ผ๋ก๋ง ์ฐ์ธ๋ค). ์ด์ ๊ฐ ์ฝ๋๋ก ์ค๋ฉด ํ๋ฉด์ด ์ฎ๊ธธ ์ ์๋ค.\n */\n const err: any = new Error(`instance \"${instanceId}\" is running โ stop before re-provisioning`)\n err.code = 'twin-running'\n err.params = { instanceId }\n throw err\n }\n\n /**\n * ๋๋ฉด์ ๊ณต์ฅ์ ์ ํํ๋ค โ **๋ฏธ๋ฌ ์ ์ฉ.**\n *\n * ๋ฏธ๋ฌ๊ฐ ๋น์ถ๋ ํ์ค์ ์ ๋ฉ์ถ๋ค. ์ค๋น ํ ๋๊ฐ ๋์๋ค๊ณ ํธ์์ ๋ฉ์ท๋ค ์ธ์ฐ๋ฉด ๊ทธ ์ฌ์ด์ ์ฌ์ค์\n * ์๊ณ , ๋ผ์ด๋ธ์์ ์ ์ค์ ๊ณง ๊ฑฐ์ง์ด๋ค. ๊ทธ๋์ ๋ฏธ๋ฌ๋ **๋์ ์ค์** ์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋๋ค.\n *\n * ์๋ฎฌ๋ ์ด์
์ ์ฌ๊ธฐ ์ค์ง ์๋๋ค. ์กฐ๊ฑด์ด ๋ฐ๋ ์คํ์ ๋ค๋ฅธ ์คํ์ด๋ฏ๋ก ๋ฉ์ถ๊ณ ๋ค์ ์ธ์ฐ๋ ๊ฒ์ด\n * ์ณ๋ค โ ์ปค๋์ด ๊ทธ๋ ๊ฒ ๊ฑฐ์ ํ๋ค(`FlowEngine.adoptStructure`).\n *\n * ์ธ ๊ฐ์ง๊ฐ **ํจ๊ป** ์ผ์ด๋์ผ ํ๋ค. ํ๋๋ผ๋ ๋น ์ง๋ฉด ์ธต์ด ์ด๊ธ๋๋ค:\n * โ ๋ฆฌ๋น์ โ ์ด ์์ ์ดํ์ ์ด๋ฒคํธ๊ฐ ์ ๋ฒํธ๋ฅผ ๋ฌ๊ณ ๋ค๋๋ค(์ฌ์์ด ๋ง๋๋ฅผ ๋๋ ์ ์๊ฒ)\n * โก ์ ์ฅ modelยท๊ตฌ์กฐ ํ โ ์กฐํ๊ฐ ์ ๊ตฌ์กฐ๋ฅผ ๋ณธ๋ค\n * โข ์ปค๋ โ ์ง๊ธ ์ ํ๋ ์ด๋ฒคํธ๊ฐ ์ ๊ตฌ์กฐ ์์์ ์ ํ๋ค\n */\n static async adoptStructure(\n domainId: string,\n instanceId: string,\n model: TwinModelDef,\n comment?: string,\n origin?: any\n ): Promise<{ rev: number } & StructureShift> {\n const inst = this.instances[runtimeKey(domainId, instanceId)]\n if (!inst) throw new Error(`instance \"${instanceId}\" is not running โ provision it instead of adopting`)\n if (inst.mode !== 'live')\n throw new Error(`instance \"${instanceId}\" is a simulation โ stop it and re-provision (a changed experiment is a different experiment)`)\n\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg) throw new Error(`instance \"${instanceId}\" is running but not registered โ refusing to adopt into an unknown twin`)\n\n const rev = await this.recordStructure(domainId, instanceId, model, comment)\n await this.register(domainId, instanceId, reg.kind, model, 'running', undefined, origin)\n /* ์ปค๋์ **๋ง์ง๋ง์** ์ ํํ๋ค โ ์ ์ฅ์ด ์คํจํ๋ฉด ๋ฉ๋ชจ๋ฆฌ๋ง ์ ๊ตฌ์กฐ๊ฐ ๋์ด, ์ฌ๊ธฐ๋ํ๋ฉด ์กฐ์ฉํ\n ์ ๊ตฌ์กฐ๋ก ๋์๊ฐ๋ค(๊ณ ์น๊ธฐ ์ด๋ ค์ด ์ด๊ธ๋จ์ด๋ค). */\n const shift: StructureShift = inst.kernel.adoptStructure(model)\n /*\n * **๊ณต์ ๋ช
์ธยทํ์ฅ์ด ์ ํ ์๊ฐ๋ ํจ๊ป ์ฃ๋๋ค** โ ์ปค๋์ ๊ตฌ์กฐ ์ ํ์ ์๋ฆฌยท์ค๋น๋ฅผ ๊ฐ์ง๋ง, ๊ณต์ ์๊ฐ์\n * ํธ์คํธ๊ฐ ์ค์ด ์ฃผ๋ ๊ฒ์ด๋ฏ๋ก(`model.localDurations`) ์ฌ๊ธฐ์ ๋ค์ ๋ถ๋ฅด์ง ์์ผ๋ฉด ๋๊ณ ์๋ ๋ฏธ๋ฌ๋\n * ์ฌ๊ธฐ๋ํ ๋๊น์ง ์ ์๊ฐ์ผ๋ก ๋๋ค(ํ๋ฉด์ ใ๋ฃ์์ต๋๋คใ๋ผ๊ณ ๋งํ ๊ฐ์ด๋ค).\n */\n this.applyOperations(inst.kernel, model, instanceId)\n\n /*\n * **ํฌ์ ํ๋ ์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฅธ๋ค** (2026-08-18 ์ค์ธก์ผ๋ก ๋ถ์).\n *\n * ํ(`twin_locations`ยท`twin_equipment`)์ ๊ตฌ์กฐ์ ์บ์๋ค. ๊ทธ๋ฐ๋ฐ ์ด ๊ฒฝ๋ก๋ ์ปค๋๋ง ๊ฐ๊ณ ํ์ ๊ทธ๋๋ก\n * ๋์๋ค โ ๋๊ณ ์๋ ๋ฏธ๋ฌ์ ๊ฐ์ ์ ์ธํ๋ฉด ์ปค๋์ ์ ๊ฐ์ผ๋ก ๊ณ์ฐํ๋๋ฐ **ํญ๋ชฉ ํจ๋์ ์ ํ์ ๋ณด์ฌ\n * ์ค๋ค**(๋ฃ์ ๊ฐ์ด ํ๋ฉด์์ ๋ณด์ด์ง ์๋๋ค). ๊ตฌ์กฐ๊ฐ ๋ฐ๋ ์๊ฐ์ด ๊ณง ์บ์๋ฅผ ๋ค์ ๊ทธ๋ฆด ์๊ฐ์ด๋ค.\n *\n * ์คํจ๋ ํก์ํ๋ค: ํฌ์์ด ๋งํ๋(์: ๋ชจ๋ธ์ ์ค๋ณต id) ์ปค๋์ ์ด๋ฏธ ์ ๊ตฌ์กฐ๋ก ๋๊ณ ์์ผ๋ฏ๋ก ๊ทธ ์ฌ์ค์\n * ๋๋๋ฆฌ์ง ์๋๋ค โ ๋ค๋ง ์กฐ์ฉํ ๋๊ธฐ์ง ์๊ณ ๋งํ๋ค.\n */\n await projectStructure(domainId, instanceId, model, instanceId).catch((err: any) =>\n console.warn(`[twin-engine] \"${instanceId}\" adopted a new structure but its projected rows were not refreshed โ ${err?.message ?? err}`)\n )\n\n /*\n * **๊ตฌ์กฐ๊ฐ ๋ฐ๋ ์๊ฐ์ด ์ํ๊ฐ ๋ฐ๋ ์๊ฐ์ด๋ค** โ ๊ทธ๋ฌ๋ ๋ฐฉ์กํ๋ค.\n *\n * โโ ๋ฌด์์ด ๋ฌ๋ (2026-08-18) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๊ตฌ์กฐ ์ ํ์ ์ปค๋๋ง ๊ฐ๊ณ ์กฐ์ฉํ ๋๋ฌ๋ค. ๊ทธ๋ฐ๋ฐ ํ๋ฉด์ด ๋ณด๋ ๊ฒ ์๋น์๊ฐ ๊ตฌ์กฐ์์ ํ์๋๋ค โ\n * ๊ณ์ฝ ๋๋น ํ์ , ์ฃผ๋ชฉ ์ ํธ, ์๋ฆฌ ์. ํ์ฅ์ด ๊ณ์ฝ์ ๊ณ ์ณ ์ ์ธํ ์๊ฐ ์กฐ๊ฑด์ด ์ฑ๋ฆฝํ๋๋ฐ๋, ์ํ\n * ๋ฐฉ์ก์ด ์์ด์ ์ง๋ ๋ ์ผ์ **๋ค์ ๊ณ์ธก ํ๋ณธ์ด ์ฌ ๋๊น์ง** ์ ํ๋ฉด์ ๋ค๊ณ ์์๋ค(๊ทธ ์ฌ์ด ํค๋\n * ๋ฐฐ์ง๋ 4์ด ํด๋ง์ผ๋ก ๋จผ์ ์์, ใ๋ฐฐ์ง์ ์๊ณ ๋ชฉ๋ก์ ์๋ใ ์ด๊ธ๋ ํ๋ฉด์ด ์ค์ ๋ก ๋ณด์๋ค).\n *\n * ์ ๋ฐฉ์ก ๊ฒฝ๋ก๋ฅผ ๋ง๋ค์ง ์๋๋ค: dirty ๋ฅผ ์ธ์ **์ด๋ฏธ ์๋ ๋ณํฉ ๊ท์จ**(200ms)์ ์น๋๋ค. ๊ตฌ์กฐ ์ ํ์\n * ๋๋ฌผ์ง๋ง, ์ฌ๋ฌ ํธ์์ ์๋ฌ์ ๋ค์ด์ฌ ์ ์๊ณ (ํ์ฅ ์ผ๊ด ์ ์ธ) ๊ทธ๋๋ ๋ฐฉ์ก๋ฅ ์ํ์ ์ง์ผ์ผ ํ๋ค.\n */\n inst.dirty = true\n this.ensureBroadcastCoalescer()\n\n return { rev, ...shift }\n }\n\n static async provision(\n domainId: string,\n instanceId: string,\n kind: string,\n model: TwinModelDef,\n /**\n * **์ฌ๊ธฐ๋ ์ ์ฑ
์ ์์ฑ ์์ ์ ์ ์ธ์ด๋ค**(ADR-0029 ยง2) โ ํธ์์ ์ ์ฑ
์์ด ์กด์ฌํ ์ ์๋ค.\n *\n * ์์ ์๋ ์ด ์๋ฆฌ๊ฐ ์์๊ณ `register` ๊ฐ ๊ธฐ๋ณธ๊ฐ(`sim-experiment` = ์ ๋ ์ด๊ธฐํ)์ ๊ฐ์ธํ๋ค. ๊ทธ๋์\n * ์ ์ธ์ ๋น ๋จ๋ฆฐ ํ๋ก๋น์ ๋์ด **์ฌ๊ธฐ๋๋ง๋ค ์ด๋ ฅ์ ์ง์ฐ๋ ํธ์**์ ์กฐ์ฉํ ๋ง๋ค์๋ค. ์ด์ ๋ง๋๋ ์ชฝ์ด\n * ๋งํด์ผ ํ๋ค: ์ด ํธ์์ด ์๊ธฐ ๊ณผ๊ฑฐ๋ฅผ ์ด๋ป๊ฒ ๋ํ๋์ง๋ ๋ง๋๋ ์ฌ๋์ด ์๋ ์ฌ์ค์ด๋ค.\n */\n restartPolicy: RestartPolicy,\n comment?: string,\n origin?: any,\n /** ์ด๋ฆยท์ ์ โ ์
๋ฌดํค๋ฅผ ๋๋ ๋ ๋๊ฐ๋ก ์ด๋ฆ์ ํจ๊ป ๋จ๊ธด๋ค(`register` ์ `meta` ๊ทธ๋๋ก). */\n meta?: { name?: string; description?: string; actor?: { id: string } }\n ): Promise<void> {\n this.assertNotRunning(domainId, instanceId)\n /* ์ข
๋ฅ๋ฅผ **์ ์ฅํ๊ธฐ ์ ์** ๊ฒ์ฆํ๋ค. ๋์ค์ ๊ธฐ๋ํ ๋ ๊ฑธ๋ฆฌ๋ฉด ์์ธ์ด ํ๋ก๋น์ ๋์์ ๋ฉ์ด์ง๊ณ ,\n ๊ทธ ์ฌ์ด ๋ ์ง์คํธ๋ฆฌ์๋ ๋๋ฆด ์ ์๋ ํธ์์ด ์์ ์๋ค. */\n kernelFor(kind)\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n\n /*\n * **๊ตฌ์กฐ๊ฐ ๋ฐ๋์ด๋ ์ญ์ฌ๋ฅผ ์ง์ฐ์ง ์๋๋ค.**\n *\n * ์์ ์๋ ์๋ช
์ด ๋ค๋ฅด๋ฉด ๊ทธ ํธ์์ ์ ๋์ ํต์งธ๋ก ์ง์ ๋ค. ์ ์ง์ฐ๋ฉด ์ ์ด๋ฒคํธ๋ฅผ ์ ๊ณต์ฅ์ ๋๊ณ \n * ์ ๊ฒ ๋์ด ์ด๋ ฅ์ด ๊ฑฐ์ง๋ง์ ํ๊ธฐ ๋๋ฌธ์ด๋ค โ ๋ถ์ค๊ฐ ๋์ด๋ ์์ ์ ์ฌ์ค์ ์ฌ์ฏ ๊ฐ์ง๋ฆฌ ๊ณต์ฅ์\n * ์ ์ผ๋ฉด ๊ทธ๋ ์๋ ๋ถ์ค์์ ์ผ์ด ์์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค. ์ ํ์ง๊ฐ **์ญ์ฌ๋ฅผ ์๊ฑฐ๋ ๊ฑฐ์ง๋ง์\n * ํ๊ฑฐ๋** ๋๋ฟ์ด์๊ณ , ๊ทธ๋์ ๊ณต์ฅ์ ๊ณ ์น ๋๋ง๋ค ์ด๋ ฅ์ ๋ฒ๋ ค์ผ ํ๋ค.\n *\n * ์ด์ ์
์งธ ๊ธธ๋ก ๊ฐ๋ค: ๋ฐ๋ ๊ตฌ์กฐ๋ฅผ **์ ๋ฆฌ๋น์ **์ผ๋ก ๋จ๊ธฐ๊ณ , ์์ผ๋ก ์ฐ์ด๋ ์ด๋ฒคํธ๊ฐ ๊ทธ ๋ฒํธ๋ฅผ\n * ๋ฌ๊ณ ๋ค๋๋ค. ์ฌ์์ ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ ์ง์ ์์ ์ ํํ ๋ค ์ด์ด ์ ๋๋ค(`replaySegments`).\n */\n await this.recordStructure(domainId, instanceId, model, comment)\n await this.register(domainId, instanceId, kind, model, existing?.status === 'running' ? 'stopped' : (existing?.status as any) ?? 'stopped', restartPolicy, origin, meta)\n }\n\n /**\n * ์ด ๊ตฌ์กฐ๋ฅผ ๋ฆฌ๋น์ ์ผ๋ก ๋จ๊ธฐ๊ณ ๊ทธ ๋ฒํธ๋ฅผ ๋๋ ค์ค๋ค โ **๋ฐ๋์์ ๋๋ง** ์ ๋ฒํธ๊ฐ ์๊ธด๋ค.\n *\n * ํ๋ก๋น์ ๋์ ๋ถํ
๋ง๋ค ๋ค์ ๋๋๋ฐ, ๊ทธ๋๋ง๋ค ๋ฆฌ๋น์ ์ด ๋๋ฉด ์ด๋ ฅ์ด ๋ป ์๋ ๋ง๋๋ก ์๊ฒ ์ชผ๊ฐ์ง๋ค.\n * ๊ทธ๋์ **๊ตฌ์กฐ ์๋ช
์ด ๊ฐ์ผ๋ฉด ์๋ ๋ฆฌ๋น์ ์ ๊ทธ๋๋ก ์ด๋ค.**\n */\n static async recordStructure(domainId: string, instanceId: string, model: TwinModelDef, comment?: string): Promise<number> {\n const repo = getRepository(TwinStructure)\n const signature = this.structureFingerprint(model)\n const latest = await repo.findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n\n /*\n * **์ ์ฅ๋ ์ง๋ฌธ์ด ์๋๋ผ ์ ์ฅ๋ ๊ณต์ฅ๊ณผ ๋น๊ตํ๋ค.**\n *\n * ์ง๋ฌธ ๊ณ์ฐ ๋ฐฉ์์ ํ ๋ฒ์ด๋ผ๋ ๋ฐ๊พธ๋ฉด(์๋ฌธ โ ํด์๋ก ๋ฐ๊ฟจ๋ค) ์ ์ฅ๋ ๋ฌธ์์ด์ ์ ๋ถ ์ ๋ฐฉ์์\n * ๊ฒ์ด๋ผ ๋ฌด์๊ณผ๋ ์ ๋ง๋๋ค. ๊ทธ๋ฌ๋ฉด **์๋ฌด๊ฒ๋ ์ ๋ฐ๋ ํธ์๋ค์ด ์ ๋ถ \"๊ตฌ์กฐ๊ฐ ๋ฐ๋์๋ค\"** ๋ก\n * ๊ธฐ๋ก๋๋ค โ ์ค์ ๋ก ๊ทธ๋ ๊ฒ ๋๊ณ , ์ฌ๊ธฐ๋ ํ ๋ฒ์ ๋ฆฌ๋น์ ์ด ํต์งธ๋ก ํ๋์ฉ ๋์๋ค.\n *\n * ๊ทธ๋์ ์ ๋ง์ ๋ ํ ๋ฒ ๋ ๋ฌป๋๋ค: ์ ์ฅ๋ **๋ชจ๋ธ**๋ก ์ง๋ฌธ์ ๋ค์ ๊ณ์ฐํ๋ฉด ๊ฐ์๊ฐ? ๊ฐ๋ค๋ฉด\n * ๊ณต์ฅ์ ๊ทธ๋๋ก์ด๊ณ ์ง๋ฌธ ํ๊ธฐ๋ง ๋ก์ ๊ฒ์ด๋, ๋ฆฌ๋น์ ์ ๋ง๋ค์ง ์๊ณ ํ๊ธฐ๋ง ๊ณ ์น๋ค.\n */\n if (latest && latest.signature !== signature && this.structureFingerprint(latest.model as TwinModelDef) === signature) {\n latest.signature = signature\n await repo.save(latest)\n }\n\n if (latest?.signature === signature) {\n this.structureRevCache[runtimeKey(domainId, instanceId)] = latest.rev\n return latest.rev\n }\n\n const rev = (latest?.rev ?? 0) + 1\n await repo.save(repo.create({ domain: { id: domainId } as any, instanceId, rev, signature, model: model as any, ...(comment ? { comment } : {}) }))\n this.structureRevCache[runtimeKey(domainId, instanceId)] = rev\n /* ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ฉด ์ฌ๊ตฌ์ฑ ์บ์๋ ์ ๊ณต์ฅ์ ๊ฒ์ด๋ค โ ๋ฒ๋ฆฐ๋ค(์ง์ฐ๋ ๊ฑด ์บ์๋ฟ, ์ฌ์ค์ ๋จ๋๋ค). */\n delete this.recovered[runtimeKey(domainId, instanceId)]\n if (latest) console.info(`[twin-engine] \"${instanceId}\" structure changed โ revision ${rev} (history kept; older events stay under revision ${latest.rev}).`)\n return rev\n }\n\n /**\n * ์ด ํธ์์ด ๊ฑฐ์ณ ์จ ๊ตฌ์กฐ๋ค โ **๋ฌด์์ด ์ธ์ ๋ฌ๋ผ์ก๋.**\n *\n * ๋ฆฌ๋น์ ์ ๊ทธ ์์ ๊ณต์ฅ์ ํต์งธ๋ก ๋ด์ง๋ง(์ฌ์์ ํ์ํ๋ค), ์ฌ๋์ด ๋ณด๊ณ ์ถ์ ๊ฒ์ ํต์งธ๊ฐ ์๋๋ผ\n * ์ฐจ์ด๋ค. ๋ชจ๋ธ์ ๋นผ๊ณ **์ฐจ์ด ์์ฝ๋ง** ๋ด๋ณด๋ธ๋ค โ 62KB ์ง๋ฆฌ ๋ณด๋๋ฅผ ํ๋ฉด์ ์ค์ด ๋ณด๋ผ ์ด์ ๊ฐ ์๋ค.\n */\n static async structureHistory(\n domainId: string,\n instanceId: string\n ): Promise<{ rev: number; createdAt?: Date; comment?: string; events: number; diff: StructureDiff }[]> {\n const revs = await getRepository(TwinStructure).find({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'ASC' } })\n if (!revs.length) return []\n\n /* ๋ฆฌ๋น์ ๋ง๋ค ๊ทธ ์๋์์ ๋ช ๊ฑด์ด ์ผ์ด๋ฌ๋ โ ์ด๋ ฅ์ ๋ฌด๊ฒ๋ฅผ ๋ณด์ฌ์ค๋ค(์งง๊ฒ ์ค์ณ๊ฐ ๊ตฌ์กฐ์ธ์ง). */\n const counts = new Map<number | null, number>()\n for (const row of await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('e.structureRev', 'rev')\n .addSelect('COUNT(1)', 'n')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .groupBy('e.structureRev')\n .getRawMany())\n counts.set(row.rev === null || row.rev === undefined ? null : Number(row.rev), Number(row.n))\n\n /* ๋ฒํธ ์๋ ์ ํ์ **๊ฐ์ฅ ์ค๋๋ ๋ฆฌ๋น์ **์ ๋ชซ์ด๋ค โ ์ฌ์์ด ๊ทธ๋ ๊ฒ ์ ์ผ๋ฏ๋ก ์ธ๋ ๊ฒ๋ ๊ฐ์์ผ ํ๋ค. */\n const oldest = revs[0].rev\n const legacy = counts.get(null) ?? 0\n\n return revs.map((r, i) => ({\n rev: r.rev,\n createdAt: r.createdAt,\n ...(r.comment ? { comment: r.comment } : {}),\n events: (counts.get(r.rev) ?? 0) + (r.rev === oldest ? legacy : 0),\n diff: diffStructures(i === 0 ? undefined : (revs[i - 1].model as any), r.model as any)\n }))\n }\n\n /** ์ง๊ธ ์ฐ์ด๋ ๊ตฌ์กฐ ๋ฆฌ๋น์ โ ์ด๋ฒคํธ์ ์ฐ์ ๋ฒํธ. ์์ง ์์ผ๋ฉด ๊ธฐ๋กํ๋ฉฐ ๋ง๋ ๋ค. */\n static async currentStructureRev(domainId: string, instanceId: string, model?: TwinModelDef): Promise<number | undefined> {\n const latest = await getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n if (latest) return latest.rev\n return model ? this.recordStructure(domainId, instanceId, model) : undefined\n }\n\n /** ๊ตฌ์กฐ ๋์ผ์ฑ ์ง๋ฌธ โ ์ขํ(layout) ๋ฑ ๋ทฐ ๊ด์ฌ์ฌ๋ ์ ์ธํ๊ณ ์ปค๋์ด ๋ณด๋ ์์ยท์ฉ๋ยท๋ฌด๋ฒ๋ง. */\n /**\n * ์ง๋ฌธ์ **64์๋ก ์ค์ธ๋ค** โ ์ปฌ๋ผ์ด varchar(64) ๋ค.\n *\n * ์๋ฌธ ์ง๋ฌธ์ ์๋ฆฌยท์ค๋น๋ฅผ ์ ๋ถ ์ด์ด ๋ถ์ธ ๋ฌธ์์ด์ด๋ผ ํฐ ๊ณต์ฅ์์๋ ์๋ง ์๊ฐ ๋๋ค. sqlite ๋\n * ๊ธธ์ด๋ฅผ ๊ฐ์ ํ์ง ์์ ๊ทธ๋ฅ ๋ค์ด๊ฐ์ง๋ง **Postgres ๋ ๊ฑฐ๊ธฐ์ ํฐ์ง๋ค** โ ๊ฐ๋ฐ์์๋ ๋ฉ์ฉกํ๊ณ \n * ์ด์์์๋ง ์ฃฝ๋ ์ข
๋ฅ์ ์คํจ๋ค. ๋น๊ต์๋ง ์ฐ๋ ๊ฐ์ด๋ฏ๋ก ํด์๋ก ์ถฉ๋ถํ๋ค.\n */\n private static structureFingerprint(model: TwinModelDef): string {\n return createHash('sha256').update(this.structureSignature(model)).digest('hex')\n }\n\n private static structureSignature(model: TwinModelDef): string {\n const locations = [...(model.locations ?? [])]\n .map(n => `${n.id}:${n.type}:${n.capacity}`)\n .sort()\n .join('|')\n const equipment = [...(model.equipment ?? [])]\n .map(m => `${m.id}:${m.kind}:${m.homeLocation}`)\n .sort()\n .join('|')\n return `N[${locations}]M[${equipment}]`\n }\n\n /** ๋ ์ง์คํธ๋ฆฌ model ๋ก ๊ธฐ๋(ํ๋ก๋น์ ๋ ์ธ์คํด์ค start). model ์ธ์ ์์ด ์ ์ฅ๋ ๊ตฌ์กฐ๋ก ์ฌ๊ธฐ๋. */\n static async startFromRegistry(domainId: string, instanceId: string, restartPolicy?: RestartPolicy): Promise<InstanceRuntime> {\n const key = runtimeKey(domainId, instanceId)\n if (this.instances[key]) return this.instances[key]\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.model) throw new Error(`instance \"${instanceId}\" not provisioned (no model)`)\n\n /*\n * ์์คํํธ ์ฌ๋ฃ๋ฅผ **์ฌ๊ธฐ์ ํ์คํ ํ๋ณดํ๋ค.**\n * `start()` ๋ ๋๊ธฐ๋ผ ์ค์ค๋ก ์บ์๋ฅผ ์ฝ์ ์ ์์ด์ `recovered` ์ ๋ฏธ๋ฆฌ ๋ด๊ฒจ ์๊ธฐ๋ฅผ ๊ธฐ๋ํ๋๋ฐ,\n * ๊ทธ๊ฑด `bootstrap()` ์ด ๋จผ์ ๋์์ ๋๋ง ์ฐธ์ด๋ค. ๋ถํ
์์์ ๊ธฐ๋๋ฉด ์ด๋ค ๋ ์ ์ฌ๊ณ ๊ฐ ์ด์๋๊ณ \n * ์ด๋ค ๋ ์ ์กฐ์ฉํ ๋น ์ฑ๋ก ๋ฌ๋ค โ ์ฌํ๋์ง ์๋ ๊ฒฐํจ์ด ๊ฐ์ฅ ๋์๋ค.\n * ์ฒดํฌํฌ์ธํธ ์บ์ ์ฐ์ (O(1) + ๋ผ์ด๋ธ ํ์์ํ ๋ณด์กด), ์์ผ๋ฉด ์ ๋ replay ํด๋ฐฑ(๋ถํ
๊ณผ ๊ฐ์ ์์).\n */\n if (!this.recovered[key] && reg.purpose !== 'bench') {\n const cached = await this.loadSnapshot(domainId, instanceId).catch(() => null)\n if (cached?.state) {\n this.recovered[key] = { revision: cached.revision, state: cached.state }\n } else {\n const state = await this.recover(domainId, instanceId).catch(() => null)\n if (state) this.recovered[key] = { revision: state.revision, state }\n }\n }\n\n /*\n * ์ ๋์ ๋จ์ ์๋ ๋ง์ง๋ง ๋ฒํธ โ **๋ชจ๋์ ๋ฌด๊ดํ๊ฒ** ์ด๊ฒ์ ์ด์ด ์ผ๋ค.\n *\n * ์ ๋์ ์ด๊ธฐํํ๊ณ ๊ธฐ๋ํ๋ ์ ์ฑ
(`reset`)์ด๋ผ๋ฉด ์ด ๊ฐ์ด 0์ด๋ผ ์๋ฌด ์ํฅ์ด ์๋ค. ๊ท์น์\n * ๋ชจ๋๋ณ๋ก ๊ตฌ๋ถํ์ง ์๋ ์ด์ : \"์ ๋์ด ๋น์ด ์์ง ์์ผ๋ฉด ๊ทธ ๋ค๋ถํฐ\" ํ๋๋ฉด ์ด๋ ๋ชจ๋์์๋\n * ๊ฒน์น ์ ์๊ณ , ๋ชจ๋๊ฐ ๋์ด๋ ์ด ์๋ฆฌ๋ฅผ ๋ค์ ์๋ณผ ์ผ์ด ์๋ค.\n */\n const last = await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('MAX(e.revision)', 'max')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .getRawOne()\n\n return this.start(\n instanceId,\n domainId,\n /* ์ปค๋ ์ข
๋ฅยทํ์ค ์ ์ธ์ ๋ ์ง์คํธ๋ฆฌ์ ๋ฐ๋์ ์๋ค(๋ ๋ค NOT NULL). ์์ ์๋ `?? 'wms'` ๋ก\n ๋ฉ์ ๋๋ฐ, ๊ทธ๊ฑด YMS/MES ํธ์์ **์กฐ์ฉํ WMS ๋ก ๋ถํ
**์ํค๋ ๊ธธ์ด์๋ค โ ์ค๋ฅ ์์ด ๋ค๋ฅธ ๊ณต์ฅ์ด ๋ฌ๋ค. */\n reg.kind,\n reg.model as TwinModelDef,\n /* ์ ์ฅ๋ ๊ฐ์ **์๊ฒฉํ** ์ฝ๋๋ค โ ๋ชจ๋ฅด๋ ๊ฐ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ฉ์ฐ๋ฉด ๊ทธ ํธ์์ด ์กฐ์ฉํ ๋ค๋ฅด๊ฒ ์ฌ๊ธฐ๋ํ๋ค. */\n restartPolicy ?? readRestartPolicy(reg.restartPolicy, `twin \"${instanceId}\"`),\n reg.purpose,\n Number(last?.max ?? 0) || 0\n )\n }\n\n /**\n * ์ ์ธ ๊ธฐ๋ฐ ๋ถํ
(ยง0 ํ๋ ์ โ โ ๋ถํ
๊ฑฐ๋ ๋งคํ) โ ํธ์์ด ์ ์ธํ restartPolicy ์ ๋ฐ๋ผ ์ฌ๊ธฐ๋ ๋ฐฉ์์ ๊ตฌ๋ถํ๋ค.\n * ๋ถํ
๊ฒฝ๋ก๋ฅผ ํ ๊ณณ์ ๋ชจ์ \"๋ฐํ์ โ ํ์ค\" ๋ฒ์ฃผ์ค๋ฅ๋ฅผ ์ฝ๋๋ก ๊ฐ์ ํ๋ค.\n * - 'resync' : ํ์ค=์ธ๋ถ ์ค๋ฌผ โ startLive(์ฌ๋๊ธฐ). ์ด๋ฒคํธ๋ ์ด๋ํฐ ingest ๋ก ์ ์
, ์ปค๋ tick ์์.\n * - 'resume' : ์์ฑ ํ์๋ผ์ธ ์ง์ โ ์ ๋ ๋ณด์กด + resume(ํ์ค ์ด์ด๊ฐ).\n * โ GATE(ยง8 โกโข): ์ปค๋ ์ํ ์ง๋ ฌํ/์ฌ๊ฐ๊ฐ ์์ง ์์ด ์ง์ง resume ๋ถ๊ฐ โ ์ค ํ์ยท์ค๋ถํ ์ ๊ตฌํ.\n * ๊ทธ๋๊น์ง๋ ์ ๋์ ๋ณด์กดํ๋ revision ์ถฉ๋์ ํผํ๋ ค fresh ๋ก ๊ธฐ๋ํ๊ณ , ์ ์ธ๊ณผ ๊ตฌํ์ ๊ฐ๊ทน์ ํฌ๊ฒ ๊ฒฝ๊ณ ํ๋ค.\n * - 'reset' : seed ์ฌํ โ resetJournal + fresh ๊ธฐ๋(๋ฐฑ์ง ์์์ด ๋ฒ๊ทธ๊ฐ ์๋๋ผ ์ ์ธ๋ ๊ฑฐ๋).\n * ๋ฐํ: ๊ธฐ๋๋ InstanceRuntime.\n */\n static async bootDeclared(domainId: string, instanceId: string, mode: RestartPolicy): Promise<InstanceRuntime> {\n if (mode === 'resync') {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.model) throw new Error(`instance \"${instanceId}\" not provisioned (no model)`)\n return this.startLive(instanceId, domainId, reg.kind, reg.model as TwinModelDef)\n }\n if (mode === 'resume') {\n /*\n * **์ด์ด์ง๋ ํ์ค** โ ์ ๋์ ์ง์ฐ์ง ์๋๋ค.\n *\n * ์์ ์๋ ์ฌ๊ธฐ์ ์ ๋์ ์ง์ฐ๊ณ fresh ๋ก ๋์ ๋ค. resume ๊ธฐ๊ณ์ฅ์น๊ฐ ์๋ค๊ณ ๋ดค๊ธฐ ๋๋ฌธ์ธ๋ฐ,\n * ์ค์ ๋ก ์๋ ๊ฒ์ **๋ฒํธ ์ด์ด ์ธ๊ธฐ ํ๋**์๋ค: ์ํ ๋ณต์์ ์ด๋ฏธ `startFromRegistry` ๊ฐ\n * ์ ๋ ์ฌ์(๋๋ ์ฒดํฌํฌ์ธํธ)์ผ๋ก ํ๊ณ ์์๊ณ , ๋งํ ๊ฒ์ ์ปค๋์ด ๋ฆฌ๋น์ ์ 0๋ถํฐ ๋ค์ ์ธ์ด\n * ๊ธฐ์กด ํ๊ณผ ๊ฒน์น๋ ๋ฌธ์ ์๋ค. ๊ทธ ํ๋๋ฅผ `resumeRevision` ์ผ๋ก ํ์์ผ๋ฏ๋ก ์ด์ ์ด์ด ๊ฐ๋ค.\n *\n * ์์ง ์ด์ด์ง์ง ์๋ ๊ฒ(์ ์งํ๊ฒ): ์๋๋ฆฌ์ค ์์ฑ๊ธฐ์ ๋์ ํ๋ฆ์ ์ฌ๊ธฐ๋์ ์ด์ด์ง์ง ์๋๋ค โ\n * ๊ฐ์ ์จ์์์ ๋ค์ ์์ํ๋ฏ๋ก ์๊ทน์ ํจํด์ด ์ฌ๊ธฐ๋ ์ง์ ์์ ํ ๋ฒ ๋๊ธด๋ค. ์์ธ ์ฌ์ค๊ณผ\n * ์ํ๋ ์ด์ด์ง๊ณ , ์์ผ๋ก ์ผ์ด๋ ์ผ์ ๋ฌด์์ ์์๋ง ์๋ก ์์ํ๋ค.\n */\n return this.startFromRegistry(domainId, instanceId, 'resume')\n }\n // `reset`: seed ์ฌํ โ ์ ๋ ์ด๊ธฐํ ํ revision 0 ๋ถํฐ ์ฌ์คํ.\n await this.resetJournal(domainId, instanceId)\n return this.startFromRegistry(domainId, instanceId, 'reset')\n }\n\n /**\n * ์ ๋ ์ด๊ธฐํ โ ์ธ์คํด์ค ์ด๋ฒคํธ ์ ๋ purge(๋ ์ง์คํธ๋ฆฌยท์ํ๋ ์ ์ง).\n * ๋ฐ๋ชจ fresh-start ์ฉ: ๋งค ๋ถํ
seed ๋ถํฐ ์๋ก ์คํํ๋ ๋ฐ๋ชจ์์, ๋ณต๊ตฌ๋ณธ ํ๊ธฐ ํ revision 0 ๋ถํฐ ์ฌ์คํํ๋ฉด\n * ์ ๋ฐ๊ณผ revision ์ด ๊ฒน์ณ ์ ๋์ด ์ค์ผ๋๋ค โ start ์ ์ ํธ์ถํด ํ์ฌ ๋ฐ๋ง ๋จ๊ธด๋ค.\n */\n static async resetJournal(domainId: string, instanceId: string): Promise<void> {\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n delete this.recovered[runtimeKey(domainId, instanceId)]\n }\n\n /** ์ญ์ โ ์ ์ง + ๋ ์ง์คํธ๋ฆฌ ์ญ์ + ์ ๋ purge(domain ์ค์ฝํ). */\n static async remove(domainId: string, instanceId: string): Promise<void> {\n await this.stop(domainId, instanceId)\n this.forgetInstance(domainId, instanceId)\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n await getRepository(TwinInstance).delete({ domain: { id: domainId } as any, instanceId })\n }\n\n /**\n * ์ด ํธ์์ ๋ํด **๋ฉ๋ชจ๋ฆฌ์ ๋จ์ ๊ฒ์ ์ ๋ถ ์๋๋ค** โ ์ง์์ ํ ์๋ฆฌ.\n *\n * ์บ์๊ฐ ๋ผ์ดํ์ฌ์ดํด๊ณผ ์ด๊ธ๋ ์์๋ค: ์ ๋ยท๋ฑ๋ก๋ถ๋ ์ง์ฐ๋ฉด์ ์ธ์คํด์ค๋ณ ์บ์๋ ๋จ๊ฒจ, ์ญ์ ๋ ํธ์์\n * ํญ๋ชฉ์ด **์๋ฒ ์ฌ๊ธฐ๋๊น์ง ์ด์ ์์๋ค.** ํญ๋ชฉ ํ๋๊ฐ ํ๋ฃจ์น KPI ๊ทธ๋ฃน์ ๋ฌผ๊ณ ์์ผ๋ฏ๋ก ์์ง ์์ผ๋ฉด\n * ์ง์ด ํธ์์ด ๊ณ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์งํ๋ค. TTL ์ ๊ฐ์ด ๋ก๋ ๊ฒ์ ๋ง์ ๋ฟ **์์ด์ง ์ฃผ์ธ์ ์ง์ฐ์ง ์๋๋ค.**\n *\n * ์์ ๊ฒ์ ์ฌ๊ธฐ ๋ชจ์ ๋๋ ์ด์ : ์บ์๋ฅผ ์๋ก ๋ง๋๋ ์ฌ๋์ด ์ง์ฐ๋ ์๋ฆฌ๋ฅผ ์ฐพ์ ํค๋งค์ง ์๊ฒ ํ๋ค.\n * ์ ์ธ์คํด์ค๋ณ ์บ์๋ฅผ ๋ง๋ค๋ฉด **์ด ํจ์์ ํ ์ค์ ๋ํ๋ค** โ ๊ทธ๋ฌ์ง ์์ผ๋ฉด ๊ฐ์ ๋์๊ฐ ๋ค์ ์๊ธด๋ค.\n */\n private static forgetInstance(domainId: string, instanceId: string): void {\n const key = runtimeKey(domainId, instanceId)\n delete this.recovered[key]\n this.measuredCache.delete(key)\n delete this.structureRevCache[key]\n }\n\n /** ๊ด๋ฆฌ ๋ชฉ๋ก โ domain ์ ๋ฑ๋ก ์ธ์คํด์ค ์ ์ฒด(๋ผ์ด๋ธ ์ฌ๋ถยท์ต์ ์ ๋ revisionยท๋
ธ๋/๋ฌด๋ฒ ์ ํฌํจ). */\n static async list(domainId: string): Promise<any[]> {\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n /*\n * **ํ์ฅ ์ด๋ฆ์ ํจ๊ป ๋ธ๋ค** โ ๋ชฉ๋ก์ด `spaceId` ๋ง ๋ด๋ณด๋ด์ ํ๋ฉด์ด ์ด๋ฆ์ ๋ฐ๋ก ์กฐํํ๊ณ ์์๋ค.\n * ๊ทธ ์กฐํ(`twinSpaces`)๋ ๊ณต๊ฐ๋ง๋ค ์นด์ดํธ ์ฟผ๋ฆฌ๋ฅผ ๋๋ N+1 ์ด๋ผ ๋๋ฆฌ๊ณ , ๊ทธ ์ฌ์ด ํ๋ฉด์ **id ๋ฅผ\n * ์ด๋ฆ์ฒ๋ผ** ๋ณด์ฌ ์ค๋ค(2026-08-13 ๊ด์ธก: ใํ์ฅ crew-probe-siteใ). ํ ๋ฒ์ ์ฝ์ด map ์ผ๋ก ๋ถ์ด๋ฉด\n * ์๋ณต๋ ์ค๊ณ ๊ทธ ๊น๋นก์๋ ์ฌ๋ผ์ง๋ค. ์ด๋ฆ์ด ์์ผ๋ฉด **๋น์ด๋ค** โ id ๋ฅผ ์ด๋ฆ์ผ๋ก ๋ฒ ๋ผ์ง ์๋๋ค.\n */\n const spaceNameOf = new Map(\n (await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name])\n )\n /*\n * **์ต์ ๋ฆฌ๋น์ ์ ํ ๋ฒ์ ๋ฌป๋๋ค.**\n *\n * ํธ์๋ง๋ค `findOne(order revision DESC)` ์ ๋๊ณ ์์๋ค โ 13๊ฐ๋ฉด ์ง์ 13๋ฒ์ด๊ณ , ํธ์์ด ๋๋ฉด\n * ๊ทธ๋๋ก ์๋๋ค. ์ด ๋ชฉ๋ก์ ํธ์ ๊ด๋ฆฌยทํ์ฅ ๊ตฌ์ฑยท์ํฐํฐ ํจ๋์ด ๋ชจ๋ ์ฝ๋ ์๋ฆฌ๋ค.\n * ํ ๋ฒ์ ๊ทธ๋ฃน ์ง์๋ก ๋ฐ๊พผ๋ค(๊ฐ์ ๋ชจ์์ ์ ๋ก๊ฐ ์ด ํ์ผ์ ์ด๋ฏธ ์๋ค: structureRev ์ง๊ณ).\n */\n const tipOfInstance = new Map<string, number>()\n try {\n const tips = await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('e.instanceId', 'instanceId')\n .addSelect('MAX(e.revision)', 'revision')\n .where('e.domain = :domainId', { domainId })\n .groupBy('e.instanceId')\n .getRawMany()\n for (const t of tips) if (t?.instanceId != null) tipOfInstance.set(String(t.instanceId), Number(t.revision) || 0)\n } catch (err: any) {\n /* ์ง๊ณ๊ฐ ์คํจํ๋ฉด **0 ์ผ๋ก ๋ฉ์ฐ์ง ์๋๋ค** โ ๋ฆฌ๋น์ 0 ์ \"์์ง ์๋ฌด ์ผ๋ ์์๋ค\" ๋ ์ฌ์ค ์ฃผ์ฅ์ด๋ค.\n ๋น์ ๋๋ฉด ์๋์์ `?? 0` ์ด ์๋๋ผ undefined ๋ก ๋จ๊ณ , ํ๋ฉด์ ๊ทธ๊ฒ์ \"๋ชจ๋ฆ\" ์ผ๋ก ๊ทธ๋ฆฐ๋ค. */\n console.error('[twin-engine] latest revision aggregate failed', err?.message ?? err)\n }\n\n const out: any[] = []\n for (const r of rows) {\n const model = (r.model as TwinModelDef) ?? { locations: [], equipment: [] }\n out.push({\n instanceId: r.instanceId,\n /*\n * **์ด๋ฆ์ ํจ๊ป ๋ธ๋ค.** ์
๋ฌดํค(`instanceId`)๋ง ๋ด๋ณด๋ด๊ณ ์์ด์ ๋ชฉ๋ก์ด `crew-two` ๋ง ๋ณด์๋ค โ\n * ์
๋ฌดํค๋ฅผ ๋๋ ๋ ์ค๊ณ์์๋ ์ด๋ฆ์ ๊ฐ์ด ์ค์ด์ผ ๊ทธ ๋๋์ด ๊ฐ์ ํ๋ค.\n * ์์ผ๋ฉด `undefined` ๋ค(id ๋ฅผ ๋ฒ ๋ผ์ง ์๋๋ค โ ํ๋ฉด์ด ์ด๋ฆ ์์์ ์์๋ณผ ์ ์์ด์ผ ํ๋ค).\n */\n name: r.name ?? undefined,\n description: r.description ?? undefined,\n kind: r.kind,\n status: r.status,\n spaceId: r.spaceId, // co-location: ๊ฐ์ spaceId ์ธ์คํด์ค๋ค์ด ํ ํ์ฅ ๊ณต์ โ ํ์ฅ๋ทฐ ์ง์ฝ ํค(G7)\n /* ์ฌ๋์ด ์ฝ๋ ํ์ฅ ์ด๋ฆ โ ์์ผ๋ฉด `undefined`(ํ๋ฉด์ด \"์ด๋ฆ ์์\" ์ ์์๋ณผ ์ ์์ด์ผ ํ๋ค). */\n spaceName: (r.spaceId ? spaceNameOf.get(r.spaceId) : undefined) || undefined,\n restartPolicy: r.restartPolicy, // ์ฌ๊ธฐ๋ ์ ์ฑ
(ADR-0029 ยง2) โ resync/resume/reset. ์ ์ธ์ด๋ฏ๋ก ๋น์ด ์์ ์ ์๋ค.\n purpose: r.purpose, // ์ด์ vs ๋ฒค์น ์ฌ๋ณธ(1๊ธ ๊ตฌ๋ณ โ ์ด๋ฆ ์ ๋์ฌ ์๋). ์ ์ฅ ์ ๊ฐ์ธ๋๋ฏ๋ก ๋น์ง ์๋๋ค.\n copyOf: r.copyOf ?? undefined,\n running: !!this.instances[runtimeKey(domainId, r.instanceId)],\n /*\n * **๊ณ์ธก์ด ๋ค์ด์ค๊ณ ์๋** โ ใ๋๋ ์คใ๊ณผ ๋ค๋ฅธ ์ฌ์ค์ด๋ค.\n *\n * ๋ฏธ๋ฌ ํธ์์ ํผ๋๊ฐ ๋จ์ด์ ธ๋ ์ปค๋์ด ๋๊ธฐ๋ง ํ๋ฉด ใ๋๋ ์คใ์ด์๋ค. ๊ทธ๋์ ์๋ฌด๊ฒ๋ ๋ฐ์ง ์๋\n * ํธ์๊ณผ ํ๋ฅด๋ ํธ์์ด ํ๋ฉด์์ ๋๊ฐ์ด ๋ณด์๋ค(์ฌ๊ธฐ๋ ๋ค ์ค์ ๋ก ๊ทธ๋ฌ๋ค). ์๋ฎฌยท์ ์ง ํธ์์๋\n * ใํด๋น ์์ใ์ด๋ค โ ์์ด์ผ ํ๋ ๊ฒ์ ๋๊ฒผ๋ค๊ณ ๋ถ๋ฅด์ง ์๋๋ค.\n */\n /* ์ค์ค๋ก ๋ฉ์ถ ์ด์ โ ์์ผ๋ฉด ๋ธ๋ค. ์ฌ๊ธฐ๋ ๋ค์๋ ์๋ค(๊ทธ๋๋ ใ๋ชจ๋ฅธ๋คใ๊ฐ ์ฌ์ค์ด๋ค). */\n stopNote: this.stopNotes.get(runtimeKey(domainId, r.instanceId)) || undefined,\n liveFeed: liveFeedStateOf({\n restartPolicy: r.restartPolicy,\n running: !!this.instances[runtimeKey(domainId, r.instanceId)],\n instanceId: r.instanceId\n }),\n revision: tipOfInstance.get(r.instanceId) ?? 0,\n /*\n * **๋ฆฌ๋๋ฅผ ๊ฑฐ์ณ ์ผ๋ค** โ ๋ณด๋ ํค๋ฅผ ์ง์ ์ฝ์ผ๋ฉด ์ ์ธ๋ ๋ชจ๋ธ์ด 0 ์ผ๋ก ๋ณด์ธ๋ค.\n *\n * ์ปค๋์ ์๋ฆฌยท์ค๋น ๋ฐฐ์ด์ **์ ์ธ๋ ํค๊น์ง ํก์ํด** ์ฝ์ด ์ฃผ๋๋ฐ, ์ด ๋ชฉ๋ก์ ์ ์ด๋ฆ๋ง ์ง์ \n * ์ธ๊ณ ์์๋ค. ๊ทธ๋์ ์ ๋ชจ๋ธ 12๊ฐ๊ฐ ํ๋ฉด์ **์๋ฆฌ 0 ยท ์ค๋น 0**\n * ์ผ๋ก ๋ด๋ค โ ์ค๋ฅ ์์ด, ๊ทธ๋ฅ ๋น ๊ณต์ฅ์ฒ๋ผ. ์ธ๋ ๊ท์น์ด ๋ ๋ฒ์ด๋ฉด ์ด๋ฐ ์์ผ๋ก ์ด๊ธ๋๋ค.\n */\n locationCount: readBoardLocations(model).length,\n equipmentCount: readBoardEquipment(model).length\n })\n }\n return out\n }\n\n /** ์ด์ ๊ณต๊ฐ ๋ชฉ๋ก(๋ฒค์น ์์ค ์ ํ๊ธฐ) โ ์ด๋ฆยท๊ท๋ชจ ํฌํจ, ๋ฒค์น ์ฌ๋ณธ ์ ์ธ. */\n static async listSpaces(domainId: string): Promise<{ spaceId: string; name: string; instances: number; locations: number; equipment: number }[]> {\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const agg = new Map<string, { spaceId: string; name: string; instances: number; locations: number; equipment: number }>()\n for (const r of insts) {\n /* ๋ฒค์น ์ ์ธ๋ **์ ์ธ์ผ๋ก๋ง** ํ๋จํ๋ค. ์์ ์๋ spaceId ์ด๋ฆ(`bench-`ยท`loadtest*`)์ผ๋ก๋ ์ถ์ธกํ๋๋ฐ,\n ๊ทธ๋ฌ๋ฉด ๊ทธ๋ ๊ฒ ์ด๋ฆ ์ง์ ์ง์ง ์ด์ ๊ณต๊ฐ์ด ๋ชฉ๋ก์์ ์กฐ์ฉํ ์ฌ๋ผ์ง๋ค. purpose ๊ฐ ์ ๋ณธ์ด๋ค. */\n if (!r.spaceId || r.purpose === 'bench') continue\n const model: any = r.model ?? {}\n const a = agg.get(r.spaceId) ?? { spaceId: r.spaceId, name: nameOf.get(r.spaceId) ?? r.spaceId, instances: 0, locations: 0, equipment: 0 }\n a.instances++\n /* ๋ชฉ๋ก๊ณผ **๊ฐ์ ๊ท์น**์ผ๋ก ์ผ๋ค โ ์ฌ๊ธฐ๋ง ์ง์ ์ธ๋ฉด ๊ณต๊ฐ ์์ฝ๊ณผ ์ธ์คํด์ค ๋ชฉ๋ก์ด ๋ค๋ฅธ ์๋ฅผ ๋งํ๋ค. */\n a.locations += readBoardLocations(model).length\n a.equipment += readBoardEquipment(model).length\n agg.set(r.spaceId, a)\n }\n return [...agg.values()]\n }\n\n /** ์ธ์คํด์ค ๋ชฉ์ ํ์(์ด์/๋ฒค์น) ์ค์ โ ๋ฒค์น ์ฌ๋ณธ์ 1๊ธ ์์ฑ์ผ๋ก ๊ตฌ๋ณ(์ด๋ฆ ์ ๋์ฌ ์๋). */\n static async setPurpose(domainId: string, instanceId: string, purpose: 'operational' | 'bench', copyOf?: string): Promise<void> {\n await getRepository(TwinInstance).update({ domain: { id: domainId } as any, instanceId }, { purpose, copyOf: copyOf ?? null } as any)\n }\n\n /**\n * ๊ณต๊ฐ ๊ตฌ์กฐ ํ๋
โ ์์ ๋ณต์ (๋ฒค์น ์ฌ๋ณธ)์ ์์ค. ์ ์ฅ๋ฌผ์ด model(์์)ยทTwinSpace.content(์น์ยทgeoยทํํ)ยทTwinArea(์์ญ)๋ก\n * ๋ถ์ฐ๋ผ ์์ผ๋ฏ๋ก ์
์ ๋ชจ์ ๋๋ ค์ค๋ค. ํธ์ถ์ธก์ด ReferenceMaster ๋ก ์ฌ๊ตฌ์ฑ โ ์ฌ์๋ณ โ ingestMaster.\n */\n static async spaceStructure(domainId: string, spaceId: string): Promise<{\n name?: string\n /** ์ค๊ณ ์ขํ๊ณ ๋ฒ์(๋ฏธํฐ)์ ์ง์ค๋ ํผ๋ฐ์ค โ ์ฌ๋ณธ์ด ์๋ณธ๊ณผ ๊ฐ์ ์๋ฆฌ์ ์๋ ค๋ฉด ํจ๊ป ๊ฐ์ผ ํ๋ค. */\n frame: { extentX?: number; extentY?: number; geo?: any; primaryRepresentationId?: string }\n areas: any[]\n instances: { instanceId: string; kind?: string; model: any }[]\n } | null> {\n const sp = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n const areas = sp\n ? (await getRepository(TwinArea).find({ where: { domain: { id: domainId } as any, space: { id: sp.id } as any } })).map(a => ({ id: a.areaId, type: a.type, name: a.name, parentId: a.parentId, layout: a.layout }))\n : []\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n if (!insts.length) return null\n return {\n name: sp?.name,\n frame: { extentX: sp?.extentX, extentY: sp?.extentY, geo: sp?.geo, primaryRepresentationId: sp?.primaryRepresentationId },\n areas,\n instances: insts.map(i => ({ instanceId: i.instanceId, kind: i.kind, model: i.model }))\n }\n }\n\n /** ๊ณต๊ฐ(+ํํยท์์ญ) ์ญ์ โ ๋ฒค์น ์ ๋ฆฌ ๋ฑ. ํธ์ถ์ธก์ด ๋ฐ์ธ๋ฉ ์ธ์คํด์ค๋ฅผ ๋จผ์ ์ ๊ฑฐํ๋ ์ ์ (๊ฐ๋ ์์). deleteTwinSpace ๋ฆฌ์กธ๋ฒ์ ๋ํ. */\n static async deleteSpace(domainId: string, spaceId: string): Promise<void> {\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (space) {\n const reps = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId }, space: { id: space.id } } })\n for (const rep of reps) await getRepository(TwinSpaceArea).delete({ domain: { id: domainId } as any, representation: { id: rep.id } as any })\n await getRepository(TwinSpaceRepresentation).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n await getRepository(TwinArea).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n }\n await getRepository(TwinSpace).delete({ domain: { id: domainId } as any, spaceId })\n }\n\n /**\n * Face2 ๋ง์คํฐ ์ธ์ ์คํธ(ADR-0018) โ ๋ ํผ๋ฐ์ค ์์คํ
(์ค ๋๋ ๊ฐ์)์ ๋ง์คํฐ๋ฅผ ์ฝ์ด ํธ์์ ์์ฑ.\n * ์ํฐํฐ๋ฅผ ์๋ฐฐ์ /๋ฐ๋ช
ํ์ง ์๊ณ ๋ง์คํฐ์์ ๋ฐ์: ๊ณต๊ฐ(Space) upsert + ์ธ์คํด์ค provision(๋ฏธ๊ธฐ๋).\n * ๋
ธ๋ํ์
์ ์ปค๋ ์นดํ๋ก๊ทธ๋ก ๊ฒ์ฆ(warning). start ๋ ํธ์ถ์ธก(bootstrap/mutation)์ด ๊ฒฐ์ .\n *\n * `into.spaceId` โ **์ด ํ์ฅ์ ๋ํ๋ค.** ํ ํ์ค์ ์ฌ๋ฌ ๋ ์ฆ(WMSยทMESยทYMS)๊ฐ ๋น์ถ๋ฏ๋ก ์ ํธ์์ด\n * ๊ธฐ์กด ๊ณต๊ฐ์ผ๋ก ๋ค์ด๊ฐ ์ ์๋ค. ์๋ ๋ณํฉ์ ์๋ ๊ทธ ๊ฒฝ์ฐ๋ฅผ ์ํด ์์๋๋ฐ(N:1) ๋ง๋๋ ํ๋ฆ์์\n * ๊ณต๊ฐ์ ๊ณ ๋ฅผ ๋ฐฉ๋ฒ์ด ์์๋ค โ ๋ง์คํฐ๊ฐ ํ์ํ id ๋ง ์ฐ์๋ค. ํ์ ์ `resolveIngestSpace`(์์).\n */\n static async ingestMaster(\n domainId: string,\n master: ReferenceMaster,\n /** ๋ง๋ค์ด์ง๋ ํธ์์ ์ฌ๊ธฐ๋ ์ ์ฑ
โ ์๋ณธ์ด ์ ํ๋ ๊ฒ์ด ์๋๋ผ **๋ง๋๋ ์ชฝ์ ์ ์ธ**์ด๋ค(ADR-0029 ยง2). */\n restartPolicy: RestartPolicy,\n into?: { spaceId?: string },\n /** ๋๊ฐ ์ธ์ ์คํธํ๋ โ ์ฌ๋์ด ์๋ ๊ฒฝ๋ก(๋ถํ
)๋ ์ฃผ์ง ์๋๋ค(๊ฐ์ฌ ๊ธฐ๋ก์ ์ง์ด๋ด์ง ์๋๋ค). */\n actor?: { id: string }\n ): Promise<{ instanceId: string; spaceId: string; warnings: IngestWarning[] }> {\n /*\n * **๊ฑฐ์ ํ ๊ฒ์ด๋ฉด ์๋ฌด๊ฒ๋ ์ฐ๊ธฐ ์ ์ ๊ฑฐ์ ํ๋ค.**\n *\n * ๊ฐ๋ ์ค ์ฌํ๋ก๋น์ ๋์ `provision` ์ด ๋ง๋๋ค. ๊ทธ๋ฐ๋ฐ ๊ทธ ํธ์ถ์ ์ด ํจ์์ **๋งจ ๋**์ด๋ผ,\n * ๊ทธ๋๊น์ง ๊ณต๊ฐยทํํยท๊ตฌ์ญ(TwinArea)์ ์ด๋ฏธ ์ ์ฅ๋ ๋ค์๋ค. ์ฌ์ฉ์์๊ฒ๋ \"์ธ์ ์คํธ ์คํจ\" ๋ก\n * ๋ณด์ด๋๋ฐ ์ค์ ๋ก๋ ์ ๋ฐ์ด ์ ์ฉ๋ ์ํ โ ์คํจ๋ผ๊ณ ๋งํ๋ฉด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พธ๋ ๊ฒ์ด ๊ฐ์ฅ ๋์๋ค.\n *\n * ๊ทธ๋์ ํ์ ์ ์์ผ๋ก ์ฎ๊ธด๋ค. ์๋ `provision` ์ ๊ฐ์ ํ์ ์ ๊ทธ๋๋ก ๋๋ค โ ์ด๊ฑด ํธ์๋ฅผ ์ํ\n * ์์ ๊ฑฐ์ ์ด๊ณ , ์ ๊ธฐ๊ฐ ์ง์ง ๋ฐฉ๋ฒฝ์ด๋ค(๋ค๋ฅธ ๊ฒฝ๋ก๊ฐ ์๊ฒจ๋ ์ง์ผ์ ธ์ผ ํ๋ค).\n *\n * **๋ฏธ๋ฌ๋ ์ฌ๊ธฐ์ ๊ฑฐ์ ํ์ง ์๋๋ค.** ๋ฏธ๋ฌ๊ฐ ๋น์ถ๋ ํ์ค์ ์ ๋ฉ์ถ๋ฏ๋ก ๋์ ์ค์ ์ ํํ๋ค\n * (์๋ `adoptStructure`). ๊ฑฐ์ ์ ์๋ฎฌ๋ ์ด์
์๋ง ๋จ๋๋ค โ ์กฐ๊ฑด์ด ๋ฐ๋ ์คํ์ ๋ค๋ฅธ ์คํ์ด๋ค.\n */\n const running = this.instances[runtimeKey(domainId, master.source)]\n if (running && running.mode !== 'live') this.assertNotRunning(domainId, master.source)\n\n const { model, spaceContent, warnings } = masterToTwin(master, DOMAIN_CATALOG)\n /*\n * โโ ํ์ฅ ์ ์ธ์ ๋ค์ ์น๋๋ค (2026-08-18) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n *\n * ์ฌ๊ธฐ๊ฐ ใ์์ฒ์์ ๋ค์ ๊ทธ๋ฆฌ๋ใ ์๋ฆฌ๋ค. ์๊ธ ๋จ๊ฐยท๊ณ์ฝ ์ ๋ณด์ฒ๋ผ **ํ์ฅ์ด ์ ํ ์**๋ ์์ฒ์ด ๋ชจ๋ฅด๋ฏ๋ก\n * ๋ค์ ๊ทธ๋ฆฌ๋ฉด ๊ทธ๋๋ก ์ฌ๋ผ์ง๋ค โ ๊ธ์ก์ด ์ฌ๋ผ์ง๊ณ , ์ฌ์ฉ์๋ ์๊ธฐ๊ฐ ๋ฃ์ ๊ฐ์ด ์ด๋๋ก ๊ฐ๋์ง ์ ์ ์๋ค.\n * ๊ทธ๋์ ๊ฒน์ผ๋ก ๋ณด๊ดํ ์ ์ธ์ ๋งค๋ฒ ๋ค์ ์น๋๋ค(`engine/local-declarations`).\n *\n * ๋์์ด ์ฌ๋ผ์ก์ผ๋ฉด(๊ตฌ์กฐ๊ฐ ๋ฐ๋์๋ค) ๊ทธ ์ฌ์ค์ ๊ฒฝ๊ณ ๋ก ๋ธ๋ค โ ๊ฐ ๊ณณ ์๋ ์ ์ธ์ ์กฐ์ฉํ ๋ฒ๋ฆฌ์ง ์๋๋ค.\n */\n const prior = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId: master.source } })\n /*\n * ๊ฒน์ด **๋**์ด๋ค โ ํ์ฅ(๊ณต๊ฐ)์ ๊ฒ๊ณผ ์ด ํธ์์ ๊ฒ. ์์๊ฐ ๊ท์จ์ด๋ค: ํ์ฅ ๋จผ์ , ํธ์์ด ๋์ค.\n * ์๊ธ์ฒ๋ผ ํ์ฅ์ด ์ ํ ์๋ ๊ทธ ํ์ฅ์ ํธ์ ์ ๋ถ๊ฐ ๊ฐ์ด ์ฝ์ด์ผ ํ๊ณ , ํ ํธ์๋ง ๋ค๋ฅด๊ฒ ๋๋ ์คํ์\n * ์ข์ ๊ฒน์ด ์ด๊ฒจ์ผ ํ๋ค(๋์ ๊ฐ์ ๊ณ ์น๋ฉด ๋๋จธ์ง ํธ์์ด ํจ๊ป ํ๋ค๋ฆฐ๋ค).\n */\n const priorSpaceId = prior?.spaceId ?? (model as any)?.spaceId\n const spaceRow = priorSpaceId\n ? await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId: priorSpaceId } })\n : null\n if (prior?.localDeclarations || spaceRow?.localDeclarations) {\n const layered = applyDeclarationLayers(model as any, spaceRow?.localDeclarations as any, prior?.localDeclarations as any)\n Object.assign(model as any, layered.model)\n /*\n * ๊ฒน์ **๋ค์ ์ ์ฅํ๋ค** โ ์ฌ๊ธฐ์ ์น์ ๊ฒ์ ์์ฒ์์ ์๋ก ๊ทธ๋ฆฐ ๋ชจ๋ธ์ด๋ฏ๋ก, ๊ทธ๋ ์ฐ๋ฆฌ๊ฐ ๋ฎ์ ๊ฐ์ด\n * ๊ณง ์ง๊ธ์ ์์ฒ ๊ฐ์ด๋ค(`replaced`). ์ ์ฅํ์ง ์์ผ๋ฉด ๊ทธ ๊ธฐ์ต์ด ๋ก์, ์ฒ ํ๊ฐ ์ ์์ฒ ๊ฐ์ผ๋ก\n * ๋๋๋ฆฐ๋ค โ ์์ฒ์ด ๊ทธ๋์ ๊ฐ์ ๊ณ ์ณค์ด๋ ์ ์ ์๋ค.\n */\n if (prior) {\n prior.localDeclarations = layered.instanceLayerApplied as any\n await getRepository(TwinInstance).save(prior)\n }\n if (spaceRow) {\n spaceRow.localDeclarations = layered.spaceLayerApplied as any\n await getRepository(TwinSpace).save(spaceRow)\n }\n /*\n * ๊ฐ ๊ณณ ์๋ ์ ์ธ์ ๊ฒฝ๊ณ ๋ก ๋ธ๋ค โ ๋ค๋ง **ํ์ฅ ๊ฒน์ ๊ฒ์ ๋บ๋ค**: ํ ํ์ฅ์๋ ์ฌ๋ฌ ์ข
๋ฅ์ ํธ์์ด\n * ์ด๊ณ (์ฐฝ๊ณ ยท์ผ๋ยท์๋์ง), ์๊ธ ์๋ฆฌ๊ฐ ์๋ ํธ์์ ์๊ธ์ด ์นํ์ง ์๋ ๊ฒ์ ์ ์์ด๋ค.\n */\n for (const t of layered.missingTargets.filter(x => x.scope === 'instance')) {\n warnings.push(unresolvedReference('localDeclaration.target', `${t.target}:${t.id}`))\n }\n }\n const repo = getRepository(TwinSpace)\n /* ํฉ์น ๊ณต๊ฐ์ ๊ณจ๋์ผ๋ฉด **์๋์ง ๋จผ์ ํ์ธํ๋ค** โ ์๋ ๊ณณ์ ์กฐ์ฉํ ์ ๊ณต๊ฐ์ ๋ง๋ค๋ฉด ์ฌ์ฉ์๋\n ํฉ์ณค๋ค๊ณ ๋ฏฟ๊ณ ํ๋ฉด์ ๋ฐ๋ก ๋
ผ๋ค. ํ์ ํจ์๊ฐ ๊ทธ ๊ฒฝ์ฐ ๊ฑฐ์ ํ๋ค. */\n const wanted = (into?.spaceId ?? '').trim()\n const wantedExists = wanted\n ? (await repo.count({ where: { domain: { id: domainId }, spaceId: wanted } })) > 0\n : false\n const choice = resolveIngestSpace(model.spaceId, wanted, wantedExists)\n const spaceId: string = choice.spaceId\n model.spaceId = spaceId // ๋ณด๋(์ปค๋ ์๋น)๋ ๊ฐ์ ๊ณต๊ฐ์ ๊ฐ๋ฆฌ์ผ์ผ ํ๋ค\n const existing = await repo.findOne({ where: { domain: { id: domainId }, spaceId } })\n if (choice.joined) {\n /* ๊ฐ์ id ์ ๊ตฌ์ญยท๋๋๋งํฌ๋ ํฉ์งํฉ์ผ๋ก ์ ํ๋ค โ ๊ตฌ๋ถํ ์ ์๋ ๊ฒ์ ๊ณ ๋ฅด์ง ์๊ณ ๋ฌด์์ด\n ํฉ์ณ์ก๋์ง ๋งํ๋ค(์ ๋นํ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ฏ๋ก ๋ง์ง ์๋๋ค). */\n }\n /*\n * ๊ณต์ ๊ณต๊ฐ(์ฌ๋ฌ ํธ์์ด ํ spaceId, N:1) โ **๋จผ์ ์ด ๊ฐ์ด ์ด๊ธด๋ค.**\n *\n * ๋ง์ง๋ง ์ธ์ ์คํธ๊ฐ ํต์งธ๋ก ๋ฎ์ด์จ ํํยท๊ตฌ์ญ์ด ์ ์ค๋๋ ๋ฌธ์ ๋ณด์ . ์ค๊ณ ์ขํ๊ณ ๋ฒ์์\n * ์ง์ค๋ ํผ๋ฐ์ค๋ ๊ณต๊ฐ์ ์ฑ์ง์ด๋ผ ํธ์๋ง๋ค ๋ค๋ฅผ ์ ์๋ค โ ๋ ๋ฒ์งธ ํธ์์ด ๋ค์ด์ค๋ฉด์ ๋ฐ๊พธ๋ฉด\n * ๋จผ์ ๋์ธ ๊ตฌ์ญ๋ค์ด ํต์งธ๋ก ์ด๊ธ๋๋ค. ๊ทธ๋์ ์ด๋ฏธ ์์ผ๋ฉด ๊ทธ๋๋ก ๋๋ค.\n */\n const cur: any = spaceContent\n const timezone = existing?.timezone || master.space.timezone\n const savedSpace = await repo.save(\n repo.create({\n ...(existing ?? {}),\n domain: { id: domainId } as any,\n spaceId,\n name: existing?.name || master.siteName,\n ...(timezone ? { timezone } : {}),\n extentX: existing?.extentX ?? cur.width,\n extentY: existing?.extentY ?? cur.depth,\n geo: existing?.geo ?? cur.geo,\n /*\n * ๋ํ ํํ ํฌ์ธํฐ๋ **ํํ์ ์ ์ฅํ ๋ค** ์ค์ ํ id ๋ก ์ฑ์ด๋ค(์๋). ์ฌ๊ธฐ์ ๋ง์คํฐ์ ๋
ผ๋ฆฌ\n * id(`r-map` ๋ฐ์)๋ฅผ ๋ฃ์ผ๋ฉด ํํ ํ์ ์์ฑ uuid ๋ฅผ ๋ฐ์ผ๋ฏ๋ก ํฌ์ธํฐ๊ฐ **์ฒ์๋ถํฐ ํ๊ณต์\n * ๊ฐ๋ฆฌํจ๋ค** โ ์ค์ ๋ก 13๊ฐ ํ์ฅ์ด ๊ทธ ์ํ์๊ณ ์ ํฉ์ฑ ์ ๊ฒ์ด ์ก์๋ค(2026-08-13). ํ๋ฉด์\n * ํ์ `isPrimary` ๋ก โ
๋ฅผ ๊ทธ๋ ค์ ์ฆ์์ด ๋ณด์ด์ง ์์๋ค(์ฌ์ค์ด ๋ ๋ฒ์ด๋ฉด ์ด๋ ๊ฒ ์กฐ์ฉํ๋ค).\n */\n primaryRepresentationId: existing?.primaryRepresentationId ?? null\n })\n )\n /*\n * ํํ์ twin_space_representations ํ
์ด๋ธ์ ์ ์ฅํ๋ค โ ๋ทฐ(twin-map-page ๋ฑ)๋ content ๊ฐ ์๋๋ผ ํ
์ด๋ธ ํํ์ ์์ฑํ๋ฏ๋ก,\n * ์ ์ฅํ์ง ์์ผ๋ฉด ์ธ์ ์คํธ ์ฌ์ดํธ์ \"๋ํ ํํ\" ์ด ์์ด ์ง๋๋ก ์์ํ์ง ๋ชปํ๋ค. rep.areas ๊ฐ ์์ผ๋ฉด TwinSpaceArea ๋ ํจ๊ป ์ ์ฅ.\n * ์ต์ด ์ธ์ ์คํธ๋ง(๊ธฐ์กด ํํ ์์ผ๋ฉด ์ฌ์ฉ์ ํธ์ง ๋ณด์กด).\n */\n const repRepo = getRepository(TwinSpaceRepresentation)\n const areaRepo = getRepository(TwinSpaceArea)\n if ((await repRepo.count({ where: { space: { id: savedSpace.id } } })) === 0) {\n const reps: any[] = (spaceContent as any).representations ?? []\n for (let i = 0; i < reps.length; i++) {\n const rep = reps[i]\n const config =\n rep.type === 'map' ? { center: rep.center, zoom: rep.zoom }\n : rep.type === 'board' ? { boardId: rep.boardId }\n : rep.type === 'image' ? { imageUrl: rep.imageUrl, width: rep.width, height: rep.height }\n : {}\n const savedRep = await repRepo.save(repRepo.create({ domain: { id: domainId } as any, space: { id: savedSpace.id } as any, type: rep.type, name: rep.name, seq: i, isPrimary: !!rep.primary || rep.id === (spaceContent as any).primaryId, config }))\n for (const area of (rep.areas ?? []) as any[]) {\n await areaRepo.save(areaRepo.create({ domain: { id: domainId } as any, representation: { id: savedRep.id } as any, name: area.name, type: area.type, geometry: area.geometry, drillTo: area.drillTo ?? null, binding: area.binding ?? null, style: area.style ?? null }))\n }\n }\n /*\n * ๋ํ๋ฅผ **์ ์ฅ๋ ํ id** ๋ก ๊ฐ๋ฆฌํจ๋ค โ ๋ง์คํฐ์ ๋
ผ๋ฆฌ id ๋ ์ ์ฅ ํค๊ฐ ์๋๋ค. ๊ณ ๋ฅธ ์์:\n * โ ๋ง์คํฐ๊ฐ primary ๋ก ํ์ํ ํํ โก ์์ผ๋ฉด ์ฒซ ํํ โข ํํ์ด ์์ผ๋ฉด ๋น์ด๋ค(์ง์ด๋ด์ง ์๋๋ค).\n */\n const saved = await repRepo.find({ where: { domain: { id: domainId } as any, space: { id: savedSpace.id } as any }, order: { seq: 'ASC' } })\n const primary = saved.find(r => r.isPrimary) ?? saved[0]\n if (primary && savedSpace.primaryRepresentationId !== primary.id) {\n await repo.save(repo.create({ ...savedSpace, primaryRepresentationId: primary.id }))\n /* ํ๋๋ง ๋ํ๋ค โ ํ ํ๋๊ทธ๋ ๊ทธ ํ๋๋ก ๋ง์ถ๋ค(๋์ด ์ผ์ ธ ์์ผ๋ฉด ํ๋ฉด์ด โ
๋ฅผ ๋ ๋ฒ ๊ทธ๋ฆฐ๋ค). */\n for (const r of saved) if (!!r.isPrimary !== (r.id === primary.id)) await repRepo.save(repRepo.create({ ...r, isPrimary: r.id === primary.id }))\n }\n }\n /*\n * area ๋จ์ผํ(space #2, P1) โ ๋
ผ๋ฆฌ ๊ตฌ์ญ์ TwinArea(์ ๊ทยทํํ๋ฌด๊ดยท๊ณต์ )์ dual-write(upsert by areaId).\n * P3: content.areas ์ ์ฅ ํ๊ธฐ โ TwinArea ๊ฐ ์ ์ผ ๊ถ์. ์์ค = masterToTwin ์ฐ์ถ spaceContent.areas(cur).\n * (์์ฒ diff ์ ๊ฑฐ[master ์์ ๋น ์ง area ์ญ์ ]๋ ์ฌ์ฉ์์ ์ area ๋ณดํธ ์ํด per-area provenance ํ์ โ ํ์.)\n */\n const twinAreaRepo = getRepository(TwinArea)\n for (const a of ((spaceContent as any).areas ?? []) as any[]) {\n if (!a?.id) continue\n const existingArea = await twinAreaRepo.findOne({ where: { domain: { id: domainId }, space: { id: savedSpace.id }, areaId: a.id } })\n await twinAreaRepo.save(\n twinAreaRepo.create({\n ...(existingArea ?? {}),\n domain: { id: domainId } as any,\n space: { id: savedSpace.id } as any,\n areaId: a.id,\n name: a.name ?? a.id,\n type: a.type,\n parentId: a.parentId ?? null,\n layout: a.x != null || a.w != null ? { x: a.x, y: a.y, w: a.w, h: a.h } : null\n })\n )\n }\n\n if (running) {\n /* ์คํ ์ค์ธ ๋ฏธ๋ฌ โ ๋ฉ์ถ์ง ์๊ณ ์ ํํ๋ค. ๋ฌด์์ด ์ฌ๋ผ์ก๋์ง๋ **๊ฒฝ๊ณ ๋ก ๋งํ๋ค**\n (๋ฉ์ท๋ค ์ธ์ฐ๋ ๋ง๋๊ฐ ์์ผ๋ฏ๋ก, ๋งํ์ง ์์ผ๋ฉด ์๋ฆฌ ํ๋๊ฐ ์กฐ์ฉํ ์์ด์ง๋ค). */\n const shift = await this.adoptStructure(domainId, master.source, model, undefined, master.origin)\n warnings.push(structureAdopted(shift.rev, shift))\n } else {\n /* ์ฌ์ดํธ ์ด๋ฆ์ด ๊ณง ํธ์์ ์ด๋ฆ์ด๋ค โ ๋ง์คํฐ๊ฐ ์ด๋ฏธ ๋งํ์ผ๋ฏ๋ก ์ง์ด๋ด์ง ์๊ณ ๊ทธ๋๋ก ์ฃ๋๋ค. */\n await this.provision(domainId, master.source, master.system, model, restartPolicy, undefined, master.origin, {\n name: master.siteName,\n description: (master as any).description,\n actor\n })\n }\n\n /*\n * ๊ตฌ์กฐ ํฌ์ โ model(์ปค๋ ์
๋ ฅ ๋ฌธ์)๋ฅผ **ํ์ค ์ํฐํฐ ํ**์ผ๋ก ํผ๋ค(ADR-0032).\n *\n * ์ธ์ ์คํธ๊ฐ ์ ์ผํ ์ฐ๊ธฐ ๊ฒฝ๋ก๋ค. ์ฌ๊ธฐ์ ์คํจํด๋ ์ธ์ ์คํธ ์์ฒด๋ ์ฑ๊ณต์ผ๋ก ๋๋ค โ\n * ํ์ **์๋ณธ์์ ์ธ์ ๋ ๋ค์ ๊ทธ๋ฆด ์ ์๋ ์บ์**์ด๊ณ , ํธ์ ์์ฒด๋ model ๋ก ์ด๋ฏธ ๋์ํ๋ค.\n * ๋ค๋ง **์กฐ์ฉํ ๋๊ธฐ์ง ์๋๋ค**: ๋ชป ์ด์ ์ฐธ์กฐ๋ ์ธ์ ์คํธ ๊ฒฝ๊ณ ๋ก ์ฌ๋ผ๊ฐ๋ค.\n */\n try {\n const projected = await projectStructure(domainId, master.source, model, master.source)\n for (const ref of projected.unresolvedHome) warnings.push(unresolvedReference('equipment.homeLocation', ref))\n for (const ref of projected.unresolvedArea) warnings.push(unresolvedReference('location.area', ref))\n /*\n * ๋ฐ์ ํ์์ **์๊ฐ**์ ์ฝ๋๋ค โ ์๊ฐ๋๋ฅผ ๋ชจ๋ฅด๋ฉด UTC ๋ก ์ฝํ๊ณ , ํ์ฅ ์ ์ค๊ฐ ์๋ ์๊ฐ์ ํผํฌ๊ฐ ์ ๋ค.\n * ์๊ฐ๋๋ฅผ ์ง์ด๋ด์ง ์๊ณ ๊ทธ ์กฐํฉ์ ๋งํ๋ค(๊ณต๊ฐ์ ์ ์ธํ๋ฉด ์ฌ๋ผ์ง๋ค).\n */\n if ((model as any)?.utcOffsetMinutes === undefined) {\n for (const e of ((model as any)?.equipment ?? []) as any[]) {\n const hasProfile = ((e?.properties ?? []) as any[]).some(p => String(p?.id) === EMS_PROPERTY.genDailyProfile && String(p?.value ?? '').trim())\n if (hasProfile) warnings.push(generationWithoutTimeZone(String((model as any)?.spaceId ?? ''), String(e.id)))\n }\n }\n } catch (err: any) {\n console.error(`[twin-engine] structure projection failed for \"${master.source}\":`, err?.message)\n warnings.push(projectionFailed(err?.message ?? 'unknown'))\n }\n\n if (warnings.length) console.warn(`[twin-engine] ingest \"${master.source}\" warnings: ${describeWarnings(warnings)}`)\n return { instanceId: master.source, spaceId, warnings }\n }\n\n /** ๋จ๊ฑด ์์ธ โ ํ๋ก๋น์ ๋ ์๋ํฐ๊ฐ ํธ์งํ model(๊ตฌ์กฐ+layout) ํฌํจ. */\n static async detail(domainId: string, instanceId: string): Promise<any | null> {\n const r = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!r) return null\n return {\n instanceId: r.instanceId,\n kind: r.kind,\n status: r.status,\n running: !!this.instances[runtimeKey(domainId, r.instanceId)],\n restartPolicy: r.restartPolicy, // ํ์ค ์ ์ธ โ what-if ์ ์ฉ ๊ฐ๋์ฉ(mirror=์์ธก ์ ์ฉ, ์๊ทน ์ฃผ์
๋ถ๊ฐ)\n model: r.model\n }\n }\n\n /**\n * ๋ผ์ด๋ธ ๋ฐ์ธ๋ฉ ๋ธ๋ฆฌ์ง(P3, ADR-0018) โ ํธ์ ์ํฐํฐ ์ํ๋ฅผ `data(tag=์ํฐํฐid)` ์ฑ๋๋ก publish.\n * ๋ณด๋ ์ปดํฌ๋ํธ๊ฐ tag ๋ก ๊ตฌ๋
(board-ui provider)ํด `component.data` ๋ก ๋ผ์ด๋ธ ๊ฐฑ์ . delta ์์๋ง(ํฌ์).\n * tag=์ํฐํฐ id(๋ฐ๋ชจ=๋จ์ผ ์ธ์คํด์ค). ๋ฉํฐ ์ธ์คํด์ค/๋ณด๋ ์ฌ์ฌ์ฉ ์ tag ๋ค์์คํ์ด์ค๋ ํ์.\n */\n /** ๋ฐฉ์ก ์คํจ ๋ก๊ทธ ์กฐ์ โ ์ฐฝ๋ง๋ค ํ ์ค(๋งํ ๊ตฌ๋
์๋ ์ด๋น ์์ญ ๋ฒ ์คํจํ๋ค). */\n private static publishDrops = new Map<string, { count: number; lastLogMs: number }>()\n private static readonly PUBLISH_DROP_LOG_MS = 10_000\n\n /**\n * ํ ๋ฒ์ ๋ฐฉ์ก โ **๊ตฌ๋
์ ํ๋๊ฐ ํธ์คํธ๋ฅผ ์ฃฝ์ด์ง ๋ชปํ๊ฒ.**\n *\n * โโ ๋ฌด์์ด ์ฃฝ์๋ (2026-08-14) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๋ฐ๋ฆฐ push ๊ฐ 1024๋ฅผ ๋์ผ๋ฉด pubsub ์ด ๋์ง๋ค(`RepeaterOverflowError`). ๊ทธ ๋ฐฉ์ก์ ํ์ด๋จธ ์ฝ๋ฐฑ\n * ์์์ ์ผ์ด๋๋ฏ๋ก ์์ธ๊ฐ ์กํ๋ ๊ณณ ์์ด ์ฌ๋ผ๊ฐ **ํ๋ก์ธ์ค๊ฐ ๋๋ฌ๋ค** โ ํธ์ 14๊ฐ๊ฐ ๋๋ ํธ์คํธ๊ฐ\n * ์๋น๋ฅผ ๋ฉ์ถ ๊ตฌ๋
์ ํ๋ ๋๋ฌธ์ ํต์งธ๋ก.\n *\n * ๋ชป ๋ณด๋ธ ๊ฒ์ **์ฌ์ค๋ก ๋จ๊ธด๋ค**(ํ์๋ฅผ ์ธ๊ณ ์ฐฝ๋ง๋ค ํ ์ค ๋จ๊ธด๋ค). ์ผํค๋ฉด ใ๋ณด๋๋๋ฐ ํ๋ฉด์ด ๋ก์๋คใ๊ฐ\n * ๋๊ณ , ๊ทธ๊ฑด ๊ฐ์ฅ ์ฐพ๊ธฐ ์ด๋ ค์ด ๋ถ๋ฅ๋ค.\n */\n private static publishGuarded(channel: 'data' | 'twin-state', payload: any, what: string): boolean {\n try {\n pubsub.publish(channel as any, payload)\n return true\n } catch (err: any) {\n const d = this.publishDrops.get(what) ?? { count: 0, lastLogMs: 0 }\n d.count++\n const now = Date.now()\n if (now - d.lastLogMs >= this.PUBLISH_DROP_LOG_MS) {\n d.lastLogMs = now\n console.warn(`[twin-engine] broadcast dropped on \"${what}\" (${d.count} so far) โ ${err?.message ?? err}`)\n }\n this.publishDrops.set(what, d)\n return false\n }\n }\n\n static publishEntityData(inst: InstanceRuntime): void {\n const domain = inst.domain\n if (!domain) return\n /* ์ํ ์ถ์ฒ ์ค์ โ sim: ์ปค๋ runtime, live: projector ๋ฏธ๋ฌ(+OEE ๊ณ์ฐ ์ธต ๋ณด๊ฐ). ๊ณ์ฝยทpayload ๋์ผ, ๋๋ผ์ด๋ฒ๋ง ๋ค๋ฆ. */\n const load = inst.load ?? (inst.load = newLoadMeter())\n\n /* โ ์ํ ํฌ์ โ ์ํ ํฌ๊ธฐ์ ๋น๋กํ๋ค(๋๊ท๋ชจ์์ ๊ฐ์ฅ ๋ฌด๊ฑฐ์ด ์ถ). */\n const tSnap = performance.now()\n const st: any =\n inst.mode === 'live'\n ? inst.oee\n ? withLiveOee(inst.projector?.snapshot?.(), inst.oee) // ๊ด์ธก ์ปค๋ + ๊ณ์ฐ(OEE) โ equipment payload ์ oee ํฌํจ(sim ๋ํ)\n : inst.projector?.snapshot?.()\n : inst.runtime?.resync?.()?.state\n recordPhase(load, 'snapshot', performance.now() - tSnap)\n if (!st) return\n /*\n * ๋ณํํ ์ํฐํฐ๋ง ๋ฐํ โ ์ด์ ์ delta ๋ง๋ค ์ ์ํฐํฐ(๋
ธ๋+๋ฌด๋ฒ+์ค๋)๋ฅผ ๊ฐ ๋ณํ์ ๋ฌด๊ดํ๊ฒ ์ ๋ ์ฌ๋ฐํํด\n * ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋งค์ด ๋ฐ๋ณต push ํ๊ณ ์์๋ค(์ค์ฉ). ์ต์ -์ํ ์ฑ๋์ด๋ฏ๋ก ๋ฌด๋ณํ ์ฌ๋ฐฉ์ก์ ๋ฌด์๋ฏธํ๋ค.\n * ์ํฐํฐ๋ณ ์๊ทธ๋์ฒ๋ฅผ ๋น๊ตํด ๋ฐ๋ ๊ฒ๋ง push.\n */\n const sigs = inst.entitySigs ?? (inst.entitySigs = new Map())\n const seen = new Set<string>()\n /* payload ๋งคํ์ ์์ ํจ์(buildEntityDeltas)๋ก ๋ถ๋ฆฌ โ ์ฌ๊ธฐ์ ์๊ทธ๋์ฒ dedup + ๋ฐํ๋ง.\n * ๋ณํํ ์ํฐํฐ๋ง ๋ฐํ(์ต์ -์ํ ์ฑ๋์ด๋ผ ๋ฌด๋ณํ ์ฌ๋ฐฉ์ก ๋ฌด์๋ฏธ). */\n /* โก payload ๋ง๋ค๊ธฐ โ ์ํฐํฐ ์์ ๋น๋ก. โข ์๊ทธ๋์ฒ ๋น๊ต + ๋ฐํ โ ๋ฐ๋ ๊ฒ ์์ ๋น๋ก. */\n const tDelta = performance.now()\n const deltas = buildEntityDeltas(st, inst.id)\n recordPhase(load, 'deltas', performance.now() - tDelta)\n\n const tPub = performance.now()\n for (const { tag, data } of deltas) {\n seen.add(tag)\n const sig = JSON.stringify(data)\n if (sigs.get(tag) === sig) continue // ๋ฌด๋ณํ โ ๋ฐํ ์๋ต\n sigs.set(tag, sig)\n /*\n * **๋ชป ๋ณด๋์ผ๋ฉด ๋ณด๋ธ ๊ฒ์ผ๋ก ์ ์ง ์๋๋ค.** ์๊ทธ๋์ฒ๋ฅผ ๋จ๊ฒจ ๋๋ฉด ๋ค์ ์ฃผ๊ธฐ์ ใ๋ฌด๋ณํใ๋ก ๊ฑด๋๋ฐ๊ณ ,\n * ๊ทธ ํ๊ทธ๋ ์์ํ ๋ก์ ๊ฐ์ ๋ณด์ฌ ์ค๋ค(์ค๋ฅ ์์ด). ๋๋๋ ค ๋๋ฉด ๋ค์ ์ฃผ๊ธฐ๊ฐ ๋ค์ ์๋ํ๋ค.\n */\n if (!this.publishGuarded('data', { data: { domain, tag, data } }, `data:${inst.id}`)) sigs.delete(tag)\n }\n recordPhase(load, 'publish', performance.now() - tPub)\n /* ์ฌ๋ผ์ง ์ํฐํฐ์ ์๊ทธ๋์ฒ ์ ๋ฆฌ(๋งต ๋ฌดํ ์ฑ์ฅ ๋ฐฉ์ง). */\n if (sigs.size > seen.size) for (const tag of sigs.keys()) if (!seen.has(tag)) sigs.delete(tag)\n }\n\n static async persist(domainId: string, instanceId: string, msg: any): Promise<void> {\n const repo = getRepository(TwinEvent)\n await repo.save(this.journalRow(repo, domainId, instanceId, msg.event, msg.revision, await this.structureRevOf(domainId, instanceId)))\n }\n\n /**\n * ์ฌ๋ถํ
๋ณต๊ตฌ / ์๊ฐ์ฌํ โ DB ์ ๋์ replay ํด ์ํ ์ฌ๊ตฌ์ฑ.\n * model ๋ ๋ ์ง์คํธ๋ฆฌ(TwinInstance)์์, ์ด๋ฒคํธ๋ TwinEvent(revision ASC)์์.\n * ์ปค์ ๋ ์ถ(runtime-state-model ยง4): **์๊ฐ(untilTime, ์ฌ์ฉ์ ๋ชจ๊ตญ์ดยท๊ณต๊ฐ ๊ณตํต์ถ)** ์ฐ์ , ์์ผ๋ฉด ๋ฆฌ๋น์ (untilRevision, ๋ ์ฆ ๋ด๋ถ).\n * - untilTime ์ฃผ๋ฉด `eventTime โค T` ์ธ ์ด๋ฒคํธ๋ง(๊ทธ ์์ watermark) โ ๊ณต๋๋ฐฐ์น ์ฌ๋ฌ ํธ์์ ํ๋์ ์๊ฐ T๋ก ํต์ผ ํด์.\n * - ๋ ๋ค ์์ผ๋ฉด ์ต์ (๋ผ์ด๋ธ ์ธ๋ฉ๋ชจ๋ฆฌ ์ง์ค).\n * ์ด๋ฒคํธ๋ ํญ์ revision ASC(์ธ๊ณผ ์์)๋ก ์ ์ฉ โ ์๊ฐ ํํฐ๋ ์ปท์คํ ์งํฉ๋ง ์ ํ๋ค.\n */\n static async recover(domainId: string, instanceId: string, untilRevision?: number, untilTime?: string): Promise<any> {\n // ๋ผ์ด๋ธ ์ต์ (์๊ฐ์ฌํ ์๋) + ์ธ๋ฉ๋ชจ๋ฆฌ ์ธ์คํด์ค โ ๋ผ์ด๋ธ ์ปค๋ ์ค๋
์ท์ ์ง์ ์ฌ์ฉ.\n // replay(StateProjector)๋ attentionsยทack ๋ฑ ๋ผ์ด๋ธ ์ ์ฉ ํ์ ์ํ๋ฅผ ๋ด์ง ๋ชปํ๋ฏ๋ก, ์ต์ ์ ์ปค๋ ์ง์ค์ ์ด๋ค.\n if (untilRevision == null && untilTime == null) {\n const live = this.instances[runtimeKey(domainId, instanceId)]\n if (live?.kernel?.getSnapshot) return live.kernel.getSnapshot()\n // live ๋ชจ๋๋ kernel ์ด ์๊ณ projector ๋ฏธ๋ฌ โ ์ธ๋ฉ๋ชจ๋ฆฌ ์ต์ ์ค๋
์ท(projector+OEE+attentions) ์ง์ ์ฌ์ฉ.\n // (์ ๋์ด ์์ด๋ ์ต์ ์ ์ธ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ง์ค โ replay ๋ ์๊ฐ์ฌํ/๋ณต๊ตฌ ์ ์ฉ.)\n if (live?.mode === 'live' && live.projector) return this.snapshot(domainId, instanceId)\n }\n /*\n * **๋์ ์๋ ์ค๋
์ท์ด๋ฉด ์ ์ง ์๋๋ค.**\n *\n * ๋ฉ์ถ ํธ์์ ์กฐํํ ๋๋ง๋ค ์ ๋์ ์ ๋ ์ ๊ณ ์์๋ค โ ํธ์์ ํ๋๋ ์ ๋๋ ค๋ ๋ชจ๋ธ ์กฐํ๊ฐ\n * 4.6~7.7์ด์๋ ์ด์ ๋ค(crew-probe 23,731๊ฑด). ์ค๋
์ท์ ๊ฐ์ ํด๋์ ๊ฒฐ๊ณผ์ด๋ฏ๋ก, ๊ทธ ๋ค๋ก ์ด๋ฒคํธ๋\n * ๊ตฌ์กฐ ๋ณ๊ฒฝ๋ ์๋ค๋ฉด **๋ค์ ์ ์ด ๋ด์ผ ๊ฐ์ ๊ฐ**์ด๋ค.\n *\n * ์ฐ์ง ์๋ ์กฐ๊ฑด์ ์ข๊ฒ ์ก๋๋ค: ์ง๊ธ์ ๋ฌผ์์ ๋๋ง(์๊ฐ์ฌํ์ ๊ทธ ์์ ๊น์ง ์ ์ด์ผ ํ๋ค), ๋ฆฌ๋น์ ์ด\n * ๋๊ณผ ๊ฐ์ ๋๋ง, ๊ตฌ์กฐ ๋ฆฌ๋น์ ๊น์ง ๊ฐ์ ๋๋ง. ํ๋๋ผ๋ ์ด๊ธ๋๋ฉด ์ ๋๋ค โ ์บ์๊ฐ ์ฌ์ค์ ์ด๊ธฐ์ง ์๋๋ค.\n */\n const asOfNowRead = untilRevision == null && untilTime == null\n const tip = asOfNowRead ? await this.tipOf(domainId, instanceId).catch(() => null) : null\n /* ํ ๋ฒ๋ง ์ฝ๋๋ค โ ๋์ ์์ผ๋ฉด ๊ทธ๋๋ก ์ฐ๊ณ , ์๋๋ฉด ์๋์์ **์ด์ด ์ ๋ ์จ์**์ผ๋ก ์ด๋ค. */\n const cachedForResume = asOfNowRead && tip ? await this.loadSnapshot(domainId, instanceId).catch(() => null) : null\n if (cachedForResume) {\n const state = unwrapState(cachedForResume.state)\n if (state && (cachedForResume.revision ?? 0) === tip!.revision && (cachedForResume.structureRev ?? null) === tip!.structureRev)\n return state\n }\n\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.model) throw new Error(`twin instance \"${instanceId}\" not registered (no model to replay)`)\n\n /*\n * โโ ์ฌ๊ฐ์ ์์ **์ด์ด ์ ๋๋ค** (2026-08-18) โโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n *\n * ์ฐ๋ฆฌ๋ ์ด๋ฏธ ์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋จ๊ธฐ๊ณ ์๋ค(`saveFoldedSnapshot`). ๊ทธ ์ง์ ์ **์ฌ๊ฐ์ **(๋ฆฌ๋์ ๋ด๋ถ ์ํ\n * ์ ๋ถ + ๊ฐ๋ ๋์ ๊ธฐ)์ด ํจ๊ป ์์ผ๋ฉด, ๊ทธ ๋ค์ ์ผ์ด๋ ๊ฒ๋ง ์ ์ด๋ ๊ฐ์ ๋ต์ด ๋์จ๋ค โ ๊ทธ ๋์น๋\n * ์ปค๋ ์ํ์ด ์ฆ๋ช
ํ๋ค(0๋ถํฐ ์ ๊ธฐ == ์ฌ๊ฐ์ + ๊ผฌ๋ฆฌ).\n *\n * ์ฐ๋ ์กฐ๊ฑด์ ์ข๊ฒ ์ก๋๋ค: **์ง๊ธ์ ๋ฌผ์์ ๋๋ง**(์๊ฐ์ฌํ์ ๋ชฉํ ์ด์ ์ฌ๊ฐ์ ์ด ํ์ํ๋ฐ ์ง๊ธ์\n * ์ต์ ํ๋๋ง ๋จ๊ธด๋ค โ ์ฌ์ฌ์ ๋ค์ ๋จ๊ณ๋ค), ๊ตฌ์กฐ๊ฐ ๊ทธ๋๋ก์ผ ๋๋ง(๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ฉด ๊ทธ ๊ฒฝ๊ณ์์ ๊ฐ๋ผ\n * ์ ์ด์ผ ํ๋ค), ์ฌ๊ฐ์ ์ด ์ ๋ ๋๋ณด๋ค ์์ค ๋๋ง. ํ๋๋ผ๋ ์ด๊ธ๋๋ฉด 0๋ถํฐ ์ ๋๋ค โ **์บ์๊ฐ ์ฌ์ค์\n * ์ด๊ธฐ์ง ์๋๋ค.**\n */\n /*\n * ์จ์์ ๋ ์ค ํ๋๋ค: **์ง๊ธ**์ ๋ฌผ์ผ๋ฉด ์ต์ ์ฌ๊ฐ์ , **๊ณผ๊ฑฐ**๋ฅผ ๋ฌผ์ผ๋ฉด ์ฌ์ฌ์์ ๋ชฉํ ์ง์ ์ง์ .\n *\n * ๊ณผ๊ฑฐ ์จ์์ ๊ตฌ์กฐ๊ฐ ํ ๋ฒ๋ ๋ฐ๋์ง ์์ ํธ์์์๋ง ์ด๋ค โ ๊ตฌ์กฐ๊ฐ ๊ฐ๋ฆฐ ์ ๋์ ๋ง๋๋ง๋ค ๊ฐ์ ์ ์ด์ผ\n * ํ๊ณ , ๋ง๋๋ฅผ ๊ฑด๋๋ด ์จ์์ ๊ทธ ๊ฒฝ๊ณ์ ํ์ ์ ์๋๋ค(๊ทธ๋๋ 0๋ถํฐ ์ ๋ ๊ฒ์ด ์ณ๋ค).\n */\n const structureCount = asOfNowRead\n ? 0\n : await getRepository(TwinStructure).count({ where: { domain: { id: domainId }, instanceId } }).catch(() => 99)\n const pastSeed =\n !asOfNowRead && structureCount <= 1\n ? await this.chainSeedFor(domainId, instanceId, {\n ...(untilRevision != null ? { revision: untilRevision } : {}),\n ...(untilTime != null && !Number.isNaN(Date.parse(untilTime)) ? { timeMs: Date.parse(untilTime) } : {})\n }).catch(() => null)\n : null\n const resume =\n asOfNowRead && tip && cachedForResume && cachedForResume.fold && (cachedForResume.structureRev ?? null) === tip.structureRev\n ? cachedForResume\n : pastSeed\n\n /*\n * **์๋ฅผ ๊ฒ์ ์๋ฉด์ ๋ค ์ฝ์ด ์ค์ง ์๋๋ค** (2026-08-18 ์ค์ธก).\n *\n * ์ ๋์ ์ ๋ ์ฝ์ด ์จ ๋ค JS ์์ ๊ฑธ๋ ๋ค. 27๋ง ๊ฑด์ง๋ฆฌ ํธ์(order-check)์์ ํ ์๊ฐ ์ ์ํ๋ฅผ ๋ฌผ์ผ๋ฉด\n * **7.4์ด**๊ฐ ๊ฑธ๋ ธ๊ณ , ๊ทธ ๋๋ถ๋ถ์ด ใํ์ ์๋ ํ์ ์ฝ์ด ์ค๋ ์๊ฐใ์ด์๋ค. ์๊ฐยท๋ฆฌ๋น์ ์ํ์ SQL ์ด\n * ์๋ ์กฐ๊ฑด์ด๋ฏ๋ก ๊ฑฐ๊ธฐ์ ์๋ฅธ๋ค(TypeORM ๊ด์ฉ๊ตฌ๋ง โ ์์ SQL ์ 5๊ฐ ๋๋ผ์ด๋ฒ์์ ๊ฐ๋ผ์ง๋ค).\n *\n * ์๊ฐ ์ํ์๋ **๊ฒฝ๊ณ๋ฅผ ๊ทธ๋๋ก** ์ด๋ค(`<=`): ๊ทธ ์๊ฐ์ ์ผ์ด๋ ์ฌ์ค์ ๊ทธ ์๊ฐ์ ํ๋ฉด์ ์์ด์ผ ํ๋ค.\n * ์๊ฐ์ด ์๋ ๋ ๊ฑฐ์ ํ์ ๋ณด์์ ์ผ๋ก ํฌํจํด ์๋๋ฐ, SQL ๋ก ์๋ฅด๋ฉด ๊ทธ ํ๋ค์ด ๋น ์ง๋ค โ ๊ทธ๋์ ์๊ฐ\n * ์กฐ๊ฑด์ผ ๋๋ **์๊ฐ์ด ๋น์ด ์๋ ํ๋ ํจ๊ป** ๊ฐ์ ธ์ ์์ ๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ธ๋ค.\n */\n const cutoffMs = untilTime != null ? Date.parse(untilTime) : NaN\n const useTime = untilTime != null && !Number.isNaN(cutoffMs)\n const baseWhere = { domain: { id: domainId }, instanceId }\n /* ์ด์ด ์ ์ ๋๋ **๊ทธ ๋ค๋ง** ์ฝ๋๋ค โ ์ฌ๊ฐ์ ๊น์ง์ ์ฌ์ค์ ์ด๋ฏธ ์จ์ ์์ ์๋ค. */\n const from = resume ? (resume.revision ?? 0) : undefined\n const rows = await getRepository(TwinEvent).find({\n where: useTime\n ? from\n ? /* ์จ์ ๋ค ยท ๋ชฉํ ์ด๋ด โ ์๊ฐ์ด ๋น ์ ํ์ ์จ์ ๋ค์ ์๋ ๊ฒ๋ง ํฌํจํ๋ค(๋ณด์์ ํฌํจ์ ์ ์ง). */\n [\n { ...baseWhere, revision: MoreThan(from), eventTime: LessThanOrEqual(new Date(cutoffMs)) },\n { ...baseWhere, revision: MoreThan(from), eventTime: IsNull() }\n ]\n : [\n { ...baseWhere, eventTime: LessThanOrEqual(new Date(cutoffMs)) },\n { ...baseWhere, eventTime: IsNull() }\n ]\n : untilRevision != null\n ? from\n ? { ...baseWhere, revision: And(MoreThan(from), LessThanOrEqual(untilRevision)) }\n : { ...baseWhere, revision: LessThanOrEqual(untilRevision) }\n : from\n ? { ...baseWhere, revision: MoreThan(from) }\n : baseWhere,\n order: { revision: 'ASC' }\n })\n const wanted = rows\n\n /*\n * **๊ทธ๋์ ๊ณต์ฅ์ผ๋ก ์ ๋๋ค.**\n *\n * ์์ ์๋ ๋ชจ๋ ์ด๋ฒคํธ๋ฅผ ์ง๊ธ ๋ฑ๋ก๋ ๋ณด๋ ํ๋๋ก ์ ์๋ค. ๊ตฌ์กฐ๊ฐ ๋ฐ๋ ์ ์์ผ๋ฉด ๋ง์ง๋ง, ๋ฐ๋\n * ๋ค์๋ ์ ์ฌ์ค์ ์ ๊ณต์ฅ์ ๋๊ณ ์ ๊ฒ ๋์ด โ ๊ทธ๋ ์๋ ์ค๋น์์ ์ผ์ด ์์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค.\n * (๊ทธ๋์ ์์ ํ๋ก๋น์ ๋์ ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ฉด ์ ๋์ ์์ ์ง์ ๋ค. ์ญ์ฌ๋ฅผ ์๊ฑฐ๋ ๊ฑฐ์ง๋ง์ ํ๊ฑฐ๋.)\n *\n * ์ด์ ์ด๋ฒคํธ๊ฐ ์๊ธฐ ๊ตฌ์กฐ๋ฅผ ๋ฌ๊ณ ์ค๋ฏ๋ก, ๋ฆฌ๋น์ ์ด ๋ฐ๋๋ ์ง์ ์์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ํ๋ฉฐ ์ด์ด ์ ๋๋ค.\n * ๋ฆฌ๋น์ ์ด ํ๋๋ฟ์ด๊ฑฐ๋(๋๋ค์) ์์ ์์ผ๋ฉด(๊ตฌ์กฐ ์ด๋ ฅ ์ด์ ) ์์ ๊ณผ ๋๊ฐ์ด ํ ๋ฒ์ ์ ๋๋ค.\n */\n const structures = await getRepository(TwinStructure).find({\n where: { domain: { id: domainId }, instanceId },\n order: { rev: 'ASC' }\n })\n const boardOf = new Map<number, TwinModelDef>(structures.map(x => [x.rev, x.model as TwinModelDef]))\n /* ์ปฌ๋ผ์ด ์๊ธฐ๊ธฐ ์ ํ์ ๋ฆฌ๋น์ ์ด ๋น์ด ์๋ค โ **๊ฐ์ฅ ์ค๋๋ ๊ตฌ์กฐ**์ ์ํ๋ค(0 ์ผ๋ก ์ฑ์ฐ์ง ์๋๋ค). */\n const oldest = structures[0]?.rev\n const revOf = (r: { structureRev?: number }): number | undefined => r.structureRev ?? oldest\n\n const segments: { model: TwinModelDef; events: any[] }[] = []\n for (const r of wanted) {\n if (!r.payload) continue\n const rev = revOf(r)\n const model = (rev !== undefined && boardOf.get(rev)) || (reg.model as TwinModelDef)\n const last = segments[segments.length - 1]\n if (last && last.model === model) last.events.push(r.payload)\n else segments.push({ model, events: [r.payload] })\n }\n /*\n * **๊ฐ์ฅ ์ ๊ตฌ์กฐ๊ฐ ์ง๊ธ์ ๊ณต์ฅ์ด๋ค** โ ๊ทธ ์๋์์ ์์ง ์๋ฌด ์ผ๋ ์์๋๋ผ๋.\n *\n * ์ฌํ๋ก๋น์ ๋ ์งํ๊ฐ ์ ํํ ๊ทธ ์ํ๋ค: ๋ถ์ค๋ฅผ ๋ท ๋๋ ธ๋๋ฐ ์ ์ด๋ฒคํธ๋ ์์ง ํ๋๋ ์๋ค. ์ด๋\n * ๋ง์ง๋ง ์ด๋ฒคํธ์ ๊ตฌ์กฐ๋ก๋ง ์ ์ผ๋ฉด ํ๋ฉด์ **์ ๊ณต์ฅ**์ ๋ณด์ฌ์ค๋ค โ ๋ฐฉ๊ธ ๋๋ฆฐ ๊ฒ์ด ์ ๋ณด์ธ๋ค.\n * ๊ทธ๋์ ๋ง๋์ ๋์ ์ง๊ธ ๊ตฌ์กฐ๋ฅผ ํ ๋ฒ ๋ ์น๋๋ค(์ด๋ฒคํธ ์๋ ๋ง๋).\n *\n * **๋ค๋ง \"์ง๊ธ\" ์ ๋ฌผ์์ ๋๋ง์ด๋ค.** ๊ณผ๊ฑฐ ์์ ์ ๋ฌผ์๋๋ฐ ์ต์ ๊ตฌ์กฐ๋ฅผ ์น์ผ๋ฉด, ๊ทธ ์์ ์ ์๋\n * ์ค๋น๊ฐ ํ๋ฉด์ ์๊ณ โ ์ด ์์
์ด ๋ง์ผ๋ ค๋ ๋ฐ๋ก ๊ทธ ๊ฑฐ์ง๋ง์ด ๋๋ค.\n */\n const asOfNow = untilRevision == null && untilTime == null\n const newest = structures[structures.length - 1]?.model as TwinModelDef | undefined\n if (asOfNow && newest && segments[segments.length - 1]?.model !== newest) segments.push({ model: newest, events: [] })\n\n /*\n * ์ ์ ์ํ์ **์ฃผ์ ์ ํธ์ ์๊ฐ์ ์ฑ์ด๋ค.**\n *\n * ๋ผ์ด๋ธยท์๋ฎฌ์ ์ปค๋์ด ์ ํธ๋ฅผ ์ค์ค๋ก ๋ด์ง๋ง, ์ ๋์ ์ ๋ ์ด ๊ฒฝ๋ก๋ ํ๋ก์ ํฐ ์ํ๋ง ๋ธ๋ค โ ์ ํธ๋\n * `nowTime` ๋ ์๋ค. ๊ทธ๋์ **๊ณผ๊ฑฐ๋ฅผ ๋ค์ ๊ณ์ฐํ๋ฉด ์ฃผ์ ๋ ์ผ์ด ํ
๋น์๊ณ **(์ง๋๋ `snap.attentions` ๋ฅผ\n * ์ฝ๋๋ค), ๊ธฐ๋๋ผ ์์ง ์์ ํธ์์ ๋ณด๋ ํ๋ฉด๋ ๊ฐ์๋ค. ์ ํธ๋ ์ํ์์ ๊ณ์ฐ๋๋ ๊ฒ์ด๋ฏ๋ก\n * ์ฌ๊ธฐ์ ๊ฐ์ ๊ณต์(`deriveAttentions`)์ผ๋ก ์ฑ์ฐ๋ฉด ๋๋ค โ ๋ ๋ฒ์ ๋์ง ์๋๋ค.\n *\n * `nowTime` ์ด ๋จผ์ ๋ค: \"๋ฆ์๋\" ํ์ ์ด ๊ทธ ๊ฐ์ ๋ณธ๋ค. ๋ค์ ๊ณ์ฐํ ์์ ์ ์ ์งํ \"์ง๊ธ\" ์ ๋ฌผ์ด๋ณธ ์๊ฐ\n * (`untilTime`)์ด๊ณ , ์์ผ๋ฉด ๋ง์ง๋ง์ผ๋ก ์ ์ฉํ ์ด๋ฒคํธ์ ์๊ฐ์ด๋ค. ๋ ๋ค ์์ผ๋ฉด ์ฑ์ฐ์ง ์๋๋ค โ\n * ๋ฒฝ์๊ณ๋ฅผ ๋ผ์ ๋ฃ์ผ๋ฉด ๊ณผ๊ฑฐ ํ๋ฉด์ด \"์ง๊ธ ๊ธฐ์ค์ผ๋ก ๋ฆ์๋ค\" ๊ณ ๋งํ๊ฒ ๋๋ค.\n */\n const lastEventTime = rows.length ? (rows[rows.length - 1]?.eventTime?.toISOString() ?? '') : ''\n\n /*\n * **๊ฐ๋ ์ด๋ ฅ๋ ๋์ด๋ฆฐ๋ค** โ ๋ค์ ๊ณ์ฐํ ํ๋ฉด์ ์ค๋น ๊ณ์ธก์ด ๋น์ด ์๋ ๊ฒ.\n *\n * OEE ๋ ์ ์์คํ
์ด ๋์ ์ ๋ณด๋ด ์ฃผ์ง ์์ ํธ์คํธ๊ฐ ์ํ ์ ์ด๋ฅผ ์ ๋ถํด ๋ง๋ ๋ค(๊ทธ๋์ ์ปค๋์ด ์๋๋ผ\n * ์ฌ๊ธฐ ์๋ค). ๊ทธ๋ฐ๋ฐ ๊ทธ ๋์ ๊ธฐ๋ **๋ผ์ด๋ธ์์๋ง** ๋์๊ณ , ์ ๋์ ์ ๋ ๊ฒฝ๋ก๋ ๊ทธ ๊ณ์ฐ์ ํ์ง ์์๋ค โ\n * ๊ณผ๊ฑฐ๋ฅผ ๋ค์ ๊ณ์ฐํ๋ฉด ๋ชจ๋ ์ค๋น๊ฐ \"๊ฐ๋ ์ด๋ ฅ์ด ์ ํ ์์\" ์ผ๋ก ๋ณด์๋ค.\n *\n * ์๋ ๊ฒ์ ๋ฐ์ดํฐ๊ฐ ์๋๋ผ ๊ณ์ฐ์ด๋ค: ์
๋ ฅ(`equipment.status` ์ ์ดยท`quality.output`)์ ์ ๋์ ๋ค\n * ์๋ค. ๊ทธ๋์ **๊ฐ์ ๋์ ๊ธฐ์ ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ํ์ด๋ค** โ ๊ท์น์ ๋ ๋ฒ ๋ง๋ค์ง ์๋๋ค.\n *\n * ์๊ฐ์ฌํ์์๋ ๋ง๋ค: ์ฌ๊ธฐ ํ์ฐ๋ ๊ฒ์ ์ด๋ฏธ ์๋ผ ๋ธ(`wanted`) ์ด๋ฒคํธ๋ฟ์ด๋ฏ๋ก, ๊ทธ ์์ ๊น์ง์\n * ๊ฐ๋ ์ด๋ ฅ์ด ๋์จ๋ค(๊ทธ ๋ค์ ์ผ์ด๋ ๊ณ ์ฅ์ด ๊ณผ๊ฑฐ ํ๋ฉด์ ์์ด์ง ์๋๋ค).\n */\n const oee = new OeeAccumulator()\n /* ์ฌ๊ฐ์ ์ด ์์ผ๋ฉด ๊ทธ ์์ ๊ผฌ๋ฆฌ๋ง ์น๋๋ค โ ์์ผ๋ฉด ๊ผฌ๋ฆฌ๋ถ๋ง ์ธ์ด ๊ฐ์ฉ๋ฅ ์ด ์กฐ์ฉํ ์์์ง๋ค. */\n if (resume?.fold?.oee) oee.restore(resume.fold.oee)\n for (const r of wanted) {\n try {\n oee.apply(r.payload as any)\n } catch {\n /* ํ ๊ฑด์ด ์ด์ํด๋ ๋๋จธ์ง ๊ณ์ธก์ ๋ฒ๋ฆฌ์ง ์๋๋ค โ ๋์ ๊ธฐ๋ ๋ชจ๋ฅด๋ ์ด๋ฒคํธ๋ฅผ ๋ฌด์ํ๋ ๊ณ์ฝ์ด๋ค. */\n }\n }\n\n const withNow = (st: any): any => {\n if (!st || typeof st !== 'object') return st\n const nowTime = st.nowTime || untilTime || lastEventTime || undefined\n const based = nowTime ? { ...st, nowTime } : st\n /* ๊ณ์ธก ์์ ์ ๊ทธ ํ๋ฉด์ \"์ง๊ธ\" ์ด๋ค โ ๋ฒฝ์๊ณ๋ก ์ฌ๋ฉด ๊ณผ๊ฑฐ ํ๋ฉด์ ๊ฐ์ฉ๋ฅ ์ด ์๊ฐ์ด ๊ฐ์๋ก ๋จ์ด์ง๋ค. */\n const nowMs = nowTime ? Date.parse(String(nowTime)) : Number.NaN\n const withMetrics = withLiveOee(based, oee, Number.isFinite(nowMs) ? nowMs : undefined)\n return withLiveAttentions(withMetrics)\n }\n\n /* ์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋จ๊ธด๋ค โ **์ง๊ธ์ ๋ฌผ์์ ๋๋ง**(์๊ฐ์ฌํ ๊ฒฐ๊ณผ๋ฅผ \"์ง๊ธ\" ์ผ๋ก ์ ์ฅํ๋ฉด ๊ฑฐ์ง์ด ๋๋ค). */\n /*\n * ์ ์ ์ง์ ์ ๋ฆฌ๋น์ โ ์ฌ์ฌ์ ์ ์ ์ด๋ฆ์ด๋ค. ๊ผฌ๋ฆฌ๋ฅผ ์ ์์ผ๋ฉด ๊ทธ ๊ผฌ๋ฆฌ์ ๋, ์๋ฌด๊ฒ๋ ์ ์ฝ์์ผ๋ฉด\n * ์จ์์ ์๋ฆฌ ๊ทธ๋๋ก๋ค(๋ชจ๋ฅด๋ฉด 0).\n */\n const foldedTo = rows.length ? (rows[rows.length - 1]?.revision ?? 0) : (from ?? 0)\n\n const keep = (st: any, fold?: { reducer: ReducerCheckpoint; oee: OeeCheckpoint }): any => {\n /* ์ฌ๊ฐ์ ์ ํจ๊ป ๋จ๊ธด๋ค โ ์ํ๋ง ๋จ๊ธฐ๋ฉด ๋ค์ ๋ฒ์ ๋ 0๋ถํฐ ์ ์ด์ผ ํ๋ค(๊ทธ๊ฒ์ด ์ด ์์
์ ์์ ์ด๋ค).\n **๊ตฌ์กฐ๊ฐ ๊ฐ๋ฆฐ ํด๋์๋ ์ฌ๊ฐ์ ์ ๋ถ์ด์ง ์๋๋ค**: ๋ง๋๋ฅผ ๊ฑด๋๋ด ์จ์์ ๊ทธ ๊ฒฝ๊ณ์ ํ์ ์ ์๋๋ค. */\n if (asOfNowRead && tip && st) {\n void this.saveFoldedSnapshot(domainId, instanceId, { revision: tip.revision, state: st, structureRev: tip.structureRev, fold })\n }\n /*\n * ์ฌ์ฌ์๋ **๊ณผ๊ฑฐ๋ฅผ ์ ์์ ๋๋** ํ ์ง์ ์ ๋จ๊ธด๋ค (2026-08-18 ์ค์ธก์ผ๋ก ๊ณ ์นจ).\n *\n * ์ฒ์์๋ ใ์ง๊ธ ์ฝ๊ธฐใ์์๋ง ๋จ๊ฒผ๋ค. ๊ทธ๋ฐ๋ฐ ๋๋ ํธ์์ ์ง๊ธ ์ฝ๊ธฐ๋ ์ปค๋ ์ค๋
์ท์ผ๋ก ์ฆ์ ๋ตํ๊ณ \n * ํด๋์ ๋ฟ์ง ์๋๋ค โ ๊ทธ๋์ ์ฌ์ฌ์ด **์์ํ ๋น์ด ์์๋ค**(์ค์ธก: ์ง์ 0๊ฐ, ์๊ฐ์ฌํ 3.7s ๊ทธ๋๋ก).\n *\n * ์ง์ ์ ใ์ง๊ธใ์ ์ฃผ์ฅํ์ง ์๋๋ค: ์๊ธฐ ๋ฆฌ๋น์ ๊ณผ ์๊ฐ์ ๋ฌ๊ณ ์์ผ๋ฏ๋ก ๊ณผ๊ฑฐ ํด๋์ ๊ฒฐ๊ณผ๋ฅผ ๋จ๊ฒจ๋\n * ๊ฑฐ์ง์ด ์๋๋ค(๊ทธ๊ฒ์ด ์ค๋
์ท๊ณผ ๋ค๋ฅธ ์ ์ด๋ค). ๊ทธ๋์ ์ฒซ ๊ณผ๊ฑฐ ์กฐํ๊ฐ ๋ค์ ๊ณผ๊ฑฐ ์กฐํ๋ฅผ ๋น ๋ฅด๊ฒ ํ๋ค.\n */\n if (fold && st) {\n const at = asOfNowRead && tip ? tip.revision : foldedTo\n if (at > 0)\n void this.keepChainPoint(domainId, instanceId, {\n revision: at,\n ...(lastEventTime ? { eventTime: lastEventTime } : {}),\n structureRev: (asOfNowRead && tip ? tip.structureRev : null) ?? null,\n fold\n }).catch(() => {})\n }\n return st\n }\n\n /*\n * ์จ์์ด ์์ผ๋ฉด **์ด์ด ์ ๋๋ค** โ ํ ๊ตฌ์กฐ ์์์๋ง(๊ตฌ์กฐ๊ฐ ๊ฐ๋ฆฌ๋ฉด ์๋ ๋ง๋ ๊ฒฝ๋ก๊ฐ ๋งก๋๋ค).\n * ์ ์ฌ๊ฐ์ ๋ ํจ๊ป ๋จ๊ธด๋ค: ๋ค์ ๋ฒ์ ๋ ๊ผฌ๋ฆฌ๋ง ์ ์ ์ ์์ด์ผ ์ด ์ง๋ฆ๊ธธ์ด ๊ณ์ ์ฐ๋ค.\n */\n if (resume?.fold?.reducer && segments.length <= 1) {\n const model = (segments[0]?.model ?? (asOfNow && newest) ?? reg.model) as TwinModelDef\n const out = replayFrom(model, resume.fold.reducer, segments[0]?.events ?? [])\n return keep(withNow(out.state), { reducer: out.checkpoint, oee: oee.serialize() })\n }\n\n if (!segments.length) {\n const model = ((asOfNow && newest) || reg.model) as TwinModelDef\n const out = replayWithCheckpoint(model, [])\n return keep(withNow(out.state), { reducer: out.checkpoint, oee: oee.serialize() })\n }\n if (segments.length === 1) {\n const out = replayWithCheckpoint(segments[0].model, segments[0].events)\n return keep(withNow(out.state), { reducer: out.checkpoint, oee: oee.serialize() })\n }\n\n /* ์ปค๋ ๊ณ์ฝ๋ `model` ์ด๋ค(0.6.14) โ ๊ฒฝ๊ณ์์ ์ดํ๋ฅผ ๋๋๋ ค ๋ด๋ ๋ธ๋ฆฟ์ง๊ฐ ์ฌ๋ผ์ก๋ค. */\n const { state, shifts } = replaySegments(segments)\n /* ๊ฒฝ๊ณ์์ ์ฌ๋ผ์ง ๊ฒ์ ์กฐ์ฉํ ๋๊ธฐ์ง ์๋๋ค โ ์๊ฐ ์ค์ด๋ ์ด์ ๋ฅผ ์ด๋๊ฐ์๋ ๋จ๊ฒจ์ผ ํ๋ค. */\n for (const sh of shifts)\n if (sh.equipmentDropped || sh.locationsDropped || sh.personsDropped || sh.assetsDropped)\n console.info(`[twin-engine] \"${instanceId}\" replay crossed a structure change โ dropped ${sh.equipmentDropped} equipment, ${sh.locationsDropped} locations, ${sh.personsDropped} persons, ${sh.assetsDropped} assets that no longer exist.`)\n return keep(withNow(state))\n }\n\n /**\n * ๊ณต๊ฐ(๊ณต๋๋ฐฐ์น) ์๊ฐ ๋ฒ์ โ ์คํฌ๋ฌ๋ฒ ์ต์ปค(runtime-state-model ยง4ยทยง6). ๊ทธ ๊ณต๊ฐ ์ ์ธ์คํด์ค ์ ๋์ min/max eventTime.\n * ๋ฐํ {minTime, maxTime}(ISO) โ ์ด๋ฒคํธ/์๊ฐ ์์ผ๋ฉด null. ํด๋ผ ํ์คํ ๋ฆฌ ์คํฌ๋ฌ๋ฒ๊ฐ ์ด ๋ฒ์๋ฅผ ์๊ฐ์ถ์ผ๋ก ๊ทธ๋ฆฐ๋ค.\n */\n static async timeRange(domainId: string, spaceId: string): Promise<{ minTime: string | null; maxTime: string | null }> {\n const regs = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n const ids = regs.map(r => r.instanceId)\n if (!ids.length) return { minTime: null, maxTime: null }\n let min = Infinity\n let max = -Infinity\n for (const instanceId of ids) {\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId } })\n for (const r of rows) {\n const t = r.eventTime != null ? Date.parse(String(r.eventTime)) : NaN\n if (Number.isNaN(t)) continue\n if (t < min) min = t\n if (t > max) max = t\n }\n }\n if (min === Infinity) return { minTime: null, maxTime: null }\n return { minTime: new Date(min).toISOString(), maxTime: new Date(max).toISOString() }\n }\n\n /** ์ ์ง ํ
โ ์ธ์คํด์ค ์ ์ง ์ ๋ถ์์์ ์ ๋ฆฌ(์: reference-live ํผ๋ unsubscribe). ์ํ ์ํฌํธ ์์ด ๊ฒฐ์ . */\n static stopHooks: ((id: string) => void)[] = []\n static onStop(fn: (id: string) => void): void {\n this.stopHooks.push(fn)\n }\n\n static async stop(domainId: string, id: string): Promise<void> {\n const i = this.instances[runtimeKey(domainId, id)]\n if (i) {\n /*\n * **๋๊ธฐ ์ ์ ๋จ๊ธด๋ค** โ ์ง๊ธ์ด ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ง์ค์ธ ๋ง์ง๋ง ์๊ฐ์ด๋ค.\n *\n * ๋จ๊ธฐ์ง ์์ผ๋ฉด ๋ค์ ์กฐํ๊ฐ ์ ๋์ ์ ๋ ๋ค์ ์ ๋๋ค(๊ทธ ๊ฐ์ ์ด์ฐจํผ ๋ฐฉ๊ธ ๋ฉ๋ชจ๋ฆฌ์ ์๋ ๊ฒ์ด๋ค).\n * ์ฒดํฌํฌ์ธํธ ๋ฃจํ๊ฐ 20์ด๋ง๋ค ๋จ์ง๋ง ๊ทธ ์ฌ์ด์ ๋ฉ์ถ๋ฉด ๊ทธ ๊ตฌ๊ฐ์ด ํต์งธ๋ก ๋ค์ ์ ํ๋ค.\n */\n await this.persistSnapshot(domainId, id).catch(err =>\n console.error(`[twin-engine] snapshot on stop fail \"${id}\"`, err?.message ?? err)\n )\n clearInterval(i.timer)\n i.unsub()\n delete this.instances[runtimeKey(domainId, id)]\n await getRepository(TwinInstance)\n .update({ domain: { id: i.domainId }, instanceId: id }, { status: 'stopped' })\n .catch(err => console.error('twin deregister fail', err))\n }\n for (const hook of this.stopHooks) { try { hook(id) } catch { /* ํ
๊ฒฉ๋ฆฌ */ } }\n }\n\n /*\n * tick ํ ๋ฒ โ **ํ ํธ์์ ์์ธ๊ฐ ์๋ฒ๋ฅผ ๋ด๋ฆฌ์ง ๋ชปํ๊ฒ** ๊ฐ์ผ๋ค.\n *\n * ์๋ชป๋ ์๋๋ฆฌ์ค๊ฐ ์ค๋ ธ์ ๋ ๋ค์ tick ์์ `rate.meanPerHour` ๋ฅผ ์ฝ๋ค ํฐ์ก๊ณ , ํ์ด๋จธ ์ฝ๋ฐฑ์\n * ์์ธ๋ ์๋ฌด๋ ๋ฐ์ง ์์ **uncaught exception ์ผ๋ก ํ๋ก์ธ์ค๊ฐ ๋ด๋ ค๊ฐ๋ค.** ํ ํ
๋ํธ์ ์๋ชป๋\n * ์ ์ธ์ด ๋ชจ๋ ํ
๋ํธ๋ฅผ ๋ฉ์ถ ์
์ด๋ค. ๋ฌธ ์์์ ๋ง๋ ๊ฒ์ด 1์ฐจ ๋ฐฉ๋ฒฝ์ด๊ณ (`validateScenario`),\n * ์ด๊ฒ์ด 2์ฐจ ๋ฐฉ๋ฒฝ์ด๋ค.\n *\n * **์กฐ์ฉํ ์ผํค์ง ์๋๋ค.** ์คํ์ ๋ฉ์ถ๊ณ ๊ทธ ์ฌ์ค์ ๋จ๊ธด๋ค โ ์์ธ๋ฅผ ๋ฌด์ํ๊ณ ๊ณ์ tick ํ๋ฉด\n * ๊ฐ์ ์ค๋ฅ๊ฐ ๋งค ์ฃผ๊ธฐ ์์์ง๊ณ , ๊ทธ ํธ์์ \"๋๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๋ฉด์\" ์๋ฌด๊ฒ๋ ์งํํ์ง ์๋๋ค.\n */\n /**\n * ๊ฐ์ ํ์ฅ ํธ์๋ค์ **์ค๋น ์ํ**๋ฅผ ์ปค๋์ ๋๊ธด๋ค โ ์ปค๋์ด ์์ฒญํ ๋๋ง.\n *\n * โโ ๊ฒฝ๊ณ (2026-08-14) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํธ์คํธ๊ฐ ์๋ ๊ฒ์ **๋๊ฐ ๊ฐ์ ํ์ฅ์ ์๋๊ฐ** ํ๋๋ค. ๋ฌด์์ ์ฝ๊ณ ๊ทธ๊ฒ์ ์ด๋ป๊ฒ ๋ถํ๋ก ๋ฐ๊ฟ์ง๋\n * ์ปค๋์ด ์ ํ๋ค(๊ณ์๋ ํธ์์ ๋ชจ๋ธ์ด ์ ์ธํ๋ค). ํธ์คํธ๊ฐ kW ๋ฅผ ๊ณ์ฐํด ์ฃผ๋ฉด ํธ์๋ง๋ค ๋ค๋ฅธ ๊ท์น์ด\n * ์๊ธฐ๊ณ , ๊ทธ ๊ท์น์ ์ด๋์๋ ์ ํ ์์ง ์๊ฒ ๋๋ค.\n *\n * ์ํ๋ง ๋๊ธด๋ค. ์ค๋
์ท์ ํต์งธ๋ก ๋๊ธฐ๋ฉด ์ํ ํฌ๊ธฐ์ ๋น๋กํ ๋น์ฉ์ ๋งค tick ์น๋ฅด๊ฒ ๋๋ค โ\n * ์ค๋น ๋ชฉ๋ก์ ๊ทธ ํธ์์ ์ปค๋์ด ์ด๋ฏธ ๋ค๊ณ ์๋ ๊ฒ์ด๋ผ ํ๋ ๊ฐ์ด ์ธ๋ค.\n */\n private static feedPeerEquipment(inst: InstanceRuntime): void {\n const kernel: any = inst.kernel\n if (typeof kernel?.observePeerEquipment !== 'function') return // ์ด์์ ์ฝ์ง ์๋ ์ปค๋\n if (!inst.spaceId) {\n kernel.observePeerEquipment([]) // ํ์ฅ์ด ์์ผ๋ฉด ์ด์๋ ์๋ค(์ ์ํ๊ฐ ๋จ์ง ์๊ฒ ๋น์ด๋ค)\n return\n }\n const peers: { id: string; status?: string }[] = []\n for (const other of Object.values(this.instances)) {\n if (other === inst || other.domainId !== inst.domainId || other.spaceId !== inst.spaceId) continue\n const eq: Map<string, any> | undefined = (other.kernel as any)?.equipment\n if (!eq || typeof eq.forEach !== 'function') continue\n eq.forEach(e => peers.push({ id: String(e?.id ?? ''), status: String(e?.status ?? '') }))\n }\n kernel.observePeerEquipment(peers)\n }\n\n private static tickGuarded(domainId: string, id: string, runtime: TwinRuntimeType): void {\n const inst = this.instances[runtimeKey(domainId, id)]\n const load = inst && (inst.load ?? (inst.load = newLoadMeter()))\n const t0 = performance.now()\n try {\n /* ์ด์์ ์ค๋น ์ํ๋ฅผ ๋จผ์ ์ฃ๋๋ค โ ์ปค๋์ด ์ด๋ฒ tick ์์ ๋ถํ๋ฅผ ๋ง๋ค ๋ ์ฝ๋๋ค. */\n if (inst) this.feedPeerEquipment(inst)\n runtime.tick(this.TICK_MS)\n\n /* ์ฌ๊ณ ๋งํ๋ค โ ์๋ฎฌ ํฑ์ ๋ฉ์ธ ์ด๋ฒคํธ ๋ฃจํ์์ ์ํ๋๋ค. ์์ฐ(๊ฐ๊ฒฉ์ ์ ๋ฐ)์ ๋๊ธฐ๋ฉด HTTPยท๊ตฌ๋
์ด\n ํจ๊ป ๋๋ ค์ง๋๋ฐ, ์์ ์๋ ๊ทธ๊ฒ์ ๋ณผ ๊ณ๊ธฐํ์ด ์์ด \"ํฐ์ง๋ฉด ์๊ณ ๋๋ ค์ง๋ฉด ๋ชฐ๋๋ค\". */\n if (load) {\n const took = performance.now() - t0\n recordPhase(load, 'tick', took)\n const j = judgeCycle(load, took, this.TICK_MS, Date.now())\n if (j.warn) console.warn(slowTickMessage(id, took, j.budgetMs, load))\n this.guardStarvation(domainId, id, took)\n }\n } catch (err: any) {\n /*\n * ๋ฉ์ถ๋ ๊ธธ์ **ํ๋**๋ค(`stop`) โ ์์ ์๋ ํ์ด๋จธ๋ง ๊ป๋ค. ๊ทธ๋ฌ๋ฉด ๋ฑ๋ก๋ถ๋ ๊ณ์ `running` ์ด๋ผ\n * ๋งํ๊ณ (์๋ฌด ํฑ๋ ์๋ ์ฑ๋ก), ๋ถํ
์ฌ๊ฐ๋ ๊ทธ ๊ฑฐ์ง์ ๊ทผ๊ฑฐ๋ก ๋ค์ ์ธ์ด๋ค. ์ค๋
์ท ๋ณด์กดยทํผ๋ ์ ๋ฆฌยท\n * ๋ฑ๋ก๋ถ ๊ฐฑ์ ์ด ๋ชจ๋ `stop` ์์ ์๋ค.\n */\n this.stopWithNote(\n domainId,\n id,\n { code: 'tick-failed', params: { reason: String(err?.message ?? err) } },\n `[twin-engine] \"${id}\" tick failed โ this twin is stopped (other twins keep running). ` +\n `Fix the declaration and start it again. Reason: ${err?.message ?? err}`\n )\n }\n }\n\n /**\n * ํธ์คํธ๋ฅผ ๊ตถ๊ธฐ๋ ํธ์์ ๋ฉ์ถ๋ค โ **๋๋ ์ฒํ๋ ๊ฒ๋ณด๋ค ๋ฉ์ถ ๊ฒ์ด ๋ซ๋ค.**\n *\n * ๊ตถ๊น ๋ฌธํฑ์ ๋๋ ํฑ์ด ์ฐ์ `STARVE_STREAK` ๋ฒ์ด๋ฉด ๊ทธ ํธ์์ ๊ตฌ์กฐ์ ์ผ๋ก ๋ฌด๊ฒ๋ค(์ฐ์ฐ์ด ์๋๋ค).\n * ๋ฌธํฑ ์๋๋ก ํ ๋ฒ๋ง ๋ด๋ ค์๋ ์ฐ์์ ๋๋๋ค โ ๋ฌด๊ฑฐ์ด ์๊ฐ ํ๋๋ก ํธ์์ ๋ด๋ฆฌ์ง ์๋๋ค.\n */\n private static guardStarvation(domainId: string, id: string, tookMs: number): void {\n const key = runtimeKey(domainId, id)\n const starveMs = this.TICK_MS * this.STARVE_FACTOR\n if (!(tookMs >= starveMs)) {\n this.starveStreak.delete(key)\n return\n }\n const streak = (this.starveStreak.get(key) ?? 0) + 1\n this.starveStreak.set(key, streak)\n if (streak < this.STARVE_STREAK) return\n\n this.starveStreak.delete(key)\n const secs = Math.round(tookMs) / 1000\n this.stopWithNote(\n domainId,\n id,\n { code: 'starved', params: { streak, thresholdSec: starveMs / 1000, lastSec: secs } },\n `[twin-engine] \"${id}\" stopped โ ${streak} consecutive ticks over ${starveMs / 1000}s (last ${secs}s). ` +\n `A simulation tick runs on the main loop, so this twin was stalling HTTP, subscriptions and every other twin. ` +\n `Its state is checkpointed; start it again after making it lighter (fewer orders/resources) or wait for off-loop ticking.`\n )\n }\n\n /** ๋ฉ์ถ๊ณ **์ด์ ๋ฅผ ๋จ๊ธด๋ค** โ ์ด์ ์๋ ใ์ ์งใ๋ ์ฌ๋์ด ์๊ธฐ๊ฐ ๋ฉ์ถ ๊ฒ์ผ๋ก ์ฝ๋๋ค. */\n private static stopWithNote(domainId: string, id: string, note: StopNote, log: string): void {\n console.error(log)\n this.stopNotes.set(runtimeKey(domainId, id), note)\n this.stop(domainId, id).catch(err => console.error(`[twin-engine] stop after guard failed \"${id}\"`, err?.message ?? err))\n }\n\n /** ์ด ํธ์์ด ์ค์ค๋ก ๋ฉ์ถ ์ด์ (์์ผ๋ฉด) โ ํ๋ฉด์ด ์ฎ๊ฒจ ๋งํ๋ค. */\n static stopNoteOf(domainId: string, id: string): StopNote | undefined {\n return this.stopNotes.get(runtimeKey(domainId, id))\n }\n\n /**\n * ์ด ํธ์์ด **์ง๊ธ ์คํ ์ค์ธ๊ฐ** โ ํ์ ์ ์ง ํ๋.\n *\n * \"์ค๋
์ท์ด ์๋\" ๋ก๋ ๋ต์ด ๋์ง ์๋๋ค: ์์คํํธ๊ฐ ๋์ด๋ฆฐ ์ํ๊ฐ ์บ์์ ๋จ์ ์์ผ๋ฉด ๋ฉ์ถ ํธ์๋\n * ์ค๋
์ท์ ๋ธ๋ค. ๊ทธ๊ฒ์ ๊ด์ธก ์ค์ผ๋ก ์ฝ์ผ๋ฉด ํ๋ฉด์ด **๋ฉ์ถ ํธ์์ ์์
์ 0 ๊ฑด์ด๋ผ๊ณ ๋จ์ธ**ํ๋ค\n * (์ค์ ๋ก ๊ทธ๋ ๊ฒ ๋์๋ค โ ๊ด์ธก์ด ์๋ ๊ฒ๊ณผ 0 ๊ฑด์ ๋ค๋ฅด๋ค๋ ์ด ํ๋ก์ ํธ์ ๊ท์จ์ ํ๋ฉด์ด ์ด๊ฒผ๋ค).\n *\n * ๋ชฉ๋ก์ด ์ฐ๋ ๊ฒ๊ณผ **๊ฐ์ ์ ์ด**๋ค(`list()` ์ `running`) โ ๋ ๋ฒ์ด๋ฉด ์ด๊ธ๋๋ค.\n */\n static isRunning(domainId: string, id: string): boolean {\n return !!this.instances[runtimeKey(domainId, id)]\n }\n\n static runtime(domainId: string, id: string): TwinRuntimeType | undefined {\n return this.instances[runtimeKey(domainId, id)]?.runtime\n }\n\n /*\n * ์ปค๋งจ๋ ์คํ โ **ํ์ ์ `routeCommand`(์์)๊ฐ ํ๊ณ ์ฌ๊ธฐ์๋ ์คํ๋ง** ํ๋ค.\n * ํ์ ์ ์ฝ๋ ํ๊ฐ์ด๋ฐ ๋๋ฉด ์ด ๋ถ๋ฅ๋ฅผ ํ
์คํธ๋ก ๋ชป ์ก๋๋ค(์์ง์ DB ๋ฅผ ๋ฌผ๊ณ ์์ด ๋จ์ ํ
์คํธ๊ฐ\n * ๋ถ๋ฌ์ฌ ์ ์๋ค). ์์ ์๋ ๋ฆฌ์กธ๋ฒ๊ฐ `inst.runtime.dispatch` ๋ฅผ ๊ณง๋ฐ๋ก ๋ถ๋ฌ ๋ฏธ๋ฌ์์ ํฐ์ก๋ค.\n */\n static async dispatchCommand(domainId: string, instanceId: string, command: any): Promise<{ accepted: boolean; error?: string; errorCode?: string; errorParams?: Record<string, string | number> }> {\n const inst = this.instances[runtimeKey(domainId, instanceId)]\n const type = String(command?.type ?? '')\n const route = routeCommand(\n inst && { mode: inst.mode, hasRuntime: !!inst.runtime, hasKernelDispatch: typeof (inst.kernel as any)?.dispatch === 'function' },\n !!inst && inst.domainId === domainId,\n type\n )\n if (route.target === 'reject') {\n return { accepted: false, errorCode: route.errorCode, errorParams: route.errorParams, error: route.errorCode }\n }\n\n const cmd = { ...command, tenantId: domainId } // tenantId ๋ ํธ์ถ์ ๋๋ฉ์ธ์ผ๋ก ๊ฐ์ธ(๊ฐ์ฌยท๋ฌด๊ฒฐ์ฑ)\n if (route.target === 'runtime') return inst!.runtime!.dispatch(cmd)\n\n /*\n * ๋ฏธ๋ฌ โ ๊ด์ธก ์ปค๋๋ก ๋ณด๋ด๊ณ , **์ปค๋งจ๋๊ฐ ๋ธ ์ฌ์ค์ ์ ๋ ํ์ ์ค์ด** ์ฝ์ผ๋ ์๊ฐ ๋ฒํธ๋ฅผ ๋ถ์ฌํ๊ฒ ํ๋ค.\n * ๋ฏธ๋ฌ์๋ State ๊ตฌ๋
๋ฐฐ๊ด์ด ์์ด(์๋ฎฌ์ ๊ทธ ๊ฒฝ๋ก๋ก ์ ๋๋ง) ์ปค๋ ๋ฐฉ์ถ์ด ์๋ฌด ๋ฐ๋ ๋ฟ์ง ์๋๋ค.\n * ์ฌ๊ธฐ์ DB ๋ฅผ ๋ฐ๋ก ์ฝ์ด ๋ฒํธ๋ฅผ ๋งค๊ธฐ๋ฉด ์ธ๋ฉ๋ชจ๋ฆฌ ์นด์ดํฐ์ ์ด๊ธ๋ ๋ฆฌ๋น์ ์ด ๊ฒน์น๋ค(๊ฒน์นจ์ ์ค๋ฅ๋ฅผ\n * ๋ด์ง ์๊ณ ์ฌ์ ์์๋ง ์กฐ์ฉํ ๋ค์๋๋ค).\n */\n const kernel: any = inst!.kernel\n const emitted: any[] = []\n const off = kernel.onEvent?.((e: any) => emitted.push(e))\n let ack: any\n try {\n ack = kernel.dispatch(cmd)\n } finally {\n off?.()\n }\n if (ack?.accepted && emitted.length) {\n inst!.pendingJournal = [...(inst!.pendingJournal ?? []), ...emitted]\n inst!.dirty = true // ์ฝ์ผ๋ ์๊ฐ ์ด๋ฒ ์ฃผ๊ธฐ์ ๋น์ฐ๊ณ ๋ฐฉ์ก๊น์ง ํ๊ฒ ํ๋ค\n }\n return ack ?? { accepted: false, errorCode: 'unknown-command', error: 'unknown-command' }\n }\n\n /**\n * ๋๋ฉ์ธ ์์ ๊ฒ์ดํธ โ ์ธ์คํด์ค๊ฐ ์ด ๋๋ฉ์ธ ์์ ์ผ ๋๋ง true(ํ
๋ํธ ๊ฒฉ๋ฆฌ).\n * ์๊ฑฐ๋ ๋ค๋ฅธ ๋๋ฉ์ธ์ด๋ฉด false. ๋
ธ์ถ ๋ฆฌ์กธ๋ฒ(per-id metrics/attentions/state/stop/forecast)๊ฐ\n * this.instances[id] ๋ฅผ ๋ง์ง๊ธฐ ์ ์ ๋ฐ๋์ ์ด๊ฑธ๋ก ํ์ธํด์ผ ํ๋ค. ์ธ์คํด์ค id ๋ ์ถ์ธก ๊ฐ๋ฅํ๋ฏ๋ก\n * ๊ฒ์ฆ ์์ด ์ ๊ทผํ๋ฉด ํฌ๋ก์คํ
๋ํธ ์ฝ๊ธฐ/์ ์ง๊ฐ ๊ฐ๋ฅํด์ง๋ค.\n */\n /**\n * ์ด ๋ฐํ์์ **๊ด์ธก ๋ชจ๋** โ `'live'`(์ธ๋ถ ์ค๋ฌผ์ ๋ฏธ๋ฌ) ๋๋ `'sim'`(์ปค๋์ด ์คํํ๋ค). ๊ธฐ๋ ์ค์ด ์๋๋ฉด ์๋ค.\n *\n * ์๋น์ฒ๊ฐ `instances[id].mode` ๋ฅผ ์ง์ ์ฝ๋ ์๋ฆฌ๋ฅผ ๋์ ํ๋ค. ๋ ์ง์คํธ๋ฆฌ๋ฅผ ๋ฐ์ ์ด๋ฉด ๋๋ฉ์ธ ํ์ธ์ด\n * ์๋ฆฌ๋ง๋ค ์ ๊ฐ๊ฐ์ด ๋๊ณ , ์ค์ ๋ก ๊ทธ๋ ๊ฒ ๋๋ค(ํ
๋ํธ ๊ฒฉ๋ฆฌ ์ ์ ํ์ธ, 2026-08-06).\n */\n static modeOf(domainId: string, id: string): 'live' | 'sim' | undefined {\n return this.instances[runtimeKey(domainId, id)]?.mode\n }\n\n static owns(domainId: string, id: string): boolean {\n return !!this.instances[runtimeKey(domainId, id)]\n }\n\n /**\n * ์ด ํธ์์ด ์ด ํ
๋ํธ ๊ฒ์ธ๊ฐ โ **๋ ์๋ ์๋๋ .**\n *\n * `owns()` ๋ **๊ธฐ๋ ์ค์ธ** ๋ฐํ์๋ง ์๋ค. ๊ทธ๊ฒ์ ์ด๋ ฅ ์กฐํ์ ๊ด๋ฌธ์ผ๋ก ์ฐ๋ฉด, ๊บผ์ง ํธ์์ ์ ๋์\n * ์ฝ์ผ๋ ค ํ ๋ \"์ด ํ
๋ํธ์ ์๋ค\" ๋ ๋ต์ด ๋์์จ๋ค โ ๋ ๊ฐ์ง๊ฐ ํ๋ ธ๋ค. ์ฒซ์งธ, ์ ๋์ ํธ์์ด ๊บผ์ ธ\n * ์์ ๋ **๊ฐ์ฅ ํ์ํ ๊ฒ**์ด๋ค(๊ทธ๊ฒ ์ด๋ ฅ์ ์กด์ฌ ์ด์ ๋ค). ๋์งธ, ๊ทธ ๋ฌธ์ฅ์ ๋จ์ ๊ฒ์ด๋ผ๋ ๋ป์ด๋ผ\n * ์ฌ์ฉ์๊ฐ ๊ถํ ๋ฌธ์ ๋ก ์คํดํ๋ค. ์ค์ ๋ก๋ ๊ทธ๋ฅ ์คํ ์ค์ด ์๋ ๋ฟ์ด๋ค.\n *\n * ์์ ๋ **๋ฑ๋ก๋ถ**๊ฐ ์๋ค. ์ด๋ ฅยท์ง๊ณ์ฒ๋ผ ๋ฐํ์๊ณผ ๋ฌด๊ดํ ์ง๋ฌธ์ ์ด์ชฝ์ ๋ฌป๋๋ค.\n */\n static async ownsRegistered(domainId: string, instanceId: string): Promise<boolean> {\n if (this.owns(domainId, instanceId)) return true\n return !!(await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } }))\n }\n\n /**\n * **์ด ๊ณต๊ฐ์ ์ธ์คํด์ค๋ค** โ ํ ํ์ค์ ์ฌ๋ฌ ๋ ์ฆ๊ฐ ๋น์ถ๋ฏ๋ก, ๊ณต๊ฐ์ ๋ฌผ์ผ๋ฉด ๊ทธ ๋ ์ฆ ์ ๋ถ๋ฅผ ๋ตํ๋ค.\n *\n * ํ๋ฉด์ด ์ด ๊ท์น์ ์์ผ๋ก ์ง์ง ์๊ฒ ์๋ฒ๊ฐ ๋ตํ๋ค. ์์ธก ํ๋ฉด์ ๊ฐ์ ํ์ฅ์ **ํ ํ์ผ์์ ๋ ๋ฒ**\n * ๋ณต์ ํ๊ณ ์์๋ค(์ ์ฒด ๋ชฉ๋ก์ ๋ฐ์ ํด๋ผ์ด์ธํธ์์ ๊ฑธ๋ ๋ค) โ ๊ท์น์ด ํฉ์ด์ง๋ฉด ํ์ชฝ๋ง ๊ณ ์ณ์ง๋ค.\n *\n * ๋ ์์ง ์์ ๊ฒ๋ ํฌํจํ๋ค: ๊ณต๊ฐ์ ๋ฌด์์ด ์๋์ง๋ ๊ธฐ๋ ์ฌ๋ถ์ ๋ค๋ฅธ ์ฌ์ค์ด๋ค.\n */\n static async instanceIdsOfSpace(domainId: string, spaceId: string): Promise<string[]> {\n if (!spaceId) return []\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n return rows.map(r => r.instanceId).filter((x): x is string => !!x)\n }\n\n /**\n * **์ด ๊ณต๊ฐ์์ ๋ด์ผ ํ ๊ฒ** โ ๊ณต๊ฐ์ ๋ชจ๋ ๋ ์ฆ์์ ์ ํธ๋ฅผ ๋ชจ์๋ค.\n *\n * ํฉ์งํฉ์ด ๊ทธ๋๋ก ๋ป์ด ์๋ ์ ์ผํ ๋ ์ฆ๋ค(์์ธก์ ํฉ์น ์ ์๋ค โ P50 ๋ ๊ฐ๋ฅผ ๋ํ ์ ์๋ค).\n * ์ ๋ ฌยท์๋ผ๋ด๊ธฐ๋ ํ๋ฉด๊ณผ **๊ฐ์ ๊ท์น**์ ์ด๋ค(`digestAttentions`) โ ์๋ฒ๊ฐ ๊ณ ๋ฅธ ์์ N ์ด ํ๋ฉด์ด\n * ๊ณ ๋ฅผ N ๊ณผ ๋ฌ๋ผ์ง๋ฉด ๊ทธ ์ด๊ธ๋จ์ ์๋ฌด ๋ฐ์๋ ์ค๋ฅ๋ก ๋๋ฌ๋์ง ์๋๋ค.\n *\n * ์ ํธ๋ง๋ค ์ด๋ ํธ์์์ ์๋์ง(`instanceId`)๋ฅผ ๋ถ์ธ๋ค. ๊ณต๊ฐ์์ ๋ณด๋ฉด ๊ฐ์ ์๋ฆฌ id ๊ฐ ๋ ์ฆ๋ง๋ค\n * ๋ค๋ฅธ ๊ฒ์ ๊ฐ๋ฆฌํฌ ์ ์๊ณ , ์กฐ์น๋ ๊ฒฐ๊ตญ ๊ทธ ํธ์์ ๋ณด๋ด์ผ ํ๋ค.\n */\n static async attentionsOfSpace(domainId: string, spaceId: string, limit?: number): Promise<{ attentions: any[]; attentionTotal: number; severityByLocation: Record<string, string> }> {\n const ids = await this.instanceIdsOfSpace(domainId, spaceId)\n const lenses = ids\n /* ๋ ์์ง ์์ ํธ์์ **์ง๊ธ** ์ ํธ๊ฐ ์๋ค(๊ทธ ์์ ์ ํธ๋ ์๊ฐ์ฌํ์ด ๋ตํ๋ค). */\n .filter(id => this.owns(domainId, id))\n .map(id => {\n const kernel: any = this.kernel(domainId, id)\n const snap = kernel?.getSnapshot?.() ?? this.snapshot(domainId, id)\n return { instanceId: id, attentions: snap?.attentions ?? [] }\n })\n /* ๋ชจ์ผ๋ ๊ท์น(ํ๊น
ยท๊ธํ ์์ยท์๋ฆฌ ์)์ ์์ ํจ์๊ฐ ๋ค๊ณ ์๋ค โ ์ฌ๊ธฐ์ ์์ผ๋ก ์ ์ง ์๋๋ค. */\n return mergeLensAttentions(lenses, limit)\n }\n\n /** ๋ผ์ด๋ธ ์ปค๋(ForecastTwin) โ forecast/divergence ์์ธก ์ฐ์ฐ์ฉ. */\n static kernel(domainId: string, id: string): any {\n return this.instances[runtimeKey(domainId, id)]?.kernel\n }\n\n /** ๋ผ์ด๋ธ ์ฒ๋ฆฌ๋ ๊ณ์ธก ์ค๋
์ท(๋ชจ๋ํฐ, โฃ-1) โ ๋ด๋ถ ๋์ (_acc*) ์ ์ธํ ๊ณต๊ฐ ์งํ. live ์๋๋ฉด null. */\n static metrics(domainId: string, id: string): any {\n const m = this.instances[runtimeKey(domainId, id)]?.metrics\n if (!m) return null\n return {\n instanceId: id,\n ingestedTotal: m.ingestedTotal, broadcastTotal: m.broadcastTotal, journaledTotal: m.journaledTotal,\n ingestRate: m.ingestRate, broadcastRate: m.broadcastRate, journalRate: m.journalRate,\n backlog: m.backlog, broadcastCoalesceMs: this.BROADCAST_COALESCE_MS,\n /* ์์
๋ณ ๋ถํ โ ๋ฌด๊ฑฐ์ด ๊ฒ๋ถํฐ. ์ฐ ์ ์ด ์์ผ๋ฉด null(0 ์ผ๋ก ์ฑ์ฐ๋ฉด \"๋น ๋ฅด๋ค\" ๋ก ์ฝํ๋ค). */\n load: loadSummary(this.instances[runtimeKey(domainId, id)]?.load, this.TICK_MS)\n }\n }\n\n /**\n * ๋ถํ ๊ณ๊ธฐํ๋ง ๋ฐ๋ก โ **์๋ฎฌ ํธ์๋ ํฌํจํ๋ค.**\n *\n * `metrics()` ๋ ๋ผ์ด๋ธ ์งํ(`inst.metrics`)๊ฐ ์์ด์ผ ๋ฌด์ธ๊ฐ๋ฅผ ๋๋ ค์ค๋ค. ๊ทธ๋ฐ๋ฐ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ์ ์ ํ๋\n * ๊ฒ์ ์ฃผ๋ก **์๋ฎฌ ํฑ**์ด๊ณ , ์๋ฎฌ ์ธ์คํด์ค์๋ ๊ทธ ์งํ๊ฐ ์์ด ํต์งธ๋ก ์ ๋ณด์๋ค.\n */\n static load(domainId: string, id: string): any {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (!inst) return null\n\n return {\n instanceId: id,\n mode: inst.mode ?? 'sim',\n domainId: inst.domainId,\n domainLabel: inst.domain?.subdomain,\n restartPolicy: inst.restartPolicy,\n tickMs: this.TICK_MS,\n running: !!inst.timer || inst.mode === 'live',\n ...(loadSummary(inst.load, this.TICK_MS) ?? { recent: null, total: null, forksCreated: 0, overBudget: 0, budgetMs: this.TICK_MS * 0.5, loadRatio: null })\n }\n }\n\n /**\n * **ํ ๊ณณ์์ ๋ณด๋ ์ ์ฒด ๋ถํ** โ ๋ช ๊ฐ๊ฐ ์คํ ์ค์ด๊ณ , ๋๊ฐ ๋ฃจํ๋ฅผ ์ ์ ํ๊ณ ์๋.\n *\n * ์๋ฎฌ ํธ์๋ ํฌํจํ๋ค(`metrics()` ๋ ๋ผ์ด๋ธ ์งํ๊ฐ ์์ด์ผ ๋ตํด์ ์๋ฎฌ์ด ํต์งธ๋ก ์ ๋ณด์๋ค).\n */\n static fleet(domainId?: string): any {\n const keys = Object.keys(this.instances).filter(key => !domainId || isOfDomain(key, domainId))\n const rows = keys.map(key => {\n const at = parseRuntimeKey(key)\n const inst = this.instances[key]\n /* ๋๋ฉ์ธ์ ํจ๊ป ๋๊ธด๋ค โ ์ด์์๊ฐ ๋จผ์ ๋ฌป๋ ๊ฒ์ \"์ด๋ ํ
๋ํธ๊ฐ ๋ฃจํ๋ฅผ ๋จน๋\" ๋ค.\n ์ฝ์ ์ ์๋ ์ด๋ฆ(subdomain)์ ๋ผ์ด๋ธ ์ธ์คํด์ค์๋ง ๋ถ์ด ์์ผ๋ฏ๋ก, ์์ผ๋ฉด ๋ฆฌ์กธ๋ฒ๊ฐ ์ฑ์ด๋ค. */\n return {\n instanceId: at.instanceId,\n mode: inst.mode ?? 'sim',\n domainId: at.domainId,\n domainLabel: inst.domain?.subdomain,\n meter: inst.load\n }\n })\n\n return {\n tickMs: this.TICK_MS,\n broadcastCoalesceMs: this.BROADCAST_COALESCE_MS,\n ...fleetLoad(rows, this.TICK_MS),\n /* ์ค๋ง๋ค ์์ธ โ ํ๋ฉด์ด ํผ์ณ ๋ณผ ์ ์๊ฒ. ์ต๊ทผ ๋ถํ ์์๋ fleetLoad ๊ฐ ์ ํ๋ค. */\n details: keys.map(key => { const at = parseRuntimeKey(key); return this.load(at.domainId, at.instanceId) }).filter(Boolean)\n }\n }\n\n /** ์ด ํธ์์์ fork ๊ฐ ๋ง๋ค์ด์ก๋ค โ ์์ธก ํ ๋ฒ์ด ์์ญ ๊ฐ๋ฅผ ๋ง๋ ๋ค. */\n static countForks(domainId: string, id: string, count: number): void {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (inst) recordFork(inst.load ?? (inst.load = newLoadMeter()), count)\n }\n\n /** ์์ง ๋ฐ(์์ธก ์ง์ ๋ฑ)์์ ๋ฌด๊ฑฐ์ด ์์
์ ์ฐ๋ค โ ๊ฐ์ ๊ณ๊ธฐํ์ ๋ชจ์ธ๋ค. */\n static recordLoad(domainId: string, id: string, phase: LoadPhase, tookMs: number): void {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (inst) recordPhase(inst.load ?? (inst.load = newLoadMeter()), phase, tookMs)\n }\n\n /** ์ ์ฒด ๋ผ์ด๋ธ ์ธ์คํด์ค ๊ณ์ธก(๋ชจ๋ํฐ ๋์๋ณด๋์ฉ). */\n static async allMetrics(domainId?: string): Promise<any[]> {\n /* ๋๋ฉ์ธ ์์ด ๋ถ๋ฅด๋ฉด ์ ํ
๋ํธ๋ฅผ ํ๋๋ค(๋ด๋ถ ๋ชจ๋ํฐ์ฉ) โ ํค์์ ๋๋ฉ์ธ์ ๋๋๋ ค ๊ฐ์์๊ฒ ๋ฌป๋๋ค. */\n const rows = Object.keys(this.instances)\n .filter(key => !domainId || isOfDomain(key, domainId))\n .map(key => {\n const at = parseRuntimeKey(key)\n return this.metrics(at.domainId, at.instanceId)\n })\n .filter(Boolean)\n if (!rows.length || !domainId) return rows\n // ํ์ ์ด๋ฆ ๋ถ์ฌ โ ์คํ์ค ์นด๋๊ฐ id ๋ง ๋ณด์ด์ง ์๋๋ก ๊ณต๊ฐ๋ช
์ ์ค์ด์ค๋ค(๊ณต๊ฐ ์นด๋์ ๋์ผ). name=๊ณต๊ฐ๋ช
ํด๋ฐฑ spaceId ํด๋ฐฑ instanceId.\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const spaceOf = new Map(insts.map(i => [i.instanceId, i.spaceId]))\n /* ์ฉ๋ ์ ์ธ๋ ํจ๊ป ์ค์ด ๋ณด๋ธ๋ค โ ํ๋ฉด์ด ๊ณต๊ฐ ์ด๋ฆ์ผ๋ก ๋ฒค์น๋ฅผ **์ถ์ธกํ์ง ์๊ฒ** ํ๋ค.\n ์ถ์ธกํ๋ฉด `loadtest-` ๋ก ์ด๋ฆ ์ง์ ์ด์ ํธ์์ ๋ฒค์น ๋ฑ์ง๊ฐ ๋ถ๋๋ค. */\n const purposeOf = new Map(insts.map(i => [i.instanceId, i.purpose]))\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n for (const r of rows) {\n const sp = spaceOf.get(r.instanceId)\n r.spaceId = sp\n r.purpose = purposeOf.get(r.instanceId)\n r.name = (sp && nameOf.get(sp)) || sp || r.instanceId\n }\n return rows\n }\n\n /*\n * `buildForecastKernel` ์ **์ฌ๋ผ์ก๋ค**(ํตํฉ P3, 2026-08-01).\n *\n * ๋ผ์ด๋ธ๊ฐ `StateProjector` ์์ ๋๋ ์ปค๋์ด ์์ด์, ์์ธกํ๋ ค๋ฉด ๊ด์ธก ์ค๋
์ท + ์ ๋์ ์ค๋ ์๊ฐ์ผ๋ก\n * **์ผํ์ฉ ์ปค๋์ ์ธ์์ผ** ํ๋ค. ์ด์ ๋ผ์ด๋ธ ์ธ์คํด์ค๊ฐ ๊ณง ์ปค๋์ด๋ฏ๋ก(`startLive`) ๊ทธ ์๋ฆฌ์์\n * `fork` ํ๋ฉด ๋๋ค โ `TwinEngine.kernel(id)` ๊ฐ simยทlive ๋ ๋ค ๋๋ ค์ค๋ค.\n *\n * (์ค๋ ์๊ฐ์ ์ ๋์์ ๋์ฐพ๋ ์ด์ ๋ ์ฌ๋ผ์ก๋ค โ ์ํ๊ฐ requestedยทfulfilledยทlines ๋ฅผ ์งํจ๋ค.)\n */\n\n /**\n * ์์ธก์ฉ ์ปค๋์ **์์ ์๊ฐ T ๊ธฐ์ค**์ผ๋ก ์ฌ๊ตฌ์ฑ โ ๊ณผ๊ฑฐ-vantage ์์ธก(๋ฐฑํ
์คํธ)ยท\"๊ทธ๋ ์์ ๋ณธ ๋ฏธ๋\".\n * recover(untilTime)๋ก T ์์ ์ํ๋ฅผ, T ์ดํ ์ค๋ ๊ด์ธก์ ๋ชจ์ hydrate โ monteCarloForecast ๊ฐ T ์์ ์์ผ๋ก ์คํํ๋ค.\n * sim/live ๋ฌด๊ด(์ ๋ ๊ธฐ๋ฐ ์ฌ๊ตฌ์ฑ). untilTime ์๋ต ์ ์ต์ . ๋๋ฉ์ธ ์ค์ฝํ(regยทjournal ์กฐํ๊ฐ domainId).\n */\n static async buildForecastKernelAt(domainId: string, instanceId: string, untilTime?: string): Promise<any | null> {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.model) return null\n const Kernel = kernelFor(reg.kind)\n const k = new Kernel(domainId, undefined, this.productionSpecOf(reg.model as TwinModelDef))\n k.loadTwinModel(reg.model as TwinModelDef)\n this.applyOperations(k, reg.model, instanceId) // ์์ธก๋ ๊ฐ์ ๋ช
์ธ๋ก ๊ตด๋ฌ์ผ ํ๋ค(ํ๋ฉด๊ณผ ๋ค๋ฅธ ์ซ์ ๊ธ์ง)\n await this.installEstimators(k, domainId, instanceId, reg.model) // ์์ธก์ ๊ธฐ๋ค๋ฆฐ๋ค โ ์ค์ธก์ ๋์น๋ฉด ์์ธก์ด ์์๋ก ๊ณ์ฐ๋๋ค\n const state = await this.recover(domainId, instanceId, undefined, untilTime).catch(() => null)\n if (!state) return null\n const cutoff = untilTime != null ? Date.parse(untilTime) : Infinity\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId, eventType: OP_EVENT.order }, order: { revision: 'ASC' } })\n const latest = new Map<string, any>()\n for (const r of rows) {\n if (Number.isFinite(cutoff) && (r.eventTime?.getTime() ?? NaN) > cutoff) continue\n const d = (r.payload as any)?.data\n if (d?.orderId) latest.set(d.orderId, d)\n }\n k.hydrateObserved(state, [...latest.values()])\n return k\n }\n\n /** ํ์ฌ ์ ์ฒด ์ค๋
์ท โ ๋ผ์ด๋ธ ์ฐ์ , ์์ผ๋ฉด ์ ๋ ๋ณต๊ตฌ ์บ์. */\n static snapshot(domainId: string, id: string): any {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (inst?.mode === 'live' && inst.projector) {\n /* live: **์ปค๋์ด ์ฃผ๋ชฉ ์ ํธ๋ฅผ ์ค์ค๋ก ๋ธ๋ค**(๊ด์ธก ๋ชจ๋) โ ํธ์คํธ๊ฐ ๋ง๋ถ์ด๋ withLiveAttentions ๋\n * ํ์ ์๋ค. OEE ๋ง ํธ์คํธ๊ฐ ์ฑ์ด๋ค: ์ ์์คํ
์ด ์๊ฐ ๋์ ์ ๋ณด๋ด ์ฃผ์ง ์์ ์ํ ์ ์ด๋ฅผ ์ ๋ถํด\n * ๋ง๋๋ ๊ฐ์ด๋ผ ์ปค๋์ด ๋์ ํ ์ ์๋ค(์ ํฉ์ฑ ํ๋ค์ค์ ์ ์ผํ ์์ธ). */\n const st = inst.projector.snapshot()\n return inst.oee ? withLiveOee(st, inst.oee) : st\n }\n return inst?.runtime?.resync() ?? this.recovered[runtimeKey(domainId, id)]\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"twin-engine.js","sourceRoot":"","sources":["../../server/engine/twin-engine.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,qCAAuD;AACvD,iDAAqE;AACrE,6DAA6D;AAC7D,qCAAgE;AAChE,iEAA4D;AAI5D,uEAA+D;AAC/D,iFAAwE;AACxE,mDAAgF;AAChF,mEAAgE;AAChE,qDAA0E;AAC1E,6DAAmD;AACnD,gFAAwE;AACxE,yCAAyC;AACzC,8EAAsE;AACtE,mFAA2E;AAC3E,uEAA+D;AAC/D,kFAAsE;AACtE,qGAA4F;AAC5F,iFAAwE;AACxE,qEAA6D;AAC7D,kFAA6F;AAC7F,0EAAyE;AACzE,kFAAmL;AACnL,qFAA6E;AAC7E,+DAA6E;AAC7E,mEAAgE;AAChE,2DAAyD;AACzD,iEAAmE;AACnE,2DAA2E;AAE3E,iDAA+C;AAC/C,6CAAwC;AAExC,+FAA6F;AAC7F,mDAA4J;AAC5J,+CAAuC;AACvC,iGAA4F;AAC5F,2DAAwE;AACxE,6DAAkE;AAClE,6DAAyD;AACzD,+DAA6E;AAE7E,mEAAyD;AACzD,yDAY2B;AAC3B,sDAAmD;AAGnD,uFAAuF;AACvF,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,oBAAoB,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;AAEjQ,MAAM,OAAO,GAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,CAAA;AAEvG;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAE5B;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,SAAS,CAAC,CAAU;IAC3B,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,IAAI,CAAA;IAC1B,IAAI,CAAC,YAAY,IAAI;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAE/E,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC1B,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IACnB,yDAAyD;IACzD,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC/C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;IAC3D,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACtC,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvB,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,uBAAuB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAC5G,OAAO,CAAC,CAAA;AACV,CAAC;AAED,mEAAmE;AACnE,IAAI,wBAAwB,GAAG,KAAK,CAAA;AAEpC;;;;;;;;;;;;;GAaG;AACH,SAAS,eAAe,CAAC,MAAW,EAAE,IAAY;IAChD,IAAI,OAAO,MAAM,EAAE,OAAO,KAAK,UAAU,EAAE,CAAC;QAC1C,MAAM,CAAC,OAAO,EAAE,CAAA;QAChB,OAAM;IACR,CAAC;IACD,IAAI,wBAAwB;QAAE,OAAM;IACpC,wBAAwB,GAAG,IAAI,CAAA;IAC/B,IAAA,iBAAQ,EACN,iBAAiB,IAAI,8EAA8E;QACjG,2GAA2G,CAC9G,CAAA;AACH,CAAC;AAoGD,MAAa,UAAU;IACrB;;;;;;OAMG;aACI,cAAS,GAAoC,EAAE,CAAA;IACtD,+CAA+C;IAC/C,8DAA8D;aACvD,cAAS,GAAwB,EAAE,CAAA;aACnC,YAAO,GAAG,IAAI,CAAA;IAErB;;;;;;;;;;;;OAYG;IACH;;;;;;;;;OASG;IACH,8DAA8D;aACvD,kBAAa,GAAG,EAAE,CAAA;aACV,cAAS,GAAG,CAAC,CAAA;IAC5B;;;;OAIG;IACK,MAAM,CAAC,cAAc,CAAC,EAAc,EAAE,IAAsB;QAClE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAA;QACzD,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAA;QAC1E,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;YAC9C,IAAI,OAAO,QAAQ,EAAE,KAAK,KAAK,UAAU;gBAAE,QAAQ,CAAC,KAAK,EAAE,CAAA;YAC3D,IAAI,CAAC,QAAQ,CAAC,CAAA,CAAC,sBAAsB;YACrC,EAAE,EAAE,CAAA;QACN,CAAC,EAAE,MAAM,CAAC,CAAA;QACV,IAAI,OAAO,KAAK,EAAE,KAAK,KAAK,UAAU;YAAE,KAAK,CAAC,KAAK,EAAE,CAAA;QACrD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,qDAAqD;aAC9C,kBAAa,GAAG,CAAC,CAAA;IACxB,mDAAmD;aAC5C,kBAAa,GAAG,CAAC,CAAA;aACT,iBAAY,GAAG,IAAI,GAAG,EAAkB,CAAA;IACvD;;;OAGG;aACY,cAAS,GAAG,IAAI,GAAG,EAAoB,CAAA;IAEtD;;0EAEsE;aAC/D,sBAAiB,GAAG,eAAe,CAAA;IAC1C;;;;;;;;;;OAUG;aACI,mBAAc,GAAG,iBAAiB,CAAA;aAClC,yBAAoB,GAAG,uBAAuB,CAAA;aAC9C,iBAAY,GAAG,IAAI,CAAA,GAAC,iCAAiC;aACrD,eAAU,GAAG,CAAC,CAAA,GAAC,kCAAkC;aACjD,mBAAc,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA,GAAC,qCAAqC;aACpE,kBAAa,GAAG,KAAK,CAAA,GAAC,0CAA0C;IACvE;;;;;;;;;;;;;;;;;;;;;OAqBG;aACI,2BAAsB,GAAY,SAAS,CAAA;aAc3C,uBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA,GAAC,4BAA4B;IAIvE,8EAA8E;IAC9E,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,UAAkB;QAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;QAC7D,IAAI,CAAC,IAAI;YAAE,OAAM;QACjB;;;;WAIG;QACH,MAAM,KAAK,GAAG,IAAA,2BAAW,EAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;QAC9D,IAAI,CAAC,KAAK;YAAE,OAAM;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAA;QACrD,wDAAwD;QACxD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAQ,CAAC,CAAA;QAC5G,MAAM,4BAAY,CAAC,UAAU,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;IACzI,CAAC;IAED;;;;;OAKG;aACqB,cAAS,GAAG,+DAA+D,CAAA;IAEnG,oFAAoF;IACpF,MAAM,CAAC,KAAK,CAAC,YAAY,CACvB,QAAgB,EAChB,UAAkB;QAElB,MAAM,KAAK,GAAG,MAAM,4BAAY,CAAC,YAAY,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAA;QAC/F,OAAQ,KAAa,EAAE,KAAK,IAAI,IAAI,CAAA;IACtC,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAC7B,QAAgB,EAChB,UAAkB,EAClB,KAAgI;QAEhI,IAAI,CAAC,KAAK,EAAE,KAAK;YAAE,OAAM;QACzB,MAAM,4BAAY;aACf,UAAU,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC;aACxF,KAAK,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,IAAA,kBAAS,EAAC,qCAAqC,UAAU,GAAG,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC,CAAA;IAC5G,CAAC;IAGD,8CAA8C;IACtC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,UAAkB;QAClE,MAAM,KAAK,GAAG,MAAM,4BAAY,CAAC,YAAY,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QACpH,MAAM,IAAI,GAAI,KAAa,EAAE,KAAK,EAAE,SAAS,CAAA;QAC7C,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACrH,CAAC;IAED;;;;;;OAMG;IACK,MAAM,CAAC,KAAK,CAAC,YAAY,CAC/B,QAAgB,EAChB,UAAkB,EAClB,MAA8C;QAE9C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACxD,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAA;QAC7B,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3C,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,IAAI,QAAQ,GAAG,MAAM,CAAC,QAAQ;gBAAE,SAAQ;YACnE,MAAM,KAAK,GAAG,MAAM,4BAAY,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;YACxH,MAAM,KAAK,GAAI,KAAa,EAAE,KAAK,CAAA;YACnC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO;gBAAE,SAAQ;YACnC,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;gBAC1B,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;gBACrE,qDAAqD;gBACrD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM;oBAAE,SAAQ;YACxD,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,mDAAmD;IAC3C,MAAM,CAAC,KAAK,CAAC,cAAc,CACjC,QAAgB,EAChB,UAAkB;IAClB;;;;;OAKG;IACH,KAAuI;QAEvI,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;QAC9D,IAAI,KAAK,CAAC,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC,YAAY;YAAE,OAAM,CAAC,gBAAgB;QACxE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QACnD,MAAM,4BAAY,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;QAClI,MAAM,4BAAY,CAAC,UAAU,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;QAC5H;;;;;WAKG;QACH,IAAI,OAAO,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,kBAAkB,UAAU,wBAAwB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAA;IAC/J,CAAC;IAED,0DAA0D;IAClD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,UAAkB;QAC7D,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACtC,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC;YAClH,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC;SAClH,CAAC,CAAA;QACF,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAA;IAC5E,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,QAAgB;QACxC,sEAAsE;QACtE,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAChH,MAAM,IAAI,GAAG,SAAS,IAAI,IAAI,CAAC,sBAAsB,CAAA;QACrD,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;QAExE,+DAA+D;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,GAAG,KAAK,CAAA;QAC3C,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC7C,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YAC3B,IAAA,iBAAQ,EACN,mCAAmC,IAAI,cAAc,OAAO,aAAa,aAAa,SAAS;gBAC7F,gDAAgD,CACnD,CAAA;QACH,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,GAAG,KAAK,GAAG,IAAI,CAAC,CAAA;QAElE,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAA;QAC5F,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,IAAI,SAAS,GAAG,CAAC,CAAA;QACjB,MAAM,OAAO,GAAa,EAAE,CAAA;QAE5B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;YAC9E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAA;YACxC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,yCAAyC;gBACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;gBAC1B,SAAQ;YACV,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC;iBACvC,kBAAkB,EAAE;iBACpB,MAAM,EAAE;iBACR,IAAI,CAAC,yBAAS,CAAC;iBACf,KAAK,CAAC,uBAAuB,EAAE,EAAE,QAAQ,EAAE,CAAC;iBAC5C,QAAQ,CAAC,2BAA2B,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC;iBACnE,QAAQ,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,CAAC;iBACvC,QAAQ,CAAC,wBAAwB,CAAC;iBAClC,QAAQ,CAAC,sBAAsB,EAAE,EAAE,MAAM,EAAE,CAAC;iBAC5C,OAAO,EAAE,CAAA;YACZ,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAA;YAC3B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACV,OAAO,IAAI,CAAC,CAAA;gBACZ,SAAS,EAAE,CAAA;gBACX,oDAAoD;gBACpD,IAAA,gBAAO,EACL,iCAAiC,CAAC,CAAC,UAAU,OAAO,CAAC,iBAAiB,IAAI,MAAM,MAAM,CAAC,WAAW,EAAE,QAAQ;oBAC1G,mBAAmB,CACtB,CAAA;YACH,CAAC;QACH,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,IAAA,gBAAO,EACL,uCAAuC,OAAO,CAAC,MAAM,oCAAoC;gBACvF,4BAA4B,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAChG,CAAA;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAA;IACxC,CAAC;IAED,6CAA6C;IAC7C,MAAM,CAAC,kBAAkB,CAAC,QAAgB;QACxC,IAAI,IAAI,CAAC,cAAc;YAAE,OAAM;QAC/B;;;WAGG;QACH,IAAI,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAM;QACjE,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;YACrC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,kBAAS,EAAC,oCAAoC,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC,CAAA;QAChH,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAA;QAC3B,IAAI,OAAO,IAAI,CAAC,cAAc,EAAE,KAAK,KAAK,UAAU;YAAE,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;QACjF,IAAA,gBAAO,EACL,wCAAwC,IAAI,CAAC,sBAAsB,IAAI,UAAU,MAAM;YACrF,GAAG,IAAI,CAAC,kBAAkB,GAAG,KAAK,KAAK,CAC1C,CAAA;IACH,CAAC;IAED,kDAAkD;IAClD,MAAM,CAAC,mBAAmB;QACxB,IAAI,IAAI,CAAC,eAAe;YAAE,OAAM;QAChC,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;YACtC,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzD,MAAM,EAAE,UAAU,EAAE,GAAG,IAAA,gCAAe,EAAC,GAAG,CAAC,CAAA;gBAC3C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAC1D,IAAA,kBAAS,EAAC,2CAA2C,UAAU,GAAG,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CACzF,CAAA;YACH,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAA;QACtB,IAAI,OAAO,IAAI,CAAC,eAAe,EAAE,KAAK,KAAK,UAAU;YAAE,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;IACrF,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,SAAS;QACpB,8DAA8D;QAC9D,qBAAO,CAAC,KAAK,EAAE,CAAA;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAA;YACxC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAA;YAC9D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,UAAU;oBAAE,SAAQ;gBAC9C,4DAA4D;gBAC5D,yEAAyE;gBACzE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;gBACtF,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;oBAClB,8DAA8D;oBAC9D,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAA,2BAAW,EAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;oBAC1H;;;;;;;uBAOG;oBACH,IAAA,gBAAO,EAAC,yCAAyC,GAAG,CAAC,UAAU,gBAAgB,MAAM,CAAC,QAAQ,qBAAqB,CAAC,CAAA;oBACpH,SAAQ;gBACV,CAAC;gBACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;gBAChF,IAAI,KAAK,EAAE,CAAC;oBACV,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAA;oBAC9F,IAAA,gBAAO,EAAC,4BAA4B,GAAG,CAAC,UAAU,6BAA6B,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAA;gBACnG,CAAC;YACH,CAAC;YACD;;;;;;;eAOG;YACH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;gBACzB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAA;YACvE,CAAC;YACD,IAAI,CAAC,mBAAmB,EAAE,CAAA,CAAC,kCAAkC;YAC7D;;;;eAIG;YACH,KAAK,MAAM,QAAQ,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC,EAAE,CAAC;gBACtF,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAA;YACnC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAA,kBAAS,EAAC,oCAAoC,EAAE,GAAG,CAAC,CAAA;QACtD,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACK,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,GAAiB;QAC9C,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,GAAG,CAAA;QACpC,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU;YAAE,OAAM;QACpC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAAE,OAAM,CAAC,mBAAmB;QAEhF;;;;WAIG;QACH,IAAI,GAAG,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,kEAAkE,CAAC,CAAA;YAC/F,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH;;;;;;eAMG;YACH,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;YAClD,IAAI,GAAG,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;gBACnC;kFACkE;gBAClE,IAAA,gBAAO,EAAC,iCAAiC,UAAU,iDAAiD,CAAC,CAAA;YACvG,CAAC;iBAAM,CAAC;gBACN,IAAA,gBAAO,EAAC,yBAAyB,GAAG,CAAC,aAAa,KAAK,UAAU,IAAI,CAAC,CAAA;YACxE,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,IAAI,eAAe,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC;IAED,oDAAoD;IAC5C,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,GAAiB,EAAE,GAAW;QAC7D,IAAA,iBAAQ,EAAC,kBAAkB,GAAG,CAAC,UAAU,kBAAkB,GAAG,gCAAgC,CAAC,CAAA;QAC/F,IAAI,CAAC;YACH,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;QACjF,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,IAAA,kBAAS,EAAC,iCAAiC,GAAG,CAAC,UAAU,yCAAyC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAA;QACjH,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACK,MAAM,CAAC,SAAS,CAAC,QAAgB,EAAE,EAAU,EAAE,MAAkB,EAAE,OAAgB;QACzF,MAAM,OAAO,GAAI,MAAc,CAAC,eAAe,CAAA;QAC/C,MAAM,IAAI,GAAG,IAAA,6BAAa,EAAC,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,OAAO,KAAK,UAAU,CAAC,CAAA;QAEnH,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC5B,IAAA,gBAAO,EAAC,kBAAkB,EAAE,qFAAqF,CAAC,CAAA;YACpH,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;gBACzC,IAAA,iBAAQ,EACN,6BAA6B,EAAE,iHAAiH,CACjJ,CAAA;YACH,CAAC;YACD,OAAM;QACR,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/B,MAAM,QAAQ,GAAG;YACf,GAAG,IAAI,CAAC,SAAS,UAAU;YAC3B,GAAG,IAAI,CAAC,cAAc,YAAY;YAClC,GAAG,IAAI,CAAC,UAAU,gBAAgB;YAClC,GAAG,IAAI,CAAC,SAAS,UAAU;YAC3B,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,4DAA4D;YAC5D,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,4BAA4B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,gDAAgD;YAChD,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,mBAAmB,0BAA0B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACZ,IAAA,gBAAO,EAAC,+BAA+B,EAAE,gBAAgB,QAAQ,GAAG,CAAC,CAAA;QACrE,0DAA0D;QAC1D,IAAI,IAAI,CAAC,mBAAmB,GAAG,CAAC,EAAE,CAAC;YACjC,IAAA,iBAAQ,EACN,kBAAkB,EAAE,MAAM,IAAI,CAAC,mBAAmB,8DAA8D;gBAC9G,gHAAgH,CACnH,CAAA;QACH,CAAC;IACH,CAAC;IAED,oFAAoF;IACpF;;;;;;;;OAQG;IACK,MAAM,CAAC,eAAe,CAAC,MAAW,EAAE,KAAU,EAAE,EAAU;QAChE;;;;;;WAMG;QACH,MAAM,QAAQ,GAAG,KAAK,EAAE,cAAoD,CAAA;QAC5E,IAAI,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;YAC7C,IAAI,OAAO,MAAM,EAAE,gBAAgB,KAAK,UAAU,EAAE,CAAC;gBACnD,IAAA,iBAAQ,EACN,kBAAkB,EAAE,6BAA6B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,4DAA4D;oBACvI,6JAA6J,CAChK,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC;oBACH,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAA;gBACnC,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,oDAAoD;oBACpD,IAAA,iBAAQ,EAAC,kBAAkB,EAAE,2DAA2D,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;gBAChH,CAAC;YACH,CAAC;QACH,CAAC;QACD,4DAA4D;QAC5D,MAAM,MAAM,GAAG,KAAK,EAAE,WAAiE,CAAA;QACvF,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;YACzC,IAAI,OAAO,MAAM,EAAE,iBAAiB,KAAK,UAAU,EAAE,CAAC;gBACpD,IAAA,iBAAQ,EACN,kBAAkB,EAAE,sDAAsD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,mDAAmD;oBACrJ,4GAA4G,CAC/G,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC;oBACH,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAClC,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,IAAA,iBAAQ,EAAC,kBAAkB,EAAE,4DAA4D,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;gBACjH,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,GAAG,GAAG,KAAK,EAAE,UAAU,CAAA;QAC7B,IAAI,CAAC,GAAG,EAAE,MAAM;YAAE,OAAM;QACxB,IAAI,OAAO,MAAM,EAAE,cAAc,KAAK,UAAU,EAAE,CAAC;YACjD,IAAA,iBAAQ,EAAC,kBAAkB,EAAE,qBAAqB,GAAG,CAAC,MAAM,2JAA2J,CAAC,CAAA;YACxN,OAAM;QACR,CAAC;QACD,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAW,EAAE,QAAgB,EAAE,UAAkB,EAAE,KAAU;QAC1F,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAM;QACjD,MAAM,MAAM,GAAG,IAAA,0CAAoB,EAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAC9G,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACnE,MAAM,OAAO,GAAG,IAAA,qCAAe,EAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAA;QACxE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,uDAAuD;YACvD,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM;gBAAE,IAAA,iBAAQ,EAAC,kBAAkB,UAAU,wCAAwC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACpI,OAAM;QACR,CAAC;QACD,MAAM,CAAC,iBAAiB,GAAG,OAAO,CAAA;QAClC;;;;;WAKG;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC7D,IAAI,MAAM,EAAE,SAAS,EAAE,CAAC;YACtB,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;gBACzC,IAAA,iBAAQ,EACN,kBAAkB,UAAU,wBAAwB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,sDAAsD;oBAC1I,kHAAkH,CACrH,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,SAAS,CAAA;gBACxC,IAAA,gBAAO,EACL,kBAAkB,UAAU,iCAAiC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;qBACxF,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;qBAC3G,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAClI,CAAA;YACH,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YAClC,+DAA+D;YAC/D,IAAA,gBAAO,EACL,kBAAkB,UAAU,4CAA4C,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,OAAO;iBACzG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;iBAClC,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAA;QACH,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA;QACpD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA;QACnD,IAAA,gBAAO,EACL,kBAAkB,UAAU,qDAAqD,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;YAC5H,2BAA2B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG;YACvE,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,mCAAmC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,yBAAyB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CACnK,CAAA;IACH,CAAC;IAED;;;;;;OAMG;aACY,kBAAa,GAAG,IAAI,GAAG,EAQnC,CAAA;aACqB,oBAAe,GAAG,MAAM,CAAA;IAChD;;;;;;;;;;;;OAYG;aACqB,iBAAY,GAAG,KAAK,CAAA;IAE5C,oEAAoE;IAC5D,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,QAAgB,EAAE,UAAkB;QACrE,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAClD,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,EAAE,MAAM,CAAA;IACzE,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,QAAgB,EAAE,UAAkB;QACzE,8DAA8D;QAC9D,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,eAAe;YAAE,OAAO,GAAG,CAAC,KAAK,CAAA;QACvE,IAAI,KAA4D,CAAA;QAChE,IAAI,MAA0D,CAAA;QAC9D,IAAI,CAAC;YACH,wDAAwD;YACxD,MAAM,GAAG,GAAQ,MAAM,IAAA,6BAAc,EAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAA;YAC5G,KAAK,GAAG,IAAA,8CAAsB,EAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;YACtD,6CAA6C;YAC7C,MAAM,GAAG,IAAA,uCAAmB,EAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;QACtD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAA,iBAAQ,EAAC,kBAAkB,UAAU,kFAAkF,EAAG,GAAW,EAAE,OAAO,CAAC,CAAA;QACjJ,CAAC;QACD,kEAAkE;QAClE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC9B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;QAC9D,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAA;YAC/C,IAAI,CAAC,MAAM,CAAC,IAAI;gBAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC3D,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED;;;;;;;;;;;;;OAaG;IACK,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,UAAkB,EAAE,IAAqB;QAC9F,IAAI,MAAW,CAAA;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;YACnH,MAAM,GAAG,GAAG,EAAE,gBAAgB,CAAA;QAChC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAA,iBAAQ,EAAC,kBAAkB,UAAU,6CAA6C,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;YACxG,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAA,mCAAY,EAAC,MAAM,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,gBAAuB,CAAC,CAAA;QAC5H,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC3B,+DAA+D;YAC/D,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC3B,IAAA,iBAAQ,EACN,kBAAkB,UAAU,+DAA+D,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI;oBAChJ,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,yEAAyE,CAAC,CAAC,CAAC,EAAE,CAAC,CAChH,CAAA;YACH,CAAC;YACD,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,qDAAqD;YACrD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;YAC/B,IAAI,CAAC,OAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC1C,IAAI,CAAC,OAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;YAC9B,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;YACxC,IAAA,2BAAW,EAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAA,4BAAY,GAAE,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;YAC1E,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACvF,IAAA,gBAAO,EACL,kBAAkB,UAAU,0CAA0C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,CACrJ,CAAA;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAA,iBAAQ,EAAC,kBAAkB,UAAU,mDAAmD,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;QAChH,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,UAAkB,EAAE,QAAa;QAC9E,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAA;QACzC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;QAC3F,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAA,iBAAQ,EAAC,kBAAkB,UAAU,iEAAiE,CAAC,CAAA;YACvG,OAAO,KAAK,CAAA;QACd,CAAC;QACD,GAAG,CAAC,gBAAgB,GAAG,IAAA,mCAAY,EAAC,GAAG,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAA;QACnE,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACpB,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,QAAgB,EAAE,UAAkB;QACtE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACnE,OAAO,MAAM,CAAC,IAAI,CAAE,QAAgB,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA;IACtD,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,UAAkB;QAC1D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;YAC1G,MAAM,KAAK,GAAQ,GAAG,EAAE,KAAK,CAAA;YAC7B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;YACnE,MAAM,MAAM,GAAG,IAAA,0CAAoB,EAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;YAC9G,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;QAClG,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ,CACnB,QAAgB,EAChB,MAAiD,EACjD,WAAmB,EACnB,iBAAyB;QAEzB;4CACoC;QACpC,MAAM,KAAK,GAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAA;QAC/C,IAAI,MAAM,CAAC,UAAU;YAAE,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;;YACtD,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;QACnC,MAAM,UAAU,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QAEpE,OAAO,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAA;YAC/D,MAAM,MAAM,GAAQ,EAAE,EAAE,MAAM,CAAA,CAAC,+BAA+B;YAC9D,IAAI,OAAO,MAAM,EAAE,QAAQ,KAAK,UAAU;gBAAE,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,aAAsB,EAAE,CAAA;YAEjI,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,CAAA;YACpE;yDAC6C;YAC7C,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM;gBAAE,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,eAAwB,EAAE,CAAA;YAC1H,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAA;QACjE,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAC/B,QAAgB,EAChB,MAAiD,EACjD,WAAmB,EACnB,iBAAyB,EACzB,MAA4C;QAE5C,MAAM,KAAK,GAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAA;QAC/C,IAAI,MAAM,CAAC,UAAU;YAAE,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;;YACtD,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;QACnC,MAAM,UAAU,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QAEpE,OAAO,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAA;YAC/D,MAAM,MAAM,GAAQ,EAAE,EAAE,MAAM,CAAA;YAC9B,IAAI,OAAO,MAAM,EAAE,oBAAoB,KAAK,UAAU,EAAE,CAAC;gBACvD,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,aAAsB,EAAE,CAAA;YACvF,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAC,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC,CAAA;YACtF,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM;gBAAE,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,eAAwB,EAAE,CAAA;YAC1H,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;QAC/D,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,kBAAkB,CAAC,QAAgB,EAAE,EAAU,EAAE,MAAW;QACzE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,CAAA;QAC9D,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,MAAM,IAAI,GAAG,IAAA,kCAAkB,EAAC,MAAM,CAAC,CAAA;QACvC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,mBAAmB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAM;QACzE,IAAI,OAAO,MAAM,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;YACnD,IAAA,iBAAQ,EACN,6BAA6B,EAAE,6EAA6E;gBAC1G,mEAAmE,CACtE,CAAA;YACD,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,8CAA8C;YAC9C,IAAA,iBAAQ,EAAC,6CAA6C,EAAE,4BAA4B,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;YAC1G,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG;YACd,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,8DAA8D,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,4BAA4B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,mBAAmB,0BAA0B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACZ,IAAA,gBAAO,EAAC,yBAAyB,EAAE,kBAAkB,OAAO,2CAA2C,CAAC,CAAA;IAC1G,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,EAAU,EAAE,QAAgB,EAAE,IAAY,EAAE,KAAmB,EAAE,aAA6B,EAAE,OAAgB,EAAE,UAAmB;QAChJ,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;QACpC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAEnD,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QAC9B,MAAM,MAAM,GAAe,IAAI,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAA;QACxF,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA,CAAC,0BAA0B;QACtD,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA,CAAC,6BAA6B;QACrE,8DAA8D;QAC9D,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,iBAAQ,EAAC,wCAAwC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;QAClI;;;;WAIG;QACH,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QAC/B,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;QACxC,IAAI,MAAM,IAAI,IAAI;YAAE,IAAA,gBAAO,EAAC,kBAAkB,EAAE,sBAAsB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9F;;;;;WAKG;QACH,IAAI,UAAU,IAAI,OAAQ,MAAc,CAAC,cAAc,KAAK,UAAU;YAAG,MAAc,CAAC,cAAc,CAAC,UAAU,CAAC,CAAA;QAClH;;;;;;;;WAQG;QACH,MAAM,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QACnC,MAAM,OAAO,GAAoB,IAAI,WAAW,CAAC,MAAM,CAAC,CAAA;QAExD,8EAA8E;QAC9E;;;;;;;WAOG;QACH,MAAM,IAAI,GAAoB;YAC5B,EAAE;YACF,QAAQ;YACR,IAAI,EAAE,KAAK;YACX,OAAO;YACP,MAAM;YACN,4DAA4D;YAC5D,aAAa,EAAE,IAAA,qCAAiB,EAAC,aAAa,EAAE,UAAU,EAAE,IAAI,CAAC;YACjE,OAAO,EAAG,KAAa,EAAE,OAAO;YAChC;;;;;;;;;eASG;YACH,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE;YAC1B,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;SAChB,CAAA;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;QAC1B,+DAA+D;QAC/D,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC1B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA,CAAC,mCAAmC;QAC9D,4DAA4D;QAC5D,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,iBAAQ,EAAC,kBAAkB,EAAE,gCAAgC,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC,CAAA;QAE1I,oEAAoE;QACpE,IAAA,qBAAa,EAAC,cAAM,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAEvG,+FAA+F;QAC/F,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,GAAwB,EAAE,EAAE;YACzD,IAAI,CAAC,cAAc,CACjB,YAAY,EACZ,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAG,GAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAChG,cAAc,EAAE,EAAE,CACnB,CAAA;YACD,kFAAkF;YAClF,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACzB;;;;;;;;;;;;;;;mBAeG;gBACH,CAAC;gBAAA,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAG,GAAW,CAAC,QAAQ,EAAE,CAAC,CAAA;gBAChH;;;;;;;;;;;mBAWG;gBACH,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;gBACjB,4CAA4C;gBAC5C,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;gBACtC,IAAI,CAAC,wBAAwB,EAAE,CAAA;YACjC,CAAC;QACH,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAA;QAEpC,mDAAmD;QACnD,IAAA,2BAAW,EAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAA,4BAAY,GAAE,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;QAE3E,qFAAqF;QACrF,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,kBAAS,EAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC,CAAA;QAE1H,2FAA2F;QAC3F,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,cAAc,CAC9B,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,EAC7C,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CACtB,CAAA;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;;;;;;;OAWG;IACH;;;;;;;;;OASG;IACH;;;;;;;;;OASG;IACK,MAAM,CAAC,gBAAgB,CAAC,KAA+B;QAC7D,MAAM,MAAM,GAAI,KAAa,EAAE,OAAO,CAAA;QACtC,IAAI,MAAM,IAAI,CAAE,KAAa,EAAE,cAAc,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,qFAAqF;gBACnF,gGAAgG,CACnG,CAAA;QACH,CAAC;QACD,OAAQ,KAAa,EAAE,cAAc,CAAA;IACvC,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAmB,EAAE,QAAgB,EAAE,OAAgB;QACpF,MAAM,GAAG,GAAG,OAAO,IAAK,KAAa,EAAE,OAAO,CAAA;QAC9C,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAA;QACtB,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QAC7H,MAAM,MAAM,GAAG,IAAA,iCAAW,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QAC3C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,KAAK,EAAE,QAAQ;gBAAE,IAAA,iBAAQ,EAAC,wBAAwB,GAAG,yBAAyB,KAAK,CAAC,QAAQ,gEAAgE,CAAC,CAAA;YACjK,OAAO,KAAK,CAAA;QACd,CAAC;QACD,OAAO,EAAE,GAAG,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC/C,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,EAAU,EAAE,QAAgB,EAAE,IAAY,EAAE,KAAmB;QAC9E,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;QACpC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACnD,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QAC9B,MAAM,MAAM,GAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAA;QACjF,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QAC3B;8DACsD;QACtD,eAAe,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,CAAC,CAAA;QAC5C,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA,CAAC,mCAAmC;QAC3E;2CACmC;QACnC,MAAM,SAAS,GAAG,EAAE,KAAK,EAAE,CAAC,CAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAA;QAC5G,MAAM,IAAI,GAAoB,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,mCAAc,EAAE,EAAE,OAAO,EAAG,KAAa,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAA;QACtL;;;;;;;;;;;;;WAaG;QACH,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAU,CAAA;QACtC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAoB,EAAE,EAAE;YACrD,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAW,CAAC;gBAAE,OAAO,0BAA0B;iBAC7F;YAAA,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC5D,mDAAmD;YACnD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;YACjB,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;YAC9B,IAAI,CAAC,wBAAwB,EAAE,CAAA;QACjC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAChB,yDAAyD;QACzD,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,iBAAQ,EAAC,wCAAwC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;QAClI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAA;QAChC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;QAC1B,0DAA0D;QAC1D,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,iBAAQ,EAAC,kBAAkB,EAAE,8BAA8B,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC,CAAA;QACxI;;;;;;;;;;WAUG;QACH,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;QAC7C,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAC1B,4DAA4D;QAC5D,IAAA,qBAAa,EAAC,cAAM,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QACvG;;;;;;;;;;;;;;;;;;;;WAoBG;QACH,IAAA,qBAAa,EAAC,yBAAS,CAAC;aACrB,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC;aAC7F,IAAI,CAAC,GAAG,CAAC,EAAE;YACV,MAAM,IAAI,GAAG,GAAG,EAAE,QAAQ,IAAI,CAAC,CAAA;YAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;YACpB,IAAI,CAAC,IAAI,IAAI,OAAQ,MAAc,CAAC,cAAc,KAAK,UAAU;gBAAE,OAAM;YACzE,IAAI,CAAC;gBACH,CAAC;gBAAC,MAAc,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;YACvC,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,qDAAqD;gBACrD,IAAA,iBAAQ,EAAC,kBAAkB,EAAE,mBAAmB,IAAI,2BAA2B,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;YACvG,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAA;QACnC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,kBAAS,EAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC,CAAA;QAChH,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,UAAU,CAAC,QAAgB,EAAE,EAAU,EAAE,SAA8B;QAC5E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;QACrD,IAAI,IAAI,EAAE,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,CAAA;QACtD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QACjC,gEAAgE;QAChE,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAW,CAAC,CAAA;YAC/D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YACvB,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA,CAAC,6BAA6B;QAClD,CAAC;QACD,IAAA,2BAAW,EAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAA,4BAAY,GAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAG5F;QAAA,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAA;QACvE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAAC,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,SAAS,CAAC,MAAM,CAAC;YAAC,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,SAAS,CAAC,MAAM,CAAA;QAAC,CAAC,CAAC,UAAU;QAC5H,mGAAmG;QACnG,8EAA8E;QAC9E,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACpC,IAAI,CAAC,wBAAwB,EAAE,CAAA;QAC/B,OAAO,SAAS,CAAC,MAAM,CAAA;IACzB,CAAC;IAED;;;;;;;;;;;OAWG;IACH;;;;OAIG;aACI,yBAAoB,GAAG,EAAE,CAAA;IAChC,gDAAgD;aACzC,wBAAmB,GAAG,CAAC,CAAA;IAC9B;;;;;;OAMG;aACI,oBAAe,GAAG,CAAC,CAAA;IAE1B;;;;;;OAMG;IACH,MAAM,CAAC,cAAc,CAAC,IAAqB,EAAE,MAAc;QACzD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;YAAE,OAAM,CAAC,gBAAgB;QAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;YAC3B,OAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,IAAA,kCAAe,EAAC,CAAC,CAAC,CAAA;YAClC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;gBAC3B,OAAM;YACR,CAAC;YACD,KAAK,MAAM,GAAG,IAAI,OAAO;gBAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACrD,CAAC;IACH,CAAC;IAED,kEAAkE;aAC3D,0BAAqB,GAAG,GAAG,CAAA;IAClC;;;;;;;;;;;;OAYG;aACI,8BAAyB,GAAG,IAAI,CAAA;IACvC,gEAAgE;aACzD,yBAAoB,GAAG,GAAG,CAAA;IACjC,4DAA4D;aACrD,sBAAiB,GAAG,GAAG,CAAA;IAC9B,+BAA+B;aACxB,sBAAiB,GAAG,CAAC,CAAA;IAG5B,wFAAwF;IAChF,MAAM,CAAC,wBAAwB;QACrC,IAAI,IAAI,CAAC,cAAc;YAAE,OAAM;QAC/B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,qBAAqB,CAAA;QACnD,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAC3F,IAAI,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,KAAK,UAAU;YAAE,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA,CAAC,SAAS;IAC5F,CAAC;IAED;;;;;;OAMG;IACK,MAAM,CAAC,qBAAqB,CAAC,OAAe;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAA;QACrC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC,oBAAoB,CAAA;QAC/C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAA;QACpB,IAAI,IAAI,GAAG,MAAM,CAAA;QACjB,IAAI,OAAO,GAAG,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC,yBAAyB,EAAE,CAAC;YAC9D,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,yBAAyB,EAAE,MAAM,GAAG,CAAC,CAAC,CAAA;YAC3D,IAAI,CAAC,iBAAiB,EAAE,CAAA;YACxB,IAAA,iBAAQ,EACN,kCAAkC,MAAM,QAAQ,IAAI,uBAAuB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,UAAU,CACxJ,CAAA;QACH,CAAC;aAAM,IAAI,OAAO,GAAG,GAAG,IAAI,MAAM,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAChE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;QACrE,CAAC;QACD,IAAI,IAAI,KAAK,MAAM;YAAE,OAAM;QAE3B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAA;QAC7B,IAAI,IAAI,CAAC,cAAc;YAAE,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QAC3D,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,IAAI,CAAC,CAAA;QACzE,IAAI,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,KAAK,UAAU;YAAE,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;IAClF,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,mBAAmB;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QACpC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACjD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,CAAA;YACnC;;;;;;;eAOG;YACH,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;YACtB,IAAI,CAAC,EAAE,CAAC;gBACN,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,cAAc,CAAC,GAAG,IAAI,CAAA;gBAC1C,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;oBACZ,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,GAAG,EAAE,CAAC,CAAA;oBAC5C,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAA;oBAC9D,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC,CAAA;oBAC9C,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;oBAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC;oBAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;oBAAC,CAAC,CAAC,cAAc,GAAG,GAAG,CAAA;gBAClF,CAAC;YACH,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,KAAK;gBAAE,SAAQ;YACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;YAClB,wDAAwD;YACxD,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;YACnD,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;gBACd,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAA;gBAC5B,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,oBAAoB,CAAA;YACzD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAA;YACpC,CAAC;YACD,2CAA2C;YAC3C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAA;YAC5B,IAAI,CAAC,EAAE,CAAC;gBAAC,CAAC,CAAC,cAAc,EAAE,CAAC;gBAAC,CAAC,CAAC,aAAa,EAAE,CAAA;YAAC,CAAC;YAChD,yDAAyD;YACzD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;YACvB;uEAC2D;YAC3D,IAAI,CAAC,MAAM;gBAAE,SAAQ;YACrB,sFAAsF;YACtF,qFAAqF;YACrF,wEAAwE;YACxE,IAAI,CAAC,cAAc,CACjB,YAAY,EACZ,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,EAAE,EACnF,cAAc,IAAI,CAAC,EAAE,EAAE,CACxB,CAAA;QACH,CAAC;QACD;6DACqD;QACrD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YAC/D,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YAClC,IAAI,CAAC,cAAc,GAAG,SAAS,CAAA;YAC/B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,qBAAqB,CAAA;YACnD,OAAM;QACR,CAAC;QACD,4DAA4D;QAC5D,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,CAAA;IAC5D,CAAC;IAED;;;;OAIG;IACH,uDAAuD;IAC/C,MAAM,CAAC,gBAAgB,CAAC,CAAM;QACpC,IAAI,CAAC,YAAY,IAAI;YAAE,OAAO,CAAC,CAAA;QAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;QACrD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAA;IAClD,CAAC;IAEO,MAAM,CAAC,UAAU,CAAC,IAAS,EAAE,QAAgB,EAAE,UAAkB,EAAE,CAAM,EAAE,QAAgB,EAAE,YAAqB;QACxH,OAAO,IAAI,CAAC,MAAM,CAAC;YACjB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS;YAC/B,UAAU;YACV,SAAS,EAAE,CAAC,EAAE,SAAS;YACvB,+CAA+C;YAC/C,aAAa,EAAE,CAAC,EAAE,aAAa;YAC/B,QAAQ;YACR;4DACgD;YAChD,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC;YACvD;8DACkD;YAClD,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,SAAS,CAAC;YAC9C,GAAG,IAAA,kCAAa,EAAC,CAAC,CAAC;YACnB,OAAO,EAAE,CAAC;SACX,CAAC,CAAA;IACJ,CAAC;IAED;;;;;OAKG;IACH,kEAAkE;aACnD,sBAAiB,GAAkC,EAAE,CAAA;IACpE,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAgB,EAAE,UAAkB;QAC9D,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAA;QAC1C;;;WAGG;QACH,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAA;QACrE,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;QACtI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;QACxD,OAAO,MAAM,EAAE,GAAG,CAAA;IACpB,CAAC;IAED,2DAA2D;IACnD,MAAM,CAAC,UAAU;QACvB,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;IAC7M,CAAC;IAED;;;;;;;;;;;OAWG;IACK,MAAM,CAAC,YAAY,CAAC,IAAqB;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAA;QACjC,IAAI,CAAC,KAAK,EAAE,MAAM;YAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;QAC5C,IAAI,CAAC,cAAc,GAAG,EAAE,CAAA;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;QACtB;sDAC8C;QAC9C,IAAI,CAAC,EAAE,CAAC;YAAC,CAAC,CAAC,cAAc,IAAI,KAAK,CAAC,MAAM,CAAC;YAAC,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC;YAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,CAAA;QAAC,CAAC;QAExH,kDAAkD;QAClD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAA;QACtH,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAA;QAEvH,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QAClC,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,IAAA,2BAAW,EAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAA,4BAAY,GAAE,CAAC,EAAE,SAAS,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAA;QAClH,MAAM,IAAI,GAAoB,EAAE,CAAA;QAEhC,IAAI,OAAO,CAAC,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAA;QACnF,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAA;YAC3B,IAAI,CAAC,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC,MAAM,CAAA;YACpC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;QACpE,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;QAC1C;;;;WAIG;QACH,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;QAC7C,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;aACrB,IAAI,CAAC,GAAG,EAAE;YACT,IAAI,EAAE,CAAA;YACN;;;eAGG;YACH,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QAC1D,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,kBAAS,EAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC,CAAA;IAC5D,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAgB,EAAE,UAAkB,EAAE,KAAyC;QACzG,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAA;QACrC,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACpE,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAA;QAC9G,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACnC,CAAC;IAED;;;;;;;;;OASG;IACK,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAS,EAAE,IAAW;QACpD,MAAM,KAAK,GAAG,GAAG,CAAA;QACjB;;;;;;;;;;;;;;;;;;;WAmBG;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,KAAK;YAAE,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAA;IAC1F,CAAC;IAED,mGAAmG;IACnG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,QAAgB,EAAE,UAAkB,EAAE,SAAgB,EAAE,aAAqB;QACrG,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAA;QACrC,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACpE,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,GAAG,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,CAAC,CAAA;QACzH,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACnC,CAAC;IAED,yFAAyF;IACzF,MAAM,CAAC,KAAK,CAAC,QAAQ,CACnB,QAAgB,EAChB,UAAkB,EAClB,IAAY,EACZ,KAAmB,EACnB,SAAgC,SAAS,EACzC,aAA6B,EAC7B,MAAY;IACZ;;;;OAIG;IACH,IAAsE;QAEtE,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAA;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;QACxF,MAAM,IAAI,CAAC,IAAI,CACb,IAAI,CAAC,MAAM,CAAC;YACV,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;YACnB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS;YAC/B,UAAU;YACV,IAAI;YACJ,KAAK;YACL,iGAAiG;YACjG,OAAO,EAAG,KAAa,EAAE,OAAO,IAAI,QAAQ,EAAE,OAAO;YACrD,MAAM,EAAG,KAAa,EAAE,MAAM,IAAI,QAAQ,EAAE,MAAM;YAClD;;sEAE0D;YAC1D,aAAa,EACX,aAAa;gBACb,IAAA,qCAAiB,EACf,QAAQ,EAAE,aAAa,EACvB,aAAa,UAAU,iEAAiE,CACzF;YACH;uDAC2C;YAC3C,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,aAAa;YAC3C;qEACyD;YACzD,MAAM,EAAE,MAAM,IAAI,QAAQ,EAAE,MAAM,IAAI,IAAI;YAC1C,uDAAuD;YACvD,IAAI,EAAE,QAAQ,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI;YAC1C,WAAW,EAAE,QAAQ,EAAE,WAAW,IAAI,IAAI,EAAE,WAAW,IAAI,IAAI;YAC/D,6CAA6C;YAC7C,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,EAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjF,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,EAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,MAAM;SACP,CAAC,CACH,CAAA;IACH,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,QAAgB,EAAE,UAAkB;QAClE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;QAC7D,MAAM,IAAI,GAAG,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,CAAA;QAC1C,IAAI,CAAC,IAAI,EAAE,SAAS;YAAE,OAAM;QAC5B,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAA;QACxC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;QACnF,IAAI,CAAC,GAAG,EAAE,KAAK;YAAE,OAAM;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAqB,CAAA;QACvC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS;aACzB,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aACpC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;QAC1E,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAM;QACzB,KAAK,CAAC,SAAS,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,CAAA;QACxD,GAAG,CAAC,KAAK,GAAG,KAAK,CAAA;QACjB,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACtB,CAAC;IAED;;;;OAIG;IACH;;;;;;OAMG;IACK,MAAM,CAAC,gBAAgB,CAAC,QAAgB,EAAE,UAAkB;QAClE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAAE,OAAM;QAC7D;;;;;;WAMG;QACH,MAAM,GAAG,GAAQ,IAAI,KAAK,CAAC,aAAa,UAAU,4CAA4C,CAAC,CAAA;QAC/F,GAAG,CAAC,IAAI,GAAG,cAAc,CAAA;QACzB,GAAG,CAAC,MAAM,GAAG,EAAE,UAAU,EAAE,CAAA;QAC3B,MAAM,GAAG,CAAA;IACX,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,KAAK,CAAC,cAAc,CACzB,QAAgB,EAChB,UAAkB,EAClB,KAAmB,EACnB,OAAgB,EAChB,MAAY;QAEZ,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;QAC7D,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,UAAU,qDAAqD,CAAC,CAAA;QACxG,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YACtB,MAAM,IAAI,KAAK,CAAC,aAAa,UAAU,+FAA+F,CAAC,CAAA;QAEzI,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;QAC1G,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,UAAU,0EAA0E,CAAC,CAAA;QAE5H,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QAC5E,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;QACxF;wCACgC;QAChC,MAAM,KAAK,GAAmB,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;QAC/D;;;;WAIG;QACH,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAA;QAEpD;;;;;;;;;WASG;QACH,MAAM,IAAA,uCAAgB,EAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,GAAQ,EAAE,EAAE,CACjF,IAAA,iBAAQ,EAAC,kBAAkB,UAAU,yEAAyE,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CACrI,CAAA;QAED;;;;;;;;;;;WAWG;QACH,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,kDAAkD;QAClD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QACzB,IAAI,CAAC,wBAAwB,EAAE,CAAA;QAE/B,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,CAAA;IAC1B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,SAAS,CACpB,QAAgB,EAChB,UAAkB,EAClB,IAAY,EACZ,KAAmB;IACnB;;;;;;OAMG;IACH,aAA4B,EAC5B,OAAgB,EAChB,MAAY;IACZ,iEAAiE;IACjE,IAAsE;QAEtE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC3C;6CACqC;QACrC,SAAS,CAAC,IAAI,CAAC,CAAA;QACf,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAA;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;QAExF;;;;;;;;;;WAUG;QACH,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QAChE,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,QAAQ,EAAE,MAAc,IAAI,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;IAC1K,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,UAAkB,EAAE,KAAmB,EAAE,OAAgB;QACtG,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAA;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAA;QAClD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;QAE9G;;;;;;;;;WASG;QACH,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,KAAqB,CAAC,KAAK,SAAS,EAAE,CAAC;YACtH,MAAM,CAAC,SAAS,GAAG,SAAS,CAAA;YAC5B,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACzB,CAAC;QAED,IAAI,MAAM,EAAE,SAAS,KAAK,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,iBAAiB,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAA;YACrE,OAAO,MAAM,CAAC,GAAG,CAAA;QACnB,CAAC;QAED,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QAClC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,KAAY,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QACnJ,IAAI,CAAC,iBAAiB,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,GAAG,GAAG,CAAA;QAC9D,0DAA0D;QAC1D,OAAO,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;QACvD,IAAI,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,kBAAkB,UAAU,kCAAkC,GAAG,oDAAoD,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;QAC7J,OAAO,GAAG,CAAA;IACZ,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAC3B,QAAgB,EAChB,UAAkB;QAElB,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;QAChI,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAA;QAE3B,yDAAyD;QACzD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAA;QAC/C,KAAK,MAAM,GAAG,IAAI,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC;aAC7C,kBAAkB,CAAC,GAAG,CAAC;aACvB,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC;aAC/B,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC;aAC1B,KAAK,CAAC,sBAAsB,EAAE,EAAE,QAAQ,EAAE,CAAC;aAC3C,QAAQ,CAAC,4BAA4B,EAAE,EAAE,UAAU,EAAE,CAAC;aACtD,OAAO,CAAC,gBAAgB,CAAC;aACzB,UAAU,EAAE;YACb,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAE/F,iEAAiE;QACjE,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEpC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACzB,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAClE,IAAI,EAAE,IAAA,kCAAc,EAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAa,EAAE,CAAC,CAAC,KAAY,CAAC;SACvF,CAAC,CAAC,CAAA;IACL,CAAC;IAED,mDAAmD;IACnD,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,QAAgB,EAAE,UAAkB,EAAE,KAAoB;QACzF,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;QACtI,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC,GAAG,CAAA;QAC7B,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC9E,CAAC;IAED,6DAA6D;IAC7D;;;;;;OAMG;IACK,MAAM,CAAC,oBAAoB,CAAC,KAAmB;QACrD,OAAO,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAClF,CAAC;IAEO,MAAM,CAAC,kBAAkB,CAAC,KAAmB;QACnD,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;aAC3C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;aAC3C,IAAI,EAAE;aACN,IAAI,CAAC,GAAG,CAAC,CAAA;QACZ,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;aAC3C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;aAC/C,IAAI,EAAE;aACN,IAAI,CAAC,GAAG,CAAC,CAAA;QACZ,OAAO,KAAK,SAAS,MAAM,SAAS,GAAG,CAAA;IACzC,CAAC;IAED,mEAAmE;IACnE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,QAAgB,EAAE,UAAkB,EAAE,aAA6B;QAChG,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC5C,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACnD,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;QAC1G,IAAI,CAAC,GAAG,EAAE,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,UAAU,8BAA8B,CAAC,CAAA;QAEvF;;;;;;;;;;;;;;;;;;;WAmBG;QACH,MAAM,MAAM,GAAG,aAAa,IAAI,IAAA,qCAAiB,EAAC,GAAG,CAAC,aAAa,EAAE,SAAS,UAAU,GAAG,CAAC,CAAA;QAC5F,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB;+CACmC;YACnC,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAqB,EAAE,QAAQ,CAAC,CAAC,CAAA;QAC1H,CAAC;QACD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB;;;;;;eAMG;YACH,IAAI,GAAG,CAAC,OAAO,KAAK,OAAO;gBAAE,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC5E,CAAC;QAED;;;;;;WAMG;QACH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;YAC9E,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;gBAClB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAA;YAC1E,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;gBACxE,IAAI,KAAK;oBAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAA;YACtE,CAAC;QACH,CAAC;QAED;;;;;;WAMG;QACH,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC;aACxC,kBAAkB,CAAC,GAAG,CAAC;aACvB,MAAM,CAAC,iBAAiB,EAAE,KAAK,CAAC;aAChC,KAAK,CAAC,sBAAsB,EAAE,EAAE,QAAQ,EAAE,CAAC;aAC3C,QAAQ,CAAC,4BAA4B,EAAE,EAAE,UAAU,EAAE,CAAC;aACtD,SAAS,EAAE,CAAA;QAEd,OAAO,IAAI,CAAC,KAAK,CACf,UAAU,EACV,QAAQ;QACR;8EACsE;QACtE,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,KAAqB;QACzB,oEAAoE;QACpE,MAAM,EACN,GAAG,CAAC,OAAO,EACX,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAC5B,CAAA;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,QAAgB,EAAE,UAAkB,EAAE,IAAmB;QACjF,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;YAC1G,IAAI,CAAC,GAAG,EAAE,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,aAAa,UAAU,8BAA8B,CAAC,CAAA;YACvF,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAqB,CAAC,CAAA;QAClF,CAAC;QACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB;;;;;;;;;;;eAWG;YACH,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;QAC/D,CAAC;QACD,iDAAiD;QACjD,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC7C,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IAC9D,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,QAAgB,EAAE,UAAkB;QAC5D,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,UAAU,EAAE,CAAC,CAAA;QACtF,OAAO,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;QACvD;;;;;;;;;;WAUG;QACH,MAAM,4BAAY;aACf,UAAU,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,cAAc,CAAC;aAC/G,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,iBAAQ,EAAC,kBAAkB,UAAU,kEAAkE,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC,CAAA;QAC9I,MAAM,4BAAY;aACf,UAAU,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,cAAc,CAAC;aACvG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,iBAAQ,EAAC,kBAAkB,UAAU,yEAAyE,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC,CAAA;IACvJ,CAAC;IAED,iDAAiD;IACjD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,UAAkB;QACtD,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACrC,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACzC,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,UAAU,EAAE,CAAC,CAAA;QACtF,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,UAAU,EAAE,CAAC,CAAA;IAC3F,CAAC;IAED;;;;;;;;;OASG;IACK,MAAM,CAAC,cAAc,CAAC,QAAgB,EAAE,UAAkB;QAChE,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAC1B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC9B,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAA;IACpC,CAAC;IAED,qEAAqE;IACrE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAgB;QAChC,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAA;QAC5F;;;;;WAKG;QACH,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,CAAC,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAC7G,CAAA;QACD;;;;;;;;;;;;;;;;;;;;;;WAsBG;QACH,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAA;QAC/C,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,GAAG,CAAC,KAAK,EAAC,CAAC,EAAC,EAAE;YACjB,IAAI,CAAC;gBACH;;;;;;;;;;;mBAWG;gBACH,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC;qBACvC,kBAAkB,CAAC,GAAG,CAAC;qBACvB,MAAM,CAAC,iBAAiB,EAAE,UAAU,CAAC;qBACrC,KAAK,CAAC,sBAAsB,EAAE,EAAE,QAAQ,EAAE,CAAC;qBAC3C,QAAQ,CAAC,4BAA4B,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC;qBACpE,SAAS,EAAyB,CAAA;gBACrC,2DAA2D;gBAC3D,IAAI,GAAG,EAAE,QAAQ,IAAI,IAAI;oBAAE,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;YAC/F,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB;;mEAEmD;gBACnD,IAAA,kBAAS,EAAC,gDAAgD,CAAC,CAAC,UAAU,GAAG,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAA;YACjG,CAAC;QACH,CAAC,CAAC,CACH,CAAA;QAED,MAAM,GAAG,GAAU,EAAE,CAAA;QACrB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,KAAK,GAAI,CAAC,CAAC,KAAsB,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAA;YAC3E,GAAG,CAAC,IAAI,CAAC;gBACP,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB;;;;mBAIG;gBACH,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS;gBACzB,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,SAAS;gBACvC,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,wDAAwD;gBAC5E,iEAAiE;gBACjE,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,SAAS;gBAC5E,aAAa,EAAE,CAAC,CAAC,aAAa,EAAE,+DAA+D;gBAC/F,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,qDAAqD;gBACzE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,SAAS;gBAC7B,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;gBAC7D;;;;;;mBAMG;gBACH,sDAAsD;gBACtD,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,SAAS;gBAC7E,QAAQ,EAAE,IAAA,uCAAe,EAAC;oBACxB,aAAa,EAAE,CAAC,CAAC,aAAa;oBAC9B,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;oBAC7D,UAAU,EAAE,CAAC,CAAC,UAAU;iBACzB,CAAC;gBACF,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;gBAC9C;;;;;;mBAMG;gBACH,aAAa,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,MAAM;gBAC/C,cAAc,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,MAAM;aACjD,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,gDAAgD;IAChD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,QAAgB;QACtC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACpI,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAA;QAC7F,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsG,CAAA;QACzH,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB;wEAC4D;YAC5D,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO;gBAAE,SAAQ;YACjD,MAAM,KAAK,GAAQ,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;YAChC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAA;YAC1I,CAAC,CAAC,SAAS,EAAE,CAAA;YACb,+DAA+D;YAC/D,CAAC,CAAC,SAAS,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC,MAAM,CAAA;YAC/C,CAAC,CAAC,SAAS,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC,MAAM,CAAA;YAC/C,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACvB,CAAC;QACD,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;IAC1B,CAAC;IAED,2DAA2D;IAC3D,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,UAAkB,EAAE,OAAgC,EAAE,MAAe;QAC7G,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,EAAS,CAAC,CAAA;IACvI,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAgB,EAAE,OAAe;QAO3D,MAAM,EAAE,GAAG,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QACnG,MAAM,KAAK,GAAG,EAAE;YACd,CAAC,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,uBAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACpN,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QACtG,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,IAAI,CAAA;QAC9B,OAAO;YACL,IAAI,EAAE,EAAE,EAAE,IAAI;YACd,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,uBAAuB,EAAE,EAAE,EAAE,uBAAuB,EAAE;YACzH,KAAK;YACL,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;SACxF,CAAA;IACH,CAAC;IAED,0FAA0F;IAC1F,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,OAAe;QACxD,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QACtG,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,sDAAuB,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;YAChI,KAAK,MAAM,GAAG,IAAI,IAAI;gBAAE,MAAM,IAAA,qBAAa,EAAC,kCAAa,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAS,EAAE,CAAC,CAAA;YAC7I,MAAM,IAAA,qBAAa,EAAC,sDAAuB,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAS,EAAE,CAAC,CAAA;YACxH,MAAM,IAAA,qBAAa,EAAC,uBAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAS,EAAE,CAAC,CAAA;QAC3G,CAAC;QACD,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,OAAO,EAAE,CAAC,CAAA;IACrF,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAK,CAAC,YAAY,CACvB,QAAgB,EAChB,MAAuB;IACvB,sEAAsE;IACtE,aAA4B,EAC5B,IAA2B;IAC3B,0DAA0D;IAC1D,KAAsB;QAEtB;;;;;;;;;;;;WAYG;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;QACnE,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM;YAAE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QAEtF,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,IAAA,kCAAY,EAAC,MAAM,EAAE,cAAc,CAAC,CAAA;QAC9E;;;;;;;;WAQG;QACH,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QAC3H;;;;WAIG;QACH,MAAM,YAAY,GAAG,KAAK,EAAE,OAAO,IAAK,KAAa,EAAE,OAAO,CAAA;QAC9D,MAAM,QAAQ,GAAG,YAAY;YAC3B,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,CAAC;YACxG,CAAC,CAAC,IAAI,CAAA;QACR,IAAI,KAAK,EAAE,iBAAiB,IAAI,QAAQ,EAAE,iBAAiB,EAAE,CAAC;YAC5D,MAAM,OAAO,GAAG,IAAA,8CAAsB,EAAC,KAAY,EAAE,QAAQ,EAAE,iBAAwB,EAAE,KAAK,EAAE,iBAAwB,CAAC,CAAA;YACzH,MAAM,CAAC,MAAM,CAAC,KAAY,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;YAC1C;;;;eAIG;YACH,IAAI,KAAK,EAAE,CAAC;gBACV,KAAK,CAAC,iBAAiB,GAAG,OAAO,CAAC,oBAA2B,CAAA;gBAC7D,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAC/C,CAAC;YACD,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAwB,CAAA;gBAC7D,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC/C,CAAC;YACD;;;eAGG;YACH,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,EAAE,CAAC;gBAC3E,QAAQ,CAAC,IAAI,CAAC,IAAA,yCAAmB,EAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;YACtF,CAAC;QACH,CAAC;QACD,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAA;QACrC;kDAC0C;QAC1C,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QAC3C,MAAM,YAAY,GAAG,MAAM;YACzB,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC;YAClF,CAAC,CAAC,KAAK,CAAA;QACT,MAAM,MAAM,GAAG,IAAA,oCAAkB,EAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,CAAA;QACtE,MAAM,OAAO,GAAW,MAAM,CAAC,OAAO,CAAA;QACtC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAA,CAAC,4BAA4B;QACpD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QACrF,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB;iDACqC;QACvC,CAAC;QACD;;;;;;WAMG;QACH,MAAM,GAAG,GAAQ,YAAY,CAAA;QAC7B,MAAM,QAAQ,GAAG,QAAQ,EAAE,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAA;QAC5D,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAChC,IAAI,CAAC,MAAM,CAAC;YACV,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;YACnB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS;YAC/B,OAAO;YACP,IAAI,EAAE,QAAQ,EAAE,IAAI,IAAI,MAAM,CAAC,QAAQ;YACvC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,GAAG,CAAC,KAAK;YACvC,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,GAAG,CAAC,KAAK;YACvC,GAAG,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG;YAC7B;;;;;eAKG;YACH,uBAAuB,EAAE,QAAQ,EAAE,uBAAuB,IAAI,IAAI;SACnE,CAAC,CACH,CAAA;QACD;;;;WAIG;QACH,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAC,sDAAuB,CAAC,CAAA;QACtD,MAAM,QAAQ,GAAG,IAAA,qBAAa,EAAC,kCAAa,CAAC,CAAA;QAC7C,IAAI,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7E,MAAM,IAAI,GAAW,YAAoB,CAAC,eAAe,IAAI,EAAE,CAAA;YAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;gBACnB,MAAM,MAAM,GACV,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE;oBAC3D,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;wBACjD,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;4BACzF,CAAC,CAAC,EAAE,CAAA;gBACN,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAS,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,EAAE,KAAM,YAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;gBACrP,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAU,EAAE,CAAC;oBAC9C,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC,CAAA;gBAC3Q,CAAC;YACH,CAAC;YACD;;;eAGG;YACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAS,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;YAC5I,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAA;YACxD,IAAI,OAAO,IAAI,UAAU,CAAC,uBAAuB,KAAK,OAAO,CAAC,EAAE,EAAE,CAAC;gBACjE,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,uBAAuB,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;gBACpF,2DAA2D;gBAC3D,KAAK,MAAM,CAAC,IAAI,KAAK;oBAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC;wBAAE,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;YAClJ,CAAC;QACH,CAAC;QACD;;;;WAIG;QACH,MAAM,YAAY,GAAG,IAAA,qBAAa,EAAC,uBAAQ,CAAC,CAAA;QAC5C,KAAK,MAAM,CAAC,IAAI,CAAE,YAAoB,CAAC,KAAK,IAAI,EAAE,CAAU,EAAE,CAAC;YAC7D,IAAI,CAAC,CAAC,EAAE,EAAE;gBAAE,SAAQ;YACpB,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;YACpI,MAAM,YAAY,CAAC,IAAI,CACrB,YAAY,CAAC,MAAM,CAAC;gBAClB,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;gBACvB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS;gBAC/B,KAAK,EAAE,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAS;gBACnC,MAAM,EAAE,CAAC,CAAC,EAAE;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE;gBACpB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;gBAC5B,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;aAC/E,CAAC,CACH,CAAA;QACH,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ;8DACkD;YAClD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACjG,QAAQ,CAAC,IAAI,CAAC,IAAA,sCAAgB,EAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;QACnD,CAAC;aAAM,CAAC;YACN,yDAAyD;YACzD,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;gBAC3G,IAAI,EAAE,MAAM,CAAC,QAAQ;gBACrB,WAAW,EAAG,MAAc,CAAC,WAAW;gBACxC,KAAK;aACN,CAAC,CAAA;QACJ,CAAC;QAED;;;;;;WAMG;QACH,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,IAAA,uCAAgB,EAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACvF,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,cAAc;gBAAE,QAAQ,CAAC,IAAI,CAAC,IAAA,yCAAmB,EAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC,CAAA;YAC7G,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,cAAc;gBAAE,QAAQ,CAAC,IAAI,CAAC,IAAA,yCAAmB,EAAC,eAAe,EAAE,GAAG,CAAC,CAAC,CAAA;YACpG;;;eAGG;YACH,IAAK,KAAa,EAAE,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBACnD,KAAK,MAAM,CAAC,IAAI,CAAE,KAAa,EAAE,SAAS,IAAI,EAAE,CAAU,EAAE,CAAC;oBAC3D,MAAM,UAAU,GAAI,CAAC,CAAC,EAAE,UAAU,IAAI,EAAE,CAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,0BAAY,CAAC,eAAe,IAAI,MAAM,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;oBAC9I,IAAI,UAAU;wBAAE,QAAQ,CAAC,IAAI,CAAC,IAAA,+CAAyB,EAAC,MAAM,CAAE,KAAa,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC/G,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAA,kBAAS,EAAC,kDAAkD,MAAM,CAAC,MAAM,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;YAC5F,QAAQ,CAAC,IAAI,CAAC,IAAA,sCAAgB,EAAC,GAAG,EAAE,OAAO,IAAI,SAAS,CAAC,CAAC,CAAA;QAC5D,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM;YAAE,IAAA,iBAAQ,EAAC,yBAAyB,MAAM,CAAC,MAAM,eAAe,IAAA,sCAAgB,EAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;QAChH,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;IACzD,CAAC;IAED,kDAAkD;IAClD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,UAAkB;QACtD,MAAM,CAAC,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;QACxG,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QACnB,OAAO;YACL,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;YAC7D,aAAa,EAAE,CAAC,CAAC,aAAa,EAAE,iDAAiD;YACjF,KAAK,EAAE,CAAC,CAAC,KAAK;SACf,CAAA;IACH,CAAC;IAED;;;;OAIG;IACH,uDAAuD;aACxC,iBAAY,GAAG,IAAI,GAAG,EAAgD,CAAA;aAC7D,wBAAmB,GAAG,MAAM,CAAA;IAEpD;;;;;;;;;;OAUG;IACK,MAAM,CAAC,cAAc,CAAC,OAA8B,EAAE,OAAY,EAAE,IAAY;QACtF,IAAI,CAAC;YACH,cAAM,CAAC,OAAO,CAAC,OAAc,EAAE,OAAO,CAAC,CAAA;YACvC,OAAO,IAAI,CAAA;QACb,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAA;YACnE,CAAC,CAAC,KAAK,EAAE,CAAA;YACT,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YACtB,IAAI,GAAG,GAAG,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAClD,CAAC,CAAC,SAAS,GAAG,GAAG,CAAA;gBACjB,IAAA,iBAAQ,EAAC,uCAAuC,IAAI,MAAM,CAAC,CAAC,KAAK,cAAc,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;YACvG,CAAC;YACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;YAC9B,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,IAAqB;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,4FAA4F;QAC5F,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAA,4BAAY,GAAE,CAAC,CAAA;QAEtD,4CAA4C;QAC5C,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QAC/B,MAAM,EAAE,GACN,IAAI,CAAC,IAAI,KAAK,MAAM;YAClB,CAAC,CAAC,IAAI,CAAC,GAAG;gBACR,CAAC,CAAC,IAAA,gCAAW,EAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,uDAAuD;gBAC7G,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE;YAChC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,CAAA;QACrC,IAAA,2BAAW,EAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAA;QACxD,IAAI,CAAC,EAAE;YAAE,OAAM;QACf;;;;WAIG;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,EAAE,CAAC,CAAA;QAC7D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B;sDAC8C;QAC9C,6DAA6D;QAC7D,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QAChC;;;;;;;;;;;WAWG;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAA;QAC/D,MAAM,MAAM,GAAG,IAAA,mCAAiB,EAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,UAAW,EAAE,CAAC,CAAA;QAC7F,IAAI,CAAC,eAAe,EAAE,CAAA;QACtB,IAAI,IAAI;YAAE,IAAI,CAAC,mBAAmB,EAAE,CAAA;QACpC,uCAAuC;QACvC,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,EAAE,CAAA;QAC3B,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAA;QAC7B,IAAA,2BAAW,EAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAA;QAEvD,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QAC9B,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACb,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YAChC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG;gBAAE,SAAQ,CAAC,cAAc;YAClD,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;YAClB;;;eAGG;YACH,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,IAAI,CAAC,EAAE,EAAE,CAAC;gBAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACxG,CAAC;QACD,IAAA,2BAAW,EAAC,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;QACtD;;;;;WAKG;QACH,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI;YAAE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE;gBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACxG,CAAC;IAED;;;;;OAKG;IAEH;;;;;;;OAOG;IACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAgB,EAAE,UAAkB,EAAE,aAAsB,EAAE,SAAkB;QACnG,mDAAmD;QACnD,iFAAiF;QACjF,IAAI,aAAa,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;YAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;YAC7D,IAAI,IAAI,EAAE,MAAM,EAAE,WAAW;gBAAE,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAA;YAC/D,mFAAmF;YACnF,gDAAgD;YAChD,IAAI,IAAI,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS;gBAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACzF,CAAC;QACD;;;;;;;;;WASG;QACH,MAAM,WAAW,GAAG,aAAa,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI,CAAA;QAC9D,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACzF,2DAA2D;QAC3D,MAAM,eAAe,GAAG,WAAW,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACnH,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,IAAA,2BAAW,EAAC,eAAe,CAAC,KAAK,CAAC,CAAA;YAChD,IAAI,KAAK,IAAI,CAAC,eAAe,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,GAAI,CAAC,QAAQ,IAAI,CAAC,eAAe,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,GAAI,CAAC,YAAY;gBAC5H,OAAO,KAAK,CAAA;QAChB,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;QAC1G,IAAI,CAAC,GAAG,EAAE,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,UAAU,uCAAuC,CAAC,CAAA;QAErG;;;;;;;;;;;WAWG;QACH;;;;;WAKG;QACH,MAAM,cAAc,GAAG,WAAW;YAChC,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;QACjH,MAAM,QAAQ,GACZ,CAAC,WAAW,IAAI,cAAc,IAAI,CAAC;YACjC,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE;gBAC5C,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,GAAG,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACxG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;YACtB,CAAC,CAAC,IAAI,CAAA;QACV,MAAM,MAAM,GACV,WAAW,IAAI,GAAG,IAAI,eAAe,IAAI,eAAe,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,YAAY;YAC1H,CAAC,CAAC,eAAe;YACjB,CAAC,CAAC,QAAQ,CAAA;QAEd;;;;;;;;;;WAUG;QACH,MAAM,QAAQ,GAAG,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;QAChE,MAAM,OAAO,GAAG,SAAS,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAC5D,MAAM,SAAS,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAA;QAC1D,qDAAqD;QACrD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACxD;;;WAGG;QACH,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,IAAI,CAAC;YAC/C,KAAK,EAAE,OAAO;gBACZ,CAAC,CAAC,IAAI;oBACJ,CAAC,CAAC,6DAA6D;wBAC7D;4BACE,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,IAAA,kBAAQ,EAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAA,yBAAe,EAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE;4BAC1F,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,IAAA,kBAAQ,EAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAA,gBAAM,GAAE,EAAE;yBAChE;oBACH,CAAC,CAAC;wBACE,EAAE,GAAG,SAAS,EAAE,SAAS,EAAE,IAAA,yBAAe,EAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE;wBAChE,EAAE,GAAG,SAAS,EAAE,SAAS,EAAE,IAAA,gBAAM,GAAE,EAAE;qBACtC;gBACL,CAAC,CAAC,aAAa,IAAI,IAAI;oBACrB,CAAC,CAAC,IAAI;wBACJ,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,IAAA,aAAG,EAAC,IAAA,kBAAQ,EAAC,IAAI,CAAC,EAAE,IAAA,yBAAe,EAAC,aAAa,CAAC,CAAC,EAAE;wBACjF,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,IAAA,yBAAe,EAAC,aAAa,CAAC,EAAE;oBAC9D,CAAC,CAAC,IAAI;wBACJ,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,IAAA,kBAAQ,EAAC,IAAI,CAAC,EAAE;wBAC5C,CAAC,CAAC,SAAS;YACjB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;SAC3B,CAAC,CAAA;QACF,MAAM,MAAM,GAAG,IAAI,CAAA;QAEnB;;;;;;;;;WASG;QACH,MAAM,UAAU,GAAG,MAAM,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAC,IAAI,CAAC;YACzD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE;YAC/C,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;SACtB,CAAC,CAAA;QACF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAuB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAqB,CAAC,CAAC,CAAC,CAAA;QACpG,iEAAiE;QACjE,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,CAAA;QACjC,MAAM,KAAK,GAAG,CAAC,CAA4B,EAAsB,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,MAAM,CAAA;QAE5F,MAAM,QAAQ,GAA6C,EAAE,CAAA;QAC7D,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC,CAAC,CAAC,OAAO;gBAAE,SAAQ;YACxB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;YACpB,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAK,GAAG,CAAC,KAAsB,CAAA;YACpF,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YAC1C,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK;gBAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;;gBACxD,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACpD,CAAC;QACD;;;;;;;;;WASG;QACH,MAAM,OAAO,GAAG,aAAa,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI,CAAA;QAC1D,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAiC,CAAA;QACnF,IAAI,OAAO,IAAI,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,KAAK,MAAM;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;QAEtH;;;;;;;;;;;WAWG;QACH,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAEhG;;;;;;;;;;;;WAYG;QACH,MAAM,GAAG,GAAG,IAAI,mCAAc,EAAE,CAAA;QAChC,wDAAwD;QACxD,IAAI,MAAM,EAAE,IAAI,EAAE,GAAG;YAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACnD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAc,CAAC,CAAA;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACP,0DAA0D;YAC5D,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAAG,CAAC,EAAO,EAAO,EAAE;YAC/B,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAA;YAC5C,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,IAAI,SAAS,IAAI,aAAa,IAAI,SAAS,CAAA;YACrE,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;YAC/C,8DAA8D;YAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAA;YAChE,MAAM,WAAW,GAAG,IAAA,gCAAW,EAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;YACvF,OAAO,IAAA,uCAAkB,EAAC,WAAW,CAAC,CAAA;QACxC,CAAC,CAAA;QAED,gEAAgE;QAChE;;;WAGG;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;QAEnF,MAAM,IAAI,GAAG,CAAC,EAAO,EAAE,IAAyD,EAAO,EAAE;YACvF;0EAC8D;YAC9D,IAAI,WAAW,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC;gBAC7B,KAAK,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAA;YACjI,CAAC;YACD;;;;;;;;eAQG;YACH,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;gBACf,MAAM,EAAE,GAAG,WAAW,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAA;gBACvD,IAAI,EAAE,GAAG,CAAC;oBACR,KAAK,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,UAAU,EAAE;wBAC7C,QAAQ,EAAE,EAAE;wBACZ,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACtD,YAAY,EAAE,CAAC,WAAW,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI;wBACpE,IAAI;qBACL,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACtB,CAAC;YACD,OAAO,EAAE,CAAA;QACX,CAAC,CAAA;QAED;;;WAGG;QACH,IAAI,MAAM,EAAE,IAAI,EAAE,OAAO,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAClD,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,CAAiB,CAAA;YACtF,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC,CAAA;YAC7E,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QACpF,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,CAAiB,CAAA;YAChE,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;YAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QACpF,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;YACvE,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QACpF,CAAC;QAED,4DAA4D;QAC5D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;QAClD,wDAAwD;QACxD,KAAK,MAAM,EAAE,IAAI,MAAM;YACrB,IAAI,EAAE,CAAC,gBAAgB,IAAI,EAAE,CAAC,gBAAgB,IAAI,EAAE,CAAC,cAAc,IAAI,EAAE,CAAC,aAAa;gBACrF,OAAO,CAAC,IAAI,CAAC,kBAAkB,UAAU,iDAAiD,EAAE,CAAC,gBAAgB,eAAe,EAAE,CAAC,gBAAgB,eAAe,EAAE,CAAC,cAAc,aAAa,EAAE,CAAC,aAAa,+BAA+B,CAAC,CAAA;QAChP,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;IAC7B,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,QAAgB,EAAE,OAAe;QACtD,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QACrG,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;QACvC,IAAI,CAAC,GAAG,CAAC,MAAM;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;QAExD;;;;;;WAMG;QACH,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,kBAAkB,EAAW,CAAA;QAChF,MAAM,IAAI,GAAG,KAAK,EAAE,UAAkB,EAAE,GAAkB,EAA0B,EAAE;YACpF,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC;iBACvC,kBAAkB,CAAC,GAAG,CAAC;iBACvB,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;iBAC5B,KAAK,CAAC,sBAAsB,EAAE,EAAE,QAAQ,EAAE,CAAC;iBAC3C,QAAQ,CAAC,4BAA4B,EAAE,EAAE,UAAU,EAAE,CAAC;iBACtD,SAAS,EAAkB,CAAA;YAC9B,OAAO,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QAC1B,CAAC,CAAA;QAED,IAAI,GAAG,GAAG,QAAQ,CAAA;QAClB,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAA;QAEnB;;;WAGG;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,iBAAiB,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,iBAAiB,CAAC,CAAA;YACjD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YACxF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;gBACnB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;gBACvB,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,GAAG,GAAG;oBAAE,GAAG,GAAG,EAAE,CAAA;gBACrC,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,GAAG,GAAG;oBAAE,GAAG,GAAG,EAAE,CAAA;YACvC,CAAC;QACH,CAAC;QAED,IAAI,GAAG,KAAK,QAAQ;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;QAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAA;IACvF,CAAC;IAED,gFAAgF;aACzE,cAAS,GAA6B,EAAE,CAAA;IAC/C,MAAM,CAAC,MAAM,CAAC,EAAwB;QACpC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,EAAU;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;QAClD,IAAI,CAAC,EAAE,CAAC;YACN;;;;;eAKG;YACH,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CACnD,IAAA,kBAAS,EAAC,wCAAwC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAC9E,CAAA;YACD;;;;eAIG;YACH,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;YAC1B,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;YACtB,CAAC,CAAC,KAAK,EAAE,CAAA;YACT,OAAO,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;YAC/C,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC;iBAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;iBAC7E,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,kBAAS,EAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC,CAAA;QACzD,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAAC,IAAI,CAAC;gBAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;QAAC,CAAC;IAC9E,CAAC;IAED;;;;;;;;;;OAUG;IACH;;;;;;;;;;OAUG;IACK,MAAM,CAAC,iBAAiB,CAAC,IAAqB;QACpD,MAAM,MAAM,GAAQ,IAAI,CAAC,MAAM,CAAA;QAC/B,IAAI,OAAO,MAAM,EAAE,oBAAoB,KAAK,UAAU;YAAE,OAAM,CAAC,eAAe;QAC9E,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAA,CAAC,kCAAkC;YAClE,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAsC,EAAE,CAAA;QACnD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO;gBAAE,SAAQ;YAClG,MAAM,EAAE,GAAkC,KAAK,CAAC,MAAc,EAAE,SAAS,CAAA;YACzE,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,CAAC,OAAO,KAAK,UAAU;gBAAE,SAAQ;YACrD,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAC3F,CAAC;QACD,MAAM,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAA;IACpC,CAAC;IAEO,MAAM,CAAC,WAAW,CAAC,QAAgB,EAAE,EAAU,EAAE,OAAwB;QAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;QACrD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAA,4BAAY,GAAE,CAAC,CAAC,CAAA;QAChE,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QAC5B,IAAI,CAAC;YACH,sDAAsD;YACtD,IAAI,IAAI;gBAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAA;YACtC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAE1B;iEACqD;YACrD,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,CAAA;gBACnC,IAAA,2BAAW,EAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;gBAC/B,MAAM,CAAC,GAAG,IAAA,0BAAU,EAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;gBAC1D,IAAI,CAAC,CAAC,IAAI;oBAAE,IAAA,iBAAQ,EAAC,IAAA,+BAAe,EAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAA;gBACjE,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB;;;;eAIG;YACH,IAAI,CAAC,YAAY,CACf,QAAQ,EACR,EAAE,EACF,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,EAAE,EACxE,kBAAkB,EAAE,mEAAmE;gBACrF,mDAAmD,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAC3E,CAAA;QACH,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,eAAe,CAAC,QAAgB,EAAE,EAAU,EAAE,MAAc;QACzE,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAA;QAClD,IAAI,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC7B,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACpD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAClC,IAAI,MAAM,GAAG,IAAI,CAAC,aAAa;YAAE,OAAM;QAEvC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;QACtC,IAAI,CAAC,YAAY,CACf,QAAQ,EACR,EAAE,EACF,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EACrF,kBAAkB,EAAE,eAAe,MAAM,2BAA2B,QAAQ,GAAG,IAAI,WAAW,IAAI,MAAM;YACtG,+GAA+G;YAC/G,0HAA0H,CAC7H,CAAA;IACH,CAAC;IAED,wDAAwD;IAChD,MAAM,CAAC,YAAY,CAAC,QAAgB,EAAE,EAAU,EAAE,IAAc,EAAE,GAAW;QACnF,IAAA,kBAAS,EAAC,GAAG,CAAC,CAAA;QACd,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAA;QAClD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,kBAAS,EAAC,0CAA0C,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC,CAAA;IACvH,CAAC;IAED,yCAAyC;IACzC,MAAM,CAAC,UAAU,CAAC,QAAgB,EAAE,EAAU;QAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;IACrD,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAS,CAAC,QAAgB,EAAE,EAAU;QAC3C,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;IACnD,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,QAAgB,EAAE,EAAU;QACzC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAA;IAC1D,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,UAAkB,EAAE,OAAY;QAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;QAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,CAAA;QACxC,MAAM,KAAK,GAAG,IAAA,iCAAY,EACxB,IAAI,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAQ,IAAI,CAAC,MAAc,EAAE,QAAQ,KAAK,UAAU,EAAE,EAChI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EACpC,IAAI,CACL,CAAA;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,CAAA;QAChH,CAAC;QAED,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA,CAAC,kCAAkC;QACjF,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,IAAK,CAAC,OAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;QAEnE;;;;;WAKG;QACH,MAAM,MAAM,GAAQ,IAAK,CAAC,MAAM,CAAA;QAChC,MAAM,OAAO,GAAU,EAAE,CAAA;QACzB,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QACzD,IAAI,GAAQ,CAAA;QACZ,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;QAC5B,CAAC;gBAAS,CAAC;YACT,GAAG,EAAE,EAAE,CAAA;QACT,CAAC;QACD,IAAI,GAAG,EAAE,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACpC,IAAK,CAAC,cAAc,GAAG,CAAC,GAAG,CAAC,IAAK,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAA;YACpE,IAAK,CAAC,KAAK,GAAG,IAAI,CAAA,CAAC,kCAAkC;QACvD,CAAC;QACD,OAAO,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAA;IAC3F,CAAC;IAED;;;;;OAKG;IACH;;;;;OAKG;IACH,MAAM,CAAC,MAAM,CAAC,QAAgB,EAAE,EAAU;QACxC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,CAAA;IACvD,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,QAAgB,EAAE,EAAU;QACtC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;IACnD,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAgB,EAAE,UAAkB;QAC9D,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC;YAAE,OAAO,IAAI,CAAA;QAChD,OAAO,CAAC,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,CAAA;IAC3G,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,QAAgB,EAAE,OAAe;QAC/D,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAA;QACvB,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QACrG,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACpE,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,QAAgB,EAAE,OAAe,EAAE,KAAc;QAC9E,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC5D,MAAM,MAAM,GAAG,GAAG;YAChB,oDAAoD;aACnD,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;aACrC,GAAG,CAAC,EAAE,CAAC,EAAE;YACR,MAAM,MAAM,GAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;YAC7C,MAAM,IAAI,GAAG,MAAM,EAAE,WAAW,EAAE,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;YACnE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,IAAI,EAAE,EAAE,CAAA;QAC/D,CAAC,CAAC,CAAA;QACJ,2DAA2D;QAC3D,OAAO,IAAA,yCAAmB,EAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAC3C,CAAC;IAED,yDAAyD;IACzD,MAAM,CAAC,MAAM,CAAC,QAAgB,EAAE,EAAU;QACxC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,CAAA;IACzD,CAAC;IAED,wEAAwE;IACxE,MAAM,CAAC,OAAO,CAAC,QAAgB,EAAE,EAAU;QACzC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAA;QAC3D,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QACnB,OAAO;YACL,UAAU,EAAE,EAAE;YACd,aAAa,EAAE,CAAC,CAAC,aAAa,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc;YAClG,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW;YACpF,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,CAAC,iBAAiB;YAC/D,4DAA4D;YAC5D,IAAI,EAAE,IAAA,2BAAW,EAAC,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;SAChF,CAAA;IACH,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,IAAI,CAAC,QAAgB,EAAE,EAAU;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;QACrD,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAA;QAEtB,OAAO;YACL,UAAU,EAAE,EAAE;YACd,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK;YACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS;YACnC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,MAAM,EAAE,IAAI,CAAC,OAAO;YACpB,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAC7C,GAAG,CAAC,IAAA,2BAAW,EAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;SAC1J,CAAA;IACH,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,QAAiB;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAA,2BAAU,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAA;QAC9F,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAC1B,MAAM,EAAE,GAAG,IAAA,gCAAe,EAAC,GAAG,CAAC,CAAA;YAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;YAChC;0EAC8D;YAC9D,OAAO;gBACL,UAAU,EAAE,EAAE,CAAC,UAAU;gBACzB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK;gBACxB,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS;gBACnC,KAAK,EAAE,IAAI,CAAC,IAAI;aACjB,CAAA;QACH,CAAC,CAAC,CAAA;QAEF,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,OAAO;YACpB,mBAAmB,EAAE,IAAI,CAAC,iBAAiB;YAC3C,oDAAoD;YACpD,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,yDAAyD;YACzD,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;YAC7C,kBAAkB,EAAE,IAAI,CAAC,oBAAoB;YAC7C,kEAAkE;YAClE,OAAO,EAAE,qBAAO,CAAC,IAAI,EAAE;YACvB,GAAG,IAAA,yBAAS,EAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;YAChC,wDAAwD;YACxD,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,IAAA,gCAAe,EAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,CAAA,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;SAC5H,CAAA;IACH,CAAC;IAED,+CAA+C;IAC/C,MAAM,CAAC,UAAU,CAAC,QAAgB,EAAE,EAAU,EAAE,KAAa;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;QACrD,IAAI,IAAI;YAAE,IAAA,0BAAU,EAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAA,4BAAY,GAAE,CAAC,EAAE,KAAK,CAAC,CAAA;IACxE,CAAC;IAED,gDAAgD;IAChD,MAAM,CAAC,UAAU,CAAC,QAAgB,EAAE,EAAU,EAAE,KAAgB,EAAE,MAAc;QAC9E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;QACrD,IAAI,IAAI;YAAE,IAAA,2BAAW,EAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAA,4BAAY,GAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;IACjF,CAAC;IAED;;;;;;;OAOG;aACY,kBAAa,GAAiC,EAAE,CAAA;IAK/D;;;;;OAKG;IACH,MAAM,CAAC,oBAAoB,CACzB,EAAgF;QAEhF,IAAI,CAAC,cAAc,GAAG,EAAE,CAAA;IAC1B,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,kBAAkB,CACvB,QAAgB,EAChB,UAAkB,EAClB,OAAe,EACf,QAA+D,EAC/D,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;IAClB;;;;OAIG;IACH,WAAW,GAAG,CAAC;QAEf,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,IAAA,kCAAe,GAAE,CAAC,CAAA;QACvF,IAAA,+BAAY,EACV,MAAM,EACN,OAAO,EACP,QAAQ,EACR,KAAK,EACL,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,EACjE,WAAW,CACZ,CAAA;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,uBAAuB,CAAC,QAAgB,EAAE,UAAkB,EAAE,MAAc,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,MAAe;QACtH,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,IAAA,kCAAe,GAAE,CAAC,CAAA;QACvF,IAAA,oCAAiB,EAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;IAClD,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,sBAAsB,CAAC,QAAgB,EAAE,UAAkB;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;QACnE,IAAI,MAAM;YAAE,IAAA,mCAAgB,EAAC,MAAM,CAAC,CAAA;IACtC,CAAC;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,kBAAkB,CAAC,QAAgB,EAAE,UAAkB,EAAE,IAAY,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;QAC9F,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,IAAA,kCAAe,GAAE,CAAC,CAAA;QACvF,IAAA,qCAAiB,EAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,CAAC,CAAA;IAC3G,CAAC;IAED;;;;;;OAMG;IACH;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,iBAAiB,CACtB,QAAgB,EAChB,WAAqB;QAErB,OAAO,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;YACtD,OAAO;gBACL,UAAU;gBACV,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,yDAAyD;gBACzD,aAAa,EAAE,IAAI,CAAC,MAAM,EAAE,aAAa,IAAI,IAAI;gBACjD;;;mBAGG;gBACH,uDAAuD;gBACvD,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBACpH,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,cAAc,CAAC,QAAgB,EAAE,UAAkB;QACxD,MAAM,GAAG,GAAG,IAAA,2BAAU,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;QACtC,IAAI,MAAM,EAAE,CAAC;YACX,IAAA,mCAAgB,EAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,CAAC,CAAA;QAC/G,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAChC,MAAM,SAAS,GAAG,IAAA,uCAAe,EAAC;YAChC,aAAa,EAAE,IAAI,EAAE,aAAa;YAClC,OAAO,EAAE,CAAC,CAAC,IAAI;YACf,UAAU;SACX,CAAC,CAAA;QACF,OAAO,IAAA,+BAAY,EAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;IAC1D,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,QAAiB;QACvC,6DAA6D;QAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;aACrC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAA,2BAAU,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;aACrD,GAAG,CAAC,GAAG,CAAC,EAAE;YACT,MAAM,EAAE,GAAG,IAAA,gCAAe,EAAC,GAAG,CAAC,CAAA;YAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,CAAA;QACjD,CAAC,CAAC;aACD,MAAM,CAAC,OAAO,CAAC,CAAA;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAA;QAC1C,2FAA2F;QAC3F,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAA;QAC7F,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAClE;yDACiD;QACjD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACpE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACpI,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;YACpC,CAAC,CAAC,OAAO,GAAG,EAAE,CAAA;YACd,CAAC,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;YACvC,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,UAAU,CAAA;QACvD,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;;;;OAQG;IAEH;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,QAAgB,EAAE,UAAkB,EAAE,SAAkB;QACzF,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;QAC1G,IAAI,CAAC,GAAG,EAAE,KAAK;YAAE,OAAO,IAAI,CAAA;QAC5B,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAClC,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAqB,CAAC,CAAC,CAAA;QAC3F,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,KAAqB,CAAC,CAAA;QAC1C,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA,CAAC,kCAAkC;QACjF,MAAM,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA,CAAC,kCAAkC;QACnG,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QAC9F,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QACvB,MAAM,MAAM,GAAG,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;QACnE;;;;;;;WAOG;QACH,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;QAC5J,MAAM,MAAM,GAAG,IAAI,GAAG,EAAe,CAAA;QACrC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,GAAG,MAAM;gBAAE,SAAQ;YACjF,MAAM,CAAC,GAAI,CAAC,CAAC,OAAe,EAAE,IAAI,CAAA;YAClC,IAAI,CAAC,EAAE,OAAO;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QAC1C,CAAC;QACD,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QAC9C,OAAO,CAAC,CAAA;IACV,CAAC;IAED,wCAAwC;IACxC,MAAM,CAAC,QAAQ,CAAC,QAAgB,EAAE,EAAU;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;QACrD,IAAI,IAAI,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5C;;wDAE4C;YAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAA;YACpC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAA,gCAAW,EAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAClD,CAAC;QACD,OAAO,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,IAAA,2BAAU,EAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;IAC5E,CAAC;;AArkHH,gCAskHC","sourcesContent":["/*\n * TwinEngine โ operato-twin ์ปค๋ ์ธ์คํด์ค๋ฅผ things-factory ์์์ ํธ์คํ
.\n * integration-base ์ ScenarioEngine ํจํด ๋ฏธ๋ฌ: ๋ฉ๋ชจ๋ฆฌ ์ธ์คํด์ค ๋งต + ๋ฐฑ๊ทธ๋ผ์ด๋ tick + pubsub ์ํ ๋ฐํ.\n *\n * ์ปค๋(zero-dep, ESM+CJS ์ด์ค๋ฐฐํฌ)์ CJS require ๋ก ๋ก๋(Node 20 CommonJS ์๋น โ require(ESM) ํํผ). (vocabulary-guard: allow โ Node ๋ฐํ์ ๋ฒ์ ํ๊ธฐ)\n * ์ปค๋์ ๊ฒฐ์ ์ ๋
ผ๋ฆฌ ์ฐ์ฐ ์ฝ์ด โ ์ด host ๊ฐ ์ ์ก(pubsub)ยท์์(TypeORM)ยท์ค์ผ์ค(tick)ยท๋ณต๊ตฌ(replay)๋ง ์๊ฒ ๋ํ.\n * (์ค๊ณ SoT: operato-twin/design/integration/things-factory-host.md)\n */\n\nimport { twinLog, twinWarn, twinError } from './log.js'\nimport { pubsub, getRepository, Domain } from '@things-factory/shell'\n/* ์ ๋์ ์๋ฅผ ์กฐ๊ฑด์ SQL ์ด ์๋ค โ ๊ด์ฉ๊ตฌ๋ง ์ด๋ค(์์ SQL ์ 5๊ฐ ๋๋ผ์ด๋ฒ์์ ๊ฐ๋ผ์ง๋ค). */\nimport { And, IsNull, LessThanOrEqual, MoreThan } from 'typeorm'\nimport { cacheService } from '@things-factory/cache-service'\n\nimport type { ReducerCheckpoint } from '@operato/twin-kernel'\nimport type { OeeCheckpoint } from './oee-accumulator.js'\nimport { TwinEvent } from '../service/twin-event/twin-event.js'\nimport { twinEventKeys } from '../service/twin-event/twin-event-keys.js'\nimport { planLiveContinuity, planWarmStart, unwrapState } from './warm-start.js'\nimport { applyDeclarationLayers } from './local-declarations.js'\nimport { isOfDomain, parseRuntimeKey, runtimeKey } from './runtime-key.js'\nimport { routeCommand } from './command-routing.js'\nimport { TwinInstance } from '../service/twin-instance/twin-instance.js'\n/* ์๊ทน์ ์ง์ ์๋ณธ์ด๋ค(ADR-0029) โ ๊ทธ ํ์ ์ฝ๊ณ ์ด๋ค. */\nimport { TwinReference } from '../service/reference/twin-reference.js'\nimport { TwinStructure } from '../service/twin-structure/twin-structure.js'\nimport { TwinSpace } from '../service/twin-space/twin-space.js'\nimport { utcOffsetOf } from '../service/reference/reference-master.js'\nimport { TwinSpaceRepresentation } from '../service/twin-space/twin-space-representation.js'\nimport { TwinSpaceArea } from '../service/twin-space/twin-space-area.js'\nimport { TwinArea } from '../service/twin-space/twin-area.js'\nimport { masterToTwin, type ReferenceMaster } from '../service/reference/reference-master.js'\nimport { resolveIngestSpace } from '../service/reference/ingest-space.js'\nimport { type IngestWarning, describeWarnings, unresolvedReference, projectionFailed, structureAdopted, generationWithoutTimeZone } from '../service/reference/reference-master.js'\nimport { projectStructure } from '../service/twin-model/project-structure.js'\nimport { buildTravelEstimator, chainEstimators } from './travel-estimator.js'\nimport { buildMeasuredEstimator } from './measured-estimator.js'\nimport { buildYieldEstimator } from './measured-yield.js'\nimport { planStimulus, withStimulus } from './declared-stimulus.js'\nimport { readRestartPolicy, type RestartPolicy } from './restart-policy.js'\nimport { describeModelBasis, type ModelBasis } from './model-basis.js'\nimport { computeTwinKpi } from './kpi-query.js'\nimport { createHash } from 'node:crypto'\n\nimport { buildEntityDeltas } from '@things-factory/headless-twin/dist-shared/entity-delta.js'\nimport { fleetLoad, judgeCycle, loadSummary, newLoadMeter, recordFork, recordPhase, slowTickMessage, type LoadMeter, type LoadPhase } from './load-meter.js'\nimport { loopLag } from './loop-lag.js'\nimport { touchedItemKeys } from '@things-factory/headless-twin/dist-shared/touched-items.js'\nimport { diffStructures, type StructureDiff } from './structure-diff.js'\nimport { OeeAccumulator, withLiveOee } from './oee-accumulator.js'\nimport { withLiveAttentions } from './live-attentions.js'\nimport { digestAttentions, mergeLensAttentions } from './attention-digest.js'\n\nimport { liveFeedStateOf } from './live-feed-registry.js'\nimport {\n ingestHealth,\n newIngestLedger,\n recordIngest,\n recordReadFailure,\n clearReadFailure,\n rollIngestWindow,\n /* ๋ณ์นญ โ ๊ฐ์ ์ด๋ฆ์ ์ ์ ๋ฉ์๋์ ํท๊ฐ๋ฆฌ์ง ์๊ฒ(๊ทธ ๋ฉ์๋๊ฐ ์ด๊ฒ์ ๋ถ๋ฅธ๋ค). */\n recordJournalWrite as recordLedgerWrite,\n type IngestHealthView,\n type IngestLedger,\n type IngestWindow\n} from './ingest-health.js'\nimport { EMS_PROPERTY } from '@operato/twin-kernel'\nimport type { TwinKernel, TwinModelDef, StructureShift, SubscriptionMessage, TwinRuntime as TwinRuntimeType, CanonicalEnvelope } from '@operato/twin-kernel'\n\n/* ์ปค๋ ๋ฐํ์ ๋ก๋ โ CJS ๋ฒ๋ค(dist-cjs). ํ์
์ ์ import type ๋ก. replay = ์ด๋ฒคํธ์ดโ์ํ ์ฌ๊ตฌ์ฑ(๋ณต๊ตฌยท์๊ฐ์ฌํ). */\nconst { WmsKernel, YmsKernel, MesKernel, EmsKernel, TwinRuntime, StateProjector, replay, replayFrom, replayWithCheckpoint, replaySegments, readBoardLocations, readBoardEquipment, DOMAIN_CATALOG, OP_EVENT, validateScenario } = require('@operato/twin-kernel')\n\nconst KERNELS: Record<string, any> = { wms: WmsKernel, yms: YmsKernel, mes: MesKernel, ems: EmsKernel }\n\n/**\n * ์๊ฐ์ถ์ ๊ตฌํ ๋ ํ ๋ฒ์ ๋์ฐ๋ ํธ์ ์.\n *\n * ํธ์๋ง๋ค ์๋ณต์ด ๋์ด๋ผ, ๊ณต๊ฐ์ ํธ์์ด ์๋ฐฑ์ด๋ฉด ๋์ ์๋ณต๋ ์๋ฐฑ์ด ๋๋ค โ ์ปค๋ฅ์
ํ์ด ๋ง๋ฅด๋ฉด ์ด\n * ํจ์ ํ๋ ๋๋ฌธ์ ๋ค๋ฅธ ์ง์๊ฐ ์ค์ ์ ๋ค. 20์ด๋ฉด ์๋ณต 40๊ฐ๋ก ์ง์ฐ์ ๊ฐ์ถ๋ฉด์ ํ์ ๋จ๋๋ค.\n */\nconst TIME_RANGE_FANOUT = 20\n\n/**\n * DB ๊ฐ ์ค ์๊ฐ์ epoch ms ๋ก โ **๋ชจ์์ด ๋๋ผ์ด๋ฒ๋ง๋ค ๋ค๋ฅด๋ค.**\n *\n * ์ง๊ณ(MIN/MAX)์ ๋ฐํ์ ๋๋ผ์ด๋ฒ๊ฐ ์ ํ๋ค: sqlite ๋ ๋ฌธ์์ด, pgยทmysqlยทmssql ์ `Date`. ์ํฐํฐ\n * ํ์ด๋๋ ์ด์
์ ๊ฑด๋๋ฐ๋ฉด TypeORM ์ ๋ ์ง ๋ณํ๋ ํจ๊ป ๊ฑด๋๋ฐ๋ฏ๋ก ๋ฐ๋ ์ชฝ์์ ํ ๋ฒ ์ ๊ทํํ๋ค.\n *\n * โโ ์๊ฐ๋๋ฅผ ์์ง ์๋๋ค (์ํ์ด ์ก์๋ค) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ฒ์์ `Date.parse(String(v))` ๋ก ๋์๋๋ **9์๊ฐ์ด ๋ฐ๋ ธ๋ค.** sqlite ๋ UTC ๋ก ์ ์ฅํ ๊ฐ์\n * `2026-01-15 09:00:00.000` ์ฒ๋ผ **์๊ฐ๋ ํ์ ์์ด** ๋๋ ค์ฃผ๋๋ฐ, ๊ทธ ํํ๋ฅผ `Date.parse` ๋ **๋ก์ปฌ\n * ์๊ฐ**์ผ๋ก ์ฝ๋๋ค(์ฌ๊ธฐ๊ฐ KST ๋ผ UTC 00:00 ์ด ๋๋ค). ์๋ ์ฝ๋๊ฐ ์ด ํจ์ ์ ํผํ ๊ฒ์ TypeORM ์ด\n * ํ์ด๋๋ ์ด์
์์ ๋จผ์ `Date` ๋ก ๋ฐ๊ฟ ์คฌ๊ธฐ ๋๋ฌธ์ด๋ค โ ๊ทธ ๋จ๊ณ๋ฅผ ๊ฑด๋๋ด ๋๊ฐ๋ฅผ ์ฌ๊ธฐ์ ์น๋ฅธ๋ค.\n *\n * ๊ทธ๋์ ์๊ฐ๋ ํ์๊ฐ **์๋ ๋ฌธ์์ด์ UTC ๋ก ์ฝ๋๋ค**(TypeORM ์ด UTC ๋ก ์ ์ผ๋ฏ๋ก). ํ์๊ฐ ์์ผ๋ฉด\n * ๊ทธ๋๋ก ๋ฏฟ๊ณ , `Date` ๋ ์๋์ง ์๋๋ค.\n *\n * ์ฝ์ ์ ์๋ ๊ฐ์ **์์(`null`)** ์ด๋ค โ 0 ์ผ๋ก ๋จ์ด๋จ๋ฆฌ๋ฉด 1970๋
์ด ์๊ฐ์ถ์ ์์์ด ๋๋ค.\n */\nfunction parseTime(v: unknown): number | null {\n if (v == null) return null\n if (v instanceof Date) return Number.isFinite(v.getTime()) ? v.getTime() : null\n\n const s = String(v).trim()\n if (!s) return null\n /* ๋์ `Z` ๋ `ยฑhh:mm` ์ด ๋ถ์ด ์์ผ๋ฉด ์๊ฐ๋๋ฅผ ์๋ ๋ฌธ์์ด์ด๋ค โ ๊ทธ๋๋ก ๋ฏฟ๋๋ค. */\n const zoned = /(?:Z|[+-]\\d{2}:?\\d{2})$/.test(s)\n const t = Date.parse(zoned ? s : `${s.replace(' ', 'T')}Z`)\n return Number.isFinite(t) ? t : null\n}\n\n/**\n * ์ข
๋ฅ ๋ฌธ์์ด โ ์ปค๋. **๋ชจ๋ฅด๋ ๊ฐ์ด๋ฉด ์ค๋ฅ๋ฅผ ๋ธ๋ค.**\n *\n * ์์ ์๋ ํ๋ฅผ ์ฐพ๊ณ ์์ผ๋ฉด WmsKernel ๋ก ๋จ์ด์ก๋ค. `kind` ๋ ๊ฒ์ฆ ์๋ ์์ ๋ฌธ์์ด(`@Arg('kind') kind: string`)\n * ์ด๋ผ ์คํ ํ๋ยท๋์๋ฌธ์ ํ๋๋ก ์ผ๋/์์ฐ ํธ์์ด **์กฐ์ฉํ ์ฐฝ๊ณ ์ปค๋๋ก ๋์๋ค.** ์ค๋ฅ๊ฐ ์์ผ๋ ํ๋ฉด์๋\n * ํธ์์ด ์ ์์ผ๋ก ๋ณด์ด๊ณ , ์์์ ๋๋ ๊ท์น๋ง ๋ค๋ฅธ ๋๋ฉ์ธ์ ๊ฒ์ด๋ค. ์์ธก ๊ฒฝ๋ก๊ฐ ๊ฐ์ฅ ๋์๋ค โ\n * ์ผ๋์ ๋ฏธ๋๋ฅผ ์ฐฝ๊ณ ๊ท์น์ผ๋ก ์คํํด ๋๊ณ ์ซ์๋ง ๋ฌ๋ค.\n *\n * ํ๋ฆฐ ๊ณต์ฅ์ ์กฐ์ฉํ ๋์ฐ๋ ๊ฒ๋ณด๋ค ๋จ์ง ์๋ ํธ์ด ๋ซ๋ค.\n */\nfunction kernelFor(kind: string): any {\n const K = KERNELS[kind]\n if (!K) throw new Error(`unknown twin kind \"${kind}\" โ expected one of ${Object.keys(KERNELS).join(' | ')}`)\n return K\n}\n\n/** `observe()` ๋ฅผ ๊ฐ์ง ์์ ์ปค๋์ ๋ง๋ ์ ์ด ์๋๊ฐ โ ๊ฒฝ๊ณ ๋ฅผ ํ ๋ฒ๋ง ๋ธ๋ค(ํฑ๋ง๋ค ์์ง ์๋๋ค). */\nlet observeUnavailableWarned = false\n\n/**\n * **์ด ์ปค๋์ ์ง์ค์ด ์๋ณธ์์ ์จ๋ค๊ณ ์ ์ธํ๋ค** โ ๊ทธ๋ฆฌ๊ณ ์ ์ธ์ด ๋ฟ์ง ์์์ผ๋ฉด ๋งํ๋ค.\n *\n * โโ ๋ฌด์์ด ํ๋ ธ๋ (2026-08-21) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์์ ์๋ `kernel.observe?.()` ์๋ค. ์ต์
๋ ํธ์ถ์ด๋ผ **๋ฉ์๋๊ฐ ์์ผ๋ฉด ์กฐ์ฉํ ์๋ฌด๊ฒ๋ ํ์ง ์๋๋ค.**\n * ์ค์น๋ ์ปค๋ 0.7.39 ์๋ ๊ทธ ๋ฉ์๋๊ฐ ์์ผ๋ฏ๋ก, ์ง๊ธ ๋ฐฐํฌ๋ณธ์์๋ ๋ฏธ๋ฌ๊ฐ ๊ด์ธก ๊ตฌ๋์ผ๋ก ์ ์ธ๋์ง\n * ์๋๋ค โ ๊ทธ๋ฐ๋ฐ ์ฝ๋๋ฅผ ์ฝ์ผ๋ฉด ์ ์ธํ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค.\n *\n * ๊ทธ ์ฐจ์ด๊ฐ ์ค์ ๊ฑฐ๋์ ๊ฐ๋ฅธ๋ค: ๊ด์ธก ๊ตฌ๋์ ์๋ณธ์ ๋นํ์ ๋ฐ์๋ค์ด๊ณ ์ธ์ง๋ง, ์๋ฎฌ๋ก ์ค์ธ๋ ๋ฏธ๋ฌ๋\n * **๋ฉ์ถ๋ค.** ์ฆ ใ๊ด์ฉ์ด ์ผ์ง ์ค ์์๋๋ฐ ์ ์ผ์ ธ ์๋คใ๊ฐ ์กฐ์ฉํ ์ง๋๊ฐ๊ณ , ์ฅ์ ๊ฐ ๋ฌ์ ๋ ์์ธ์ด\n * ์ปค๋์ ์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค โ ์์ธ์ ๋ฒ์ ์ด๋ค.\n *\n * ๊ทธ๋์ ์ต์
๋ ํธ์ถ์ ์์ ๊ณ , ์์ผ๋ฉด **ํ ๋ฒ ๊ฒฝ๊ณ ํ๋ค.** ์ปค๋์ด ๋ฐฐํฌ๋๋ฉด ์ด ๊ฒฝ๊ณ ๋ ์ฌ๋ผ์ง๋ค.\n */\nfunction declareObserved(kernel: any, what: string): void {\n if (typeof kernel?.observe === 'function') {\n kernel.observe()\n return\n }\n if (observeUnavailableWarned) return\n observeUnavailableWarned = true\n twinWarn(\n `[twin-engine] ${what}: kernel has no observe() โ this mirror is not declared observation-driven. ` +\n 'Source gaps will stop it instead of being tolerated and counted. Deploy a kernel that provides observe().'\n )\n}\n\n/* ๋ผ์ด๋ธ ์ฒ๋ฆฌ๋ ๊ณ์ธก(๋ชจ๋ํฐ) โ ์ ์
/๋ธ๋ก๋์บ์คํ
/์ ๋๋ฅ ยท๋ฐฑ๋ก๊ทธ. ์ค ๋๊ธฐ ์ธํฐํ์ด์ค ๋ถํ๋ฅผ ์ฝ๋ ์ผ๊ธ ์งํ. */\ninterface TwinMetrics {\n ingestedTotal: number // ๋์ ์ ์
์ด๋ฒคํธ\n broadcastTotal: number // ๋์ ๋ธ๋ก๋์บ์คํ
ํ์\n journaledTotal: number // ๋์ ์ ๋ ๊ธฐ๋ก ์ด๋ฒคํธ\n ingestRate: number // ์ต๊ทผ ์ ์
๋ฅ (ev/s)\n broadcastRate: number // ์ต๊ทผ ๋ธ๋ก๋์บ์คํ
๋ฅ (ํ/s)\n journalRate: number // ์ต๊ทผ ์ ๋๋ฅ (ev/s)\n /**\n * **์ง๊ธ ๋๊ธฐ ์ค์ธ** ์ ๋ ๊ฑด์ โ ์์ง DB ๋ก ๋๊ฐ์ง ์์ ๊ฒ.\n *\n * โโ ๋ฌด์์ด ํ๋ ธ์๋ (2026-08-21) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์์ ์๋ ใ๋ง์ง๋ง flush ์์ ์ด ๊ฑด์ใ๋ฅผ ์ฌ๊ธฐ ๋ฃ์๋ค. ๊ทธ๋ฐ๋ฐ 200ms ๋ง๋ค ๋ชจ์ ํ ๋ฌธ์ผ๋ก ๋ฃ๋ ๊ฒ์\n * **์ ์ ๋์**์ด๋ค(๊ทธ๋ ๊ฒ ๋ง๋ ๊ฒ์ด ์ด์ ๊ณ ์น ์ฑ๋ฅ ์์
์ด๋ค). ๊ทธ๋์ ์ ์์ ์ผ๋ก 10๊ฑด์ ์ด ์งํ\n * ํ๋ฉด์ ใ๋ฐ๋ฆผ 10ใ ๊ฒฝ๊ณ ๊ฐ ๋ด๊ณ , ๋ค์ flush ๊น์ง ๊ทธ ๊ฐ์ด ๋จ์๋ค โ ํ๋ ์ด๋ฏธ 0 ์ธ๋ฐ๋.\n *\n * ์ด์์์๊ฒ ๊ทธ๊ฒ์ ใ์ ์ฅ์ด 10๊ฑด ๋ฐ๋ ค ์๋คใ๋ก ์ฝํ๋ค. ๊ฑฐ์ง ๊ฒฝ๋ณด๋ ์ฐธ ๊ฒฝ๋ณด๋ฅผ ์ฃฝ์ธ๋ค.\n *\n * ์ด์ ์ด ๊ฐ์ **์ง๊ธ ๋จ์ ์๋ ๊ฒ**์ด๋ค: ๋ค ๋๊ฐ์ผ๋ฉด 0 ์ด๊ณ , ์ ๋ง๋ก ์์ด๋ ์ค์ด๋ฉด ๊ทธ ์๊ฐ ์๋๋ค.\n */\n backlog: number\n // ์ฐฝ(window) ์ง๊ณ์ฉ ๋ด๋ถ ๋์ \n _accIngest: number\n _accBroadcast: number\n _accJournal: number\n _windowStartMs: number\n}\n\n/*\n * ์ฌ๊ธฐ๋ ์ ์ฑ
์ **์ ์ธ์ด๊ณ ๊ธฐ๋ณธ๊ฐ์ด ์๋ค** โ ์ ์ยทํ์ ์ `engine/restart-policy.ts` ๊ฐ ๋ ๋ค(ADR-0029 ยง2).\n *\n * ์์ ์๋ ์ฌ๊ธฐ์ `DEFAULT_REALITY_MODE = 'sim-experiment'` ๊ฐ ์์๊ณ , ๋ฏธ์ ์ธ์ด ์กฐ์ฉํ **์ ๋ ์ด๊ธฐํ**๋ก\n * ๋จ์ด์ก๋ค. ๊ทธ ๊ด์ฉ์ ๊ฐ์ด ํ๋ ์ด๊ธ๋๋ ์๊ฐ ์ด๋ ฅ์ ์ง์ฐ๋ ๊ธธ์ด ๋๋ค โ ๊ทธ๋์ ์์ด๋ค.\n */\nexport type { RestartPolicy } from './restart-policy.js'\n\n/* ์ธ๋ฉ๋ชจ๋ฆฌ ๋ผ์ด๋ธ ๋ฐํ์ ํ๋(์์ ์ํฐํฐ TwinInstance ์ ๊ตฌ๋ถ). */\ninterface InstanceRuntime {\n /** ๋ถํ ๊ณ๊ธฐํ โ ์์
๋ณ ์์. ์๋ฎฌยท๋ผ์ด๋ธ ๋ชจ๋ ๋ถ๋๋ค(๋๊ฐ ๋ฃจํ๋ฅผ ์ ์ ํ๋์ง ๋ณด๋ ค๋ฉด ๋ ๋ค ํ์ํ๋ค). */\n load?: LoadMeter\n /** ํ์ค ์ถ์ฒ ์ ์ธ(ยง0 ํ๋ ์ โ ). ๋ถํ
๊ฑฐ๋(reset/resume/resync)์ ๊ทผ๊ฑฐ. */\n restartPolicy?: RestartPolicy\n id: string\n domainId: string\n domain?: any // ๋ผ์ด๋ธ ๋ฐ์ธ๋ฉ(data ์ฑ๋)์ฉ Domain ๊ฐ์ฒด(subdomain ํํฐ). start ์ ๋น๋๊ธฐ ํด์.\n runtime?: TwinRuntimeType // sim: ์ปค๋ ๋ฐํ์(tick/subscribe/dispatch). live ๋ projector ์ฌ์ฉ.\n kernel?: any // sim: ForecastTwin(fork/getSnapshot/tick/scenario). live ๋ฏธ์ฌ์ฉ.\n mode?: 'sim' | 'live' // ์ํ ๋๋ผ์ด๋ฒ โ sim=์ปค๋ tick / live=projector ๋ฏธ๋ฌ(face2-inbound-live). ๋ฏธ์ง์ =sim.\n /** ์ด ํธ์์ด ์ ํ์ฅ โ ๊ฐ์ ํ์ฅ์ ํธ์๋ผ๋ฆฌ ์๋ก์ ์ค๋น ์ํ๋ฅผ ์ฝ์ ์ ์๊ฒ ํ๋ ์ด์ . */\n spaceId?: string\n /**\n * live ์ ์ํ ์ ๊ทผ ์ด๋ํฐ โ ์ด์ **๊ด์ธก ๋ชจ๋ ์ปค๋**์ ๊ฐ๋ฆฌํจ๋ค(`kernel` ๊ณผ ๊ฐ์ ๊ฒ).\n * ์ด๋ฆ์ ์๋น์ฒ ํธํ์ผ๋ก ๋จ์๊ณ , P3 ์์ ์ปค๋ ์ดํ๋ก ์ ๋ฆฌํ๋ฉด ์ฌ๋ผ์ง๋ค.\n */\n projector?: any\n oee?: OeeAccumulator // live: OEE ๊ณ์ฐ ์ธต(์ด๋ฒคํธ ๋์ โ equipment payload ๋ณด๊ฐ). sim ์ ์ปค๋์ด ๊ณ์ฐ.\n unsub: () => void\n /**\n * ๋ฐฉ๊ธ ์ธ์
ํ ๋ดํฌ๋ค โ ์ปค๋์ด ๊ทธ๊ฒ์ ์ฌ๋ฐฉ์ถํ ๋ **์ ๋์ ๋ ๋ฒ ์ ์ง ์๊ธฐ** ์ํ ํ์.\n * ๋ผ์ด๋ธ๋ง ์ด๋ค(sim ์ ์ปค๋์ด ์ค์ค๋ก ๋ธ ๊ฒ๋ง ํ๋ฆฐ๋ค). ์ฝํ ์ฐธ์กฐ๋ผ ๋ฐ๋ก ๋น์ธ ๊ฒ์ด ์๋ค.\n */\n applying?: WeakSet<object>\n timer?: any\n /** ์ํฐํฐ๋ณ ๋ง์ง๋ง ๋ฐํ ์๊ทธ๋์ฒ โ ๊ฐ์ด ๋ฐ๋ ์ํฐํฐ๋ง ์ฌ๋ฐํ(๋ฌด๋ณํ ๋ฐ๋ณต push ๋ฐฉ์ง). */\n entitySigs?: Map<string, string>\n /** live ๋ธ๋ก๋์บ์คํ
๋ณํฉ(ingest-scale ยง4.4) โ ingest ๋ง๋ค ๋ธ๋ก๋์บ์คํ
ํ์ง ์๊ณ dirty ํ์ โ coalescer tick ์ด ์ฃผ๊ธฐ ๋ธ๋ก๋์บ์คํ
. */\n dirty?: boolean\n /**\n * ์ด ์ฐฝ์ **๊ฑด๋๋ฆฐ ๋ฌผํ ํ๊ทธ** โ ๋ธ๋ก๋์บ์คํ
์ด ๊ทธ๊ฒ๋ง ๋ง๋ ๋ค.\n *\n * `undefined` ๋ ใ๋งํ ์ ์๋คใ๋ค(๋ฏ์ ์ฌ๊ฑด์ด ํ๋๋ผ๋ ์๋ค) โ ์ ๋ถ ๋ง๋ ๋ค. ๋น ์งํฉ์ ใ๋ฌผํ์\n * ํ๋๋ ๊ฑด๋๋ฆฌ์ง ์์๋คใ์ด๊ณ , ๊ทธ ๋์ ๋ค๋ฅธ ์ฌ์ค์ด๋ค.\n */\n dirtyItems?: Set<string>\n /** ๋ค์ ๋ธ๋ก๋์บ์คํ
์์ ์ ๋ถ ๋ง๋ค์ด์ผ ํ๋ โ ์ฃผ๊ธฐ๋ง๋ค ํ ๋ฒ์ ๊ทธ๋ฌผ๋ก ์ ๋ถ ๋ง๋ ๋ค. */\n fullBroadcastDue?: boolean\n /** ์ ๋ถ ๋ง๋ค๊ธฐ๊น์ง ๋จ์ ์ฐฝ ์. */\n fullBroadcastCountdown?: number\n /** live ์ ๋ ๊ฒฐ์ โ ingest ์ด๋ฒคํธ๋ฅผ ๋ชจ์๋ค๊ฐ coalescer tick ์์ ๋ฐฐ์น ๊ธฐ๋ก(์ด๋ฒคํธ๋ง๋ค DB write ๊ธ์ง). */\n pendingJournal?: any[]\n /** live ์ ๋ revision ์นด์ดํฐ(sim ์ delta revision ๋์ โ ์๊ฐ์ฌํยทํ์คํ ๋ฆฌ ๋
ธ๋ธ ์ต์ปค). */\n revision?: number\n /** live ์ฒ๋ฆฌ๋ ๊ณ์ธก(๋ชจ๋ํฐ, โฃ-1). */\n metrics?: TwinMetrics\n}\n\n/**\n * ํธ์์ด **์ค์ค๋ก ๋ฉ์ถ ์ด์ ** โ ๋ฌธ์ฅ์ด ์๋๋ผ ์ฝ๋๋ค.\n *\n * ์๋ฒ๊ฐ ๋ง๋ ์์ด ๋ฌธ์ฅ์ ๊ทธ๋๋ก ์ค์ผ๋ฉด ํ๊ตญ์ดยท์ผ๋ณธ์ด ํ๋ฉด์ ๊ทธ ์์ด๊ฐ ๋ฌ๋ค. ์ด ์์คํ
์ ๊ฑฐ์ ๋ฉ์์ง์์\n * ๊ฐ์ ๊ฒฐ๋ก ์ ์ด๋ฅด๋ ๋ค(์ฝ๋+ํ๋ผ๋ฏธํฐ๋ฅผ ๋ด๊ณ ํ๋ฉด์ด ์ฎ๊ธด๋ค). `reason` ๋ง์ ์๋ฌธ ๊ทธ๋๋ก๋ค โ ์ปค๋ยท๋ฐํ์์ด\n * ๋ธ ์ค๋ฅ ๋ฌธ๊ตฌ๋ ์ฎ๊ธธ ์ ์๋ ์ดํ๊ฐ ์๋๊ณ , ์ฎ๊ธฐ๋ ค ๋ค๋ฉด ์์ธ์ ์๋๋ค.\n */\nexport interface StopNote {\n code: 'starved' | 'tick-failed'\n params: Record<string, string | number>\n}\n\nexport class TwinEngine {\n /*\n * ๊ธฐ๋ ์ค์ธ ๋ฐํ์ โ **ํค๋ `runtimeKey(domainId, instanceId)`** ๋ค(`runtime-key.ts` ์ ์ด์ ).\n *\n * ์์ ์ `instanceId` ํ๋๋ก ํค๋ฅผ ์ก์๋ค. ๊ทธ๋ฐ๋ฐ ์ ์ฒด์ฑ์ `(domain, instanceId)` ์ด๊ณ DB ์ ์ผ์ฑ๋\n * ๊ทธ์ชฝ์ด๋ผ, ๋ ํ
๋ํธ๊ฐ ๊ฐ์ id ๋ฅผ ์ฐ๋ฉด(๋ ํผ๋ฐ์ค ๊ฒฝ๋ก๊ฐ ์์ค ์ด๋ฆ์ id ๋ก ์ด๋ค) ํ ์๋ฆฌ๋ฅผ ๋คํ๋ค.\n * **์์ง ๋ฐ์์ ์ด ๋งต์ ์ง์ ์์ธํ์ง ์๋๋ค** โ `owns`ยท`runtime`ยท`kernel` ๊ฐ์ ์ ๊ทผ์๋ฅผ ์ด๋ค.\n */\n static instances: Record<string, InstanceRuntime> = {}\n /** ๋ผ์ด๋ธ ๋ฐํ์์ด ์์ ๋(๋ณต๊ตฌ ํ ๋ฏธ๊ธฐ๋) ์ ๋์์ ์ฌ๊ตฌ์ฑํ ์ํ ์บ์. */\n /** ์์คํํธ ์จ์ โ `instances` ์ **๊ฐ์ ํค**(๊ฒน์น๋ฉด ๋จ์ ์ค๋
์ท์ผ๋ก ์ฌ๊ณ ๊ฐ ์์ธ๋ค). */\n static recovered: Record<string, any> = {}\n static TICK_MS = 1000\n\n /*\n * โโ ๊ตถ๊น ์์ ๋ง (2026-08-14) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์๋ฎฌ ํฑ์ **๋ฉ์ธ ์ด๋ฒคํธ ๋ฃจํ**์์ ๋๋ค. ๊ทธ๋์ ํ ํธ์์ ํฑ์ด ๊ธธ์ด์ง๋ฉด ๊ทธ ์๊ฐ๋งํผ ํธ์คํธ ์ ์ฒด๊ฐ\n * ๋ฉ์ถ๋ค โ HTTPยท๊ตฌ๋
ยท๋ค๋ฅธ ํธ์์ ํฑ๊น์ง. ์ค์ธก์ผ๋ก `order-check` ์ ํฑ ํ๋๊ฐ 34.9์ด์๊ณ , ๊ทธ ์ฌ์ด\n * ๊ตฌ๋
์๊ฐ ์๋ฌด๊ฒ๋ ๋นผ๋ด์ง ๋ชปํด pubsub ์ด ๋์ณ ํ๋ก์ธ์ค๊ฐ ์ฃฝ์๋ค.\n *\n * ๋ธ๋ก๋์บ์คํ
๋ฐ๋ณต์ ๊ฑท์ด๋์ง๋ง(`flushLiveBroadcasts` ๋ก ๋ณํฉ) **์ปค๋ ํฑ ์์ฒด๋ ์ฌ์ ํ ๋ฉ์ธ ๋ฃจํ์ ์๋ค.**\n * ๊ทผ๋ณธ ํด๊ฒฐ์ ๋ถ์ฐ์ด๊ณ ๊ทธ๊ฒ์ ์ด์ฐ๋๋ค โ ๊ทธ๋๊น์ง์ ์์ ๋ง์ด ์ด ์
์ด๋ค.\n *\n * ํ์ ์ ์์ฐ(500ms)์ด ์๋๋ผ **๊ตถ๊น ๋ฌธํฑ**์ผ๋ก ๋ฐ๋ก ๋๋ค: ์กฐ๊ธ ๋๋ฆฐ ํธ์์ ๊ณ๊ธฐํ์ด ๋งํ๊ฒ ๋๊ณ \n * (๊ฒฝ๊ณ ), ํธ์คํธ๋ฅผ ๊ตถ๊ธฐ๋ ํธ์๋ง ๋ฉ์ถ๋ค. ํ ๋ฒ์ผ๋ก ๋ฉ์ถ์ง ์๋๋ค โ ์์คํํธ ์งํ์ ์ฒซ ํฑ์ ์๋\n * ๋ฌด๊ฒ๋ค(๋ณต๊ตฌํ ์ํ๋ฅผ ์ฒ์ ์ ๋๋ค). **์ฐ์**์ผ๋ก ์ด์ด์ง ๋๊ฐ ๊ตฌ์กฐ์ ์ผ๋ก ๋๋ฆฐ ๊ฒ์ด๋ค.\n */\n /*\n * โโ ํฑ์ **ํ ์๊ฐ์ ๋ชฐ์ง ์๋๋ค** (2026-08-21 ์ค์ธก) โโโโโโโโโโโโโโโโโโโโโโโโ\n * ํธ์๋ง๋ค `setInterval(TICK_MS)` ๋ฅผ ๋ถํ
๋ ๋๋ํ ์ธ์ฐ๋ฉด, ์ค๋ฌด ๊ฐ๊ฐ **๊ฐ์ ๋ฐ๋ฆฌ์ด์** ๊นจ์ด๋๋ค.\n * ๊ฐ์์ ํฑ์ด ์งง์๋(์ค์ธก: ๋ฌผํ 2,400 ๊ฐ์์ 0.23ms) ๊ทธ ์๊ฐ์๋ ์ค๋ฌด ๊ฐ๊ฐ ํ ์ค๋ก ๋ถ์ด ์คํ๋๊ณ ,\n * ๊ทธ ์ฌ์ด ๋์ฐฉํ HTTP ์์ฒญ์ ์ ๋ถ ๋ค์์ ๊ธฐ๋ค๋ฆฐ๋ค. ์ด๋น ํ ๋ฒ์ ์ ์ฒด๊ฐ ใ๋๋ฅผ ๋๋ง๋ค ๊ฑธ๋ฆฐ๋คใ๋ก\n * ๋ํ๋๋ ์๋ฆฌ๋ค.\n *\n * ๊ทธ๋์ ์ฒซ ๋ฐํ๋ง ๊ฐ๊ฒฉ ์์์ **๊ณ ๋ฅด๊ฒ ํฉ๋๋ค** โ ์ด ์์
๋์ ๊ฐ๊ณ ํ ์๊ฐ์ ์ต๋์น๋ง ๋ฎ์์ง๋ค.\n * ํธ์์ด ๊ฐ๊ฒฉ๋ณด๋ค ๋ง์์ง๋ฉด ๋ค์ ๊ฒน์น๋ฏ๋ก, ๊ทธ๋๋ ์ด ํฉ๊ธฐ๊ฐ ์๋๋ผ ๋ถ์ฐ์ด ๋ต์ด๋ค(์ด์ฐ๋จ).\n */\n /** ๋ถํ
๋ ํธ์ ํ๋๋ฅผ ๋์ด๋ฆฐ ๋ค ๋ฃจํ๋ฅผ ๋น์ ์ฃผ๋ ์๊ฐ(ms) โ ๊ทธ ์ฌ์ด ๋์ฐฉํ ์์ฒญ์ด ์ฒ๋ฆฌ๋๋ค. */\n static BOOT_YIELD_MS = 25\n private static tickPhase = 0\n /**\n * ํฉ์ด์ง ์ฒซ ๋ฐํ ๋ค ์ฃผ๊ธฐ ํฑ. **ํธ๋ค์ ํญ์ ์ง์ง ํ์ด๋จธ**๋ค โ ์ ์งํ๋ ์ชฝ์ด `clearInterval(inst.timer)`\n * ํ๋๋ก ๋๋ด์ผ ํ๋ฏ๋ก, ์ฒซ ๋ฐํ ์ ์๋ ๊ทธ `setTimeout` ์, ์ดํ์๋ `setInterval` ์ ๊ฐ์ ์๋ฆฌ์ ๋๋ค\n * (๊ฐ์ผ ๊ฐ์ฒด๋ฅผ ์ฃผ๋ฉด `clearInterval` ์ด ์๋ฌด ์ผ๋ ํ์ง ์๊ณ ํธ์์ด ๋ฉ์ถ์ง ์๋๋ค โ ์กฐ์ฉํ ๊ฒฐํจ์ด ๋๋ค).\n */\n private static startTickTimer(fn: () => void, hold: (t: any) => void): any {\n const spread = Math.max(1, Math.round(this.TICK_MS / 20))\n const offset = (this.tickPhase = (this.tickPhase + spread) % this.TICK_MS)\n const first = setTimeout(() => {\n const interval = setInterval(fn, this.TICK_MS)\n if (typeof interval?.unref === 'function') interval.unref()\n hold(interval) // ์ ์ง ๊ฒฝ๋ก๊ฐ ์ง์ธ ๋์์ ๋ฐ๊ฟ ์ค๋ค\n fn()\n }, offset)\n if (typeof first?.unref === 'function') first.unref()\n return first\n }\n\n /** ๊ตถ๊น ๋ฌธํฑ โ ํฑ ๊ฐ๊ฒฉ์ ๋ฐฐ์(1์ด ๊ฐ๊ฒฉ์ด๋ฉด 5์ด). ์ด ์๊ฐ๋งํผ ํธ์คํธ๊ฐ ๋ฉ์ถ๋ค. */\n static STARVE_FACTOR = 5\n /** ์ฐ์ ๋ช ๋ฒ์ด๋ฉด ๋ฉ์ถ๋ โ 3๋ฒ์ด๋ฉด 15์ด๋ฅผ ๊ตถ๊ธด ์
์ด๊ณ , ๊ทธ๊ฑด ์ฐ์ฐ์ด ์๋๋ค. */\n static STARVE_STREAK = 3\n private static starveStreak = new Map<string, number>()\n /**\n * ์ ๋ฉ์ท๋ โ **ํ๋ฉด์ด ๊ทธ๋๋ก ๋งํ ์ ์๊ฒ.** ์ค์ค๋ก ๋ฉ์ถ ํธ์์ด ์ด์ ์์ด ใ์ ์งใ๋ก๋ง ๋ณด์ด๋ฉด\n * ์ฌ๋์ ์๊ธฐ๊ฐ ๋ฉ์ถ ์ค ์๋ค. ๋ฉ๋ชจ๋ฆฌ์๋ง ๋๋ค(์ฌ๊ธฐ๋ํ๋ฉด ์ฌ๋ผ์ง๋ค โ ๊ทธ๋๋ ใ๋ชจ๋ฅธ๋คใ๊ฐ ์ฌ์ค์ด๋ค).\n */\n private static stopNotes = new Map<string, StopNote>()\n\n /* ์ต์ ์ค๋
์ท ์์(warm-start) โ ์ฌ๊ธฐ๋ ์ ์ ๋ fold-from-0 replay ๋์ ๋ง์ง๋ง ๋ผ์ด๋ธ ์ค๋
์ท์ผ๋ก ๋ณต์.\n * ํ๋ ์์ํฌ ๊ณตํต cache-service(@things-factory/cache-service) ์ฌ์ฌ์ฉ(์ฌ๋ฐ๋ช
๊ธ์ง, framework-leverage ยง4).\n * ์ ๋์ ๊ทธ๋๋ก ์ง์ค(์๊ฐ์ฌํ/history replay ๋ฌด๋ณ๊ฒฝ) โ ์บ์๋ display-only ์์คํํธ ์ต์ ํ. */\n static SNAPSHOT_CACHE_ID = 'twin-snapshot'\n /*\n * โโ ์ฌ๊ฐ์ **์ฌ์ฌ** โ ๊ณผ๊ฑฐ๋ฅผ ๋ฌผ์์ ๋ ๋ชฉํ ์ง์ ์์ ์ ๊ธฐ ์ํด (2026-08-18) โโ\n *\n * ์ต์ ์ฌ๊ฐ์ ํ๋๋ก๋ ์๊ฐ์ฌํ์ ๋์ธ ์ ์๋ค: ๊ทธ๊ฒ์ ์ธ์ ๋ ๋ชฉํ๋ณด๋ค **๋ค**์ ์๋ค. ๊ทธ๋์ ์ง์ ์\n * ์ฌ๋ฌ ๊ฐ ๋จ๊ธด๋ค. ๋ค๋ง ๊ทธ๊ฒ๋ค์ ๊ฐ๊ฐ ์ํ ์ ์ฒด๋ฅผ ๋ค๊ณ ์์ด ๋ฌด๊ฒ๋ค โ ํ ํ์ ๋ชฐ์ ๋ฃ์ผ๋ฉด ๊ฑฐ๋ํ\n * JSON ์ด ๋๋ฏ๋ก **์ง์ ๋ง๋ค ๋ฐ๋ก ๋๊ณ ์์ธ์ ๋๋ค**(cache-service ๋ ํด์ ํค ์กฐํ๋ผ ์ด๊ฑฐ๊ฐ ์ ๋๋ค).\n *\n * ๊ฐ๊ฒฉ์ ๋ฆฌ๋น์ ๋๊ธ์ผ๋ก ์ก๋๋ค(`CHAIN_STRIDE`): ๋๊ธ์ ๋์ ๋๋ง ํ ์ง์ ์ ๋จ๊ธฐ๋ฏ๋ก, ์ ๋์ด ๋น ๋ฅด๊ฒ\n * ์๋ผ๋ ํธ์์์๋ ์ง์ ์๊ฐ ํญ๋ฐํ์ง ์๋๋ค. ์ค๋๋ ๊ฒ๋ถํฐ ๋ฒ๋ฆฌ๊ณ ์ต๊ทผ `CHAIN_KEEP` ๊ฐ๋ง ๋ ๋ค โ\n * ๊ณผ๊ฑฐ๋ก ๊น์ด ๊ฐ์๋ก ์ง์ ์ด ์์ด 0๋ถํฐ ์ ๋ ๊ฒ์ **์๋ ค์ง ํ๊ณ**๋ค(๋ฌดํ ๋ณด๊ด๋ณด๋ค ์ ์งํ๋ค).\n */\n static CHAIN_CACHE_ID = 'twin-fold-chain'\n static CHAIN_INDEX_CACHE_ID = 'twin-fold-chain-index'\n static CHAIN_STRIDE = 5000 // ๋ฆฌ๋น์ ๋๊ธ โ ์ด ๊ฐ๊ฒฉ์ ๋์ ๋๋ง ํ ์ง์ ์ ๋จ๊ธด๋ค\n static CHAIN_KEEP = 5 // ์ต๊ทผ ๋ช ์ง์ ์ ๋ค๊ณ ์๋(๊ทธ๋ณด๋ค ๊ณผ๊ฑฐ๋ 0๋ถํฐ ์ ๋๋ค)\n static SNAPSHOT_TTL_S = 7 * 24 * 3600 // 7์ผ โ ์ ์ ๋ค์ดํ์ ์์กด, ๋ง๋ฃ ์ ์ ๋ replay ํด๋ฐฑ\n static CHECKPOINT_MS = 20000 // ์ฒดํฌํฌ์ธํธ ์ฃผ๊ธฐ(ํซ ๋ธ๋ก๋์บ์คํธ ๊ฒฝ๋ก์ ๋ถ๋ฆฌ, O(state) ์ค๋กํ)\n /**\n * **์ ๋ ๋ณด์กด โ ์ง์ฐ๋ ๊ฒ์ ์ ์ธ์ด ์์ ๋๋ง ํ๋ค.**\n *\n * โโ ์ ํ์ํ๊ฐ (2026-08-22 ์ค์ธก) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๊ฐ๋ฐ ์ ๋์ด ์๊ฐ๋น **581,794ํ ยท 0.85GB** ๋ก ์๋๋ค(ํ๋ฃจ 20GB). ๋ฐ๋ชจ MES ํธ์ ์
์ด ์ ์ฒด์ **97%**\n * ๋ฅผ ๋ง๋ค๊ณ ์ง์ฐ๋ ๊ฒ์ด ์์๋ค. ์ค๋ ๊ณ ์น ๊ฒ๋ค์ ใ๊ทธ ํฌ๊ธฐ์์๋ ์ง์๊ฐ ๋น ๋ฅด๊ฒใ์ด๊ณ , **ํฌ๊ธฐ ์์ฒด๋ฅผ\n * ์ค์ด๋ ๊ฒ์ ์๋ฌด๊ฒ๋ ์์๋ค.** ๊ทธ๋ฌ๋ฉด ๋ฉฐ์น ๋ง๋ค ๊ฐ์ ์๋ฆฌ๋ก ๋์์จ๋ค.\n *\n * โโ ๊ทธ๋ฐ๋ฐ ์ ๋์ ์ง์ฐ๋ ๊ฒ์ ์ฌ์ค์ ์๋ ์ผ์ด๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๊ทธ๋์ ์ธ ๊ท์จ์ ์งํจ๋ค.\n *\n * โ **์ ์ธ์ด ์์ผ๋ฉด ์๋ฌด๊ฒ๋ ์ง์ฐ์ง ์๋๋ค.** ๊ธฐ๋ณธ๊ฐ์ ์์์ด๋ค โ ์กฐ์ฉํ ์ง์ฐ๋ ํธ์ด ์กฐ์ฉํ ์๋\n * ๊ฒ๋ณด๋ค ๋์๋ค. ์ง์ฐ๋ ๊ฒ์ ์ฌ๋์ด ์ ํ๋ค.\n * โก **์ฒดํฌํฌ์ธํธ๊ฐ ๋์ ํ ์ ์๋ ๋งํผ๋ง.** ์ค๋
์ท์ด ์๊ฑฐ๋ ๊ทธ ๋ฆฌ๋น์ ์ ๋๋ ์๋ฆฌ๋ ๊ฑด๋๋ฆฌ์ง ์๋๋ค.\n * ์ฃผ์์ด ใ๋ง๋ฃ ์ ์ ๋ replay ํด๋ฐฑใ์ด๋ผ๊ณ ์ ์ด ๋ ๊ทธ๋๋ก โ ์ค๋
์ท์ด ์ฌ๋ผ์ง๋ฉด ์ ๋์ด **์ ์ผํ**\n * ๋ณต๊ตฌ ์๋จ์ด๋ฏ๋ก, ๋์ ํจ๊ป ์์ผ๋ฉด ๊ทธ ํธ์์ ์ํ๋ ๋๋๋ฆด ์ ์๋ค.\n * โข **์ง์ด ๊ฒ์ ๋งํ๋ค.** ๋ช ๊ฑด์ ์ด๋ ์๊ฐ๊น์ง ์ง์ ๋์ง ๋ก๊ทธ์ ๋จ๊ธด๋ค. ์กฐ์ฉํ ์ค์ด๋ ์ ๋์\n * ใ์์๋ ์ผใ๊ณผ ๊ตฌ๋ณ๋์ง ์๋๋ค.\n *\n * ๊ทธ๋ฆฌ๊ณ ๋ณด์กด ๊ธฐ๊ฐ์ **์ค๋
์ท TTL(7์ผ)๋ณด๋ค ์งง์ ์ ์๋ค.** ๋ ์งง์ผ๋ฉด ์ค๋
์ท์ด ์ด์ ์๋๋ฐ ๊ทธ๊ฒ์ด\n * ๊ฐ๋ฆฌํค๋ ์์ชฝ ์ ๋์ด ์๋ ๊ตฌ๊ฐ์ด ์๊ธฐ๊ณ , ์๊ฐ์ฌํยท๊ณ๋ณด ์ถ์ ์ด ๊ทธ ๊ตฌ๊ฐ์์ ์กฐ์ฉํ ๋น๋ค.\n */\n static JOURNAL_RETENTION_DAYS?: number = undefined\n /**\n * **๋๋ฉ์ธ๋ง๋ค ๋ค๋ฅธ ๋ณด์กด ๊ธฐ๊ฐ์ ์ฑ์ด ๋ตํ๋ค** โ ์์ง์ ๊ทธ ๊ฐ์ด ์ด๋์ ์ค๋์ง ๋ชจ๋ฅธ๋ค.\n *\n * ๋ณด์กด ๊ธฐ๊ฐ์ ํ
๋ํธ์ ์ ์ฑ
์ด๋ค: ํ ๊ณ ๊ฐ์ 30์ผ์ด ํ์ํ๊ณ ๋ค๋ฅธ ๊ณ ๊ฐ์ 7์ผ์ด๋ฉด ๋๋ค. ๊ทธ๋ฐ๋ฐ ์์ง์ด\n * `Setting` ์ ์ฝ๊ฒ ๋ง๋ค๋ฉด **์์ง์ด ํ๋ฉด ๊ด์ฌ์ฌ๋ฅผ ์๊ฒ ๋๋ค** โ ๋ฐฉํฅ์ด ๊ฑฐ๊พธ๋ก๋ค(์์ง์ ์ปค๋์ ํธ์คํธ์ด๊ณ \n * ๊ทธ ์์ ์ด๋ค ํ๋ฉด์ด ์๋์ง ๋ชฐ๋ผ์ผ ํ๋ค).\n *\n * ๊ทธ๋์ ์์์ ๋๋ค. ์ฑ์ด ์ด ํจ์๋ฅผ ์ฌ๊ณ , ๊ทธ ์์์ `Setting` ์ด๋ ๋ค๋ฅธ ๋ฌด์์ด๋ ์ฝ๋๋ค. ์ฌ์ง ์์ผ๋ฉด\n * `JOURNAL_RETENTION_DAYS`(์ค์ ํ์ผ์์ ์จ ํ๋ก์ธ์ค ๊ธฐ๋ณธ๊ฐ)๊ฐ ๋ตํ๋ค.\n *\n * `undefined` ๋ฅผ ๋๋ ค์ฃผ๋ฉด **๊ทธ ๋๋ฉ์ธ์ ์ง์ฐ์ง ์๋๋ค** โ ใ๋ชจ๋ฅธ๋คใ๋ฅผ ใ์ง์๋ ๋๋คใ๋ก ์ฝ์ง ์๋๋ค.\n */\n static retentionDaysOf?: (domainId: string) => Promise<number | undefined>\n static RETENTION_SWEEP_MS = 10 * 60 * 1000 // 10๋ถ๋ง๋ค ํ ๋ฒ โ ์ง์ฐ๋ ์ผ์ ๊ธํ์ง ์๋ค\n private static retentionTimer?: any\n private static checkpointTimer?: any\n\n /** ์ต์ ์ค๋
์ท์ cache-service ์ ์ฒดํฌํฌ์ธํธ(๋๋ฉ์ธ+instanceId ํค). display-onlyยท๋น์ฐจ๋จยท์ค๋ฅํก์. */\n static async persistSnapshot(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[runtimeKey(domainId, instanceId)]\n if (!inst) return\n /*\n * **๋ดํฌ๊ฐ ์๋๋ผ ์ํ๋ฅผ ์ ์ฅํ๋ค.** `snapshot()` ์ ์๋ฎฌ์์ `runtime.resync()` ๋ดํฌ๋ฅผ ์ฃผ๋๋ฐ,\n * ๊ทธ๊ฒ์ ๋ค์ `{revision, state}` ๋ก ๊ฐ์ธ ๋ฃ์ด ์๋ค โ ๊บผ๋ธ ๊ฐ์ ์ถ์ด ํ๋๋ ์์ด ์์คํํธ๊ฐ\n * ์กฐ์ฉํ ๋์ด๊ฐ๋ค(์ ๋์ ์์ฒ ๊ฑด์ด ์์ด๋ ํธ์์ด ๋น ์ฑ๋ก ๋ด๋ค).\n */\n const state = unwrapState(this.snapshot(domainId, instanceId))\n if (!state) return\n const revision = inst.revision ?? state.revision ?? 0\n /* ๊ตฌ์กฐ ๋ฆฌ๋น์ ๋ ํจ๊ป โ ์ฝ๋ ์ชฝ์ด \"์ด ์ํ๊ฐ ์ง๊ธ์ ๊ณต์ฅ์ธ๊ฐ\" ๋ฅผ ๊ฐ๋ฆด ์ ์์ด์ผ ํ๋ค. */\n const { structureRev } = await this.tipOf(domainId, instanceId).catch(() => ({ structureRev: null }) as any)\n await cacheService.setInCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId }, { revision, state, structureRev }, this.SNAPSHOT_TTL_S)\n }\n\n /**\n * ์ ๊ธฐ์ **์ฌ๊ฐ์ ** โ ๋ฆฌ๋์ ๋ด๋ถ ์ํ ์ ๋ถ + ๊ฐ๋ ๋์ ๊ธฐ.\n *\n * ์ค๋
์ท(`state`)์ ์๋น์ฒ๊ฐ ๋ณด๋ ๊ฐ์ด๋ผ ์ด์ด ์ ๊ธฐ์ ์จ์์ด ๋์ง ๋ชปํ๋ค(๋ณด๋ฅ๋ ๋ด๊นยท์งํฉยท๋ฐ์ ๋ชป ํ\n * ์ฌ๊ฑด ์ง๊ณ๊ฐ ์๋ค โ ๊ทธ ์ํ๋ก ๋ค๋ฅผ ์ ์ผ๋ฉด 0๋ถํฐ ์ ์ ๊ฒฐ๊ณผ์ ์กฐ์ฉํ ๋ฌ๋ผ์ง๋ค). ๊ทธ๋์ ์จ์์ ๋ฐ๋ก ๋ ๋ค.\n */\n private static readonly FOLD_NOTE = 'reducer + oee checkpoint โ the seed for folding only the tail'\n\n /** ์ฒดํฌํฌ์ธํธ๋ ์ต์ ์ค๋
์ท ๋ก๋(์์ผ๋ฉด null). getFromCache ๋ CacheStore ์ํฐํฐ๋ฅผ ๋ฐํ โ ํ์ด๋ก๋๋ .value. */\n static async loadSnapshot(\n domainId: string,\n instanceId: string\n ): Promise<{ revision: number; state: any; structureRev?: number | null; fold?: { reducer: ReducerCheckpoint; oee: OeeCheckpoint } } | null> {\n const entry = await cacheService.getFromCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId })\n return (entry as any)?.value ?? null\n }\n\n /**\n * ์ ์ ์ํ๋ฅผ ์ค๋
์ท์ผ๋ก ๋จ๊ธด๋ค โ **๋ผ์ด๋ธ๊ฐ ์๋์ด๋.**\n *\n * `persistSnapshot` ์ ๊ธฐ๋ ์ค์ธ ์ธ์คํด์ค์์๋ง ๋ฌ๋ค(๋ฉ๋ชจ๋ฆฌ๊ฐ ์ง์ค์ด๋ฏ๋ก ์ณ๋ค). ๊ทธ๋ฐ๋ฐ **๋ฉ์ถ**\n * ํธ์์ ์กฐํํ ๋๋ง๋ค ์ ๋์ ์ ๋ ๋ค์ ์ ๊ณ ์์๋ค(23,731๊ฑด์ง๋ฆฌ ํธ์์์ 4.6์ด). ๊ทธ ํด๋์ ๊ฒฐ๊ณผ๋ฅผ\n * ๋จ๊ฒจ ๋๋ฉด **์ฒ์ ํ ๋ฒ๋ง ๋๋ฆฌ๋ค.**\n *\n * `structureRev` ๋ฅผ ํจ๊ป ์ ๋๋ค: ์ด๋ฒคํธ๊ฐ ํ๋๋ ์ ๋์ด๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์์น์ฐ๋ฉด(์ฌํ๋ก๋น์ ๋) ๊ทธ\n * ์ํ๋ ๋ก์ ๊ฒ์ด๋ค. ๋ฆฌ๋น์ ๋ง ๋ณด๋ฉด ์ ์ค๋น๊ฐ ์๋ ์ ์ํ๋ฅผ \"์ง๊ธ\" ์ผ๋ก ๋ด๊ฒ ๋๋ค.\n */\n static async saveFoldedSnapshot(\n domainId: string,\n instanceId: string,\n value: { revision: number; state: any; structureRev?: number | null; fold?: { reducer: ReducerCheckpoint; oee: OeeCheckpoint } }\n ): Promise<void> {\n if (!value?.state) return\n await cacheService\n .setInCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId }, value, this.SNAPSHOT_TTL_S)\n .catch((err: any) => twinError(`[twin-engine] snapshot save fail \"${instanceId}\"`, err?.message ?? err))\n }\n\n\n /** ์ฌ์ฌ ์์ธ โ ์ด๋ค ๋ฆฌ๋น์ ์ง์ ์ ๋ค๊ณ ์๋(์ต์ ์ ์๋, ์ค๋ฆ์ฐจ์). */\n private static async chainIndex(domainId: string, instanceId: string): Promise<number[]> {\n const entry = await cacheService.getFromCache(this.CHAIN_INDEX_CACHE_ID, { domainId, instanceId }).catch(() => null)\n const revs = (entry as any)?.value?.revisions\n return Array.isArray(revs) ? revs.filter((r: any) => Number.isFinite(r)).sort((a: number, b: number) => a - b) : []\n }\n\n /**\n * ๋ชฉํ ์ด์ ์ **๊ฐ์ฅ ๊ฐ๊น์ด ์ง์ **์ ๊ณ ๋ฅธ๋ค โ ์์ผ๋ฉด `null`(0๋ถํฐ ์ ๋๋ค).\n *\n * ์๊ฐ์ผ๋ก ๋ฌผ์์ผ๋ฉด ๊ทธ ์ง์ ์ ๋ง์ง๋ง ์ฌ์ค ์๊ฐ์ด ๋ชฉํ ์ด๋ด์ฌ์ผ ํ๋ค(๋ฆฌ๋น์ ๋ง ๋ณด๋ฉด ๋ชฉํ๋ณด๋ค ๋ค์\n * ์ฌ์ค์ด ์จ์์ ์์ธ๋ค). ๊ตฌ์กฐ๊ฐ ๋ฐ๋ ํธ์์์๋ ์ฐ์ง ์๋๋ค โ ๋ง๋๋ฅผ ๊ฑด๋๋ด ์จ์์ ๊ทธ ๊ฒฝ๊ณ์\n * ํ์ ์ ์๋๋ค(๊ทธ ๊ฒฝ์ฐ๋ 0๋ถํฐ ์ ๋ ๊ฒ์ด ์ณ๋ค).\n */\n private static async chainSeedFor(\n domainId: string,\n instanceId: string,\n target: { revision?: number; timeMs?: number }\n ): Promise<{ revision: number; eventTime?: string; structureRev?: number | null; fold?: { reducer: ReducerCheckpoint; oee: OeeCheckpoint } } | null> {\n const revs = await this.chainIndex(domainId, instanceId)\n if (!revs.length) return null\n for (const revision of [...revs].reverse()) {\n if (target.revision != null && revision > target.revision) continue\n const entry = await cacheService.getFromCache(this.CHAIN_CACHE_ID, { domainId, instanceId, revision }).catch(() => null)\n const value = (entry as any)?.value\n if (!value?.fold?.reducer) continue\n if (target.timeMs != null) {\n const t = value.eventTime ? Date.parse(String(value.eventTime)) : NaN\n /* ์๊ฐ์ ๋ชจ๋ฅด๋ ์ง์ ์ ์ฐ์ง ์๋๋ค โ ๋ชฉํ ์ด๋ด์ธ์ง ๊ฐ๋ฆด ์ ์๋ค(์ง์ํ์ง ์๋๋ค). */\n if (!Number.isFinite(t) || t > target.timeMs) continue\n }\n return value\n }\n return null\n }\n\n /** ๋๊ธ์ ๋์์ผ๋ฉด ํ ์ง์ ์ ๋จ๊ธด๋ค โ ์ค๋๋ ๊ฒ์ ๋ฒ๋ฆฐ๋ค(์์ธ๋ ํจ๊ป ์ค์ธ๋ค). */\n private static async keepChainPoint(\n domainId: string,\n instanceId: string,\n /*\n * **๋ณด๊ธฐ(state)๋ ๋ด์ง ์๋๋ค** (2026-08-18 ์ค์ธก์ผ๋ก ๊ณ ์นจ).\n *\n * ์ฒ์์๋ ์ํ๊น์ง ๋ด์๋๋ ์ง์ ํ๋๊ฐ **11.4 MB** ์๋ค(27๋ง ๊ฑด ํธ์). ์ฌ์ฌ์ด ํ์ํ ๊ฒ์ ์จ์\n * (์ฌ๊ฐ์ )๋ฟ์ด๊ณ , ์๋น์ฒ๊ฐ ๋ณด๋ ๊ฐ์ ๊ทธ ์จ์์์ ๋ค์ ๋ง๋ค์ด์ง๋ค โ ๊ฐ์ ์ฌ์ค์ ๋ ๋ฒ ์ ์ฅํ์ง ์๋๋ค.\n */\n value: { revision: number; eventTime?: string; structureRev?: number | null; fold: { reducer: ReducerCheckpoint; oee: OeeCheckpoint } }\n ): Promise<void> {\n const revs = await this.chainIndex(domainId, instanceId)\n const newest = revs.length ? revs[revs.length - 1] : -Infinity\n if (value.revision - newest < this.CHAIN_STRIDE) return // ์์ง ๋๊ธ์ ๋์ง ์์๋ค\n const next = [...revs, value.revision].slice(-this.CHAIN_KEEP)\n const dropped = revs.filter(r => !next.includes(r))\n await cacheService.setInCache(this.CHAIN_CACHE_ID, { domainId, instanceId, revision: value.revision }, value, this.SNAPSHOT_TTL_S)\n await cacheService.setInCache(this.CHAIN_INDEX_CACHE_ID, { domainId, instanceId }, { revisions: next }, this.SNAPSHOT_TTL_S)\n /*\n * ๋ฒ๋ฆฐ ์ง์ ์ **์์ธ์์๋ง** ๋น ์ง๋ค โ ๊ณต์ฉ ์บ์์ ์ญ์ API ๊ฐ ์๋ค(`ICacheService` ๋ getยทsetยท\n * clearStaleCache ๋ฟ์ด๋ค). ๊ทธ๋์ ๊ฐ์ TTL(7์ผ)๊น์ง ๋จ๋๋ค: ์๋ฌด๋ ๋ฟ์ง ๋ชปํ์ง๋ง ์๋ฆฌ๋ ์ฐจ์งํ๋ค.\n * ์ง๊ธ ๊ท๋ชจ์์ ๊ฐ๋นํ ์ ์๋ ๋ญ๋น์ด๊ณ , ๊ณต์ฉ ๋ชจ๋์ ์ญ์ ๋ฅผ ์ฌ๋ ๊ฒ์ ๋ค๋ฅธ ์๋น์ฒ๊น์ง ํจ๊ป ๋ณผ\n * ์ผ์ด๋ผ ์ฌ๊ธฐ์ ๋ชฐ๋ ํ์ง ์๋๋ค โ **์๋ ค์ง ํ๊ณ๋ก ์ ์ด ๋๋ค.**\n */\n if (dropped.length) console.info(`[twin-engine] \"${instanceId}\" fold chain dropped ${dropped.join(', ')} from the index (values expire with the cache TTL).`)\n }\n\n /** ์ด ํธ์ ์ ๋์ ๋ ๋ฆฌ๋น์ ยท ์ต์ ๊ตฌ์กฐ ๋ฆฌ๋น์ โ ์ค๋
์ท์ด ์ง๊ธ์ ์ฌ์ค์ธ์ง ๊ฐ๋ฆฌ๋ ๋ ๊ฐ. */\n private static async tipOf(domainId: string, instanceId: string): Promise<{ revision: number; structureRev: number | null }> {\n const [tip, newest] = await Promise.all([\n getRepository(TwinEvent).findOne({ where: { domain: { id: domainId }, instanceId }, order: { revision: 'DESC' } }),\n getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n ])\n return { revision: tip?.revision ?? 0, structureRev: newest?.rev ?? null }\n }\n\n /**\n * **์ ๋์ ๋ณด์กด ๊ธฐ๊ฐ๊น์ง๋ง ๋๋ค** โ ์ฒดํฌํฌ์ธํธ๊ฐ ๋์ ํ ์ ์๋ ๋งํผ๋ง ์ง์ด๋ค.\n *\n * ํ ์ธ์คํด์ค์์ ์ง์ฐ๋ ์กฐ๊ฑด์ **๋ ๋ค** ๋ง์กฑํด์ผ ํ๋ค.\n *\n * ยท `createdAt` ์ด ๋ณด์กด ๊ธฐ๊ฐ๋ณด๋ค ์ค๋๋๋ค โ **ํ์ด ์ฐ์ธ ์ค์ ์๊ฐ**์ด ๊ธฐ์ค์ด๋ค\n * ยท `revision` ์ด **์ฒดํฌํฌ์ธํธ ๋ฆฌ๋น์ ์ดํ**๋ค โ ๊ทธ ์์ ์ค๋
์ท์ด ๋์ ํ๋ค\n *\n * โโ ์ `eventTime` ์ด ์๋๋ผ `createdAt` ์ธ๊ฐ (2026-08-22 ์ค์ธก์ผ๋ก ๊ณ ์นจ) โโโโ\n * ์ฒ์์ `eventTime` ์ผ๋ก ์ ์๋ค. ๊ทธ๊ฒ์ **ํธ์์ ์๊ณ**๋ค โ ์๋ฎฌ๋ ์ด์
์ ์๊ธฐ ์๊ณ๋ก ์ฌ๊ฑด์ ์ฐ๊ณ ,\n * ๊ทธ ์๊ณ๋ ์ค์ ์๊ฐ๊ณผ ๋ฌด๊ดํ๊ฒ ์์๊ฑฐ๋ ๋ค์ ๋ค. ์ค์ธก:\n *\n * order-check ๊ฐ์ฅ ๋ฆ์ eventTime = 2027-06-08 โ ์ค์ ์๊ฐ๋ณด๋ค 10๊ฐ์ ์\n * hatio-mx2 2026-01-01 ~ ์ง๊ธ โ 7๊ฐ์์น๋ฅผ ํ ๋ฒ์ ์ง์ฐ๊ฒ ๋๋ค\n *\n * ์ฆ ใ7์ผใ์ด ํธ์๋ง๋ค ๋ค๋ฅธ ๋ป์ด ๋๋ค: ์๊ณ๊ฐ ์์ ํธ์์ ์์ํ ์ง์์ง์ง ์๊ณ , ๊ณผ๊ฑฐ๋ถํฐ ์ฐ์ ํธ์์\n * ๊ฑฐ์ ์ ๋ถ๊ฐ ํ ๋ฒ์ ์ง์์ง๋ค. **๋ณด์กด์ ์ ์ฅ ๋์ด์ ๋ฌธ์ **์ด๊ณ ์ ์ฅ ๋์ด๋ ์ค์ ์๊ณ๋ค.\n *\n * `createdAt` ์ ๊ทธ ํ์ด DB ์ ์ฐ์ธ ์๊ฐ์ด๊ณ 1,599๋ง ํ ์ ๋ถ ์ฑ์์ ธ ์๋ค(ํ์ธํจ). ๋๋ฉ์ธ ์๊ฐ์\n * ์ ์ฑ
์ ์ฐ์ง ์๋๋ค โ ๊ทธ ๋์ ์์ผ๋ฉด ์๋ฎฌ๊ณผ ๋ฏธ๋ฌ์์ ๊ฐ์ ์ค์ ์ด ๋ค๋ฅด๊ฒ ๋์ํ๋ค.\n *\n * ์ค๋
์ท์ด ์์ผ๋ฉด **๊ทธ ์ธ์คํด์ค๋ ๊ฑด๋๋ฆฌ์ง ์๋๋ค.** ์ ๋์ด ์ ์ผํ ๋ณต๊ตฌ ์๋จ์ธ ์ํ์ด๋ฏ๋ก, ์ง์ฐ๋ฉด\n * ๊ทธ ํธ์์ ์ํ๋ฅผ ๋๋๋ฆด ์ ์๋ค. ใ์ง์ธ ์ ์์๋คใ๋ ์ฌ์ค๋ ํจ๊ป ์ผ๋ค โ ์กฐ์ฉํ ๋๊ธฐ๋ฉด ใ๋ณด์กด์ด\n * ๋๋๋ฐ ์ ์ ์ค์ด๋๋ใ๊ฐ ๋๋ค.\n *\n * `createdAt` ์ด ๋น ์ ํ์ **์ง์ฐ์ง ์๋๋ค**(์๊ฐ์ ๋ชจ๋ฅด๋ ๊ฒ์ ใ์ค๋๋๋คใ๋ก ์ฝ์ง ์๋๋ค).\n *\n * ๋๋ผ์ด๋ฒ ๋ค์ฏ์ ๋ค ์ง๋์ผ ํ๋ฏ๋ก raw SQL ์ ์ฐ์ง ์๋๋ค โ ์กฐ๊ฑด ์ญ์ ๋ ์ฟผ๋ฆฌ๋น๋๊ฐ ์ด์ํ๋ค.\n */\n static async pruneJournal(domainId: string): Promise<{ deleted: number; instances: number; skipped: string[] }> {\n /* ๋๋ฉ์ธ์ ์ ์ฑ
์ด ๋จผ์ ๋ค(ยง`retentionDaysOf`). ์์ผ๋ฉด ํ๋ก์ธ์ค ๊ธฐ๋ณธ๊ฐ. ๋ ๋ค ์์ผ๋ฉด ์ง์ฐ์ง ์๋๋ค. */\n const perDomain = this.retentionDaysOf ? await this.retentionDaysOf(domainId).catch(() => undefined) : undefined\n const days = perDomain ?? this.JOURNAL_RETENTION_DAYS\n if (!days || days <= 0) return { deleted: 0, instances: 0, skipped: [] }\n\n /* ๋ณด์กด ๊ธฐ๊ฐ์ ์ค๋
์ท TTL ๋ณด๋ค ์งง์ ์ ์๋ค โ ์งง์ผ๋ฉด ์ค๋
์ท์ด ๊ฐ๋ฆฌํค๋ ์์ชฝ์ด ๋น๋ ๊ตฌ๊ฐ์ด ์๊ธด๋ค. */\n const minDays = this.SNAPSHOT_TTL_S / 86400\n const effectiveDays = Math.max(days, minDays)\n if (effectiveDays !== days) {\n twinWarn(\n `[twin-engine] journal retention ${days}์ผ์ ์ค๋
์ท TTL(${minDays}์ผ)๋ณด๋ค ์งง๋ค โ ${effectiveDays}์ผ๋ก ์ฌ๋ฆฐ๋ค ` +\n '(๋ ์งง์ผ๋ฉด ์ค๋
์ท์ด ์ด์ ์๋๋ฐ ๊ทธ๊ฒ์ด ๊ฐ๋ฆฌํค๋ ์์ชฝ ์ ๋์ด ์๋ ๊ตฌ๊ฐ์ด ์๊ธด๋ค)'\n )\n }\n const cutoff = new Date(Date.now() - effectiveDays * 86400 * 1000)\n\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n let deleted = 0\n let instances = 0\n const skipped: string[] = []\n\n for (const r of rows) {\n const snap = await this.loadSnapshot(domainId, r.instanceId).catch(() => null)\n const upTo = Number(snap?.revision ?? 0)\n if (!upTo) {\n /* ์ค๋
์ท์ด ์๋ค โ ์ ๋์ด ์ ์ผํ ๋ณต๊ตฌ ์๋จ์ด๋ฏ๋ก ์๋์ง ์๋๋ค. */\n skipped.push(r.instanceId)\n continue\n }\n const res = await getRepository(TwinEvent)\n .createQueryBuilder()\n .delete()\n .from(TwinEvent)\n .where('domain_id = :domainId', { domainId })\n .andWhere('instance_id = :instanceId', { instanceId: r.instanceId })\n .andWhere('revision <= :upTo', { upTo })\n .andWhere('created_at IS NOT NULL')\n .andWhere('created_at < :cutoff', { cutoff })\n .execute()\n const n = res.affected ?? 0\n if (n > 0) {\n deleted += n\n instances++\n /* **์ง์ด ๊ฒ์ ๋งํ๋ค** โ ์กฐ์ฉํ ์ค์ด๋ ์ ๋์ ใ์์๋ ์ผใ๊ณผ ๊ตฌ๋ณ๋์ง ์๋๋ค. */\n twinLog(\n `[twin-engine] journal pruned \"${r.instanceId}\" โ ${n}๊ฑด (revision โค ${upTo} ยท ${cutoff.toISOString()} ์ด์ ). ` +\n '๊ทธ ์์ ์ฒดํฌํฌ์ธํธ๊ฐ ๋์ ํ๋ค.'\n )\n }\n }\n if (skipped.length) {\n twinLog(\n `[twin-engine] journal prune skipped ${skipped.length} instance(s) with no checkpoint โ ` +\n `์ ๋์ด ์ ์ผํ ๋ณต๊ตฌ ์๋จ์ด๋ผ ์๋์ง ์์๋ค: ${skipped.slice(0, 5).join(', ')}${skipped.length > 5 ? ' โฆ' : ''}`\n )\n }\n return { deleted, instances, skipped }\n }\n\n /** ๋ณด์กด ์ ๋ฆฌ ์ฃผ๊ธฐ ๊ธฐ๋(1ํ) โ ์ ์ธ์ด ์์ผ๋ฉด ์๋ฌด๊ฒ๋ ํ์ง ์๋๋ค. */\n static startRetentionLoop(domainId: string): void {\n if (this.retentionTimer) return\n /*\n * ๊ฑธ์ง ์๋ ์กฐ๊ฑด: ํ๋ก์ธ์ค ๊ธฐ๋ณธ๊ฐ๋ ์๊ณ **๋๋ฉ์ธ์ ๋ฌผ์ ๊ธธ๋ ์์** ๋๋ค. ์์์ด ์ฌ๊ฒจ ์์ผ๋ฉด\n * ๊ธฐ๋ณธ๊ฐ์ด ์์ด๋ ๊ฑธ์ด์ผ ํ๋ค โ ๊ทธ ๋๋ฉ์ธ์ด ์๊ธฐ ๊ฐ์ ๊ฐ์ง ์ ์๋ค.\n */\n if (!this.JOURNAL_RETENTION_DAYS && !this.retentionDaysOf) return\n this.retentionTimer = setInterval(() => {\n this.pruneJournal(domainId).catch(err => twinError('[twin-engine] journal prune failed', err?.message ?? err))\n }, this.RETENTION_SWEEP_MS)\n if (typeof this.retentionTimer?.unref === 'function') this.retentionTimer.unref()\n twinLog(\n `[twin-engine] journal retention on โ ${this.JOURNAL_RETENTION_DAYS ?? '(๋๋ฉ์ธ ์ ์ฑ
)'}์ผ ยท ` +\n `${this.RETENTION_SWEEP_MS / 60000}๋ถ๋ง๋ค`\n )\n }\n\n /** ์ฒดํฌํฌ์ธํธ ๋ฃจํ ๊ธฐ๋(1ํ) โ ๋ผ์ด๋ธ ์ธ์คํด์ค๋ค์ ์ต์ ์ค๋
์ท์ ์ฃผ๊ธฐ ์์. */\n static startCheckpointLoop(): void {\n if (this.checkpointTimer) return\n this.checkpointTimer = setInterval(() => {\n for (const [key, inst] of Object.entries(this.instances)) {\n const { instanceId } = parseRuntimeKey(key)\n this.persistSnapshot(inst.domainId, instanceId).catch(err =>\n twinError(`[twin-engine] snapshot checkpoint fail \"${instanceId}\"`, err?.message ?? err)\n )\n }\n }, this.CHECKPOINT_MS)\n if (typeof this.checkpointTimer?.unref === 'function') this.checkpointTimer.unref()\n }\n\n /**\n * ๋ถํ
ํ
โ DB ์ status='running' ์ผ๋ก ๋จ์ ์ธ์คํด์ค๋ฅผ ์ ๋์์ ์ํ ์ฌ๊ตฌ์ฑ(DBโreplay).\n * ๋ผ์ด๋ธ tick ์ฌ๊ฐ(sim ๊ฒฐ์ ์ re-run / live ์ธ์ ์คํธ ์ง์)๋ ํ์. ์ฌ๊ธฐ์ ์ํ ๋ณต์ + ๋
ธ์ถ.\n */\n static async bootstrap(): Promise<void> {\n /* ๋ถํ
๋ถํฐ ์ฐ๋ค โ ์ฌ๋์ด ๊ฐ์ฅ ๋ต๋ตํ ๊ตฌ๊ฐ์ด ์ฌ๊ธฐ์ด๊ณ , ๊ทธ ๊ตฌ๊ฐ์ ์ฌ์ง ์์ผ๋ฉด ๊ฐ์ผ๋ก ๋งํ ์ ์๋ค. */\n loopLag.start()\n try {\n const repo = getRepository(TwinInstance)\n const rows = await repo.find({ where: { status: 'running' } })\n for (const row of rows) {\n if (!row.domainId || !row.instanceId) continue\n // ์์คํํธ: ์บ์๋ ์ต์ ์ค๋
์ท ์ฐ์ (O(1) + attentions/OEE ๋ฑ ๋ผ์ด๋ธ ํ์์ํ ๋ณด์กด).\n // ์์ผ๋ฉด ์ ๋ fold-from-0 replay(์ง์ค ํด๋ฐฑ โ replay ๋ ๋ผ์ด๋ธ ํ์์ํ๋ฅผ ๋ชป ๋ด์ผ๋ฏ๋ก ์บ์๊ฐ ๋ ์ถฉ์ค).\n const cached = await this.loadSnapshot(row.domainId, row.instanceId).catch(() => null)\n if (cached?.state) {\n /* ์์ ์ ๊ฒนํฌ์ฅ์ผ๋ก ์ ์ฅ๋ ๊ฐ์ด ๋จ์ ์์ ์ ์๋ค โ ์ฝ๋ ์ชฝ์์๋ ๋ฒ๊ธด๋ค(ํ ๋ฒ์ ๋ฐ๋์ ๋ง๋๋ค). */\n this.recovered[runtimeKey(row.domainId, row.instanceId)] = { revision: cached.revision, state: unwrapState(cached.state) }\n /*\n * **ใ์์คํํธํ๋คใ๊ณ ๋งํ์ง ์๋๋ค** โ ์ฌ๊ธฐ์๋ ์ํ๋ฅผ **์ฐพ์ ๋ ๊ฒ**๋ฟ์ด๋ค.\n *\n * ์ค์ ์ฃผ์
์ ๊ธฐ๋ ๋ ์ผ์ด๋๊ณ (`warmStart` ๊ฐ ๊ทธ๋ ๋ฌด์์ ์ฌ์๋์ง ๋งํ๋ค), ๋ฏธ๋ฌ(live) ํธ์์\n * ๊ทธ ์จ์์ ์์ ์ฐ์ง ์๋๋ค(`startLive` ๊ฐ ๋ฒ๋ฆฐ๋ค). ๊ทธ๋ฐ๋ฐ ์ด ์ค์ด ใwarm-startedใ๋ผ๊ณ ๋งํด\n * ๋ก๊ทธ๋ง ์ฝ์ผ๋ฉด ์ฌ๊ธด ์ค ์๊ฒ ๋๋ค โ ์ค์ ๋ก ๊ทธ๋ ๊ฒ ์ฝ๊ณ ์ฌ๊ธฐ๋ ๋ค ์ง์์๊ฐ์ด ์ฌ๋ผ์ง ๊ฒ์\n * ๋ฐ์ดํฐ ๋ฌธ์ ๋ก ์ค์งํ ๋ปํ๋ค.\n */\n twinLog(`[twin-engine] found cached state for \"${row.instanceId}\" โ revision ${cached.revision} (seeded at start).`)\n continue\n }\n const state = await this.recover(row.domainId, row.instanceId).catch(() => null)\n if (state) {\n this.recovered[runtimeKey(row.domainId, row.instanceId)] = { revision: state.revision, state }\n twinLog(`[twin-engine] recovered \"${row.instanceId}\" from journal โ revision ${state.revision}.`)\n }\n }\n /*\n * ์ํ๋ง ๋์ฐพ๋ ๊ฒ์ผ๋ก๋ **๋๋ ํธ์์ด ๋์ง ์๋๋ค** โ ๋ฐํ์๊น์ง ๋์ด๋ฆฐ๋ค(์๋).\n *\n * ๋์ด๋ฆฌ๊ธฐ ์ฌ์ด์ **๋ฃจํ๋ฅผ ํ ๋ฒ ๋น์ ์ค๋ค** (2026-08-21). ์์คํํธ ํ๋๊ฐ ๋ฌผํ ์์ฒ ๊ฐ๋ฅผ ์ ์ผ๋ฏ๋ก\n * ์ค๋ฌด ๊ฐ๋ฅผ ์ฐ๋ฌ์ ํ๋ฉด ๊ทธ ์๊ฐ ๋ด๋ด HTTP ๊ฐ ์์ง ์๋๋ค โ ์๋ฒ๋ ์ด๋ฏธ `Server ready` ๋ฅผ ์ฐ์\n * ๋ค๋ผ์, ์ฌ๋์๊ฒ๋ ใ์ด๋ ธ๋๋ฐ ์๋ฌด ๋ฐ์์ด ์๋ ํ๋ฉดใ์ผ๋ก ๋ณด์ธ๋ค. ์ด ์๊ฐ์ ๊ฐ๊ณ , ๊ทธ ์ฌ์ด์\n * ๋์ฐฉํ ์์ฒญ์ด ์ฒ๋ฆฌ๋ ํ๋ง ์๊ธด๋ค.\n */\n for (const row of rows) {\n await this.resumeRow(row)\n await new Promise(resolve => setTimeout(resolve, this.BOOT_YIELD_MS))\n }\n this.startCheckpointLoop() // ์ดํ ๊ธฐ๋๋๋ ๋ผ์ด๋ธ ์ธ์คํด์ค์ ์ต์ ์ค๋
์ท์ ์ฃผ๊ธฐ ์์\n /*\n * ๋ณด์กด ์ ๋ฆฌ โ **์ ์ธ์ด ์์ ๋๋ง** ๋๋ค(ยง`JOURNAL_RETENTION_DAYS`). ๋๋ฉ์ธ๋ง๋ค ํ ๋ฒ ๊ฑด๋ค.\n * ์ฒดํฌํฌ์ธํธ ๋ฃจํ ๋ค์ ๋๋ ์ด์ : ์ง์ธ ์ ์๋ ๊ฒฝ๊ณ๊ฐ ์ค๋
์ท์ด๋ฏ๋ก, ์ค๋
์ท์ ๋จ๊ธฐ๋ ์ชฝ์ด ๋จผ์ \n * ๋์์ผ ์ฒซ ์ ๋ฆฌ๊ฐ ์ค์ ๋ก ์ง์ธ ๊ฒ์ ๊ฐ๋๋ค.\n */\n for (const domainId of new Set(rows.map(r => r.domainId).filter(Boolean) as string[])) {\n this.startRetentionLoop(domainId)\n }\n } catch (err) {\n twinError('[twin-engine] recovery scan failed', err)\n }\n }\n\n /**\n * ๋ถํ
๋ **๋๋ ํธ์์ ์ค์ ๋ก ๋์ด๋ฆฐ๋ค** โ ใ๋๋ ์คใ์ด ์ฌ์ค์ด ๋๊ฒ.\n *\n * โโ ๋ฌด์์ด ๊ฑฐ์ง๋ง์ด์๋ (2026-08-14) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * `bootstrap()` ์ ์ํ๋ง ๋์ฐพ์ `recovered` ์ ๋ด์๊ณ , ์ปค๋์ ์ธ์ฐ๋ ๊ฒ์ **๋ช
์ mutation ๋ฟ**์ด์๋ค\n * (์ด ํ์ผ ์์ชฝ ์ฃผ์์ด ใํฅํใ๋ผ๊ณ ์ ์ด ๋ ๊ทธ ์๋ฆฌ๋ค). ๊ทธ๋์ ์๋ฒ๋ฅผ ํ ๋ฒ ์ฌ๊ธฐ๋ํ๋ฉด ๋ฑ๋ก๋ถ๋\n * `running` ์ด๋ผ ๋งํ๋๋ฐ **์๋ฌด ์ปค๋๋ ๋์ง ์์๋ค** โ ํ๋ฉด์ ๋๋ ํธ์์, ์ค์ ๋ก๋ ๋ฉ์ถ ํธ์์.\n * ๋ฏธ๋ฌ ํธ์์์๋ ๋ ๋์๋ค: ๊ณ์ธก์ด ์กฐ์ฉํ ๋๊ธฐ๊ณ , ์ฌ๋์ ใ๊ฐ์ด ์ ๋ณํ๋คใ๋ก ์๊ฒ ๋๋ค.\n *\n * โโ ๋ชจ๋๋ฅผ ์ง์ด๋ด์ง ์๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๋ฏธ๋ฌ์๋ ํธ์์ ์๋ฎฌ๋ก ๋์ด๋ฆฌ๋ฉด **์๋ ์์ง์์ ๋ง๋ค์ด ๋ธ๋ค**(๊ด์ธก ํธ์์ด ์ค์ค๋ก ๋ฌผ๊ฑด์ ์ฎ๊ธด๋ค).\n * ๊ทธ๋์ ์ ์ธ๋ `restartPolicy` ๊ทธ๋๋ก ๋์ด๋ฆฐ๋ค โ ๋ฏธ๋ฌ๋ ๊ด์ธก ๊ตฌ๋์ผ๋ก, ์๋ฎฌ์ ์๋ฎฌ๋ก.\n *\n * โโ ๋์ด๋ฆด ์ ์์ผ๋ฉด ๊ทธ๋ ๊ฒ ์ ๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์คํจ๋ฅผ ์ผํค๋ฉด ๋ฑ๋ก๋ถ๊ฐ ๊ณ์ `running` ์ด๋ผ ๋งํ๋ค โ ์ฐ๋ฆฌ๊ฐ ๊ณ ์น๋ ค๋ ๊ทธ ๊ฑฐ์ง๋ง์ด๋ค. ๊ทธ๋์ ์คํจํ\n * ํ์ `stopped` ๋ก ์ ๊ณ ์ด์ ๋ฅผ ๋จ๊ธด๋ค. ใ๋ฉ์ท๋คใ๋ ์ฌ์ค์ด๊ณ , ใ๋๋ ์คใ์ ์ฌ์ค์ด ์๋์๋ค.\n */\n private static async resumeRow(row: TwinInstance): Promise<void> {\n const { domainId, instanceId } = row\n if (!domainId || !instanceId) return\n if (this.instances[runtimeKey(domainId, instanceId)]) return // ์ด๋ฏธ ์ธ์์ก๋ค(๋ฐ๋ชจ ์๋ ๋ฑ)\n\n /*\n * ๋ฒค์น ์ฌ๋ณธ์ ๋์ด๋ฆฌ์ง ์๋๋ค โ ๊ทธ๊ฒ์ **๋๊ตฐ๊ฐ ์ง์ผ๋ณด๋ ์คํ**์ด๊ณ , ๋ฌด์ธ์ผ๋ก ๋์ด์๋๋ฉด ํธ์คํธ๋ฅผ\n * ๊ทธ๋๋ก ๋๋ค๊ธด๋ค(๊ฒฉ๋ฆฌ ์ฌ๋ณธ์ ๋ป์ ใ์ด์๊ณผ ์์ด์ง ์๋๋คใ์ด์ง ใ์์ํ ๋๋คใ๊ฐ ์๋๋ค).\n * ์คํ์ ์ฌ๊ธฐ๋์ ๋๊ธฐ์ง ๋ชปํ์ผ๋ฏ๋ก ๋ฑ๋ก๋ถ๋ ๊ทธ๋ ๊ฒ ์ ๋๋ค.\n */\n if (row.purpose === 'bench') {\n await this.markStopped(row, 'bench copy โ an experiment does not survive a restart unattended')\n return\n }\n\n try {\n /*\n * **์ ์ธ๋ ๋ชจ๋๋ก ๋์ด๋ฆฌ๋ ํ๋จ์ ํ ๊ณณ์ ์๋ค**(`startFromRegistry`) โ 2026-08-20.\n *\n * ์์ ์๋ ์ด ์๋ฆฌ์์ `resync` ๋ฅผ ๊ฐ๋ผ `startLive` ๋ฅผ ๋ถ๋ ๋ค. ๊ทธ๋์ ๋ถํ
์ผ๋ก ์ด์๋ ๋ฏธ๋ฌ๋\n * ๊ด์ธก ๊ตฌ๋์ด์์ง๋ง **์ฌ๋์ด ํ๋ฉด์์ ์์ํ ๋ฏธ๋ฌ๋ ์๋ฎฌ๋ก ๋ด๋ค**(๊ทธ ๋ฌธ์๋ ๊ฐ๋ฆผ์ด ์์๋ค).\n * ๊ฐ์ ์ ์ธ์ด ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ด์ง ์๋๋ก ๊ฐ๋ฆผ์ ๋ฌธ ์์ผ๋ก ์ฎ๊ฒผ๋ค.\n */\n await this.startFromRegistry(domainId, instanceId)\n if (row.restartPolicy === 'resync') {\n /* ๊ณ์ธก์ ๋๋ฅด๋ ํผ๋๋ ์ปค๋ฅํฐ์ ๊ฒ์ด๋ค โ ๋ ํผ๋ฐ์ค ๊ณ์ธต์ด ๋ถํ
ํ
์์ ๋ค์ ๋ถ์ธ๋ค\n (`resumeReferenceLiveFeeds`). ์ฌ๊ธฐ์ ์ด๋ํฐ๋ฅผ ์๋ ๊ฒ์ ๊ณ์ธต์ ๊ฑฐ๊พธ๋ก ์๋ ๊ฒ์ด๋ค. */\n twinLog(`[twin-engine] resumed mirror \"${instanceId}\" โ feed reattach is the reference layer's job.`)\n } else {\n twinLog(`[twin-engine] resumed ${row.restartPolicy} \"${instanceId}\".`)\n }\n } catch (err: any) {\n await this.markStopped(row, err?.message ?? 'resume failed')\n }\n }\n\n /** ๋์ด๋ฆฌ์ง ๋ชปํ ํ์ ์ ์งํ๊ฒ ์ ๋๋ค โ ใ๋๋ ์คใ์ด๋ผ ๋งํ๋ ์ฑ๋ก ๋์ง ์๋๋ค. */\n private static async markStopped(row: TwinInstance, why: string): Promise<void> {\n twinWarn(`[twin-engine] \"${row.instanceId}\" not resumed (${why}) โ registry says stopped now.`)\n try {\n await getRepository(TwinInstance).update({ id: row.id }, { status: 'stopped' })\n } catch (e: any) {\n twinError(`[twin-engine] could not mark \"${row.instanceId}\" stopped โ registry now lies about it.`, e?.message)\n }\n }\n\n /**\n * ์์คํํธ โ ๊ธฐ๋ํ๋ ์ปค๋์ **์ง์ ๊ด์ธก ์ํ**๋ฅผ ์ฃผ์
ํ๋ค.\n *\n * โโ ์ ํ์ํ๊ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * `loadTwinModel` ๋ **๊ตฌ์กฐ๋ง** ์ฃ๋๋ค(์๋ฆฌยท์ค๋น). ์ํ(๋ฌด์์ด ์ด๋์ ์ผ๋ง๋)๋ ์๋ค. ๊ทธ๋์ ์ฌ๊ธฐ๋ํ\n * ํธ์์ ์ ๋์ ์
๊ณ 540๊ฑด์ด ๋จ์ ์์ด๋ ์ฌ๊ณ ๊ฐ 0 ์ด์๊ณ , ํ๋ฉด์ \"๋ณด์ ์ค์ธ ๊ฒ์ด ์์ต๋๋ค\" ๋ผ๊ณ \n * ๋งํ๋ค โ ์๋ ์ฌ๊ณ ๋ฅผ ์๋ค๊ณ ํ๋ ์
์ด๋ค(2026-07-31 hatiolab-wms ์ค์ธก์ผ๋ก ํ์ธ).\n * `bootstrap()` ์ด ์ด๋ฏธ ์ฒดํฌํฌ์ธํธ ์บ์(์์ผ๋ฉด ์ ๋ replay)๋ก ์ํ๋ฅผ ๋ณต๊ตฌํด `recovered` ์ ๋ด์ ๋๋๋ฐ,\n * ๊ธฐ๋ ์๊ฐ ๊ทธ๊ฑธ **๋ฒ๋ฆฌ๊ณ ** ์์๋ค. ๋ฐ๋ง ์ฐ๊ฒฐ๋ผ ์๋ ์ฅ์น๋ฅผ ์๋๋ค.\n *\n * โโ ๋ฐ์ชฝ์ด๋ ๋ณต๊ตฌ๋ฅผ ๋ง๋ฌด๋ฆฌํ๋ค (2026-08-05) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ฌ๊ณ ๋ ์ด์๋ฌ๋๋ฐ **์งํ ์ค ์ฃผ๋ฌธ์ด ํต์งธ๋ก ์ฌ๋ผ์ง** ํ๋ฉด์ด ๋จ์ ์์๋ค. ์จ์์ด ์๋ฆฌยท๋ฌผํยท์ค๋น\n * ์
๋ง ๋๊ฒผ๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ ๊ทผ๊ฑฐ๋ \"์ค๋
์ท ์ค๋์ progress ๋ฐ์ ์๋ค\" ์๊ณ , ๊ทธ๋๋ ๋ง์๋ค โ\n * ๊ทธ๋ฌ๋ ์ปค๋ `OrderState` ๊ฐ ์๊ฐ(`requested`ยท`fulfilled`ยท`lines`)์ ๋์ฐพ์ ๋ค์๋ ์ด ์๋ฆฌ๋ง\n * ๊ทธ๋๋ก ๋จ์๋ค. ์ค๋ฅ๋ฅผ ๋ด์ง ์๋ ์ข
๋ฅ๋ผ ์ค๋ ๋ฒํ
ผ๋ค.\n *\n * ์ง๊ธ์ **๊ด์ธก ์ค๋
์ท ์ ์ฒด**๋ฅผ ๋๊ธด๋ค(์ค๋ยท์์
ยท์ฌ๋ยท์์ฐ ํฌํจ). ์๋ฎฌ์ ์ปค๋ `snapshot()`,\n * ๋ผ์ด๋ธ๋ `StateProjector` ๊ฐ ๊ทธ ์ผ๊ณฑ ์ถ์ ๋ชจ๋ ๋ด๋๋ค. ๋ฌด์์ ์ฌ์ ์ ์๋์ง ํ์ ํ๋ ๊ท์น\n * (์ดํ ์๋ฃ ์ค๋ ์ ์ธยท๊ณ ์ ์์
์ ์ธ)์ ์ปค๋์ ์๊ณ , ํธ์คํธ๊ฐ ๋ฏธ๋ฆฌ ๊ณจ๋ผ๋ด์ง ์๋๋ค.\n *\n * โโ ๋จ์ ํ๊ณ๋ ์จ๊ธฐ์ง ์๊ณ ์ผ๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ยท ์๊ฐ์ด ์๋ ์ค๋(progress ๋ง ์๋ ๊ฒ)๋ ๋จ์ ์๋์ ์ ์ ์์ด ์ฃผ์
ํ์ง ์๋๋ค. **์ง์ด๋ด์ง ์๋\n * ๋์ ๋ช ๊ฑด์ธ์ง ๋งํ๋ค** โ ์ธ์ง ์์ผ๋ฉด \"์ฃผ๋ฌธ์ด ์๋ค\" ์ \"์ฃผ๋ฌธ์ ๋ชป ์ฌ์๋ค\" ๊ฐ ํ๋ฉด์์ ๊ฐ์์ง๋ค.\n * ยท ์งํ ์ค ๊ฐ๋ณ ์์
์ ๋ด๋ถ ์ํ๋ ๊ด์ธก๋ง์ผ๋ก ์์ ํ ๋ณต์๋์ง ์๋๋ค(์ปค๋์ด ๋ช
์ํ ํ๊ณ, ์ฌ๊ณํ์ ๋งก๊น).\n *\n * โโ ๋ฒค์น๋ ์๋ํ์ง ์๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๋ถํ ๋ฒค์น๋ **์ ์์์์ ์ฉ๋์ ์ฌ๋ ๊ฒ**์ด ๋ชฉ์ ์ด๋ผ ํ์ฌ ์ํ๋ฅผ ์ฃผ์
ํ๋ฉด ์ธก์ ์ด ์ค์ผ๋๋ค.\n */\n private static warmStart(domainId: string, id: string, kernel: TwinKernel, purpose?: string): void {\n const hydrate = (kernel as any).hydrateObserved\n const plan = planWarmStart(this.recovered[runtimeKey(domainId, id)]?.state, purpose, typeof hydrate === 'function')\n\n if (plan.action === 'skip') {\n if (plan.reason === 'bench') {\n twinLog(`[twin-engine] \"${id}\" is a bench twin โ starting empty on purpose (seeding would skew the measurement).`)\n } else if (plan.reason === 'unsupported') {\n twinWarn(\n `[twin-engine] kernel for \"${id}\" cannot be warm-started (no hydrateObserved) โ it starts with structure only, so held stock will read as zero.`\n )\n }\n return\n }\n\n hydrate.call(kernel, plan.seed)\n const restored = [\n `${plan.itemCount} item(s)`,\n `${plan.equipmentCount} equipment`,\n `${plan.orderCount} open order(s)`,\n `${plan.taskCount} task(s)`,\n ...(plan.personCount ? [`${plan.personCount} person(s)`] : []),\n ...(plan.assetCount ? [`${plan.assetCount} asset(s)`] : []),\n /* ํ์ธํด ๋ ์ ํธ๋ฅผ ์ด์ด๋ฐ์๋ค๋ ์ฌ์ค๋ ๋งํ๋ค โ ์์ผ๋ฉด ํ์ธ ์ฒ๋ฆฌ๊ฐ ๋ค์ ๋นจ๊ฐ์ง๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค. */\n ...(plan.ackedCount ? [`${plan.ackedCount} acknowledged attention(s)`] : []),\n /* ใ์ธ์ ๋ถํฐ์ธ๊ฐใ๋ ๋งํ๋ค โ ์์ผ๋ฉด ์ง์๋ ์กฐ๊ฑด์ด ๋ชจ๋ ใ๋ฐฉ๊ธใ์ผ๋ก ๋ณด์ธ๋ค. */\n ...(plan.attentionSinceCount ? [`${plan.attentionSinceCount} attention start time(s)`] : [])\n ].join(', ')\n twinLog(`[twin-engine] warm-started \"${id}\" โ restored ${restored}.`)\n /* ๋บ ๊ฒ์ ์กฐ์ฉํ ๋๊ธฐ์ง ์๋๋ค โ ์ง์ด๋ด์ง ์์๋ค๋ ์ฌ์ค ์์ฒด๋ฅผ ๋งํด์ผ ํ๋ฉด์ ๋น์นธ์ด ์ฝํ๋ค. */\n if (plan.ordersWithoutDemand > 0) {\n twinWarn(\n `[twin-engine] \"${id}\": ${plan.ordersWithoutDemand} order(s) could not be restored โ they carry progress only, ` +\n 'with no requested/fulfilled counts, so the remaining demand is unknown. They are left out rather than guessed.'\n )\n }\n }\n\n /** ํธ์ ์ธ์คํด์ค ์์ โ ์ปค๋ ์์ฑ + ๋ชจ๋ธ ๋ก๋ + ์ง์ ์ํ ์์คํํธ + State ์คํธ๋ฆผ ๋ธ๋ฆฌ์ง + ์์ปค tick + ๋ ์ง์คํธ๋ฆฌ ์์. */\n /**\n * ๊ณต์ ๋ช
์ธ๋ฅผ ์ปค๋์ ์ฃ๋๋ค โ **์๋ฎฌ๋ ์ด์
์ ์๊ฐ์ ๋ฐ์ดํฐ๊ฐ ๋งํ๊ฒ ํ๋ ๋ง์ง๋ง ํ ์นธ.**\n *\n * `model.operations`(๋ง์คํฐ ์ธ์ ์คํธ๊ฐ ํต๊ณผ์ํจ ISA-95 OperationsSegment ๋ช
์ธ)๋ฅผ ์ปค๋์ด ์๋นํ๋ค.\n * ์์ผ๋ฉด ์ปค๋ ๊ธฐ๋ณธ ์์๋ก ๊ตด๋ฌ๊ฐ๊ณ , ์ปค๋ `specCoverage()` ๊ฐ ๋ฌด์์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ผ๋์ง ๋ณด๊ณ ํ๋ค.\n *\n * ์ปค๋์ด ์์ง ์ด API ๋ฅผ ๊ฐ์ง ์์ ๋ฒ์ ์ด๋ฉด(๋ฐํ ์ด์ ) **์กฐ์ฉํ ๋์ด๊ฐ์ง ์๊ณ ๊ฒฝ๊ณ ํ๋ค** โ ๋ช
์ธ๋ฅผ\n * ์ ์ธํ๋๋ฐ ๋ฐ์๋์ง ์๋ ์ํ๋ฅผ ๋ชจ๋ฅด๊ณ ์ง๋๊ฐ๋ฉด, ์์ธก์ด ์์๋ก ๋์๊ฐ ๊ฒ์ ์๋ฌด๋ ์ ์ ์๋ค.\n */\n private static applyOperations(kernel: any, model: any, id: string): void {\n /*\n * ํ์ฅ์ด ์ ํ ๊ณต์ ์๊ฐ โ ๋ช
์ธ ํ๊ณผ **๋ฐ๋ก** ์ฃ๋๋ค(`declareDurations`).\n *\n * ํ์ด ์๋ ์ข
๋ฅ์๋ ์๊ฐ์ ์ค ์ ์์ด์ผ ํ๋ค: ์ค์ธก์ผ๋ก ์ฐฝ๊ณ ยท์ผ๋ ํธ์์๋ ๊ณต์ ๋ช
์ธ ํ์ด 0๊ฐ์๊ณ ,\n * ๊ทธ ํธ์๋ค์ ์๊ฐ์ ์ ๋ถ ์ปค๋ ์์์์ ์๋ค. ํ์ ์ง์ด ๋ง๋๋ ๊ธธ์ ๋ง์๋ค(`label`ยท`intent` ๋ฅผ\n * ์ง์ด๋ด๋ฉด ๋ฅ๋ ฅ ๊ณ์ฐ๊น์ง ์ค์ผ๋๋ค) โ ๊ทธ๋์ ์๊ฐ๋ง ๋ฐ๋ ์ฐฝ๊ตฌ๊ฐ ์ปค๋์ ์๋ค.\n */\n const declared = model?.localDurations as Record<string, string> | undefined\n if (declared && Object.keys(declared).length) {\n if (typeof kernel?.declareDurations !== 'function') {\n twinWarn(\n `[twin-engine] \"${id}\": this facility declared ${Object.keys(declared).length} operation duration(s) but the kernel cannot consume them ` +\n '(declareDurations missing โ kernel needs publishing). The simulation keeps running on built-in constants, and specCoverage() will keep reporting \"default\".'\n )\n } else {\n try {\n kernel.declareDurations(declared)\n } catch (err: any) {\n /* ์ปค๋์ด ๊ฑฐ์ ํ ๊ฐ์ ์กฐ์ฉํ ๋๊ธฐ์ง ์๋๋ค โ ํ๋ฉด์ ใ๋ฃ์์ต๋๋คใ๋ผ๊ณ ๋งํ ๊ฐ์ด๋ค. */\n twinWarn(`[twin-engine] \"${id}\": declared operation duration rejected by the kernel โ ${err?.message ?? err}`)\n }\n }\n }\n /* ๊ณต์ ๋ชจ์(์์จยท์
์
)๋ ๊ฐ์ ๊ท์จ๋ก ์ฃ๋๋ค โ ์ปค๋์ด ๊ทธ ์ฐฝ๊ตฌ๋ฅผ ๊ฐ์ง ์์ผ๋ฉด ๊ทธ ์ฌ์ค์ ๋งํ๋ค. */\n const params = model?.localParams as Record<string, Record<string, string>> | undefined\n if (params && Object.keys(params).length) {\n if (typeof kernel?.declareParameters !== 'function') {\n twinWarn(\n `[twin-engine] \"${id}\": this facility declared operation parameters for ${Object.keys(params).length} operation(s) but the kernel cannot consume them ` +\n '(declareParameters missing โ kernel needs publishing). Yield and setup keep running on built-in constants.'\n )\n } else {\n try {\n kernel.declareParameters(params)\n } catch (err: any) {\n twinWarn(`[twin-engine] \"${id}\": declared operation parameter rejected by the kernel โ ${err?.message ?? err}`)\n }\n }\n }\n const ops = model?.operations\n if (!ops?.length) return\n if (typeof kernel?.loadOperations !== 'function') {\n twinWarn(`[twin-engine] \"${id}\": model declares ${ops.length} operation spec(s) but the kernel cannot consume them (loadOperations missing โ kernel needs publishing). Simulation will use built-in default durations.`)\n return\n }\n kernel.loadOperations(ops)\n }\n\n /**\n * ์์์๊ฐ ์ถ์ ๊ธฐ ์ฃผ์
โ **์์๋ฅผ ๋ฐ์ดํฐ๋ก ๋ฐ๊พธ๋ ๋ ๋ฒ์งธยท์ธ ๋ฒ์งธ ์ธต.**\n *\n * ์ปค๋ `durationOf` ์ ์ฐ์ ์์๋ ์ถ์ ๊ธฐ > ๋ช
์ธ > ์์๋ค. ๊ทธ ์ถ์ ๊ธฐ ์๋ฆฌ์ ๋ ๊ฐ์ง๋ฅผ ์ฌ์ฌ๋ก ๋ฃ๋๋ค:\n * โ **์ค์ธก**(์ ๋์ ์์
์ข
๋ฅ๋ณ ์์
์๊ฐ p50) โ ๊ทธ ํ์ฅ์์ ์ค์ ๋ก ์ผ๋ง ๊ฑธ๋ ธ๋. ๊ฐ์ฅ ๊ฐํ ๊ทผ๊ฑฐ.\n * โก **๊ฑฐ๋ฆฌ ร ์๋**(model.layout + ์ค๋น ์๋ ์์ฑ) โ ์ด๋์ ๊ฑฐ๋ฆฌ์ ๋น๋กํ๋ค. ์ปค๋์ ์ขํ๋ฅผ ๋ชจ๋ฅด๋ฏ๋ก\n * ํธ์คํธ๊ฐ ๊ณ์ฐํด ๋ฃ๋๋ค.\n * ๋ ๋ค ๋ชป ๋ง๋ค๋ฉด ์ฃผ์
ํ์ง ์๋๋ค โ ์ปค๋์ด ๋ช
์ธยท์์๋ก ๊ตด๋ฌ๊ฐ๊ณ `specCoverage()` ๊ฐ ๊ทธ ์ฌ์ค์ ๋จ๊ธด๋ค.\n *\n * ์ค์ธก์ DB ์กฐํ๋ผ ๋น๋๊ธฐ๋ค. ๊ทธ๋์ ์ด ํจ์๋ **await ํ์ง ์๋ ์ชฝ์์๋ ์์ **ํ๋๋ก ์คํจ๋ฅผ ์ผํค๋,\n * ๋ฌด์์ ์ ๋ชป ๋ฃ์๋์ง๋ ๋ก๊ทธ๋ก ๋จ๊ธด๋ค(์กฐ์ฉํ ๋ฌดํจํ ๊ธ์ง).\n */\n static async installEstimators(kernel: any, domainId: string, instanceId: string, model: any): Promise<void> {\n if (!kernel || typeof kernel !== 'object') return\n const travel = buildTravelEstimator({ layout: model?.layout, equipment: model?.equipment, unit: model?.unit })\n const measured = await this.measuredEstimator(domainId, instanceId)\n const chained = chainEstimators([measured?.estimator, travel.estimator])\n if (!chained) {\n /* ์ ๋ชป ๋ฃ์๋์ง ํ ๋ฒ๋ง ์๋ฆฐ๋ค โ ์ด๋์๊ฐ์ด ์์๋ก ๋จ์ ์ด์ ๋ฅผ ๋ชจ๋ฅด๊ณ ์ง๋๊ฐ์ง ์๊ฒ. */\n if (travel.reasons.length) twinWarn(`[twin-engine] \"${instanceId}\": no duration estimator installed โ ${travel.reasons.join('; ')}`)\n return\n }\n kernel.durationEstimator = chained\n /*\n * **์ํ๋ฅ ๋ ์ด๋ ฅ์์ ๋ฐฐ์ด๋ค** (2026-08-19) โ ์์์ ๊ฐ์ ์๋ฆฌ์์ ๋ถ์ธ๋ค.\n *\n * ์ปค๋์ด ๊ทธ ์์์ ๊ฐ์ง ์์ ๋ฒ์ ์ด๋ฉด(๋ฐํ ์ด์ ) ์กฐ์ฉํ ๋์ด๊ฐ์ง ์๊ณ ๋งํ๋ค: ์์จ์ด ์์๋ก ๋จ์\n * ์ด์ ๋ฅผ ๋ชจ๋ฅด๊ณ ์ง๋๊ฐ๋ฉด, ํ๋ฉด์ ๋ถ๋ ํ์ ์ด ๊ทธ ํ์ฅ์ ์ฌ์ค์ด ์๋๋ผ ์ฐ๋ฆฌ ์์์ ๊ฒฐ๊ณผ๋ค.\n */\n const yields = await this.measuredYield(domainId, instanceId)\n if (yields?.estimator) {\n if (typeof kernel.yieldOf !== 'function') {\n twinWarn(\n `[twin-engine] \"${instanceId}\": learned yield for ${Object.keys(yields.learned).length} operation kind(s) but the kernel cannot consume it ` +\n '(yieldOf missing โ kernel needs publishing). Yield keeps running on the declared value or the built-in constant.'\n )\n } else {\n kernel.yieldEstimator = yields.estimator\n twinLog(\n `[twin-engine] \"${instanceId}\": measured yield installed โ ${Object.entries(yields.learned)\n .map(([k, v]) => `${k}=${Math.round(v * 1000) / 10}%(${yields.samples[k].good + yields.samples[k].scrap}๊ฑด)`)\n .join(', ')}${yields.skipped.length ? ` ยท ํ๋ณธ ๋ถ์กฑ์ผ๋ก ๋บ ์ข
๋ฅ: ${yields.skipped.map(s => `${s.kind}(${s.judged})`).join(', ')}` : ''}`\n )\n }\n } else if (yields?.skipped.length) {\n /* ๋ฐฐ์ด ๊ฒ์ด ์๊ณ ๋ฒ๋ฆฐ ๊ฒ๋ง ์์ผ๋ฉด ๊ทธ ์ฌ์ค๋ ๋งํ๋ค โ ใ์ด๋ ฅ์ด ์๋คใ์ ใํ๋ณธ์ด ๋ชจ์๋ผ๋คใ๋ ๋ค๋ฅด๋ค. */\n twinLog(\n `[twin-engine] \"${instanceId}\": no measured yield yet โ samples below ${yields.minSamples}: ${yields.skipped\n .map(s => `${s.kind}(${s.judged})`)\n .join(', ')}`\n )\n }\n const learned = Object.keys(measured?.learned ?? {})\n const spread = Object.keys(measured?.spreads ?? {})\n twinLog(\n `[twin-engine] \"${instanceId}\": duration estimator installed โ measured kinds: ${learned.length ? learned.join(',') : 'none'}` +\n ` (with observed spread: ${spread.length ? spread.join(',') : 'none'})` +\n `${travel.estimator ? `, travel from distance (speeds: ${Object.keys(travel.speedsByKind).join(',')})` : `, travel not derived (${travel.reasons.join('; ')})`}`\n )\n }\n\n /**\n * ์ค์ธก ์ถ์ ๊ธฐ โ **์์ธก ์์ฒญ๋ง๋ค ์ ๋์ ๋ค์ ์ ์ง ์๋๋ค.**\n *\n * ์์ธก ์ปค๋์ ์์ฒญ๋ง๋ค ์๋ก ์ธ์์ง๊ณ (๋ฏธ๋ฌ ์์ธกยท๋ฐฑํ
์คํธ), ํ๋ฉด์ ์๊ฐ์ ๊ธ์ผ๋ฉด ๊ณ์ ์ฌ์์ธกํ๋ค.\n * ๊ฑฐ๊ธฐ์ KPI ์กฐํ๋ฅผ ๊ทธ๋๋ก ๋ฌ๋ฉด ์์ฒญ๋น ์ ๋ ์ค์บ์ด ํ๋์ฉ ๋ถ๋๋ค โ ์ค์ธก์ ๋ถ ๋จ์๋ก ๋ฐ๋์ง ์์ผ๋ฏ๋ก\n * ์งง์ TTL ๋ก ์ฌ์ฌ์ฉํ๋ค. ์บ์๋ ์ธ์คํด์ค๋ณ์ด๊ณ , ๋ง๋ฃ ์ ์๋ ๊ฐ์ ๊ฐ์ ์ด๋ค(์์ธก ๊ฐ ์ผ๊ด์ฑ๋ ์ป๋๋ค).\n */\n private static measuredCache = new Map<\n string,\n {\n at: number\n value: ReturnType<typeof buildMeasuredEstimator> | undefined\n /** ๊ฐ์ ํด๋์์ ๋์จ ์ํ๋ฅ โ **์ ๋์ ๋ ๋ฒ ์ ์ง ์๋๋ค**(์์์ ์์จ์ ๊ฐ์ ์ฐฝ์ ๊ฐ์ ์ฌ์ค์ด๋ค). */\n yields?: ReturnType<typeof buildYieldEstimator>\n }\n >()\n private static readonly MEASURED_TTL_MS = 60_000\n /**\n * ์บ์ ํญ๋ชฉ ์ํ โ **๋ผ์ดํ์ฌ์ดํด์ด ๋์น ๊ฒ๊น์ง ๋ง๋ ๋ ๋ฒ์งธ ๋ฐฉ์ด.**\n *\n * ์ง์์ `forgetInstance` ๊ฐ ํ๋ค(๊ทธ๊ฒ์ด ์ฒซ ๋ฒ์งธ ๋ฐฉ์ด์ด๊ณ ์ ํํ ์ชฝ์ด๋ค). ๊ทธ๋ฐ๋ฐ ํธ์์ด ์ฐ๋ฆฌ API ๋ฅผ\n * ์ง๋์ง ์๊ณ ์ฌ๋ผ์ง๋ ๊ธธ์ด ์๋ค: ๋๋ฉ์ธ(ํ
๋ํธ)์งธ๋ก ์ง์์ง๊ฑฐ๋ DB ๋ฅผ ์ง์ ์๋๋ ๊ฒฝ์ฐ๋ค. ๊ทธ๋\n * ๋จ์ ํญ๋ชฉ์ ์ง์ธ ์ฃผ์ธ์ด ์์ผ๋ฏ๋ก ์ํ์ด ํ์ํ๋ค.\n *\n * ๋์น๋ฉด **๊ฐ์ฅ ์ค๋ ์๋์ง ์์ ๊ฒ**๋ถํฐ ๋ฒ๋ฆฐ๋ค(Map ์ ์ฝ์
์์๊ฐ ๊ณง ๊ทธ ์์๋ค โ ๊ฐ์ ์ธ ๋๋ง๋ค\n * ๋ค์ ๋ฃ์ผ๋ฏ๋ก). ๋ฒ๋ฆฌ๋ ๊ฒ์ด ์ํด๊ฐ ์๋ ์ด์ : ์ด ๊ฐ์ ์บ์์ด๊ณ , ์์ผ๋ฉด ๋ค์ ๊ณ์ฐํ๋ค.\n *\n * ์๋ฅผ ํฌ๊ฒ ์ก๋๋ค โ ํธ์ ๊ท๋ชจ๋ ๋ ํฌ๊ณ , ํญ๋ชฉ ํ๋๋ ์์
์ข
๋ฅ๋ณ ์์ ๋ช ์ค์ด๋ค. ์ํ์ด ์์ผ๋ฉด\n * ์ ์ ๊ท๋ชจ์์ ์๋ก ๋ฐ์ด๋ด๋ฉฐ ์บ์๊ฐ ๋ฌด์๋ฏธํด์ง๋ค(๊ทธ๊ฒ ๋ ๋์๋ค: ์กฐ์ฉํ ๋๋ ค์ง๋ค).\n */\n private static readonly MEASURED_MAX = 5_000\n\n /** ์ด ํธ์์ด ์ด๋ ฅ์์ ๋ฐฐ์ด ์ํ๋ฅ โ ์์์ **๊ฐ์ ํด๋ยท๊ฐ์ ์บ์**์์ ์จ๋ค(์ ๋์ ๋ ๋ฒ ์ ์ง ์๋๋ค). */\n private static async measuredYield(domainId: string, instanceId: string) {\n await this.measuredEstimator(domainId, instanceId)\n return this.measuredCache.get(runtimeKey(domainId, instanceId))?.yields\n }\n\n private static async measuredEstimator(domainId: string, instanceId: string) {\n /* ํค๋ `runtimeKey` ํ๋๋ก โ ์์ผ๋ก ์กฐ๋ฆฝํ๋ฉด ์ง์ฐ๋ ์ชฝ๊ณผ ์ด๊ธ๋ ๋ชป ์ง์ฐ๋ ํญ๋ชฉ์ด ์๊ธด๋ค. */\n const key = runtimeKey(domainId, instanceId)\n const hit = this.measuredCache.get(key)\n if (hit && Date.now() - hit.at < this.MEASURED_TTL_MS) return hit.value\n let value: ReturnType<typeof buildMeasuredEstimator> | undefined\n let yields: ReturnType<typeof buildYieldEstimator> | undefined\n try {\n /* ์์
์ข
๋ฅ๋ณ ์ค์ธก โ ์ฐฝ์ ๋๋ํ(ํ๋ฃจ) ๋๊ณ ํ๋ณธ์ด ๋ชจ์๋ ์ข
๋ฅ๋ ์ถ์ ๊ธฐ๊ฐ ์ค์ค๋ก ๋บ๋ค. */\n const kpi: any = await computeTwinKpi({ domainId, instanceId, windowMinutes: 24 * 60, groupBy: 'taskKind' })\n value = buildMeasuredEstimator(kpi?.groups?.items, {})\n /* ๊ฐ์ ๊ทธ๋ฃน์์ ์ํ๋ฅ ๋ ๋ฐฐ์ด๋ค โ ํ ๋ฒ ์ ์ ์ ๋์ ๋์ด ๋๋ ์ด๋ค. */\n yields = buildYieldEstimator(kpi?.groups?.items, {})\n } catch (err) {\n twinWarn(`[twin-engine] \"${instanceId}\": measured duration lookup failed โ falling back to declared/default durations.`, (err as any)?.message)\n }\n /* ๋ค์ ๋ฃ์ด **์ต๊ทผ ์ด ๊ฒ**์ผ๋ก ๋ง๋ ๋ค โ ์ฝ์
์์๊ฐ ๊ณง ๋ฒ๋ฆด ์์์ด๋ฏ๋ก ์ด ํ ์ค์ด LRU ๋ฅผ ๋ง๋ ๋ค. */\n this.measuredCache.delete(key)\n this.measuredCache.set(key, { at: Date.now(), value, yields })\n if (this.measuredCache.size > this.MEASURED_MAX) {\n const oldest = this.measuredCache.keys().next()\n if (!oldest.done) this.measuredCache.delete(oldest.value)\n }\n return value\n }\n\n /**\n * **์๋ณธ์ด ์ ์ธํ ์๊ทน์ ์ฃ๋๋ค** โ ์ฌ๊ธฐ๋ํด๋ ์ด์ ์๊ฒ (2026-08-19).\n *\n * โโ ๋ฌด์์ด ๋ฌ๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๋ฐ๋ชจ์ ์๋๋ฆฌ์ค๋ ์๋ ์ฝ๋๊ฐ ๋ฉ๋ชจ๋ฆฌ์๋ง ์ค์๋ค. ๊ทธ๋์ ํธ์์ ์ฌ๊ธฐ๋ํ๋ฉด ์๊ทน์ด ์ฌ๋ผ์ง๊ณ ๊ตฌ์กฐ๋ง\n * ์ ์๋ ํธ์์ด ๋จ์๋ค(์์
0ยท์ค๋ 0) โ ใ์ด์ ์๋ ๋ฐ๋ชจใ๊ฐ **์ฒซ ์ฌ๊ธฐ๋๊น์ง๋ง** ์ด์๋ค.\n *\n * ์๊ทน์ ์ง์ **์๋ณธ**์ด๋ค(`TwinReference.connectionConfig.scenario`, ADR-0029 ยท\n * `plans/simulator-as-source.md` ยง4): ๋ฌด์์ด ๋ค์ด์ค๊ณ ๋ฌด์จ ์ฃผ๋ฌธ์ด ๋๋์ง๋ ์๋ฎฌ๋ ์ดํฐ๊ฐ ์ ํ๋ ์ฌ์ค์ด๊ณ \n * ํธ์์ ๋ฐ์ํ๋ค. ํธ์์ ์ ์ถ์ ๋ง๋ค๋ฉด ADR-0029 ๊ฐ ๊ฑท์ด๋ด์ผ ํ ํ๋ฉด์ด ํ๋ ๋์ด๋๋ค.\n *\n * ํ์ ์ ์์ ํจ์๊ฐ ํ๋ค(`planStimulus`) โ ๋ฏธ๋ฌ์ ์ฃ์ง ์๊ณ , ๊ฒ์ฌ๋ฅผ ํต๊ณผํ์ง ๋ชปํ ์ ์ธ์ ํ์ฐ์ง ์๊ณ \n * (๊ทธ ์ด๋ ฅ์ด ์๋ค: ์๋ชป๋ ์ ์ธ ํ๋๊ฐ ๋ค์ ํฑ์์ ์๋ฒ๋ฅผ ๋ด๋ ธ๋ค), ๋ชป ์ค์ ์ด์ ๋ **๋งํ๋ค.**\n */\n private static async installStimulus(domainId: string, instanceId: string, inst: InstanceRuntime): Promise<void> {\n let config: any\n try {\n const ref = await getRepository(TwinReference).findOne({ where: { domain: { id: domainId }, source: instanceId } })\n config = ref?.connectionConfig\n } catch (err: any) {\n twinWarn(`[twin-engine] \"${instanceId}\": could not read the declared stimulus โ ${err?.message ?? err}`)\n return\n }\n const plan = planStimulus(config, { hasScenarioEngine: !!inst.runtime?.scenario, mode: inst.mode }, validateScenario as any)\n if (plan.action === 'skip') {\n /* ์ ์ธ์ด ์๋ ๊ฒ์ ์ ์์ด๋ฏ๋ก ์กฐ์ฉํ ์ง๋๋ค. ๋๋จธ์ง ์
์ **๋งํ๋ค** โ ์ ์ธํ๋๋ฐ ์ ์ค๋ฆฐ ์ํ๋ค. */\n if (plan.reason !== 'none') {\n twinWarn(\n `[twin-engine] \"${instanceId}\": a stimulus is declared on its source but was not loaded (${plan.reason}${plan.detail ? `: ${plan.detail}` : ''}).` +\n (plan.reason === 'observed' ? ' This twin runs on observation โ we do not manufacture arrivals for it.' : '')\n )\n }\n return\n }\n try {\n /* ์๊ทน์ ์ฃ๊ณ ์์ํ๋ ๋ฐ ๋ ์๊ฐ โ ์ค์ธก์์ ํฐ ํธ์์ ์ด ๊ตฌ๊ฐ์ด 29~72์ด์๋ค. */\n const tStim = performance.now()\n inst.runtime!.scenario.load(plan.scenario)\n inst.runtime!.scenario.start()\n const stimMs = performance.now() - tStim\n recordPhase(inst.load ?? (inst.load = newLoadMeter()), 'stimulus', stimMs)\n const kinds = (plan.scenario.generators ?? []).map((g: any) => g?.kind).filter(Boolean)\n twinLog(\n `[twin-engine] \"${instanceId}\": stimulus from its source started in ${Math.round(stimMs)}ms โ ${kinds.length ? kinds.join(', ') : 'no generators'}.`\n )\n } catch (err: any) {\n twinWarn(`[twin-engine] \"${instanceId}\": the declared stimulus was rejected at load โ ${err?.message ?? err}`)\n }\n }\n\n /**\n * ์๊ทน์ **์๋ณธ์ ์ ์ธํ๋ค** โ ํ๋ก๋น์ ๋ยท๋ฐ๋ชจ ์๋๊ฐ ๋ถ๋ฅด๋ ๋ฌธ.\n *\n * ํธ์์ด ์๋๋ผ ์๋ณธ์ ์ ๋ ์ด์ ๋ ์์ ๊ฐ๋ค(ADR-0029). ์๋ณธ ํ์ด ์์ผ๋ฉด ๋ง๋ค์ง ์๋๋ค โ ์ด๋ค ์๋ณธ์์\n * ์จ ํธ์์ธ์ง ๋ชจ๋ฅด๋ ์ฑ ์๊ทน์ ์ง์ด ๋ถ์ด๋ฉด, ๊ทธ ์๊ทน์ด ์ด๋์ ์๋์ง ์๋ฌด๋ ๋์ง์ ์ ์๋ค.\n */\n static async declareStimulus(domainId: string, instanceId: string, scenario: any): Promise<boolean> {\n const repo = getRepository(TwinReference)\n const ref = await repo.findOne({ where: { domain: { id: domainId }, source: instanceId } })\n if (!ref) {\n twinWarn(`[twin-engine] \"${instanceId}\": no source reference โ a stimulus has nowhere to be declared.`)\n return false\n }\n ref.connectionConfig = withStimulus(ref.connectionConfig, scenario)\n await repo.save(ref)\n return true\n }\n\n /**\n * ์ด ํธ์์ด **์ด๋ ฅ์์ ์๊ฐ์ ๋ฐฐ์ด ์์
์ข
๋ฅ๋ค** โ ์ฌ๊ธฐ๋์๋ ๋จ๋ ๊ทผ๊ฑฐ.\n *\n * โโ ์ ํ์ํ๊ฐ (2026-08-18 ์ค์ธก) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ปค๋์ ์๊ธฐ๋ณด๊ณ (`specCoverage()`)๋ **์์
์ด ์๋ก ์๊ธธ ๋** ์ฑ์์ง๋ค. ๊ทธ๋์ ์ฌ๊ธฐ๋ ์งํ์๋ ์ด๋ ฅ์ด\n * ํ๋ถํ ํธ์์์๋ ๋ชฉ๋ก์ด ๋น๊ณ , ใ์ด ํธ์์ด ๋ฌด์จ ๊ณต์ ์ ๋๋ฆฌ๋ใ ํ๋ฉด์ด ๋น์นธ์ด ๋๋ค โ ๊ฐ์ ์ฑ์ธ ๊ณณ์\n * ๋ณด์ฌ์ผ ํ๋ ํ๋ฉด์ด ์ ์ ๊ทธ๋ ์๋ฌด ๋ง๋ ๋ชป ํ๋ค.\n *\n * ๊ทธ ๋น์นธ์ ์ด๋ ฅ๋ก ๋ฉ์ด๋ค: ์ ๋์์ ๋ฐฐ์ด ์ข
๋ฅ๋ **์ถ์ ๊ธฐ๊ฐ ์ด๋ฏธ ๋ตํ ์ ์๋ ์ข
๋ฅ**์ด๋ฏ๋ก, ์ง์ด๋ด๋\n * ๊ฒ์ด ์๋๋ผ ์๋ ์ฌ์ค์ ๊บผ๋ด๋ ๊ฒ์ด๋ค. ๊ฐ์ ์บ์(60์ด)๋ฅผ ์ฐ๋ฏ๋ก ์กฐํ๋ง๋ค ์ ๋์ ๋ค์ ์ ์ง ์๋๋ค.\n */\n static async measuredOperationKinds(domainId: string, instanceId: string): Promise<string[]> {\n const measured = await this.measuredEstimator(domainId, instanceId)\n return Object.keys((measured as any)?.learned ?? {})\n }\n\n /**\n * ์ง๊ธ ์ด ํธ์์ด ์ด๋ค ๋ชจ๋ธ๋ก ๊ตด๋ฌ๊ฐ๋๊ฐ โ ์์ธก ์ถ๋ ฅ ๋ณด์ ์ด **์๊ธฐ๊ฐ ๋ฐฐ์ด ๋ชจ๋ธ**์๋ง ์ ์ฉ๋๋๋ก\n * ๋น๊ตํ๋ ์ง๋ฌธ. ์ฌ๋ฃ๋ ํธ์คํธ๊ฐ ์๋ ๊ฒ(์ค์ธกยท์๋ยท์ ์ธ ๋ช
์ธ)์ด๋ผ ์ปค๋ ๋ฐํ ์ํ์ ๋ฌด๊ดํ๋ค.\n * ์คํจํ๋ฉด undefined โ ๊ทธ๋๋ ๋น๊ต๋ฅผ ํ์ง ์๋๋ค(๋ชจ๋ฅด๋ ๊ฒ์ ๊ทผ๊ฑฐ๋ก ๋ณด์ ์ ๋์ง ์๋๋ค).\n */\n static async modelBasis(domainId: string, instanceId: string): Promise<ModelBasis | undefined> {\n try {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n const model: any = reg?.model\n const measured = await this.measuredEstimator(domainId, instanceId)\n const travel = buildTravelEstimator({ layout: model?.layout, equipment: model?.equipment, unit: model?.unit })\n return { measured: measured?.learned, speeds: travel.speedsByKind, declared: model?.operations }\n } catch {\n return undefined\n }\n }\n\n /**\n * **์ด ํธ์์ด ํ๋ฃจ ๋ช ๋๋ฅผ ๋ผ ์ ์๋๊ฐ** โ ์คํํด ๋ณด์ง ์๊ณ ๋ตํ๋ค.\n *\n * ๊ณ์ฐ์ ์ปค๋์ด ์๊ธฐ ์ํ์์ ํ๋ค(`kernel.capacity`). ์ฌ๊ธฐ์ ํ๋ ์ผ์ **๊ธฐ์ค ์ฃผ๋ฅผ ์ ํด ์ฃผ๋\n * ๊ฒ**๋ฟ์ด๋ค: ๊ณตํด์ผ์ด ์๋ ํ์์ฃผ์ฌ์ผ ํ๋ค โ ๊ณตํด์ผ์ ์ฐ๊ฐ ๊ฐ์ฉ๋์ ๋ฐ๋ก ๊น์ง, ์ด ๊ณต์ฅ์ ํ์์\n * ์ํ์ ์ ํ์ง ์๋๋ค. ์ปค๋์ด ์์๋ก ๊ณ ๋ฅด๊ฒ ๋๋ฉด ๊ทธ ์ฃผ์ ๊ณตํด์ผ์ด ๋ผ์์ ๋ ์ํ์ด ์กฐ์ฉํ ๋ฎ์์ง๋ค.\n *\n * ํธ์์ด ๊ธฐ๋ ์ค์ด ์๋๋ฉด `undefined` ๋ค โ 0 ์ด ์๋๋ค. ๊ธฐ๋ํ์ง ์์ ํธ์์ ์ํ์ 0 ์ด๋ผ๊ณ ๋ตํ๋ฉด ํ๋ฉด์\n * \"์ด ๊ณต์ฅ์ ์๋ฌด๊ฒ๋ ๋ชป ๋ง๋ ๋ค\" ๊ณ ๋งํ๋ค.\n */\n static async capacity(\n domainId: string,\n target: { instanceId?: string; spaceId?: string },\n unitsPerDay: number,\n sampleWeekStartMs: number\n ): Promise<{ instanceId: string; kind?: string; analysis?: any; reason?: 'not-running' | 'no-operations' }[]> {\n /* ๋์์ **๋ฑ๋ก๋ถ**๊ฐ ์ ํ๋ค โ ๊ธฐ๋ ์ค์ธ ๋ฐํ์๋ง ํ์ผ๋ฉด \"์ ๋ ์์ด์ ์ ๋ณด์ด๋ ๊ฒ\" ๊ณผ \"์๋ ๊ฒ\" ์ด\n ๊ตฌ๋ณ๋์ง ์๋๋ค. ํ๋ฉด์ ๊ทธ ๋์ ๋ค๋ฅด๊ฒ ๋งํด์ผ ํ๋ค. */\n const where: any = { domain: { id: domainId } }\n if (target.instanceId) where.instanceId = target.instanceId\n else where.spaceId = target.spaceId\n const registered = await getRepository(TwinInstance).find({ where })\n\n return registered.map(reg => {\n const rt = this.instances[runtimeKey(domainId, reg.instanceId)]\n const kernel: any = rt?.kernel // ํค์ ๋๋ฉ์ธ์ด ์์ผ๋ฏ๋ก ๋จ์ ๋ฐํ์์ ์ง์ ์ ์๋ค\n if (typeof kernel?.capacity !== 'function') return { instanceId: reg.instanceId, kind: reg.kind, reason: 'not-running' as const }\n\n const analysis = kernel.capacity({ unitsPerDay, sampleWeekStartMs })\n /* ๊ณต์ ์ ์ ์ธํ์ง ์์ ํธ์(๋๊ฐ YMSยทWMS)์ **ํ์ ๋์์ด ์๋๋ค.** 0 ์ผ๋ก ์ฑ์ ๋ฃ์ผ๋ฉด\n \"์ผ๋๊ฐ ๋ณ๋ชฉ\" ์ด๋ผ๋ ์๋ ์ฌ์ค์ด ์๊ธด๋ค โ ์ด ๊ฒ์ด ์๋ค๊ณ ๋งํ๋ค. */\n if (!analysis?.operations?.length) return { instanceId: reg.instanceId, kind: reg.kind, reason: 'no-operations' as const }\n return { instanceId: reg.instanceId, kind: reg.kind, analysis }\n })\n }\n\n /**\n * **์์ฐ ๋ฅ๋ ฅ ๋ณด๊ณ ์** โ ISA-95 Part 4 `OperationsCapability`. ๊ตฌ๊ฐ์ ์์ ์ข
๋ฅ๋ก ๊ตฌ๋ถํ๋ค\n * (์ฝ์ ยท๊ฐ์ฉยท๋ฌ์ฑ๋ถ๊ฐ). ์ฉ๋(`capacity`)์ ๋น์จ์ ๋ด๊ณ ์ด๊ฒ์ **๊ตฌ๊ฐ์ ์**์ ๋ธ๋ค.\n *\n * ๋์ ์ ์ ยท๊ฑฐ์ ์ฌ์ ๋ `capacity` ์ **๊ฐ์ ๊ท์จ**์ด๋ค: ๋ฑ๋ก๋ถ๊ฐ ๋์์ ์ ํ๊ณ (์ ๊ธฐ๋ ์ค์ธ ๊ฒ๊ณผ\n * ์๋ ๊ฒ์ ๊ตฌ๋ณํ๋ค), ๊ณต์ ์ ์ ์ธํ์ง ์์ ํธ์์ ํ์ ๋์์ด ์๋๋ผ๊ณ ๋งํ๋ค(0 ์ผ๋ก ์ฑ์ฐ๋ฉด\n * \"์ผ๋๊ฐ ๋ณ๋ชฉ\" ์ด๋ผ๋ ์๋ ์ฌ์ค์ด ์๊ธด๋ค).\n */\n static async operationsCapability(\n domainId: string,\n target: { instanceId?: string; spaceId?: string },\n unitsPerDay: number,\n sampleWeekStartMs: number,\n window: { fromTime: string; toTime: string }\n ): Promise<{ instanceId: string; kind?: string; report?: any; reason?: 'not-running' | 'no-operations' }[]> {\n const where: any = { domain: { id: domainId } }\n if (target.instanceId) where.instanceId = target.instanceId\n else where.spaceId = target.spaceId\n const registered = await getRepository(TwinInstance).find({ where })\n\n return registered.map(reg => {\n const rt = this.instances[runtimeKey(domainId, reg.instanceId)]\n const kernel: any = rt?.kernel\n if (typeof kernel?.operationsCapability !== 'function') {\n return { instanceId: reg.instanceId, kind: reg.kind, reason: 'not-running' as const }\n }\n const report = kernel.operationsCapability({ unitsPerDay, sampleWeekStartMs, window })\n if (!report?.perOperation?.length) return { instanceId: reg.instanceId, kind: reg.kind, reason: 'no-operations' as const }\n return { instanceId: reg.instanceId, kind: reg.kind, report }\n })\n }\n\n /**\n * ๋ฏธ๋ฌ ๊ธฐ๋์ ์ฐ์์ฑ ์จ์ โ ์ด์ด๋ฐ์ ๊ฒ์ **๋งํ๋ค**(์กฐ์ฉํ ์์ง ์๋๋ค).\n *\n * ์ปค๋์ด ๊ทธ ๋ฌธ์ ์ด์ด ๋์ง ์์์ผ๋ฉด ๊ทธ ์ฌ์ค๋ ๋งํ๋ค: ๊ทธ ํธ์์ ์ฌ๊ธฐ๋๋ง๋ค ์ด๋ฆฐ ๊ตฌ๊ฐ์ ์๋๋ค.\n */\n private static seedLiveContinuity(domainId: string, id: string, kernel: any): void {\n const cached = this.recovered[runtimeKey(domainId, id)]?.state\n if (!cached) return\n const plan = planLiveContinuity(cached)\n if (!plan.ackedCount && !plan.attentionSinceCount && !plan.energy) return\n if (typeof kernel.hydrateContinuity !== 'function') {\n twinWarn(\n `[twin-engine] kernel for \"${id}\" cannot carry continuity (no hydrateContinuity) โ the open demand window, ` +\n 'its peak and the attention start times are lost on every restart.'\n )\n return\n }\n try {\n kernel.hydrateContinuity(plan.seed)\n } catch (err: any) {\n /* ์ด์ด๋ฐ๊ธฐ๊ฐ ์คํจํด๋ ๋ฏธ๋ฌ๋ ๋์์ผ ํ๋ค โ ๋ค๋ง ๋ฌด์์ ์์๋์ง ๋งํ๋ค. */\n twinWarn(`[twin-engine] continuity seed failed for \"${id}\" โ starting without it: ${err?.message ?? err}`)\n return\n }\n const carried = [\n ...(plan.energy ? ['energy accumulation (open window, totalizer baselines, peak)'] : []),\n ...(plan.ackedCount ? [`${plan.ackedCount} acknowledged attention(s)`] : []),\n ...(plan.attentionSinceCount ? [`${plan.attentionSinceCount} attention start time(s)`] : [])\n ].join(', ')\n twinLog(`[twin-engine] mirror \"${id}\" carried over ${carried} โ observation axes come from the source.`)\n }\n\n static start(id: string, domainId: string, kind: string, model: TwinModelDef, restartPolicy?: RestartPolicy, purpose?: string, resumeFrom?: number): InstanceRuntime {\n const key = runtimeKey(domainId, id)\n if (this.instances[key]) return this.instances[key]\n\n const Kernel = kernelFor(kind)\n const kernel: TwinKernel = new Kernel(domainId, undefined, this.productionSpecOf(model))\n kernel.loadTwinModel(model) // ๊ตฌ์กฐ๋ง. ์ํ๋ ์๋ ์์คํํธ๊ฐ ์ฃผ์
ํ๋ค.\n this.applyOperations(kernel, model, id) // ์๊ฐยท์์จ ๋ช
์ธ(์์ผ๋ฉด) โ ์์ผ๋ฉด ์ปค๋ ๊ธฐ๋ณธ๊ฐ\n /* ์ถ์ ๊ธฐ๋ DB ์กฐํ๋ฅผ ํฌํจํด ๋น๋๊ธฐ โ ๊ธฐ๋์ ๋ง์ง ์๊ณ ๋ถ๋๋ค(๋ถ๊ธฐ ์ ์์
์ ๋ช
์ธยท์์๋ก ์ฐ์ถ). */\n this.installEstimators(kernel, domainId, id, model).catch(err => twinWarn('[twin-engine] estimator install failed', err?.message))\n /*\n * **์์คํํธ์ ๋ ์๊ฐ์ ๊ฐ์ผ๋ก ๋จ๊ธด๋ค** (2026-08-22). ์ค์ธก์ผ๋ก ๋ถํ
์ด 620~717์ด์๊ณ ํธ์ ํ๋์\n * 15~93์ด์๋๋ฐ, ์ด๋ ์์
์ด ๊ทธ ์๊ฐ์ ์ฐ๋์ง ๋ตํ ๊ณ๊ธฐ๊ฐ ์์๋ค. ๋ก๊ทธ์๋ ๋ฐ๋ฆฌ์ด๊น์ง ์ ์ด\n * ๋ถํ
๋ก๊ทธ๋ง์ผ๋ก ๊ตฌ๊ฐ์ ์ฝ์ ์ ์๊ฒ ํ๋ค.\n */\n const tWarm = performance.now()\n this.warmStart(domainId, id, kernel, purpose)\n const warmMs = performance.now() - tWarm\n if (warmMs >= 1000) twinLog(`[twin-engine] \"${id}\": warm start took ${Math.round(warmMs)}ms.`)\n /*\n * **๋ฒํธ๋ฅผ ์ด์ด ์ผ๋ค** โ ์ ๋์ ์ด๋ฏธ ์๋ ๋ฒํธ์ ๊ฒน์น์ง ์๊ฒ.\n *\n * ์ ๋์ด ๋น์ด ์์ผ๋ฉด(0) ์๋ฌด ์ผ๋ ์ ํ๋ค. ๋น์ด ์์ง ์์๋ฐ 0๋ถํฐ ๋ค์ ์ธ๋ฉด ๊ฐ์ ํธ์์ ๊ฐ์\n * ๋ฆฌ๋น์ ์ด ๋ ์๊ธฐ๊ณ , ์ฌ์ ์์๊ฐ ๋ค์์ด๋ฉฐ, ์๊ฐ์ฌํ์ด ์๋ฑํ ์์ ์ ๋ตํ๋ค โ ์ค๋ฅ๋ ์ ๋๋ค.\n */\n if (resumeFrom && typeof (kernel as any).resumeRevision === 'function') (kernel as any).resumeRevision(resumeFrom)\n /*\n * โโ ์ด ํธ์์ ์๊ณ๋ฅผ **์ง๊ธ**์ ๋ง์ถ๋ค (2026-08-15) โโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ปค๋์ ๊ธฐ๋ณธ ๊ธฐ์ค์ ์ ์์(2026-01-01)๋ค. ๊ทธ๋๋ก ๋๋ฉด ์๋ฎฌ ํธ์์ ์ ๋ ์๊ฐ์ด **์ฌ๊ธฐ๋๋ง๋ค\n * ๋๊ฐ๊ฒจ** ๋ฉฐ์น ์น ์ฌ๊ฑด์ด ์ ๋ถ ๊ฐ์ ๋ถ์ ๋ชฐ๋ฆฐ๋ค โ ใ์ธ์ ์์๋ ์ผ์ธ๊ฐใ๋ฅผ ๋์ง์ ์ ์๊ณ ,\n * ์ค ์๊ฐ์ผ๋ก ์ฐฝ์ ์๋ฅด๋ ์ฑ๊ณผยท์ด๋ ฅ ์ง์์๋ ๊ทธ ํธ์์ด ์์ ๋ณด์ด์ง ์๋๋ค.\n *\n * ์ฌ๊ธฐ๋ํ๋ฉด ๊ทธ๋งํผ ์๊ณ๊ฐ ์์ผ๋ก ๋ฐ๋๋ฐ, ๊ทธ๊ฒ์ด ์ฌ์ค์ด๋ค: ๊ทธ ์ฌ์ด ์ด ํธ์์ ๋์ง ์์๊ณ \n * ์ ๋์ ๋น ๊ตฌ๊ฐ์ด ๊ทธ ์ฌ์ค์ ๋งํ๋ค.\n */\n kernel.setClockOrigin?.(Date.now())\n const runtime: TwinRuntimeType = new TwinRuntime(kernel)\n\n /* subscribe ๋ RuntimeSubscription({ unsubscribe() }) ๋ฐํ โ () => void ๋ก ๊ฐ์. */\n /*\n * **๋ชจ๋๋ฅผ ์ ์ด ๋๋ค** (2026-08-18 ์ค์ธก์ผ๋ก ๊ณ ์นจ).\n *\n * ์๋ฎฌ ๊ฒฝ๋ก๋ `mode` ๋ฅผ ๋น์ ๋์๊ณ (ใ๋ฏธ์ง์ =simใ์ด๋ผ๋ ๊ท์ฝ์ ๊ธฐ๋), ๋ผ์ด๋ธ๋ง ์ ์๋ค. ๊ทธ๋์\n * `modeOf()` ๊ฐ **๋๋ ์๋ฎฌ๋ ์ด์
์ undefined** ๋ฅผ ๋ตํ๊ณ , ์ ์ธยท์ฒ ํ์ ๋ต์ด ใ์ ์ฅํ๋คใ๋ก ๋๊ฐ๋ค โ\n * ์ค์ ๋ก๋ ๋๋ ์ปค๋์ด ์ ์๋ฅผ ๊ทธ๋๋ก ์ฐ๊ณ ์ฌ๊ธฐ๋ ๋ ๋ฐ๋๋ฐ, ๊ทธ ์ฌ์ค์ด ๋ต์์ ์ฌ๋ผ์ง ๊ฒ์ด๋ค.\n * ๊ท์ฝ์ ๊ธฐ๋๋ ๋์ ์ฌ์ค์ ์ ๋๋ค: ใ๋๊ณ ์๋ใ๋ฅผ ๋ฌป๋ ์ชฝ์ด ๊ทธ ๋ต์ ๋ฐ์์ผ ํ๋ค.\n */\n const inst: InstanceRuntime = {\n id,\n domainId,\n mode: 'sim',\n runtime,\n kernel,\n /* ์ ์ฑ
์ ๋ถ๋ฅด๋ ์ชฝ์ด ์ ์ธํ๋ค โ ์ฌ๊ธฐ์ ๊ณ ๋ฅด๋ฉด ๊ฐ์ ํธ์์ด ๋ถ๋ฅด๋ ์๋ฆฌ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ฌ๊ธฐ๋ํ๋ค. */\n restartPolicy: readRestartPolicy(restartPolicy, `start(\"${id}\")`),\n spaceId: (model as any)?.spaceId,\n /*\n * **์๋ฎฌ๋ ๊ณ๊ธฐ๋ฅผ ๋ ๋ค** (2026-08-20).\n *\n * ์์ ์๋ `startLive` ์์๋ง ๋ง๋ค์๋ค. ๊ทธ๋์ ๋๋ ํธ์ 22๊ฐ๊ฐ ์๋ฎฌ์ธ ์๋ฒ์์ ใ์ด๋น ๋ช ํ์\n * ์ฐ๋ใยทใ๋ฐ๋ฆฐ ๊ฒ ์๋ใ๋ฅผ ๋ฌผ์ ์๋ฆฌ๊ฐ **์์ ์์๋ค** โ ์ ๋ ์ฐ๊ธฐ๋ฅผ ๋ฐฐ์น๋ก ๊ณ ์น ๋ค์๋ ๊ทธ ํจ๊ณผ์\n * ํ๊ท๋ฅผ ์ซ์๋ก ๋ณผ ์ ์๋ค. ์ธ์ง ์๋ ๊ฐ์ ์ ๋ค์ ์ฌ๋์ด ๋๋๋ ค๋ ์๋ฌด๋ ๋ชจ๋ฅธ๋ค.\n *\n * ์ ์
(`ingested`)์ ์๋ฎฌ์ ๋ป์ด ์๋ค(์๋ณธ์์ ๋ฐ๋ ๊ฒ์ด ์๋๋ผ ์๊ธฐ๊ฐ ๋ธ๋ค) โ ๊ทธ ์นธ์ 0 ์ผ๋ก\n * ๋จ๊ณ , ๊ทธ๊ฒ์ด ์ฌ์ค์ด๋ค(ใ๋ฐ์ ๊ฒ์ด ์๋คใ).\n */\n metrics: this.newMetrics(),\n unsub: () => {}\n }\n this.instances[key] = inst\n /* ๋ค์ ์ธ์ ์ผ๋ฏ๋ก ์ง๋ ์ ์ง ์ด์ ๋ ์ฌ์ค์ด ์๋๋ค โ ๋จ๊ฒจ ๋๋ฉด ๋๋ ํธ์์ด ใ๊ตถ๊ฒจ์ ๋ฉ์ท๋คใ๊ณ ๋งํ๋ค. */\n this.stopNotes.delete(key)\n delete this.recovered[key] // ์์คํํธ๋ก ์ปค๋์ ์ฎ๊ฒจ ์ฌ์๋ค โ ์ด์ ๋ผ์ด๋ธ๊ฐ ์ง์ค์ด๋ค.\n /* ์๋ณธ์ด ์ ์ธํ ์๊ทน โ ๊ธฐ๋์ ๋ง์ง ์๋๋ค(์ถ์ ๊ธฐ์ ๊ฐ์ ๊ท์จ). ๋ชป ์ค์์ผ๋ฉด ๊ทธ ์ฌ์ค์ ๋งํ๋ค. */\n this.installStimulus(domainId, id, inst).catch(err => twinWarn(`[twin-engine] \"${id}\": stimulus install failed โ ${err?.message ?? err}`))\n\n /* ๋ผ์ด๋ธ ๋ฐ์ธ๋ฉ(P3): data ์ฑ๋ ํํฐ๊ฐ subdomain ์ ๋ณด๋ฏ๋ก Domain ๊ฐ์ฒด๋ฅผ 1ํ ํด์ํด ๋๋ค. */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n\n /* State ์ฑ๋: runtime.subscribe(snapshotโdeltaโclock) โ pubsub ๋ธ๋ก๋์บ์คํ
(๊ตฌ๋
๋ฆฌ์กธ๋ฒ๊ฐ instanceId ํํฐ). */\n const sub = runtime.subscribe((msg: SubscriptionMessage) => {\n this.publishGuarded(\n 'twin-state',\n { twinState: { instanceId: id, kind: msg.kind, revision: (msg as any).revision, payload: msg } },\n `twin-state:${id}`\n )\n /* ์์ + ๋ผ์ด๋ธ ๋ฐ์ธ๋ฉ ๋ธ๋ฆฌ์ง: delta ๋ฅผ ์ ๋ ๋ฒํผ์ ๋ด๊ณ + ์ํฐํฐ๋ณ data(tag:) publish โ ๋ณด๋ ์ปดํฌ๋ํธ ๋ผ์ด๋ธ. */\n if (msg.kind === 'delta') {\n /*\n * โโ ์ฐ๊ธฐ๋ **๋ชจ์์** ํ ๋ฒ (2026-08-20 ์ค์ธก์ผ๋ก ์ก์) โโโโโโโโโโโโโโโโโโโโ\n *\n * ์ฌ๊ธฐ์ ๋ธํ๋ง๋ค `persist()` ๋ฅผ ๋ถ๋ ๋ค โ ํ ํ๋๋น `save()` ํ๋, ๊ทธ๋ฆฌ๊ณ ๊ทธ ์์์\n * `structureRevOf` ๋ฅผ await(๊ตฌ์กฐ ํ์ด ์๋ ํธ์์ ์บ์ ๋ฏธ์ค๊ฐ ๊ธฐ์ต๋์ง ์์ **๋ธํ๋ง๋ค\n * SELECT** ์๋ค). ๋ฐ๋ชจ ์๊ทน์ ์ผ ํธ์ 23๊ฐ์์ ๊ทธ ๊ฒฐ๊ณผ๊ฐ ์ด๋ฌ๋ค: ํ๋ก์ธ์ค CPU 81~112%,\n * ์๋ฌด ์ผ๋ ํ์ง ์๋ ์ง์๊ฐ 8~14์ด. ํ๋กํ์ผ์ `JSON.parse`ยท๋ํ GCยท์ค๋ ๋ํ์ ๊ฐ๋ฆฌํค๊ณ \n * ๊ณ๊ธฐ๋ ํฑ์ ๋ชซ์ด 16% ๋ผ๊ณ ๋งํ๋ค โ **ํฑ์ด ์๋๋ผ ์ฐ๊ธฐ์๋ค.**\n *\n * ๋ฐ๋ก ์ ์ฃผ์์ด **๋ธ๋ก๋์บ์คํ
**์์ ๊ฐ์ ํจ์ ์ ์ ์ด ๋์๋ค(ํฑ ํ๋๊ฐ 35์ด). ๋ธ๋ก๋์บ์คํ
์ ๋ชจ์ผ๋๋ก\n * ๊ณ ์ณค๊ณ ์ฐ๊ธฐ๋ ๋จ๊ฑด์ผ๋ก ๋จ์ ์์๋ค. ๊ฐ์ ๊ท์จ๋ก ๋ค์ธ๋ค โ ADR-0030 ์ด *\"๊ธฐ๋ก ๊ฒฝ๋ก๊ฐ ๋์ธ\n * ๊ฒ์ ์๋ฎฌ๋ง ์๋ฌธ์ผ๋ก ๋ค์ด์ค๊ธฐ ๋๋ฌธ\"* ์ด๋ผ ์๊ณ ํ ๊ทธ ์๋ฆฌ๋ค.\n *\n * **๋ฆฌ๋น์ ์ ์ปค๋์ ๊ฒ์ ๊ทธ๋๋ก ๋ ๋ค**(๋ผ์ด๋ธ๋ flush ๋ ํธ์คํธ๊ฐ ๋ถ์ฌํ๋ค). ์๋ฎฌ์ ์ ๋์\n * ์ปค๋ ๋ฆฌ๋น์ ์ผ๋ก ์ ํ๋ฏ๋ก ์ฌ๊ธฐ์ ๋ค์ ๋ฒํธ๋ฅผ ๋งค๊ธฐ๋ฉด ์๊ฐ์ฌํ์ด ์ด๊ธ๋๋ค.\n */\n ;(inst.pendingJournal ?? (inst.pendingJournal = [])).push({ event: msg.event, revision: (msg as any).revision })\n /*\n * โโ ๋ธ๋ก๋์บ์คํ
์ **๋ชจ์์** ํ ๋ฒ (2026-08-14 ์ค์ธก์ผ๋ก ์ก์) โโโโโโโโโโโโโโโโโโโโ\n * ์ฌ๊ธฐ์ ๊ณง๋ฐ๋ก ๋ธ๋ก๋์บ์คํ
ํ๊ณ ์์๋ค. ๊ทธ๋ฐ๋ฐ ์ปค๋์ ํ ๋ฒ์ tick ์์ ์ฌ์ค์ **์ฌ๋ฌ ๊ฐ** ๋ธ๋ค\n * (์์ฝยท๋ฐฐ์นยท์๋ฃโฆ). ๊ทธ๋์ tick ํ๋๊ฐ ์ ์ํ ํฌ์์ ์๋ฐฑ ๋ฒ ๋ฐ๋ณตํ๋ค โ `order-check`\n * ํธ์์์ **ํฑ ํ๋๊ฐ 35์ด**๋ฅผ ๋จน๊ณ (๋จ๊ณ ํฉ์ 32ms ์๋ค: ์๊ฐ์ ๋ฐ๋ณต ํ์์ ์์๋ค) ๊ทธ\n * 35์ด ๋์ ์ด๋ฒคํธ ๋ฃจํ๊ฐ ๋งํ ๊ตฌ๋
์๊ฐ ์๋ฌด๊ฒ๋ ๋นผ๋ด์ง ๋ชปํ๋ค. ๋ฐ๋ฆฐ push ๊ฐ 1024๋ฅผ ๋๋\n * ์๊ฐ pubsub ์ด ์ค๋ฅ๋ฅผ ๋ด๊ณ , ๊ทธ ์์ธ๊ฐ ํ์ด๋จธ ์ฝ๋ฐฑ์ ํ๊ณ ์ฌ๋ผ์ **ํธ์คํธ๊ฐ ์ฃฝ์๋ค.**\n *\n * ๋ผ์ด๋ธ๋ ์ด๋ฏธ dirty ํ์ + ์ฃผ๊ธฐ flush ๋ก ์ด ๋ฌธ์ ๋ฅผ ํ์ด ๋์๋ค(BROADCAST_COALESCE_MS).\n * ์๋ฎฌ๋ง ๊ทธ ๊ท์จ ๋ฐ์ ์์๋ค โ ๊ฐ์ ๊ท์จ๋ก ๋ค์ธ๋ค(์ต์ -์ํ ์ฑ๋์ด๋ผ ์ค๊ฐ ์ํ๋ฅผ ๋ชจ๋\n * ๋ณด๋ผ ์ด์ ๊ฐ ์๋ค: 200ms ๋ง๋ค ๋ง์ง๋ง ๊ฒ ํ๋๋ฉด ํ๋ฉด์ ๊ฐ๋ค).\n */\n inst.dirty = true\n /* ์ด ์ฌ์ค์ด ๊ฑด๋๋ฆฐ ๋ฌผํ๋ง ๋ค์ ๋ธ๋ก๋์บ์คํ
์์ ๋ง๋ ๋ค(๋ชจ๋ฅด๋ฉด ์ ๋ถ). */\n this.markItemsDirty(inst, [msg.event])\n this.ensureBroadcastCoalescer()\n }\n })\n inst.unsub = () => sub.unsubscribe()\n\n /* ์์์ ์ฐ ์์คํํธ ์๊ฐ์ ๊ณ๊ธฐ์ ์ ๋๋ค โ ๊ณ๊ธฐ๋ ์ธ์คํด์ค๊ฐ ์๊ธด ๋ค์์ผ ์๋ค. */\n recordPhase(inst.load ?? (inst.load = newLoadMeter()), 'warmStart', warmMs)\n\n /* ๋ณต๊ตฌ ์ต์ปค: ๋ ์ง์คํธ๋ฆฌ์ model/kind/status/restartPolicy ์์(์ฌ๋ถํ
์ ์ด๊ฒ ์์ด์ผ replayยท์ ์ธ ๊ฑฐ๋ ๊ฐ๋ฅ). */\n this.register(domainId, id, kind, model, 'running', inst.restartPolicy).catch(err => twinError('twin register fail', err))\n\n /* ์์ปค tick โ ์ค์ผ๋ ํค์ setInterval(๋ฉ์ธ ๋ฃจํ). ๊ธด ์๋ฎฌ ์คํ-๋ฃจํ(worker thread)๋ ์ค์ผ์ผ ํ๋๋(ํฅํ, ยงhost ๊ฒฝ๊ณ). */\n inst.timer = this.startTickTimer(\n () => this.tickGuarded(domainId, id, runtime),\n t => (inst.timer = t)\n )\n return inst\n }\n\n /**\n * live-๋ชจ๋ ๊ธฐ๋ โ **๊ด์ธก ๋ชจ๋ ์ปค๋**๋ก ์ค ์ด๋ฒคํธ๋ฅผ ๋ฏธ๋ฌํ๋ค(ํตํฉ P2).\n *\n * ์์ ์๋ `StateProjector` ๋ฅผ ์ธ์ ๋ค. ๊ทธ๋์ ๋ผ์ด๋ธ์๋ **์ปค๋์ด ์์๊ณ **, ๊ทธ ํ๋ ๋๋ฌธ์ ์ฐํ๊ฐ\n * ์ค์ค์ด ์๊ฒผ๋ค: ์์ธกํ๋ ค๋ฉด ์์ ์ปค๋์ ์ธ์์ผ ํ๊ณ (`buildForecastKernel`), ์ฃผ๋ชฉ ์ ํธ๋ฅผ ํธ์คํธ๊ฐ\n * ๋ง๋ถ์ฌ์ผ ํ๊ณ (`withLiveAttentions`), AI ์์ธก ๋๊ตฌ๋ ๋ฏธ๋ฌ์์ \"์ฐพ์ ์ ์๋ค\" ๋ก ๋๋ฌ๋ค.\n *\n * ์ด์ ๋ผ์ด๋ธ ์ธ์คํด์ค๋ **์ปค๋์ด๋ค.** ๊ฐ์ ๊ท์น(`ObservedReducer`)์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์ ๊ณ , ์ฃผ๋ชฉ ์ ํธ๋ฅผ\n * ์ค์ค๋ก ๋ด๊ณ , ๊ทธ ์๋ฆฌ์์ `fork` ํด ์์ธกํ๋ค. ๊ตฌ๋๋ง ๋ค๋ฅด๋ค โ sim ์ `tick`, live ๋ `apply`.\n *\n * ์ค ์ด๋ฒคํธ์ = reference ์ด๋ํฐ openLiveFeed โ face2-adapter.ingest โ CanonicalEnvelope โ ingestLive().\n */\n /**\n * ๋ชจ๋ธ์ด ์ค์ **์์ฐ ์ ์**(๋ ์ํผยท๋ผ์ฐํธยท๋ฐ์ธ๋ฉ)๋ฅผ ๊บผ๋ธ๋ค โ ์ปค๋์ ์ ์-๊ตฌ๋ ๋ชจ๋ ์
๊ตฌ.\n *\n * โโ ์์ ๋ ๋ฌด์์ด ์ผ์ด๋ฌ๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ปค๋์๋ ์ ์-๊ตฌ๋ MES ๊ฒฝ๋ก๊ฐ ์๋๋ฐ **ํธ์คํธ๊ฐ ๊ทธ๊ฒ์ ํ ๋ฒ๋ ๋๊ธฐ์ง ์์๋ค.** ๊ทธ๋์ ๋ชจ๋ MES\n * ํธ์์ด **ํ๋์ฝ๋ฉ๋ ๋ ๊ฑฐ์ ํ๋ฆ**์ผ๋ก ๋์๋ค โ ํ์ฅ ๋ ์ํผ๋ฅผ ์๋ฌด๋ฆฌ ์ ์ฑ๊ป ์ ์ด๋ ์ปค๋์ ๊ทธ๊ฒ์\n * ๋ณด์ง ๋ชปํ๊ณ ํ ์ด ๋ถํ์ผ๋ก ํ ์ด ์ ํ์ ๋ง๋ค์๋ค. ์ ์ธ๊ณผ ์คํ์ด ๊ฐ๋ผ์ ธ ์๋ ์๋ฆฌ๋ค.\n *\n * ๋ชจ๋ธ์ ์์ผ๋ฉด `undefined` โ ๋ ๊ฑฐ์ ๊ฒฝ๋ก ๊ทธ๋๋ก๋ค(๊ธฐ์กด ํธ์์ ๊ฑฐ๋์ ๋ฐ๊พธ์ง ์๋๋ค).\n */\n /**\n * ์์ฐ ์ ์ธ์ ๊บผ๋ธ๋ค โ ์ปค๋ ์์ฑ์์ ๋๊ธด๋ค.\n *\n * **์ ์ด๋ฆ(`mesSpec`)์ ์ฝ์ง ์๋๋ค.** ๊ทธ๊ฒ์ ๊ณ์ฝ์ ์ ์ธ์กฐ์ฐจ ์๋ ํ๋์๊ณ (MES ์ปค๋ ์์ฑ์ ์ธ์\n * ์ด๋ฆ์ด ๊ทธ๋๋ก ๊ตณ์ ๊ฒ), ์ผ๋ฐ ๊ธฐ์ ์ ํ ์์คํ
์ด๋ฆ์ด ๋ถ์ด ์์๊ธฐ ๋๋ฌธ์ ์ฐฝ๊ณ ํธ์์ด ์ด ์๋ฆฌ๋ฅผ\n * ์ฐ์ง ๋ชปํ๋ค. ๋ณ๋ช
์ผ๋ก ๋จ๊ฒจ ๋๋ฉด ๊ทธ ํผ๋์ด ๊ณ์๋๋ฏ๋ก ํ๋๋ก ํต์ผํ๋ค.\n *\n * ์ ์ด๋ฆ๋ง ๊ฐ์ง ๋ชจ๋ธ์ด ์์ผ๋ฉด **์กฐ์ฉํ ์์ฐ ์ ์ธ์ ์๋ ๋์ ๋ถ๋ช
ํ ๋ฉ์ถ๋ค** โ ๊ทธ ํธ์์ ๊ณต์ ์ด\n * ์๋ ์ฑ๋ก ๋๊ฒ ๋๊ณ (๋ผ์ธ์ด ์ ์๋ ์ฐฝ๊ณ ), ์์ธ์ ์ฐพ๊ธฐ ์ด๋ ต๋ค.\n */\n private static productionSpecOf(model: TwinModelDef | undefined): any {\n const legacy = (model as any)?.mesSpec\n if (legacy && !(model as any)?.productionSpec) {\n throw new Error(\n 'the twin model carries the retired `mesSpec` field โ rename it to `productionSpec` ' +\n '(same shape; the name was tied to one kernel while the declaration is ISA-95 operations + BOM)'\n )\n }\n return (model as any)?.productionSpec\n }\n\n /**\n * ํ์ฅ(๊ณต๊ฐ)์ **์๊ฐ ๊ธฐ์ค**์ ๋ชจ๋ธ์ ์น๋๋ค โ ์ปค๋์ด ๊ต๋์ `HH:MM` ์ ์ฝ์ ๊ธฐ์ค.\n *\n * **ํ
๋ํธ๊ฐ ์๋๋ผ ๊ณต๊ฐ์ด ๊ถ์๋ค.** ํ ํ
๋ํธ๊ฐ Rosarito(ํํ์)์ ํ๊ตญ ๊ณต์ฅ์ ํจ๊ป ๊ฐ์ง ์ ์๊ณ ,\n * ํ
๋ํธ ๋จ์(`Domain.timezone`)๋ก ๋๋ฉด ๋ ์ค ํ๋๋ ๋ฐ๋์ ํ๋ฆฐ๋ค. ๊ทธ๋์ ์ธ์คํด์ค๊ฐ ์ฐ๊ฒฐ๋ ๊ณต๊ฐ์\n * `timezone` ์ ์ฝ๋๋ค. ๊ณต๊ฐ์ด ๋งํ์ง ์์ผ๋ฉด **ํ
๋ํธ๋ก ๋ด๋ ค๊ฐ์ง ์๋๋ค** โ ์๋ชป๋ ์
์๋ก ๋ตํ๋ ๊ฒ์ด\n * ๋ชจ๋ฅด๋ ๊ฒ๋ณด๋ค ๋์๋ค(๊ทธ๋๋ ์ปค๋์ด UTC ๋ก ์ฝ๊ณ , ๊ทธ ๊ธฐ๋ณธ๊ฐ์ ๊ณ์ฝ์ ๋ฐํ์ ธ ์๋ค).\n *\n * ์ปค๋์ zero-dep ์ด๋ผ ์๊ฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ฐ์ง ์์ผ๋ฏ๋ก **๋ถ ์คํ์
**์ผ๋ก ํ์ด ๋๊ธด๋ค. ๊ทธ ๊ฐ์\n * ์ง๊ธ ๊ณ์ ์ ๊ฒ์ด๋ค(์ผ๊ด์ ์ฝ์๊ฐ) โ ๊ณ์ ์ ๋๋ ๊ธด ์์ธก์ ํ ์๊ฐ ์ด๊ธ๋๋ค(๊ณ์ฝ์ ๋ช
์).\n */\n static async withSpaceTimeBase(model: TwinModelDef, domainId: string, spaceId?: string): Promise<TwinModelDef> {\n const sid = spaceId ?? (model as any)?.spaceId\n if (!sid) return model\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId: sid } }).catch(() => null)\n const offset = utcOffsetOf(space?.timezone)\n if (offset === undefined) {\n if (space?.timezone) twinWarn(`[twin-engine] space \"${sid}\" declares time zone \"${space.timezone}\" but it is not a known IANA zone โ times will be read as UTC.`)\n return model\n }\n return { ...model, utcOffsetMinutes: offset }\n }\n\n static startLive(id: string, domainId: string, kind: string, model: TwinModelDef): InstanceRuntime {\n const key = runtimeKey(domainId, id)\n if (this.instances[key]) return this.instances[key]\n const Kernel = kernelFor(kind)\n const kernel: any = new Kernel(domainId, undefined, this.productionSpecOf(model))\n kernel.loadTwinModel(model)\n /* **์ธ์ฐ๋ ์ชฝ์ด ์๋ ์ฌ์ค์ ์ธ์ธ ๋ ๋งํ๋ค.** ์์ ์๋ ์ฒซ ์ด๋ฒคํธ๊ฐ ๋์ฐฉํด์ผ ์ปค๋์ด ์ค์ค๋ก๋ฅผ\n ๊ด์ธก ๊ตฌ๋์ผ๋ก ์ฌ๊ฒผ๊ณ , ๊ทธ๋์ ์์ง ์๋ฌด๊ฒ๋ ๋ชป ๋ฐ์ ๋ฏธ๋ฌ๋ ์๋ฎฌ๋ ์ด์
์ทจ๊ธ์ ๋ฐ์๋ค. */\n declareObserved(kernel, `live twin '${id}'`)\n this.applyOperations(kernel, model, id) // ๋ช
์ธ๋ ๋ผ์ด๋ธ์๋ ์ค๋ฆฐ๋ค(์์ธก ์๊ฒฉ์ด sim ๊ณผ ๊ฐ์์ง๋ค)\n /* `projector` ํ๋๋ ์ ์ด๋ฆ์ผ๋ก ๋จ๊ธด๋ค โ ์๋น์ฒ๊ฐ `snapshot()` ์ ๋ถ๋ฅด๋ฏ๋ก ์์ ์ด๋ํฐ๋ก ์๋๋ค.\n * (P3 ์์ ์๋น์ฒ๋ฅผ ์ปค๋ ์ดํ๋ก ๋ฐ๊พธ๋ฉด ์ฌ๋ผ์ง๋ค.) */\n const projector = { apply: (e: CanonicalEnvelope) => kernel.apply(e), snapshot: () => kernel.getSnapshot() }\n const inst: InstanceRuntime = { id, domainId, mode: 'live', restartPolicy: 'resync', kernel, projector, oee: new OeeAccumulator(), spaceId: (model as any)?.spaceId, unsub: () => {} }\n /*\n * โโ ์ปค๋์ด **ํ์ ์ผ๋ก ๋ธ ์ฌ์ค**๋ ์ ๋์ ๋จ๋๋ค (2026-08-14 ์ค์ธก์ผ๋ก ์ก์) โโโโ\n *\n * ๋ผ์ด๋ธ๋ ์ธ์
๋ดํฌ๋ง ์ ๋์ ์ ๊ณ ์์๋ค(`ingestLive`). ๊ทธ๋ฐ๋ฐ ์ปค๋์ ๊ด์ธก์ ์ ๋ค๊ฐ **์๊ธฐ ์ฌ์ค**์\n * ๋ธ๋ค โ ์๋์ง์ ์์ ๊ตฌ๊ฐ ๋ง๊ฐยทํผํฌ ๊ฒฝ์ ยท๊ฐ์ถ ์ ์์ด ๊ทธ๋ ๋ค(`emitOp`). ๊ทธ๊ฒ์ ๊ตฌ๋
ํ๋ ๊ณณ์ด\n * ์์ด์ ๊ทธ ์ฌ์ค๋ค์ด **์ปค๋ ์์์ ์ฌ๋ผ์ก๋ค**: ํ๋ณธ 48๊ฑด์ด ์ ๋์ ์์๋๋ฐ ๊ตฌ๊ฐ ๋ง๊ฐ์ 0๊ฑด์ด์๊ณ ,\n * ์ ๋์ ์ฝ๋ ์ฑ๊ณผ ํ๋ฉด์ ์ ๋ ฅ ํ์ผ์ ์์ํ ๋์ค์ง ์์๋ค.\n *\n * sim ์ `runtime.subscribe` ๋ก ๊ฐ์ ์ผ์ ํ๋ค โ ๋ผ์ด๋ธ์๋ง ๊ทธ ๋ฐฐ์ ์ด ์์๋ค.\n *\n * **์ธ์
์ ์ฌ๋ฐฉ์ถ์ ๊ฑธ๋ฌ๋ธ๋ค**: `apply()` ๋ ๋ฐ์ ๋ดํฌ๋ฅผ ๊ตฌ๋
์์๊ฒ ๊ทธ๋๋ก ํ๋ฆฐ๋ค(ํธ์คํธ๊ฐ ๋ ๋ชจ๋์์\n * ๊ฐ์ ๋ฐฐ์ ์ ์ฐ๊ฒ ํ๋ ค๊ณ ). ๊ทธ๊ฒ๊น์ง ์ ์ผ๋ฉด ์ธ์
์ด ์ ๋์ ๋ ๋ฒ ๋ค์ด๊ฐ๋ค โ ๊ทธ๋์ ๋ฐฉ๊ธ ๋ฃ์ ๊ฒ๊ณผ\n * **๊ฐ์ ๊ฐ์ฒด**์ธ์ง ๋ณด๊ณ ๊ฑด๋๋ด๋ค(id ๋น๊ต๋ ์ด๋ํฐ๊ฐ id ๋ฅผ ์ด๋ป๊ฒ ๋ง๋๋์ง์ ๊ธฐ๋๊ฒ ๋์ด ์ฝํ๋ค).\n */\n const applying = new WeakSet<object>()\n inst.applying = applying\n inst.unsub = kernel.onEvent?.((e: CanonicalEnvelope) => {\n if (e && typeof e === 'object' && applying.has(e as object)) return // ์ธ์
์ ์ฌ๋ฐฉ์ถ โ ์ ๋์ ์ธ์
์์ ํ ๋ฒ๋ง\n ;(inst.pendingJournal ?? (inst.pendingJournal = [])).push(e)\n /* ์ปค๋์ด ๋ธ ์ฌ์ค๋ ์ํ๋ฅผ ๋ฐ๊พผ๋ค(ํผํฌยท๋ง๊ฐ) โ ๋ค์ ๋ธ๋ก๋์บ์คํ
์ฃผ๊ธฐ์ ์ค๋ฆฐ๋ค. */\n inst.dirty = true\n this.markItemsDirty(inst, [e])\n this.ensureBroadcastCoalescer()\n }) ?? (() => {})\n /* ์ถ์ ๊ธฐ(์ค์ธกยท๊ฑฐ๋ฆฌ)๋ ๋ผ์ด๋ธ์ ๋ถ์ธ๋ค โ ์์ธก์ด ์์๋ก ๊ณ์ฐ๋์ง ์๊ฒ. ๊ธฐ๋์ ๋ง์ง ์๋๋ค. */\n this.installEstimators(kernel, domainId, id, model).catch(err => twinWarn('[twin-engine] estimator install failed', err?.message))\n inst.metrics = this.newMetrics()\n this.instances[key] = inst\n /* ๋ฏธ๋ฌ์๋ ๋ถ๋ฅธ๋ค โ ์ ์ธ์ด ์์ผ๋ฉด ใ๋ฏธ๋ฌ์๋ ์ฃ์ง ์๋๋คใ๊ณ ๋งํด์ผ ํ๋ค(์กฐ์ฉํ ๋ฌด์ ๊ธ์ง). */\n this.installStimulus(domainId, id, inst).catch(err => twinWarn(`[twin-engine] \"${id}\": stimulus check failed โ ${err?.message ?? err}`))\n /*\n * **์์ฒ์ด ๋ํ์ด ์ฃผ์ง ์๋ ๊ฒ๋ง ์๋๋ค** (2026-08-18 ์ค์ธก์ผ๋ก ๋ถ์).\n *\n * ๋ฏธ๋ฌ๋ ์ค๋ซ๋์ ์๋ฌด๊ฒ๋ ์ด์ด๋ฐ์ง ์์๋ค โ ์ง์ค์ด ์์ฒ์ ์์ผ๋ ์ณ์ ํ๋จ์ด์์ง๋ง, ์์ฒ์ด **์ ์ด์\n * ๋ค์ ๋งํด ์ฃผ์ง ์๋ ์ถ**๊น์ง ํจ๊ป ๋ฒ๋ ธ๋ค: ์ด๋ฆฐ 15๋ถ ๊ตฌ๊ฐ์ ๋์ ยท์ ์ฐ ๊ธฐ์ค์ ยท๊ด์ธก ์ดํ ์ต๋, ๊ทธ๋ฆฌ๊ณ \n * ํ์ธํด ๋ ์ ํธ์ ์กฐ๊ฑด์ด ์ธ์ ๋ถํฐ์ธ์ง. ๊ทธ๋์ ์ฌ๊ธฐ๋ํ๋ฉด ์ค๋ฅ ์์ด ๊ฐ์ด ์์์ก๋ค(๊ทธ ๊ตฌ๊ฐ์ ์ ๋ ฅ๋๊ณผ\n * ํผํฌ๊ฐ ๋ถํ
์ดํ๋ก๋ง ์กํ๊ณ , ์ธ ์๊ฐ์งธ ์ง์๋ ๊ฒฝ๋ณด๊ฐ ใ0์ด์งธใ๊ฐ ๋๋ค โ ์๊ธ์ด ๊ฑธ๋ฆฐ ์๋ค).\n *\n * ๊ด์ธก ์ถ(์ฌ๊ณ ยท์์นยท์ค๋น)์ **์ฌ์ ํ ์ฌ์ง ์๋๋ค** โ ๋ค์ ๊ณ์ธก์ด ์ ์ ํ๊ณ , ์ฌ์ผ๋ฉด ๋ ๋ ๋ฌผ๊ฑด์ด\n * ๋์ด์๋๋ค. ๋ฌด์์ ๋๊ธธ์ง๋ `planLiveContinuity` ๊ฐ ๊ณ ๋ฅด๊ณ , ์ด๋ป๊ฒ ํก์ํ ์ง๋ ์ปค๋์ด ์ ํ๋ค.\n */\n this.seedLiveContinuity(domainId, id, kernel)\n delete this.recovered[key]\n /* ๋ผ์ด๋ธ ๋ฐ์ธ๋ฉ(data ์ฑ๋) subdomain ํํฐ์ฉ Domain 1ํ ํด์(sim ๊ณผ ๋์ผ). */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n /*\n * ์ ๋ revision ์นด์ดํฐ ์๋ โ ๊ธฐ์กด ์ ๋ ์ต๋์น์์ ์ด์ด๋ถ์(์ฌ๊ธฐ๋ ์ revision ์ถฉ๋ ๋ฐฉ์ง).\n *\n * โโ **์ปค๋์๋ ๊ฐ์ ๋ฒํธ๋ฅผ ์๋ ค ์ค๋ค** (2026-08-23 ์ค์ธก) โโโโโโโโโโโโโโโโโโโโ\n * ์์ ์๋ ์ด ์๋ฆฌ์์ `inst.revision`(์ ๋ ์ค ๋ฒํธ)๋ง ์ด์ด๋ฐ๊ณ **์ปค๋์ 0 ๋ถํฐ ์ธ๊ฒ ๋์๋ค.**\n * ๊ทธ๋์ ์ฒดํฌํฌ์ธํธ๊ฐ ๋ป์ด ๋ค๋ฅธ ๋ ์๋ฅผ ๋๋ํ ์ ์๋ค.\n *\n * ๋ฐ๊นฅ revision 12,972 ์ ๋์ ์ ํ ์ค ๋ฒํธ (์ด ์๋ฆฌ์์ ์ด์ด๋ฐ๋๋ค)\n * state.revision 6,478 ์ปค๋์ด ์ฒ๋ฆฌํ ๋ดํฌ ์ (0 ๋ถํฐ ์
๋ค)\n *\n * ํฌ์ฒ ๋ฏธ๋ฌ์์ ํ์ ํ๋ค: ์ฐจ์ด 6,494 ๋ ๊ทธ ํธ์์ **๋ค์ ์ธ์ด ์๊ฐ**(09:11)์ ์ ๋์ด ์ด๋ฏธ ๊ฐ๊ณ \n * ์๋ ์ค ์์ ์ ํํ ๊ฐ์๋ค(์ค 6494 = 08:23:59, ์ค 6495 = 09:11:13). ์ฐ์๊ฐ ๋ง์๋ค.\n *\n * ๊ฒฐํจ์ ๋ ์๊ฐ ๋ค๋ฅด๋ค๋ ๊ฒ ์์ฒด๊ฐ ์๋๋ผ **๋น๋์นญ**์ด๋ค: ์ฌ๊ธฐ๋ ๊ฒฝ๋ก(`start` โ `resumeRevision`)๋\n * ์ปค๋์ ๋ฒํธ๋ฅผ ์๋ ค ์ฃผ๋๋ฐ **์ด ๊ฒฝ๋ก(๋ฏธ๋ฌ)๋ ์๋ ค ์ฃผ์ง ์์๋ค.** ๊ทธ๋์ ๊ฐ์ ์ ์ฅ๋ฌผ์ ์ฝ๋ ์๋น์ฒ๊ฐ\n * ๊ฐ์ ์ด๋ฆ์ ๋ ์๋ฅผ ๊ฐ์ ์ถ์ผ๋ก ๊ฒฌ์ฃผ๊ฒ ๋๊ณ , ์ค์ ๋ก ๊ทธ๋ ๊ฒ ์ฝํ๋ค.\n *\n * ์ ๋์ด ๋น์ด ์์ผ๋ฉด(0) ์๋ฌด ์ผ๋ ํ์ง ์๋๋ค โ ์ ํธ์์ 0 ๋ถํฐ ์ธ๋ ๊ฒ์ด ๋ง๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ์กฐํ๋\n * ๋น๋๊ธฐ๋ผ ๊ทธ ์ฌ์ด์ ์ด๋ฒคํธ๊ฐ ๋ช ๊ฑด ๋ค์ด์ ์์ ์ ์๋๋ฐ, ๊ทธ๋ ๋ค๋ก ๋๋๋ฆฌ๋ ๊ฒ์ ์ปค๋์ด ๊ฑฐ์ ํ๋ค\n * (๊ฒน์น๋ ๋ฒํธ๋ฅผ ๋ง๋ ๊ทธ ํ์ ์ด๋ค). ๊ฑฐ์ ์ ์ผํค์ง ์๊ณ ๋จ๊ธด๋ค.\n */\n getRepository(TwinEvent)\n .findOne({ where: { domain: { id: domainId }, instanceId: id }, order: { revision: 'DESC' } })\n .then(top => {\n const head = top?.revision ?? 0\n inst.revision = head\n if (!head || typeof (kernel as any).resumeRevision !== 'function') return\n try {\n ;(kernel as any).resumeRevision(head)\n } catch (err: any) {\n /* ๋ค๋ก ๊ฐ ์ ์๋ค๋ ๊ฑฐ์ โ ์ด ์กฐํ๊ฐ ๋์ฐฉํ๊ธฐ ์ ์ ์ด๋ฏธ ๊ทธ๋งํผ ์ฒ๋ฆฌํ๋ค๋ ๋ป์ด๋ค. */\n twinWarn(`[twin-engine] \"${id}\": journal head ${head} is behind the kernel โ ${err?.message ?? err}`)\n }\n })\n .catch(() => (inst.revision = 0))\n this.register(domainId, id, kind, model, 'running', 'resync').catch(err => twinError('twin register fail', err))\n return inst\n }\n\n /**\n * live ์ด๋ฒคํธ ์ธ์ ์คํธ โ projector ๊ตฌ๋ + data(tag) ๋ธ๋ก๋์บ์คํ
(ํ๋ฃจํ์ ์ธ๋ฐ์ด๋ ๋์ฐฉ ์ง์ , command-routing ยง8.2).\n * reference ์ด๋ํฐ๊ฐ ๋ธ records โ ์ปค๋ face2-adapter.ingest โ CanonicalEnvelope ๋ฅผ ์ฌ๊ธฐ๋ก ๋ฐ์ด๋ฃ๋๋ค.\n * (State ์ฑ๋ ๋ธํ/์ ๋ ๊ฒฐ์ ์ ํ์ โ ์ค์ผ๋ ํค์ data(tag) ๋ฏธ๋ฌ ์ค์ฌ.)\n *\n * โโ ๋ฃ์ ์๋ฅผ **๋ตํ๋ค** (2026-08-20) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํธ์์ด ๋ผ์ด๋ธ๋ก ๋์ง ์์ผ๋ฉด ์ฌ๊ธฐ์ ๋ดํฌ๋ฅผ ๋ฒ๋ฆฐ๋ค. ๊ทธ๊ฒ ์์ฒด๋ ๋ง๋ค(๋ฃ์ ์ปค๋์ด ์๋ค). ๋ฌธ์ ๋\n * **์กฐ์ฉํ** ๋ฒ๋ฆฐ ๊ฒ์ด์๋ค: ํธ์์ด ๋ฉ์ถ ๋ค์๋ ํผ๋๋ ๋จ์ ๋ ์ฝ๋๋ฅผ ๋๋ฅด๊ณ , ์ ์
์ฅ๋ถ๋ ๊ทธ๊ฒ์\n * ใํต๊ณผใ๋ก ์
๋ค. ํ๋ฉด์ ๋ฉ์ถ ํธ์ ์์ ใ150 ํต๊ณผ ยท 100%ใ๋ผ๊ณ ์ ์๋ค โ ์ฌ์ค์ด ์ฌ๋ผ์ง๋ ๋์\n * ํ๋ฉด์ด ์์ฌ์ํจ ๊ฒ์ด๋ค.\n *\n * ๊ทธ๋์ **๋ฃ์ ์๋ฅผ ๋๋ ค์ค๋ค.** ๋ถ๋ฅด๋ ์ชฝ์ด ์ ์ ์์ ๊ฒฌ์ฃผ์ด ๋ฒ๋ ค์ง ์๋ฅผ ์ฅ๋ถ์ ์ ๋๋ค. ๋ฐํ์\n * ๋ฌด์ํ๋ ํธ์ถ๋ถ๋ ๊ทธ๋๋ก ๋์ํ๋ค(์ ๊ณผ ๊ฐ๋ค).\n */\n static ingestLive(domainId: string, id: string, envelopes: CanonicalEnvelope[]): number {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (inst?.mode !== 'live' || !inst.projector) return 0\n const tIngest = performance.now()\n /* ์ธ์
๋ดํฌ๋ฅผ ํ์ํด ๋๊ณ ๋ฃ๋๋ค โ ์ปค๋์ด ๊ทธ๊ฒ์ ์ฌ๋ฐฉ์ถํด๋ ์ ๋์ ๋ ๋ฒ ์ ํ์ง ์๊ฒ(์ ๊ตฌ๋
์ฃผ์). */\n for (const e of envelopes) {\n if (e && typeof e === 'object') inst.applying?.add(e as object)\n inst.projector.apply(e)\n inst.oee?.apply(e) // ๊ด์ธก(projector) + ๊ณ์ฐ(OEE ๋์ )\n }\n recordPhase(inst.load ?? (inst.load = newLoadMeter()), 'ingest', performance.now() - tIngest)\n // ์ ๋ ๊ฒฐ์ (๋ผ์ด๋ธ๋ sim ์ฒ๋ผ ์ด๋ฒคํธ ์์) โ ๋จ ์ด๋ฒคํธ๋ง๋ค DB write ํ๋ฉด ๋ถํํญ๋ฐ์ด๋ผ ๋ชจ์๋๋ค๊ฐ\n // coalescer tick ์์ ๋ฐฐ์น ๊ธฐ๋ก(๋ธ๋ก๋์บ์คํ
๊ณผ ๋์ผ ์ฃผ๊ธฐ). ํ์คํ ๋ฆฌ ๋
ธ๋ธยทํ์๋ผ์ธยท๋น์ฆ๋์ค ์์ฅ์ด ์ด ์ ๋์ ์ฝ๋๋ค.\n ;(inst.pendingJournal ?? (inst.pendingJournal = [])).push(...envelopes)\n if (inst.metrics) { inst.metrics.ingestedTotal += envelopes.length; inst.metrics._accIngest += envelopes.length } // ๊ณ์ธก(โฃ-1)\n // ๋ธ๋ก๋์บ์คํ
๋ณํฉ(ingest-scale ยง1.1/ยง4.4) โ apply ๋ O(1)ยท์ธ๋ค. ๊ทธ๋ฌ๋ ๋ธ๋ก๋์บ์คํ
(snapshot O(state))์ ๋น์ธ(๋๊ท๋ชจ 5ms+)\n // ์ด๋ฒคํธ๋ง๋ค ๋ธ๋ก๋์บ์คํ
ํ๋ฉด ํญ๋ฐ โ dirty ๋ง ์ฐ๊ณ coalescer tick ์ด ์ฃผ๊ธฐ ๋ธ๋ก๋์บ์คํ
(๋ธ๋ก๋์บ์คํ
๋ฅ โ ์ธ์ ์คํธ๋ฅ ).\n inst.dirty = true\n this.markItemsDirty(inst, envelopes)\n this.ensureBroadcastCoalescer()\n return envelopes.length\n }\n\n /**\n * ๊ตฌ๊ฐ ์ฑ๊ณผ ๋ธ๋ก๋์บ์คํ
์ **์์ด๋ค**(2026-08-06). ์นด๋๊ฐ `twinKpi` ๋ฅผ ์ง์ ๋ฌป๋๋ค.\n *\n * ์: ์นด๋๋ฅผ ์ฌ๋ฌ ๋จ๊ณ(๊ณต๊ฐยทํธ์ยท๊ตฌ์ญยท์๋ฆฌยท์ค๋น)์ ๋ถ์ด๋ ค๋ฉด ๋ธ๋ก๋์บ์คํ
์ผ๋ก๋ ํ๊ทธ๊ฐ ํธ์๋น 1,200๊ฐ๊ฐ ๋๊ณ ,\n * **๋ชจ๋ธ์ ์นด๋๋ฅผ ํ๋๋ ์ ๋์๋** 30์ด๋ง๋ค ํธ์๋ง๋ค ์ ๋์ ์ ์๋ค. ์ง์๋ก ๋ฐ๊พธ๋ ๋ณด๊ณ ์๋ ์นด๋\n * ์๋งํผ๋ง ๋ค๊ณ , ๊ฐ์ (๋์ยท์ฐฝยท์ถ) ์ ํด๋ผ์ด์ธํธ๊ฐ ํ๋๋ก ํฉ์น๋ค.\n *\n * ๋ค์ผ๋ก ์ง์๋ง ํ ์ ์๋ ๊ฒ์ด ๋ ์๊ฒผ๋ค โ **๊ณผ๊ฑฐ ์๊ฐ**(`toTime`)๊ณผ **๊ณต๊ฐ ๋จ์ ํฉ์ฐ**(์ฌ๋ฌ ํธ์์\n * ํ ๋ฒ์ ์ ๊ธฐ). ๋ธ๋ก๋์บ์คํ
๋ฃจํ๋ ํธ์๋ณ์ด๋ผ ๋ ๋ค ๋ชป ํ๋ค.\n *\n * ์ถ์ ๋๋ ๋ ํด๋ ๋น์ฉ์ด ๊ฐ๋ค๋ ์ค์ธก์ด ๊ทผ๊ฑฐ๋ค(`test/kpi-query-bench.test.ts`).\n */\n /**\n * ๋ช ์ฐฝ๋ง๋ค ํ ๋ฒ์ **์ ๋ถ** ๋ง๋๋ โ ์ฌ๊ฑด ์์ด ๊ฐ์ด ๋ฐ๋๋ ์๋ฆฌ์ ๋ํ ๊ทธ๋ฌผ.\n *\n * 25 ์ฐฝ์ด๋ฉด ๊ธฐ๋ณธ ์ฃผ๊ธฐ์์ 5์ด๋ค. ๋ณด์ฅ์ด ์๋๋ผ ๊ทธ๋ฌผ์ด๋ค(์ `publishEntityData` ์ฃผ์).\n */\n static FULL_BROADCAST_EVERY = 25\n /** ์ ๋ถ ๋ง๋ ํ์ โ ๋ฒ์๋ฅผ ์ขํ์ง ๋ชปํ ์ฐฝ์ด ์ผ๋ง๋ ๋๋์ง ๊ฐ์ผ๋ก ๋จ๋๋ค. */\n static broadcastFullPasses = 0\n /**\n * ๋ธ๋ก๋์บ์คํ
์ ๋ง๋ ํ์ ์ ๋ถ โ **์ ๋ถ ๋ง๋ ํ์์ ๋ถ๋ชจ.**\n *\n * ๋ถ์๋ง ๋ด๋ฉด ใ์ ๋ถ ๋ง๋ค๊ธฐ 1,200ํใ๊ฐ ๋ง์ ๊ฒ์ธ์ง ์ ์ ๊ฒ์ธ์ง ์ฝ์ ์ ์๋ค. ์ขํ๊ธฐ๊ฐ ๋ฃ๊ณ ์์ผ๋ฉด\n * ์ด ๊ฐ์ `1/FULL_BROADCAST_EVERY` ์ฏค์ด ์ ๋ถ ๋ง๋ ํ์์ด๊ณ , ๋ ๊ฐ์ด ๋น์ทํ๋ฉด ๋ฒ์๋ฅผ ๊ฑฐ์ ๋ชป ์ขํ\n * ๊ฒ์ด๋ค(์์ธ์ ๋๊ฐ ใ๋ชจ๋ฅธ๋คใ๋ก ๋จ์ด์ง๋ ์ฌ๊ฑด์ด๋ค).\n */\n static broadcastPasses = 0\n\n /**\n * ์ด ์ฐฝ์ ๊ฑด๋๋ฆฐ ๋ฌผํ์ ๋ชจ์๋ค โ **๋งํ ์ ์์ผ๋ฉด ๋ฒ์๋ฅผ ๋ฒ๋ฆฐ๋ค(์ ๋ถ ๋ง๋ ๋ค).**\n *\n * `events` ๋ฅผ ์ฃผ์ง ์์ผ๋ฉด ใ๋ฌด์์ด ๋ฐ๋์๋์ง ๋ชจ๋ฅธ๋คใ๋ค(๊ตฌ์กฐ ์ ํ์ฒ๋ผ ์ํ ์ ๋ฐ์ด ๋ฌ๋ผ์ง๋ ์๋ฆฌ).\n * ํ ์ฐฝ์์ ํ ๋ฒ ใ๋ชจ๋ฅธ๋คใ๊ฐ ๋๋ฉด ๊ทธ ์ฐฝ์ ๋๊น์ง ๋ชจ๋ฅด๋ ์ฑ๋ก ๋๋ค โ ๋ค์ ์จ ์ฌ๊ฑด์ผ๋ก ๋ฒ์๋ฅผ\n * ๋์ด๋ฆฌ๋ฉด ์ ์ฌ๊ฑด์ด ๊ฑด๋๋ฆฐ ๊ฒ์ ๋น ๋จ๋ฆฐ๋ค.\n */\n static markItemsDirty(inst: InstanceRuntime, events?: any[]): void {\n if (inst.dirtyItems === undefined) return // ์ด ์ฐฝ์ ์ด๋ฏธ ใ๋ชจ๋ฅธ๋คใ\n if (!events) {\n inst.dirtyItems = undefined\n return\n }\n for (const e of events) {\n const touched = touchedItemKeys(e)\n if (!touched) {\n inst.dirtyItems = undefined\n return\n }\n for (const epc of touched) inst.dirtyItems.add(epc)\n }\n }\n\n /** ๋ธ๋ก๋์บ์คํ
๋ณํฉ ์ฃผ๊ธฐ(ms) โ ๋ธ๋ก๋์บ์คํ
๋ฅ ์ํ. ์ธ์ ์คํธ๊ฐ ์๋ฌด๋ฆฌ ๋นจ๋ผ๋ ์ด ์ฃผ๊ธฐ๋ก๋ง ๋ธ๋ก๋์บ์คํ
. */\n static BROADCAST_COALESCE_MS = 200\n /**\n * โโ ๋ธ๋ก๋์บ์คํ
์ฃผ๊ธฐ๋ **์ฌ ๋ณธ ๋น์ฉ์ ๋ง์ถ๋ค** (2026-08-21 ์ค์ธก) โโโโโโโโโโโโโโโโโโโโ\n * ํ ๋ฒ์ ๋ธ๋ก๋์บ์คํ
์ ์ํ ํฌ๊ธฐ์ ๋น๋กํ๋ค(์ค์ธก: ๋ฌผํ 2,400 ๊ฐ์ธ ํธ์ ํ๋๊ฐ 4.5ms โ ์ํ ํฌ์ 1.7ms,\n * payload ๋ง๋ค๊ธฐ 1.8ms, ์๊ทธ๋์ฒ 1.0ms). ํธ์์ด ์ค๋ฌด ๊ฐ๋ฉด 200ms ๋ง๋ค 90ms ๊ฐ ๋ธ๋ก๋์บ์คํ
์ ๋ค์ด๊ฐ๊ณ ,\n * ๊ทธ ์๊ฐ์๋ HTTP ๋ ๊ตฌ๋
๋ ์์ง ๋ชปํ๋ค.\n *\n * ๊ทธ๋์ ํ ์ฐฝ์์ ๋ธ๋ก๋์บ์คํ
์ ์ด ์๊ฐ์ด ์ฃผ๊ธฐ์ ์ผ์ ๋ชซ์ ๋์ผ๋ฉด **์ฃผ๊ธฐ๋ฅผ ๋๋ฆฐ๋ค**. ํ๋ฉด์ ์กฐ๊ธ ๋ฆ๊ฒ\n * ๊ฐฑ์ ๋๊ณ (์ต์ -์ํ ์ฑ๋์ด๋ผ ๊ฐ์ ๋ง์ง๋ง ๊ฒ ํ๋๋ฟ์ด๋ฏ๋ก ๋ด์ฉ์ ๊ฐ๋ค), ๋๋ ธ๋ค๋ ๊ฒ์ ๊ณ๊ธฐํ์ด\n * ๋งํ๋ค(`broadcastCoalesceMs`). ์ฌ์ ๊ฐ ์๊ธฐ๋ฉด ์๋ ์ฃผ๊ธฐ๋ก ๋๋๋ฆฐ๋ค.\n *\n * ์ด๊ฒ์ ๋ธ๋ก๋์บ์คํ
๋น์ฉ์ **์ค์ด๋ ๊ฒ์ด ์๋๋ค** โ ๋น์ฉ์ ์ค์ด๋ ๊ฒ์ ๋ณ๊ฒฝ๋ถ๋ง ๋ง๋๋ ์ผ์ด๊ณ ๊ทธ๊ฒ์ ๋ณ\n * ์์
์ด๋ค. ์ฌ๊ธฐ์๋ ๊ทธ๋๊น์ง ํธ์คํธ๊ฐ ๊ตถ์ง ์๊ฒ ์ํ์ ๋๋ค.\n */\n static BROADCAST_MAX_COALESCE_MS = 1000\n /** ์ฃผ๊ธฐ์ ๋ช ๋ชซ๊น์ง ๋ธ๋ก๋์บ์คํ
์ ์จ๋ ๋๋๊ฐ โ ๋์ผ๋ฉด ์ฃผ๊ธฐ๋ฅผ ๋๋ฆฐ๋ค(์ ๋ฐ์ด๋ฉด ๋๋จธ์ง ์ ๋ฐ์ ๋จ๊ธด๋ค). */\n static BROADCAST_LOAD_RATIO = 0.3\n /** ์ง๊ธ ์ฐ๊ณ ์๋ ์ฃผ๊ธฐ(ms) โ ๊ณ๊ธฐํ์ด ์ด ๊ฐ์ ์ฝ๋๋ค. ๋์ด๋ ์ฑ๋ก ์์ผ๋ฉด ๊ทธ๊ฒ์ด ์ฌ์ค์ด๋ค. */\n static broadcastPeriodMs = 200\n /** ์ฃผ๊ธฐ๋ฅผ ๋๋ฆฐ ํ์ โ ์กฐ์ฉํ ๋ฆ์ถ์ง ์๋๋ค. */\n static broadcastBackoffs = 0\n private static broadcastTimer?: any\n\n /** live ๋ธ๋ก๋์บ์คํ
coalescer โ dirty ์ธ live ์ธ์คํด์ค๋ง ์ฃผ๊ธฐ์ ์ผ๋ก 1ํ ๋ธ๋ก๋์บ์คํ
(entitySigs ๋ก ๋ณ๊ฒฝ ์ํฐํฐ๋ง). */\n private static ensureBroadcastCoalescer(): void {\n if (this.broadcastTimer) return\n this.broadcastPeriodMs = this.BROADCAST_COALESCE_MS\n this.broadcastTimer = setInterval(() => this.flushLiveBroadcasts(), this.broadcastPeriodMs)\n if (typeof this.broadcastTimer.unref === 'function') this.broadcastTimer.unref() // ์ข
๋ฃ ๋น์ฐจ๋จ\n }\n\n /**\n * ๋ธ๋ก๋์บ์คํ
์ ์ด ์๊ฐ์ ๋ณด๊ณ ์ฃผ๊ธฐ๋ฅผ ์ ํ๋ค โ **๋๋ฆฌ๋ ๊ฒ๋ ์ค์ด๋ ๊ฒ๋ ๊ฐ์ ๊ทผ๊ฑฐํ๋ค.**\n *\n * ํ ๋ฒ์ flush ๊ฐ ์ฃผ๊ธฐ์ `BROADCAST_LOAD_RATIO` ๋ฅผ ๋๊ฒ ์ฐ๋ฉด ์ฃผ๊ธฐ๋ฅผ ๋ ๋ฐฐ๋ก(์ํ๊น์ง), ๊ทธ ๋ชซ์\n * ์ ๋ฐ ์๋๋ก ๋ด๋ ค์ค๋ฉด ์ ๋ฐ์ผ๋ก(์๋ ์ฃผ๊ธฐ๊น์ง) ๋๋๋ฆฐ๋ค. ๋ฌธํฑ์ ๋ ๊ฐ ๋๋ ์ด์ ๋ ํ๋๋ฉด ๊ฒฝ๊ณ์์\n * ๋๋ฆฌ๊ณ ์ค์ด๊ธฐ๋ฅผ ๋ฐ๋ณตํ๊ธฐ ๋๋ฌธ์ด๋ค.\n */\n private static adjustBroadcastPeriod(flushMs: number): void {\n const period = this.broadcastPeriodMs\n const high = period * this.BROADCAST_LOAD_RATIO\n const low = high / 2\n let next = period\n if (flushMs > high && period < this.BROADCAST_MAX_COALESCE_MS) {\n next = Math.min(this.BROADCAST_MAX_COALESCE_MS, period * 2)\n this.broadcastBackoffs++\n twinWarn(\n `[twin-engine] broadcast period ${period}ms โ ${next}ms โ one flush took ${Math.round(flushMs)}ms across ${Object.keys(this.instances).length} twin(s)`\n )\n } else if (flushMs < low && period > this.BROADCAST_COALESCE_MS) {\n next = Math.max(this.BROADCAST_COALESCE_MS, Math.round(period / 2))\n }\n if (next === period) return\n\n this.broadcastPeriodMs = next\n if (this.broadcastTimer) clearInterval(this.broadcastTimer)\n this.broadcastTimer = setInterval(() => this.flushLiveBroadcasts(), next)\n if (typeof this.broadcastTimer.unref === 'function') this.broadcastTimer.unref()\n }\n\n /**\n * dirty ์ธ์คํด์ค ๋ธ๋ก๋์บ์คํ
flush(์ฃผ๊ธฐ tick ๋๋ ๋ช
์ ํธ์ถ) โ **์๋ฎฌ๊ณผ ๋ผ์ด๋ธ ๋ ๋ค.**\n *\n * ์์ ์๋ ๋ผ์ด๋ธ๋ง ๋ดค๋ค(`mode !== 'live'` ๋ฉด ๊ฑด๋๋). ์๋ฎฌ์ delta ๋ง๋ค ๊ณง๋ฐ๋ก ๋ธ๋ก๋์บ์คํ
ํ๊ณ , ๊ทธ๊ฒ์ด\n * ํ tick ์์ ์๋ฐฑ ๋ฒ ๋ฐ๋ณต๋๋ฉฐ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ๋ง์๋ค(์ `start()` ์ฃผ์์ 35์ด ํฑ). ๋ธ๋ก๋์บ์คํ
์ ๋ชจ์ผ๋\n * ๊ท์จ์ ๋ชจ๋์ ์ฑ์ง์ด ์๋๋ผ **์ฑ๋์ ์ฑ์ง**์ด๋ค โ ์ต์ -์ํ ์ฑ๋์ด๋ฉด ์ค๊ฐ ์ํ๋ ๋ณด๋ผ ๊ฐ์ด ์๋ค.\n */\n static flushLiveBroadcasts(): void {\n const now = Date.now()\n const flushStart = performance.now()\n for (const inst of Object.values(this.instances)) {\n const isLive = inst.mode === 'live'\n /*\n * ์ฒ๋ฆฌ๋ ๊ณ์ธก(โฃ-1) โ ์ฐฝ(โฅ1s)๋ง๋ค ์ ์
ยท๋ธ๋ก๋์บ์คํ
ยท์ ๋๋ฅ ๊ฐฑ์ . dirty ๋ฌด๊ด(์ ํด๋ฉด 0์ผ๋ก ์๋ ด).\n *\n * **๋ ๊ตฌ๋์ ํจ๊ป ์ผ๋ค** (2026-08-20). ์์ ์๋ `isLive ? โฆ : undefined` ๋ก ์๋ฎฌ์ ์๋ผ ๋๋ค.\n * ๊ทธ๋์ ๋๋ ํธ์ ๋๋ถ๋ถ์ด ์๋ฎฌ์ธ ์๋ฒ์์ ใ์ด๋น ๋ช ํ์ ์ฐ๋ใ์ ๋ตํ ์๋ฆฌ๊ฐ ์์๋ค โ ์ ๋ ์ฐ๊ธฐ๋ฅผ\n * ๋ฐฐ์น๋ก ๊ณ ์น ๋ค์๋ ๊ทธ ํจ๊ณผ๋ฅผ ์ซ์๋ก ๋ณผ ์ ์์๋ค. ์ ์
(`ingestRate`)์ ์๋ฎฌ์์ 0 ์ผ๋ก ์๋ ดํ๊ณ ,\n * ๊ทธ๊ฒ์ด ์ฌ์ค์ด๋ค(์๋ณธ์์ ๋ฐ๋ ๊ฒ์ด ์๋ค).\n */\n const m = inst.metrics\n if (m) {\n const dt = (now - m._windowStartMs) / 1000\n if (dt >= 1) {\n m.ingestRate = Math.round(m._accIngest / dt)\n m.broadcastRate = Math.round((m._accBroadcast / dt) * 10) / 10\n m.journalRate = Math.round(m._accJournal / dt)\n m._accIngest = 0; m._accBroadcast = 0; m._accJournal = 0; m._windowStartMs = now\n }\n }\n if (!inst.dirty) continue\n inst.dirty = false\n /* ์ฃผ๊ธฐ๋ง๋ค ํ ๋ฒ์ ๋ฒ์๋ฅผ ๋ฒ๋ฆฌ๊ณ ์ ๋ถ ๋ง๋ ๋ค โ ์ฌ๊ฑด ์์ด ๊ฐ์ด ๋ฐ๋๋ ์๋ฆฌ์ ๋ํ ๊ทธ๋ฌผ. */\n const left = (inst.fullBroadcastCountdown ?? 0) - 1\n if (left <= 0) {\n inst.fullBroadcastDue = true\n inst.fullBroadcastCountdown = this.FULL_BROADCAST_EVERY\n } else {\n inst.fullBroadcastCountdown = left\n }\n // โ ์ํฐํฐ data(tag) ๋ธ๋ก๋์บ์คํ
โ ๋ณด๋ ์ปดํฌ๋ํธ ๋ผ์ด๋ธ ๋ ๋.\n this.publishEntityData(inst)\n if (m) { m.broadcastTotal++; m._accBroadcast++ }\n /* โข ์ ๋ ๋ฐฐ์น ๊ธฐ๋ก โ **๋ ๊ตฌ๋์ด ๊ฐ์ ๋ฌธ์ ์ด๋ค**(์๋ฎฌ๋ ์ฌ๊ธฐ์ ํ๋ฆฐ๋ค, ยง7.1). */\n this.flushJournal(inst)\n /* ์ฌ๊ธฐ์๋ถํฐ๋ **๋ผ์ด๋ธ๋ง**์ด๋ค: ์๋ฎฌ์ state ์ฑ๋์ ์๊ธฐ ์ฝ๋ฐฑ์ด ๋ธํ๋ง๋ค ๋ณด๋ด๋ฏ๋ก(๋ฆฌ๋น์ ์ด ์ปค๋์\n ๊ฒ์ด๋ค) ์ฌ๊ธฐ์ ๋ ๋ณด๋ด๋ฉด ๊ฐ์ ์ ํธ๊ฐ ๋ ๋ฒ ๊ฐ๋ค. ์ ๋์ ์์์ ์ด๋ฏธ ๋ ๊ตฌ๋ ๋ชซ์ ํ๋ ธ๋ค. */\n if (!isLive) continue\n // โก State ์ฑ๋ ๋ธ๋ก๋์บ์คํ
โ \"๋ฐ๋์๋ค\"๋ ๊ฐ๋ฒผ์ด ์ ํธ๋ง(kind+revision). ๋งต ๊ตฌ๋
(subscribeTwinState)์ ์ด ์ ํธ์\n // scheduleRefresh(250ms ๋๋ฐ์ด์ค)โpollLive ๋ก ๋๋ฌผ์ด๋ด. ์ค๋
์ท(O(state))์ ๋ณด๋ ์ฌ๋์ด ๋ฌผ์ ๋๋ง 1ํ ๊ณ์ฐ.\n // (์ฌ๊ธฐ์ payload ๋ก ์ค๋
์ท์ ์ค์ผ๋ฉด ์๋ฌด๋ ์ ์ฝ๋๋ฐ tick ๋ง๋ค ํต์งธ๋ก ๋ ์ ์์ ๋ญ๋น โ ์ ํธ๋ง ๋ณด๋ธ๋ค.)\n this.publishGuarded(\n 'twin-state',\n { twinState: { instanceId: inst.id, kind: 'delta', revision: inst.revision ?? 0 } },\n `twin-state:${inst.id}`\n )\n }\n /* ๊ฐ๋ ์ค์ธ ์ธ์คํด์ค๊ฐ ํ๋๋ ์์ผ๋ฉด tick ์ ๋ฉ์ถ๋ค(์์ ์ ใ๋ผ์ด๋ธ๊ฐ ์์ผ๋ฉดใ์ด์๋๋ฐ, ์ด์ \n ์๋ฎฌ๋ ์ด flush ์ ๊ธฐ๋๋ฏ๋ก ๊ทธ ์กฐ๊ฑด์ด๋ฉด ์๋ฎฌ ๋ธ๋ก๋์บ์คํ
์ด ๋ฉ์ถ ์ฑ ๋จ๋๋ค). */\n if (!Object.keys(this.instances).length && this.broadcastTimer) {\n clearInterval(this.broadcastTimer)\n this.broadcastTimer = undefined\n this.broadcastPeriodMs = this.BROADCAST_COALESCE_MS\n return\n }\n /* ์ด๋ฒ flush ๊ฐ ์ผ๋ง๋ฅผ ์ผ๋์ง๋ก ๋ค์ ์ฃผ๊ธฐ๋ฅผ ์ ํ๋ค โ ๋ธ๋ก๋์บ์คํ
์ด ๋ฃจํ๋ฅผ ๋ค ์ฐ์ง ๋ชปํ๊ฒ. */\n this.adjustBroadcastPeriod(performance.now() - flushStart)\n }\n\n /**\n * ์ ๋ ํ ํ ์ค โ **๊ธฐ๋ก ๊ฒฝ๋ก๊ฐ ๋์ด๋ผ(๋ผ์ด๋ธ ๋ฒํฌยท์ฌ ๋จ๊ฑด) ํ ๋ชจ์์ ๋ฐ๋์ ํ ๊ณณ์์ ๋ง๋ ๋ค.**\n * ๋ ๊ณณ์ ๊ฐ์ ์ ์ผ๋ฉด ์น๊ฒฉ ๊ฒ์ ํค๊ฐ ํ์ชฝ์๋ง ์ฑ์์ง๊ณ , ๋ฐ์ฏค ๋น ์์ธ์ \"์ ๋์๋ ์๋๋ฐ\n * ๊ฒ์์ผ๋ก๋ ์ ๋์ค๋ ์ด๋ฒคํธ\" ๋ฅผ ๋ง๋ ๋ค โ ์ ๋์์ ๊ฐ์ฅ ๋์ ์ข
๋ฅ์ ๊ฒฐํจ์ด๋ค.\n */\n /** ์ ๋์ ์๊ฐ ์ถ์ ๋ ์ง๋ค โ ๋ชป ์ฝ๋ ๊ฐ์ ๋น์ด๋ค(0 ์ด๋ ์ง๊ธ์ผ๋ก ์์ฅํ์ง ์๋๋ค). */\n private static toEventTimeValue(v: any): Date | undefined {\n if (v instanceof Date) return v\n const t = typeof v === 'string' ? Date.parse(v) : NaN\n return Number.isNaN(t) ? undefined : new Date(t)\n }\n\n private static journalRow(repo: any, domainId: string, instanceId: string, e: any, revision: number, structureRev?: number) {\n return repo.create({\n domain: { id: domainId } as any,\n instanceId,\n eventType: e?.eventType,\n /* ์ปค๋์ด ์ปค๋งจ๋์์ ์ด์ด ์ค ๊ฐ โ ์ด๊ฒ์ด ๊ฐ์ฌ ๊ธฐ๋ก๊ณผ ์ ๋์ ์๋ ๋ค๋ฆฌ๋ค. */\n correlationId: e?.correlationId,\n revision,\n /* **์ด ์ฌ์ค์ด ์ผ์ด๋ ๊ณต์ฅ**์ ํจ๊ป ์ฐ๋๋ค โ ์ด๊ฒ์ด ์์ผ๋ฉด ๋์ค์ ๊ตฌ์กฐ๊ฐ ๋ฐ๋์์ ๋ ์ด ํ์\n ์ ๊ณต์ฅ์ ๋๊ณ ์ ๊ฒ ๋๊ณ , ๊ทธ๋ ์๋ ์ค๋น์์ ์ผ์ด ์์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค. */\n ...(structureRev === undefined ? {} : { structureRev }),\n /* ์ปค๋์ ISO ๋ฌธ์์ด์ ์ค๋ค. ์ปฌ๋ผ์ ๋ ์ง๋ค โ **์ฌ๊ธฐ์ ์ฎ๊ธด๋ค.** ๋ฌธ์์ด์ ๊ทธ๋๋ก ๋ฃ์ผ๋ฉด\n ๋๋ผ์ด๋ฒ๊ฐ ์ ํ์์ผ๋ก ์ ๊ทํํ์ง ์์, ๋์ค์ ๋ ์ง๋ก ๊ฑฐ๋ ์ง์์ ์ ๊ฑธ๋ฆฐ๋ค. */\n eventTime: this.toEventTimeValue(e?.eventTime),\n ...twinEventKeys(e),\n payload: e\n })\n }\n\n /**\n * ์ด ํธ์์ด ์ง๊ธ ์ด๋ ๊ตฌ์กฐ๋ก ๋๋๊ฐ โ ์ด๋ฒคํธ์ ์ฐ์ ๋ฒํธ. ํ ๋ฒ ์ฝ๊ณ ์บ์ํ๋ค(์ฐ๊ธฐ๋ง๋ค ์กฐํ ๊ธ์ง).\n *\n * ์์ผ๋ฉด `undefined` ๋ค โ 0 ์ด ์๋๋ค. ๊ตฌ์กฐ ๋ฆฌ๋น์ ์ด ์๊ธฐ๊ธฐ ์ ์ ๋ง๋ค์ด์ง ํธ์์ ์์ง ๋ฆฌ๋น์ ์ด\n * ์๊ณ , ๊ทธ ์ฌ์ค์ 0 ์ด๋ผ๋ **์ ํจํด ๋ณด์ด๋ ๋ฒํธ**๋ก ์์ฅํ๋ฉด ์ ๋๋ค.\n */\n /** ๊ตฌ์กฐ ๋ฆฌ๋น์ ์บ์ โ `null` ์ **์๋ค๋ ๊ฒ์ ์๊ณ ์๋ค**๋ ๋ป์ด๋ค(๋ชจ๋ฆ๊ณผ ๊ตฌ๋ณํ๋ค, ยง7.1). */\n private static structureRevCache: Record<string, number | null> = {}\n static async structureRevOf(domainId: string, instanceId: string): Promise<number | undefined> {\n const key = runtimeKey(domainId, instanceId)\n const cached = this.structureRevCache[key]\n /*\n * **์๋ค๋ ๊ฒ๋ ๋ต์ด๋ค** โ ์์ ์๋ ์ฐพ์ง ๋ชปํ๋ฉด ์บ์ํ์ง ์์๋ค(`if (latest) โฆ`). ๊ทธ๋์ ๊ตฌ์กฐ ํ์ด\n * ์๋ ํธ์์ **๋ถ๋ฅผ ๋๋ง๋ค SELECT** ํ๊ณ , ๊ทธ ๊ฒฝ๋ก๊ฐ ๋ธํ๋ง๋ค ๋ถ๋ฆฌ๊ณ ์์๋ค(ยง7.1). `null` ๋ก ๊ธฐ์ตํ๋ค.\n */\n if (cached !== undefined) return cached === null ? undefined : cached\n const latest = await getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n this.structureRevCache[key] = latest ? latest.rev : null\n return latest?.rev\n }\n\n /** ๊ณ๊ธฐ ํ ๋ฒ โ **๋ ๊ตฌ๋์ด ๊ฐ์ ๊ฒ์ ๋ ๋ค**(ํ์ชฝ๋ง ๋ค๋ฉด ๊ทธ ๊ตฌ๋์ ๋ฌผ์ด๋ ๋ต์ด ์๋ค). */\n private static newMetrics(): TwinMetrics {\n return { ingestedTotal: 0, broadcastTotal: 0, journaledTotal: 0, ingestRate: 0, broadcastRate: 0, journalRate: 0, backlog: 0, _accIngest: 0, _accBroadcast: 0, _accJournal: 0, _windowStartMs: Date.now() }\n }\n\n /**\n * ๋ชจ์ ๋ ์ ๋์ **ํ ๋ฒ์** ์ด๋ค โ ๋ ๊ตฌ๋์ด ๊ฐ์ ๋ฌธ์ ์ด๋ค (ยง7.1).\n *\n * โโ ์ ํ ํจ์์ธ๊ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ฐ๋ ์๋ฆฌ๊ฐ ๋์ด๋ฉด(์ฃผ๊ธฐ flush ยท ์ ์ง) ํ์ชฝ๋ง ๊ณ ์ณ์ง๊ณ , ๊ทธ ์ด๊ธ๋จ์ **์ฌ์ค์ด ์กฐ์ฉํ ์ฌ๋ผ์ง๋**\n * ๋ชจ์์ผ๋ก ๋ํ๋๋ค. ๊ทธ๋์ ํ๋ฆฌ๋ ๊ท์น์ ์ฌ๊ธฐ ํ ๊ณณ์ ๋๋ค.\n *\n * โโ ๋ฆฌ๋น์ ์ ๋๊ฐ ๋งค๊ธฐ๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ยท ๋ผ์ด๋ธ โ ์์ฒ์ ๋ฆฌ๋น์ ์ ์ฃผ์ง ์์ผ๋ฏ๋ก **ํธ์คํธ๊ฐ** ์ด์ด ๋ถ์ธ๋ค(์ ๋ high-water ์์ ์๋).\n * ยท ์๋ฎฌ โ **์ปค๋์ ๋ฆฌ๋น์ **์ด ์ค๋ ค ์จ๋ค(์ ๋์ด ๊ทธ๊ฒ์ผ๋ก ์ ํ๊ณ ์๊ฐ์ฌํ์ด ๊ทธ๊ฒ์ ๋๋๋ค).\n * ๊ทธ๋์ ๋ฒํผ๋ ๋ ๋ชจ์์ ํจ๊ป ๋ ๋ค: ๋ดํฌ๋ง ์์ผ๋ฉด ๋ผ์ด๋ธ, `{ event, revision }` ์ด๋ฉด ์๋ฎฌ์ด๋ค.\n */\n private static flushJournal(inst: InstanceRuntime): Promise<void> {\n const batch = inst.pendingJournal\n if (!batch?.length) return Promise.resolve()\n inst.pendingJournal = []\n const m = inst.metrics\n /* ์ด ๊ฑด์๋ ๋์ ์, **์ง๊ธ ๋จ์ ๊ฒ**์ backlog ์. ์ด ์๋ฆฌ์์ ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ backlog ๋ก ์ ์ผ๋ฉด\n ์ ์์ ์ธ ๋ฐฐ์น ์ ์ฅ์ด ํ๋ฉด์์ ๊ฒฝ๊ณ ๋ก ๋ณด์ธ๋ค(2026-08-21 ๊ต์ ). */\n if (m) { m.journaledTotal += batch.length; m._accJournal += batch.length; m.backlog = inst.pendingJournal?.length ?? 0 }\n\n /* ์๋ฎฌ์ ์๊ธฐ ๋ฆฌ๋น์ ์ ๋ค๊ณ ์จ๋ค โ ๊ทธ๋๋ก ์ด๋ค. ๋ผ์ด๋ธ๋ ์ฌ๊ธฐ์ ์ด์ด ๋ถ์ธ๋ค. */\n const carried = batch.filter((b: any) => b && typeof b === 'object' && 'event' in b && typeof b.revision === 'number')\n const plain = batch.filter((b: any) => !(b && typeof b === 'object' && 'event' in b && typeof b.revision === 'number'))\n\n const tJournal = performance.now()\n const done = () => recordPhase(inst.load ?? (inst.load = newLoadMeter()), 'journal', performance.now() - tJournal)\n const jobs: Promise<void>[] = []\n\n if (carried.length) jobs.push(this.persistCarried(inst.domainId, inst.id, carried))\n if (plain.length && inst.revision != null) {\n const start = inst.revision\n inst.revision = start + plain.length\n jobs.push(this.persistBatch(inst.domainId, inst.id, plain, start))\n }\n if (!jobs.length) return Promise.resolve()\n /*\n * **์ฝ์์ ๋๋ ค์ค๋ค** โ ์ฃผ๊ธฐ flush ๋ ๊ธฐ๋ค๋ฆฌ์ง ์์ง๋ง(ํซ ๊ฒฝ๋ก) **์ ์ง๋ ๊ธฐ๋ค๋ ค์ผ ํ๋ค.** ๊ธฐ๋ค๋ฆฌ์ง\n * ์์ผ๋ฉด ๊ณง๋ฐ๋ก ์ด์ด์ง๋ ์ ๋ ์ฌ์์ด ์์ง ์ ์ฐ์ธ ๊ตฌ๊ฐ์ ๋ชป ๋ณด๊ณ , ์์คํํธ๊ฐ ใ์๋ ์ผใ๋ก ์์ํ๋ค\n * (์ค์ ๋ก ๊ทธ๋ ๊ฒ ๊นจ์ก๋ค: ํ๋ณด๋ถ์ ๋ ์ค๋๊ฐ ๋์ด์๋์ง ๋ชปํ๋ค).\n */\n const written = carried.length + plain.length\n return Promise.all(jobs)\n .then(() => {\n done()\n /*\n * **์ ํ ๋ค์ ์ ๋๋ค** โ ์คํจํ ๋ฐฐ์น๋ฅผ ใ๋จ์๋คใ๊ณ ์ธ๋ฉด ์ถ์ด๊ฐ ์๋ ์ฌ์ค์ ์๋ค๊ณ ๋งํ๋ค.\n * ์ฐฝ(10๋ถ)์ ์์ด๋ฏ๋ก ์ฌ๊ธฐ๋ ๋ค์๋ ใ์ง๋ ์ฌ์ฏ ์๊ฐ ์ผ๋ง๋ ์ ์๋ใ๋ฅผ ๋ตํ ์ ์๋ค.\n */\n this.recordJournalWrite(inst.domainId, inst.id, written)\n })\n .catch(err => twinError('twin journal flush fail', err))\n }\n\n /**\n * ์ปค๋์ด ๋งค๊ธด ๋ฆฌ๋น์ ์ ๊ทธ๋๋ก ๋ค๊ณ ๋ฒํฌ ์ ์ฅ โ ์๋ฎฌ ๊ฒฝ๋ก.\n *\n * ์์ ์๋ ์ด ๊ฒฝ๋ก๊ฐ **๋ธํ๋ง๋ค ํ ํ์ฉ** ์ ์ฅํ๋ค(๊ทธ๋ฆฌ๊ณ ํ๋ง๋ค ๊ตฌ์กฐ ๋ฆฌ๋น์ ์ ๋ฌผ์๋ค). ๊ท๋ชจ์์ ๊ทธ๊ฒ์ด\n * ํธ์คํธ๋ฅผ ๋จน์๋ค(ยง7.1 ์ค์ธก). ์ฌ๊ธฐ์ ๊ตฌ์กฐ ๋ฆฌ๋น์ ์ **ํ ๋ฒ๋ง** ๋ฌป๋๋ค.\n */\n static async persistCarried(domainId: string, instanceId: string, items: { event: any; revision: number }[]): Promise<void> {\n const repo = getRepository(TwinEvent)\n const structureRev = await this.structureRevOf(domainId, instanceId)\n const rows = items.map(it => this.journalRow(repo, domainId, instanceId, it.event, it.revision, structureRev))\n await this.insertRows(repo, rows)\n }\n\n /**\n * ์ ๋ ํ์ ๋ฃ๋๋ค โ **๋ฃ๊ธฐ๋ง ํ๋ค**(2026-08-20).\n *\n * ์์ ์๋ `save()` ์๋ค. ๊ทธ๋ฐ๋ฐ `save` ๋ ๋ฃ์ ๋ค ์์ฑ ์ปฌ๋ผ์ ์ฝ์ผ๋ ค๊ณ **ํ๋ง๋ค SELECT ๋ฅผ ํ ๋ฒ ๋**\n * ํ๋ค(์ํ ๋ก๊ทธ์์ ๊ทธ ์ง์๊ฐ ๊ทธ๋๋ก ๋ณด์๋ค: `SELECT โฆ FROM twin_events WHERE id = ?`). ์ ๋์\n * append-only ์ด๊ณ ๋ถ๋ฅด๋ ์ชฝ์ ๋๋ ค๋ฐ์ ์ํฐํฐ๋ฅผ ์ฐ์ง ์์ผ๋ฏ๋ก ๊ทธ ์๋ณต์ด ์์ ๋ญ๋น๋ค.\n *\n * ๋ฌถ์์ **๋๋ ์** ๋ฃ๋๋ค: ํ ๋ฌธ์ ์ด์ด ์ด๋ค์ฏ์ธ ํ์ ์์ฒ ๊ฐ ์ค์ผ๋ฉด ๋๋ผ์ด๋ฒ์ ํ๋ผ๋ฏธํฐ ํ๊ณ์\n * ๊ฑธ๋ฆฐ๋ค(pg ๋ 65,535๊ฐ). 500ํ์ด๋ฉด ์ด๋ ๋๋ผ์ด๋ฒ์์๋ ์์ ํ๋ค.\n */\n private static async insertRows(repo: any, rows: any[]): Promise<void> {\n const CHUNK = 500\n /*\n * โโ ํ ํธ๋์ญ์
์ผ๋ก ๊ฐ์ธ ๋ณด์๊ณ , **๋๋๋ ธ๋ค** (2026-08-22 ์ค์ธก) โโโโโโโโโโโโโ\n * ใ์ฒญํฌ๋ง๋ค ์ปค๋ฐํ๋ฉด fsync ๊ฐ ๊ทธ๋งํผ ๋์ด๋๋คใ๋ ์ด์ ๋ก ์ ์ฒด๋ฅผ ํ ํธ๋์ญ์
์ ๊ฐ์๋ค. ์ฐ๊ธฐ ์์ฒด๋\n * ์ค์ ๋ก ๋นจ๋ผ์ก๋ค โ ๋๋ฆฐ ์ง์ ๋ชฉ๋ก์์ ์ด INSERT ๊ฐ ์ฌ๋ผ์ก๋ค. **๊ทธ๋ฐ๋ฐ ์๋ฒ๊ฐ ๋ ๋๋ ค์ก๋ค.**\n *\n * ๊ฐ์ธ๊ธฐ ์ ๋๋ฆฐ ์ง์ ์ต๋ 32.3์ด ยท ROLLBACK ์์\n * ๊ฐ์ผ ๋ค ๋๋ฆฐ ์ง์ ์ต๋ 50.2์ด ยท ROLLBACK 36.3์ด ๋ฑ์ฅ\n *\n * ๊ธฐ์ ์ ๋๋ผ์ด๋ฒ๋ค. TypeORM ์ sqlite ๋๋ผ์ด๋ฒ๋ ์ฐ๊ฒฐ์ **ํ๋**๋ง ๋ ๋ค(ํ ์์). ํธ๋์ญ์
์ด\n * ์ด๋ ค ์๋ ๋์ ๊ทธ ์ ์ผํ ์ฐ๊ฒฐ์ ์ด ๋ฌถ์์ ๊ฒ์ด๋ฏ๋ก, **๋ฌถ์์ด ๋๋ ๋๊น์ง ์ฑ์ ๋ชจ๋ ์ง์๊ฐ\n * ๊ธฐ๋ค๋ฆฐ๋ค.** ์ฒญํฌ๋ง๋ค ์ปค๋ฐํ๋ฉด ๊ทธ ์ฌ์ด์ ๋ค๋ฅธ ์ง์๊ฐ ๋ผ์ด๋ค ์๋ฆฌ๊ฐ ์๊ธด๋ค โ fsync ๋ฅผ ๋ ์น๋ฅด๋\n * ๋์ **๋จธ๋ฆฌ ๋งํ์ด ์งง์์ง๋ค.**\n *\n * ์ฆ ์ฌ๊ธฐ์๋ ใ์ปค๋ฐ ์๋ฅผ ์ค์ด๋ ๊ฒใ์ด ๋ชฉ์ ์ด ์๋๋ค. ๋ชฉ์ ์ **ํ ๋ฒ์ ์ค๋ ๋ถ์ก์ง ์๋ ๊ฒ**์ด๋ค.\n * ์ ๋ ๋ฌถ์์ ์์์ฑ์ ๊ทธ ๋๊ฐ๋ฅผ ์น๋ฅผ ๋งํผ์ ๊ฐ์ด ์๋๋ค: ์ ๋์ append-only ์ด๊ณ ๋ฆฌ๋น์ ์ด\n * ์ด์ด์ง๋ฏ๋ก, ์ ๋ฐ๋ง ๋ค์ด๊ฐ ๋ฌถ์์ ๋ค์ ๊ธฐ๋์ replay ๊ฐ ๊ทธ ์ง์ ๋ถํฐ ์ด์ด๋ฐ๋๋ค.\n *\n * ์ฐ๊ฒฐ ํ์ด ์๋ ๋๋ผ์ด๋ฒ(postgresยทmysql)์์๋ ํ๋จ์ด ๋ฌ๋ผ์ง ์ ์๋ค โ ๊ทธ๋๋ ์ด ์ฃผ์์ ๊ทผ๊ฑฐ๋ก\n * ๋ค์ ์ฌ๊ณ ์ ํ๋ผ. **๋๋ผ์ด๋ฒ๋ง๋ค ๋ค๋ฅธ ๊ฒฐ๋ก ์ด ๋๋ ์๋ฆฌ๋ค.**\n */\n for (let i = 0; i < rows.length; i += CHUNK) await repo.insert(rows.slice(i, i + CHUNK))\n }\n\n /** live ์ ๋ ๋ฐฐ์น ๊ธฐ๋ก โ ๋ชจ์๋ CanonicalEnvelope ๋ค์ startRevision+1.. ์ ๋ถ์ฌํด ๋ฒํฌ ์ ์ฅ(coalescer tick ๋น 1ํ). */\n static async persistBatch(domainId: string, instanceId: string, envelopes: any[], startRevision: number): Promise<void> {\n const repo = getRepository(TwinEvent)\n const structureRev = await this.structureRevOf(domainId, instanceId)\n const rows = envelopes.map((e, i) => this.journalRow(repo, domainId, instanceId, e, startRevision + i + 1, structureRev))\n await this.insertRows(repo, rows)\n }\n\n /** ๋ ์ง์คํธ๋ฆฌ upsert(๋๋ฉ์ธ+instanceId ์ ๋ํฌ). status ์ธ์๋ก provision(stopped)/start(running) ๊ณต์ฉ. */\n static async register(\n domainId: string,\n instanceId: string,\n kind: string,\n model: TwinModelDef,\n status: 'running' | 'stopped' = 'running',\n restartPolicy?: RestartPolicy,\n origin?: any,\n /*\n * ์ฌ๋์ด ๋ถ๋ฅด๋ ์ด๋ฆ๊ณผ **๋๊ฐ ํ๋** โ ์
๋ฌดํค๋ฅผ ๋๋ ๋ ๋๊ฐ๋ก ์ด๋ฆ์ ํจ๊ป ์ค์ด์ผ ํ๋ค.\n * ์ฌ๋ ์๋ ๊ฒฝ๋ก(๋ถํ
์๋ ํ๋ก๋น์ ๋ยท๋ณต๊ตฌ)๋ `actor` ๋ฅผ ์ฃผ์ง ์๋๋ค โ ์๋ฌด ์ฌ์ฉ์๋ฅผ ์ ์ผ๋ฉด\n * ๊ฐ์ฌ ๊ธฐ๋ก์ด ๊ฑฐ์ง์ด ๋๋ค.\n */\n meta?: { name?: string; description?: string; actor?: { id: string } }\n ): Promise<void> {\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n await repo.save(\n repo.create({\n ...(existing ?? {}),\n domain: { id: domainId } as any,\n instanceId,\n kind,\n model,\n // ์ธ์คํด์คโ๊ณต๊ฐ 1๊ธ ๋งํฌ(space #3) โ model.spaceId/areaId ๋ฅผ ์ปฌ๋ผ์ผ๋ก ์น๊ฒฉ(dual-write). model JSON ๋ ์ ์ง(์ปค๋ยท๋ณต๊ตฌ์ฉ).\n spaceId: (model as any)?.spaceId ?? existing?.spaceId,\n areaId: (model as any)?.areaId ?? existing?.areaId,\n /* ์ฌ๊ธฐ๋ ์ ์ฑ
(ADR-0029 ยง2) โ ๋ช
์๊ฐ ์ฐ์ , ์์ผ๋ฉด ๊ธฐ์กด๊ฐ ๋ณด์กด(์ฌํ๋ก๋น์ ์ด ์ ์ธ์ ์ง์ฐ์ง ์๊ฒ).\n **๋ ๋ค ์์ผ๋ฉด ์ค๋ฅ๋ฅผ ๋ธ๋ค**: ์์ ์๋ ์ฌ๊ธฐ์ ๊ธฐ๋ณธ๊ฐ์ ๊ฐ์ธํ๋๋ฐ, ๊ทธ ๊ธฐ๋ณธ๊ฐ์ด ใ์ ๋ ์ด๊ธฐํใ๋ผ์\n ์ ์ธ์ ๋น ๋จ๋ฆฐ ํ๋ก๋น์ ๋์ด ์กฐ์ฉํ ์ด๋ ฅ์ ์ง์ฐ๋ ํธ์์ ๋ง๋ค์๋ค. ์ ์ธ์ ๋ถ๋ฅด๋ ์ชฝ์ ๋ชซ์ด๋ค. */\n restartPolicy:\n restartPolicy ??\n readRestartPolicy(\n existing?.restartPolicy,\n `register(\"${instanceId}\") did not declare a restart policy and the stored row has none`\n ),\n /* ์ฉ๋๋ ๊ฐ์ธํ๋ค. ๋ฒค์น๋ก ๋ค์ง๋ ๊ฒ์ `setPurpose` ํ๋๋ฟ์ด๋ฏ๋ก ๊ธฐ์กด๊ฐ์ ๋ฐ๋์ ๋ณด์กดํ๋ค\n โ ์ฌ๊ธฐ์ ๋ฎ์ผ๋ฉด ์ฌํ๋ก๋น์ ์ด ๋ฒค์น ์ฌ๋ณธ์ ์ด์ ํธ์์ผ๋ก ๋๋๋ฆฐ๋ค. */\n purpose: existing?.purpose ?? 'operational',\n /* **๋ค์ ์ฝ๋ ๋ฐฉ๋ฒ**์ ๊ฐ์ธํ๋ค. ๋ช
์๊ฐ ์ฐ์ , ์์ผ๋ฉด ๊ธฐ์กด๊ฐ ๋ณด์กด โ ์์ฒ์ ๋ชจ๋ฅด๋ ํธ์ถ์ด\n ํ ๋ฒ ์ง๋๊ฐ๋ฉด์ ์ด๋ฏธ ์๋ ๊ฒ์ ์ง์ ๋ฒ๋ฆฌ๋ฉด, ๊ทธ ํธ์์ ๋ค์ ์ฝ์ ์ ์๋ ํธ์์ด ๋๋ค. */\n origin: origin ?? existing?.origin ?? null,\n /* ์ด๋ฆ์ **๋ฎ์ง ์๊ณ ์ฑ์ด๋ค** โ ์ฌ์ฉ์๊ฐ ๊ณ ์น ์ด๋ฆ์ ์ฌํ๋ก๋น์ ์ด ๋๋๋ฆฌ๋ฉด ์ ๋๋ค. */\n name: existing?.name ?? meta?.name ?? null,\n description: existing?.description ?? meta?.description ?? null,\n /* ๋ง๋ ์ฌ๋์ ์ฒ์ ํ ๋ฒ๋ง. ๊ณ ์น ์ฌ๋์ ์ฌ๋์ด ํ ๊ฒฝ์ฐ์๋ง ๊ฐฑ์ ํ๋ค. */\n ...(existing ? {} : meta?.actor ? { creator: { id: meta.actor.id } as any } : {}),\n ...(meta?.actor ? { updater: { id: meta.actor.id } as any } : {}),\n status\n })\n )\n }\n\n /**\n * ๋ผ์ด๋ธ ๊ตฌ์กฐ ๋ณ์ด(resource.add ๋ฑ)๋ฅผ ์ ์ฅ๋ model ์ ๋ฐ์ โ ๋ฐํ์ ์ปค๋์ ๋ฌด๋ฒ๋ฅผ registry model.equipment ์ ๋๊ธฐ.\n * ์ด๊ฒ ์์ผ๋ฉด ๋ฐํ์์ ์ถ๊ฐ๋ผ๋(์ํยท์ ๋์ ๋ฐ์) ์ ์ฅ model ๋ ์๋ณธ์ด๋ผ ํ๋ก๋น์ ๋ ํธ์ง๊ธฐยท์ฌ๊ธฐ๋(loadTwinModel)์ด\n * ์ถ๊ฐ๋ถ์ ์๋๋ค. ๊ธฐ์กด model.equipment ํญ๋ชฉ์ ๋ณด์กด(homeLocation ์ ์ง)ํ๊ณ ์ id ๋ง append(์ถ๊ฐ ์์ location=homeLocation).\n * ์ขํ(layout)๋ง ๋ค๋ฃจ๋ register ์ ๋ฌ๋ฆฌ equipment ์งํฉ์ ๊ฐฑ์ ํ๋, ์ฌํ๋ก๋น์ (purge)์ด ์๋๋ผ in-place ๊ฐฑ์ ์ด๋ผ\n * ์ ๋์ ๋ณด์กด๋๋ค(์ถ๊ฐ๋ ์ด๋ฏธ equipment ๋ธํ๋ก ์ ๋๋จ โ replay ๋ id-keyed upsert ๋ผ ์ด์ค๊ณ์ฐ ์์).\n */\n static async syncBoardEquipment(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[runtimeKey(domainId, instanceId)]\n const snap = inst?.kernel?.getSnapshot?.()\n if (!snap?.equipment) return\n const repo = getRepository(TwinInstance)\n const reg = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.model) return\n const model = reg.model as TwinModelDef\n const known = new Set((model.equipment ?? []).map(m => m.id))\n const added = snap.equipment\n .filter((m: any) => !known.has(m.id))\n .map((m: any) => ({ id: m.id, kind: m.kind, homeLocation: m.location }))\n if (!added.length) return\n model.equipment = [...(model.equipment ?? []), ...added]\n reg.model = model\n await repo.save(reg)\n }\n\n /**\n * ํ๋ก๋น์ ๋ โ ๋ ์ง์คํธ๋ฆฌ์ ๊ตฌ์กฐ(model)๋ฅผ ๋ฑ๋ก๋ง ํ๊ณ ๊ธฐ๋ํ์ง ์์(status='stopped').\n * ์ฌํ๋ก๋น์ ์ ๊ตฌ์กฐ ์๊ทธ๋์ฒ๊ฐ ๋ฐ๋๋ฉด(๋
ธ๋ยท๋ฌด๋ฒ ์งํฉ/์์ฑ ๋ณ๊ฒฝ) ๊ธฐ์กด ์ ๋์ purge ํ๋ค(ADR-0015):\n * model ๋ replay ์ ๋ง์คํฐ๋ผ ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ฉด ๊ณผ๊ฑฐ ์ด๋ฒคํธ์ ์ ์ ๊ฐ ๊นจ์ง๋ค. ์ขํ(layout)๋ง ๋ฐ๋๋ฉด ์ ๋ ๋ณด์กด.\n */\n /**\n * ์คํ ์ค์ด๋ฉด ๊ตฌ์กฐ๋ฅผ ๊ต์ฒดํ์ง ์๋๋ค โ **ํ์ ๋ฌธ์ฅ์ ํ ๊ณณ์ ๋๋ค.**\n *\n * ์ธ์ ์คํธ๋ ์ ๋ ๊ต์ฒด๋ผ, ์ด๋ฒคํธ๋ฅผ ์ ๊ณ ์๋ ์ปค๋ ๋ฐ์์ ๋ฐ๋ฅ์ ๋ฐ๊พธ๋ ์
์ด ๋๋ค. ์ง๊ธ์ ๊ฑฐ์ ์ด\n * ์ ์ผํ ๋ต์ด์ง๋ง ์ต์ข
ํ์ ์๋๋ค(`adoptStructure` ๋ฐฐ์ ). ๋ ๊ณณ์์ ๊ฐ์ ๋ฌธ์ฅ์ผ๋ก ๊ฑฐ์ ํด์ผ\n * ๋์ค์ ์ด ๊ท์น์ ๊ฑท์ด๋ผ ๋ ๊ฑท์ด๋ผ ๊ฒ์ด ํ๋๋ก ๋ณด์ธ๋ค.\n */\n private static assertNotRunning(domainId: string, instanceId: string): void {\n if (!this.instances[runtimeKey(domainId, instanceId)]) return\n /*\n * **๊ฑฐ์ ๋ ๋ฒ์ญ๋ผ์ผ ํ๋ค.** ์ด ๋ฌธ์ฅ์ ์ ๋ฌ๋์ด ๋ฆฌ์กธ๋ฒ์ `catch` ๋ฅผ ์ง๋ ํ๋ฉด ํ ์คํธ์ ๊ทธ๋๋ก\n * ๋ด๋ค โ ๋ค์ฏ ์ธ์ด ์ ํ์์ ์์ด ํ ์ค์ด ์ฌ์ฉ์์๊ฒ ๋ณด์๋ค(2026-08-14 ์ค์ธก).\n *\n * ๊ทธ๋์ ์ฝ๋์ ํ๋ผ๋ฏธํฐ๋ฅผ ์์ธ์ ์ค์ด ๋ณด๋ธ๋ค(`ImportSpaceRefusal` ๊ณผ ๊ฐ์ ๊ท์ฝ: ์์ด ๋ฌธ์ฅ์\n * canonical ์ด๊ณ ๋ก๊ทธยทํด๋ฐฑ์ผ๋ก๋ง ์ฐ์ธ๋ค). ์ด์ ๊ฐ ์ฝ๋๋ก ์ค๋ฉด ํ๋ฉด์ด ์ฎ๊ธธ ์ ์๋ค.\n */\n const err: any = new Error(`instance \"${instanceId}\" is running โ stop before re-provisioning`)\n err.code = 'twin-running'\n err.params = { instanceId }\n throw err\n }\n\n /**\n * ๋๋ฉด์ ๊ณต์ฅ์ ์ ํํ๋ค โ **๋ฏธ๋ฌ ์ ์ฉ.**\n *\n * ๋ฏธ๋ฌ๊ฐ ๋น์ถ๋ ํ์ค์ ์ ๋ฉ์ถ๋ค. ์ค๋น ํ ๋๊ฐ ๋์๋ค๊ณ ํธ์์ ๋ฉ์ท๋ค ์ธ์ฐ๋ฉด ๊ทธ ์ฌ์ด์ ์ฌ์ค์\n * ์๊ณ , ๋ผ์ด๋ธ์์ ์ ์ค์ ๊ณง ๊ฑฐ์ง์ด๋ค. ๊ทธ๋์ ๋ฏธ๋ฌ๋ **๋์ ์ค์** ์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋๋ค.\n *\n * ์๋ฎฌ๋ ์ด์
์ ์ฌ๊ธฐ ์ค์ง ์๋๋ค. ์กฐ๊ฑด์ด ๋ฐ๋ ์คํ์ ๋ค๋ฅธ ์คํ์ด๋ฏ๋ก ๋ฉ์ถ๊ณ ๋ค์ ์ธ์ฐ๋ ๊ฒ์ด\n * ์ณ๋ค โ ์ปค๋์ด ๊ทธ๋ ๊ฒ ๊ฑฐ์ ํ๋ค(`FlowEngine.adoptStructure`).\n *\n * ์ธ ๊ฐ์ง๊ฐ **ํจ๊ป** ์ผ์ด๋์ผ ํ๋ค. ํ๋๋ผ๋ ๋น ์ง๋ฉด ์ธต์ด ์ด๊ธ๋๋ค:\n * โ ๋ฆฌ๋น์ โ ์ด ์์ ์ดํ์ ์ด๋ฒคํธ๊ฐ ์ ๋ฒํธ๋ฅผ ๋ฌ๊ณ ๋ค๋๋ค(์ฌ์์ด ๋ง๋๋ฅผ ๋๋ ์ ์๊ฒ)\n * โก ์ ์ฅ modelยท๊ตฌ์กฐ ํ โ ์กฐํ๊ฐ ์ ๊ตฌ์กฐ๋ฅผ ๋ณธ๋ค\n * โข ์ปค๋ โ ์ง๊ธ ์ ํ๋ ์ด๋ฒคํธ๊ฐ ์ ๊ตฌ์กฐ ์์์ ์ ํ๋ค\n */\n static async adoptStructure(\n domainId: string,\n instanceId: string,\n model: TwinModelDef,\n comment?: string,\n origin?: any\n ): Promise<{ rev: number } & StructureShift> {\n const inst = this.instances[runtimeKey(domainId, instanceId)]\n if (!inst) throw new Error(`instance \"${instanceId}\" is not running โ provision it instead of adopting`)\n if (inst.mode !== 'live')\n throw new Error(`instance \"${instanceId}\" is a simulation โ stop it and re-provision (a changed experiment is a different experiment)`)\n\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg) throw new Error(`instance \"${instanceId}\" is running but not registered โ refusing to adopt into an unknown twin`)\n\n const rev = await this.recordStructure(domainId, instanceId, model, comment)\n await this.register(domainId, instanceId, reg.kind, model, 'running', undefined, origin)\n /* ์ปค๋์ **๋ง์ง๋ง์** ์ ํํ๋ค โ ์ ์ฅ์ด ์คํจํ๋ฉด ๋ฉ๋ชจ๋ฆฌ๋ง ์ ๊ตฌ์กฐ๊ฐ ๋์ด, ์ฌ๊ธฐ๋ํ๋ฉด ์กฐ์ฉํ\n ์ ๊ตฌ์กฐ๋ก ๋์๊ฐ๋ค(๊ณ ์น๊ธฐ ์ด๋ ค์ด ์ด๊ธ๋จ์ด๋ค). */\n const shift: StructureShift = inst.kernel.adoptStructure(model)\n /*\n * **๊ณต์ ๋ช
์ธยทํ์ฅ์ด ์ ํ ์๊ฐ๋ ํจ๊ป ์ฃ๋๋ค** โ ์ปค๋์ ๊ตฌ์กฐ ์ ํ์ ์๋ฆฌยท์ค๋น๋ฅผ ๊ฐ์ง๋ง, ๊ณต์ ์๊ฐ์\n * ํธ์คํธ๊ฐ ์ค์ด ์ฃผ๋ ๊ฒ์ด๋ฏ๋ก(`model.localDurations`) ์ฌ๊ธฐ์ ๋ค์ ๋ถ๋ฅด์ง ์์ผ๋ฉด ๋๊ณ ์๋ ๋ฏธ๋ฌ๋\n * ์ฌ๊ธฐ๋ํ ๋๊น์ง ์ ์๊ฐ์ผ๋ก ๋๋ค(ํ๋ฉด์ ใ๋ฃ์์ต๋๋คใ๋ผ๊ณ ๋งํ ๊ฐ์ด๋ค).\n */\n this.applyOperations(inst.kernel, model, instanceId)\n\n /*\n * **ํฌ์ ํ๋ ์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฅธ๋ค** (2026-08-18 ์ค์ธก์ผ๋ก ๋ถ์).\n *\n * ํ(`twin_locations`ยท`twin_equipment`)์ ๊ตฌ์กฐ์ ์บ์๋ค. ๊ทธ๋ฐ๋ฐ ์ด ๊ฒฝ๋ก๋ ์ปค๋๋ง ๊ฐ๊ณ ํ์ ๊ทธ๋๋ก\n * ๋์๋ค โ ๋๊ณ ์๋ ๋ฏธ๋ฌ์ ๊ฐ์ ์ ์ธํ๋ฉด ์ปค๋์ ์ ๊ฐ์ผ๋ก ๊ณ์ฐํ๋๋ฐ **ํญ๋ชฉ ํจ๋์ ์ ํ์ ๋ณด์ฌ\n * ์ค๋ค**(๋ฃ์ ๊ฐ์ด ํ๋ฉด์์ ๋ณด์ด์ง ์๋๋ค). ๊ตฌ์กฐ๊ฐ ๋ฐ๋ ์๊ฐ์ด ๊ณง ์บ์๋ฅผ ๋ค์ ๊ทธ๋ฆด ์๊ฐ์ด๋ค.\n *\n * ์คํจ๋ ํก์ํ๋ค: ํฌ์์ด ๋งํ๋(์: ๋ชจ๋ธ์ ์ค๋ณต id) ์ปค๋์ ์ด๋ฏธ ์ ๊ตฌ์กฐ๋ก ๋๊ณ ์์ผ๋ฏ๋ก ๊ทธ ์ฌ์ค์\n * ๋๋๋ฆฌ์ง ์๋๋ค โ ๋ค๋ง ์กฐ์ฉํ ๋๊ธฐ์ง ์๊ณ ๋งํ๋ค.\n */\n await projectStructure(domainId, instanceId, model, instanceId).catch((err: any) =>\n twinWarn(`[twin-engine] \"${instanceId}\" adopted a new structure but its projected rows were not refreshed โ ${err?.message ?? err}`)\n )\n\n /*\n * **๊ตฌ์กฐ๊ฐ ๋ฐ๋ ์๊ฐ์ด ์ํ๊ฐ ๋ฐ๋ ์๊ฐ์ด๋ค** โ ๊ทธ๋ฌ๋ ๋ธ๋ก๋์บ์คํ
ํ๋ค.\n *\n * โโ ๋ฌด์์ด ๋ฌ๋ (2026-08-18) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๊ตฌ์กฐ ์ ํ์ ์ปค๋๋ง ๊ฐ๊ณ ์กฐ์ฉํ ๋๋ฌ๋ค. ๊ทธ๋ฐ๋ฐ ํ๋ฉด์ด ๋ณด๋ ๊ฒ ์๋น์๊ฐ ๊ตฌ์กฐ์์ ํ์๋๋ค โ\n * ๊ณ์ฝ ๋๋น ํ์ , ์ฃผ๋ชฉ ์ ํธ, ์๋ฆฌ ์. ํ์ฅ์ด ๊ณ์ฝ์ ๊ณ ์ณ ์ ์ธํ ์๊ฐ ์กฐ๊ฑด์ด ์ฑ๋ฆฝํ๋๋ฐ๋, ์ํ\n * ๋ธ๋ก๋์บ์คํ
์ด ์์ด์ ์ง๋ ๋ ์ผ์ **๋ค์ ๊ณ์ธก ํ๋ณธ์ด ์ฌ ๋๊น์ง** ์ ํ๋ฉด์ ๋ค๊ณ ์์๋ค(๊ทธ ์ฌ์ด ํค๋\n * ๋ฐฐ์ง๋ 4์ด ํด๋ง์ผ๋ก ๋จผ์ ์์, ใ๋ฐฐ์ง์ ์๊ณ ๋ชฉ๋ก์ ์๋ใ ์ด๊ธ๋ ํ๋ฉด์ด ์ค์ ๋ก ๋ณด์๋ค).\n *\n * ์ ๋ธ๋ก๋์บ์คํ
๊ฒฝ๋ก๋ฅผ ๋ง๋ค์ง ์๋๋ค: dirty ๋ฅผ ์ธ์ **์ด๋ฏธ ์๋ ๋ณํฉ ๊ท์จ**(200ms)์ ์น๋๋ค. ๊ตฌ์กฐ ์ ํ์\n * ๋๋ฌผ์ง๋ง, ์ฌ๋ฌ ํธ์์ ์๋ฌ์ ๋ค์ด์ฌ ์ ์๊ณ (ํ์ฅ ์ผ๊ด ์ ์ธ) ๊ทธ๋๋ ๋ธ๋ก๋์บ์คํ
๋ฅ ์ํ์ ์ง์ผ์ผ ํ๋ค.\n */\n inst.dirty = true\n /* ๊ตฌ์กฐ๊ฐ ๊ฐ๋ ธ์ผ๋ฉด ๋ฌด์์ด ๋ฌ๋ผ์ก๋์ง ์ฌ๊ฑด์ผ๋ก ๋งํ ์ ์๋ค โ ์ ๋ถ ๋ค์ ๋ง๋ ๋ค. */\n this.markItemsDirty(inst)\n this.ensureBroadcastCoalescer()\n\n return { rev, ...shift }\n }\n\n static async provision(\n domainId: string,\n instanceId: string,\n kind: string,\n model: TwinModelDef,\n /**\n * **์ฌ๊ธฐ๋ ์ ์ฑ
์ ์์ฑ ์์ ์ ์ ์ธ์ด๋ค**(ADR-0029 ยง2) โ ํธ์์ ์ ์ฑ
์์ด ์กด์ฌํ ์ ์๋ค.\n *\n * ์์ ์๋ ์ด ์๋ฆฌ๊ฐ ์์๊ณ `register` ๊ฐ ๊ธฐ๋ณธ๊ฐ(`sim-experiment` = ์ ๋ ์ด๊ธฐํ)์ ๊ฐ์ธํ๋ค. ๊ทธ๋์\n * ์ ์ธ์ ๋น ๋จ๋ฆฐ ํ๋ก๋น์ ๋์ด **์ฌ๊ธฐ๋๋ง๋ค ์ด๋ ฅ์ ์ง์ฐ๋ ํธ์**์ ์กฐ์ฉํ ๋ง๋ค์๋ค. ์ด์ ๋ง๋๋ ์ชฝ์ด\n * ๋งํด์ผ ํ๋ค: ์ด ํธ์์ด ์๊ธฐ ๊ณผ๊ฑฐ๋ฅผ ์ด๋ป๊ฒ ๋ํ๋์ง๋ ๋ง๋๋ ์ฌ๋์ด ์๋ ์ฌ์ค์ด๋ค.\n */\n restartPolicy: RestartPolicy,\n comment?: string,\n origin?: any,\n /** ์ด๋ฆยท์ ์ โ ์
๋ฌดํค๋ฅผ ๋๋ ๋ ๋๊ฐ๋ก ์ด๋ฆ์ ํจ๊ป ๋จ๊ธด๋ค(`register` ์ `meta` ๊ทธ๋๋ก). */\n meta?: { name?: string; description?: string; actor?: { id: string } }\n ): Promise<void> {\n this.assertNotRunning(domainId, instanceId)\n /* ์ข
๋ฅ๋ฅผ **์ ์ฅํ๊ธฐ ์ ์** ๊ฒ์ฆํ๋ค. ๋์ค์ ๊ธฐ๋ํ ๋ ๊ฑธ๋ฆฌ๋ฉด ์์ธ์ด ํ๋ก๋น์ ๋์์ ๋ฉ์ด์ง๊ณ ,\n ๊ทธ ์ฌ์ด ๋ ์ง์คํธ๋ฆฌ์๋ ๋๋ฆด ์ ์๋ ํธ์์ด ์์ ์๋ค. */\n kernelFor(kind)\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n\n /*\n * **๊ตฌ์กฐ๊ฐ ๋ฐ๋์ด๋ ์ญ์ฌ๋ฅผ ์ง์ฐ์ง ์๋๋ค.**\n *\n * ์์ ์๋ ์๋ช
์ด ๋ค๋ฅด๋ฉด ๊ทธ ํธ์์ ์ ๋์ ํต์งธ๋ก ์ง์ ๋ค. ์ ์ง์ฐ๋ฉด ์ ์ด๋ฒคํธ๋ฅผ ์ ๊ณต์ฅ์ ๋๊ณ \n * ์ ๊ฒ ๋์ด ์ด๋ ฅ์ด ๊ฑฐ์ง๋ง์ ํ๊ธฐ ๋๋ฌธ์ด๋ค โ ๋ถ์ค๊ฐ ๋์ด๋ ์์ ์ ์ฌ์ค์ ์ฌ์ฏ ๊ฐ์ง๋ฆฌ ๊ณต์ฅ์\n * ์ ์ผ๋ฉด ๊ทธ๋ ์๋ ๋ถ์ค์์ ์ผ์ด ์์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค. ์ ํ์ง๊ฐ **์ญ์ฌ๋ฅผ ์๊ฑฐ๋ ๊ฑฐ์ง๋ง์\n * ํ๊ฑฐ๋** ๋๋ฟ์ด์๊ณ , ๊ทธ๋์ ๊ณต์ฅ์ ๊ณ ์น ๋๋ง๋ค ์ด๋ ฅ์ ๋ฒ๋ ค์ผ ํ๋ค.\n *\n * ์ด์ ์
์งธ ๊ธธ๋ก ๊ฐ๋ค: ๋ฐ๋ ๊ตฌ์กฐ๋ฅผ **์ ๋ฆฌ๋น์ **์ผ๋ก ๋จ๊ธฐ๊ณ , ์์ผ๋ก ์ฐ์ด๋ ์ด๋ฒคํธ๊ฐ ๊ทธ ๋ฒํธ๋ฅผ\n * ๋ฌ๊ณ ๋ค๋๋ค. ์ฌ์์ ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ ์ง์ ์์ ์ ํํ ๋ค ์ด์ด ์ ๋๋ค(`replaySegments`).\n */\n await this.recordStructure(domainId, instanceId, model, comment)\n await this.register(domainId, instanceId, kind, model, existing?.status === 'running' ? 'stopped' : (existing?.status as any) ?? 'stopped', restartPolicy, origin, meta)\n }\n\n /**\n * ์ด ๊ตฌ์กฐ๋ฅผ ๋ฆฌ๋น์ ์ผ๋ก ๋จ๊ธฐ๊ณ ๊ทธ ๋ฒํธ๋ฅผ ๋๋ ค์ค๋ค โ **๋ฐ๋์์ ๋๋ง** ์ ๋ฒํธ๊ฐ ์๊ธด๋ค.\n *\n * ํ๋ก๋น์ ๋์ ๋ถํ
๋ง๋ค ๋ค์ ๋๋๋ฐ, ๊ทธ๋๋ง๋ค ๋ฆฌ๋น์ ์ด ๋๋ฉด ์ด๋ ฅ์ด ๋ป ์๋ ๋ง๋๋ก ์๊ฒ ์ชผ๊ฐ์ง๋ค.\n * ๊ทธ๋์ **๊ตฌ์กฐ ์๋ช
์ด ๊ฐ์ผ๋ฉด ์๋ ๋ฆฌ๋น์ ์ ๊ทธ๋๋ก ์ด๋ค.**\n */\n static async recordStructure(domainId: string, instanceId: string, model: TwinModelDef, comment?: string): Promise<number> {\n const repo = getRepository(TwinStructure)\n const signature = this.structureFingerprint(model)\n const latest = await repo.findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n\n /*\n * **์ ์ฅ๋ ์ง๋ฌธ์ด ์๋๋ผ ์ ์ฅ๋ ๊ณต์ฅ๊ณผ ๋น๊ตํ๋ค.**\n *\n * ์ง๋ฌธ ๊ณ์ฐ ๋ฐฉ์์ ํ ๋ฒ์ด๋ผ๋ ๋ฐ๊พธ๋ฉด(์๋ฌธ โ ํด์๋ก ๋ฐ๊ฟจ๋ค) ์ ์ฅ๋ ๋ฌธ์์ด์ ์ ๋ถ ์ ๋ฐฉ์์\n * ๊ฒ์ด๋ผ ๋ฌด์๊ณผ๋ ์ ๋ง๋๋ค. ๊ทธ๋ฌ๋ฉด **์๋ฌด๊ฒ๋ ์ ๋ฐ๋ ํธ์๋ค์ด ์ ๋ถ \"๊ตฌ์กฐ๊ฐ ๋ฐ๋์๋ค\"** ๋ก\n * ๊ธฐ๋ก๋๋ค โ ์ค์ ๋ก ๊ทธ๋ ๊ฒ ๋๊ณ , ์ฌ๊ธฐ๋ ํ ๋ฒ์ ๋ฆฌ๋น์ ์ด ํต์งธ๋ก ํ๋์ฉ ๋์๋ค.\n *\n * ๊ทธ๋์ ์ ๋ง์ ๋ ํ ๋ฒ ๋ ๋ฌป๋๋ค: ์ ์ฅ๋ **๋ชจ๋ธ**๋ก ์ง๋ฌธ์ ๋ค์ ๊ณ์ฐํ๋ฉด ๊ฐ์๊ฐ? ๊ฐ๋ค๋ฉด\n * ๊ณต์ฅ์ ๊ทธ๋๋ก์ด๊ณ ์ง๋ฌธ ํ๊ธฐ๋ง ๋ก์ ๊ฒ์ด๋, ๋ฆฌ๋น์ ์ ๋ง๋ค์ง ์๊ณ ํ๊ธฐ๋ง ๊ณ ์น๋ค.\n */\n if (latest && latest.signature !== signature && this.structureFingerprint(latest.model as TwinModelDef) === signature) {\n latest.signature = signature\n await repo.save(latest)\n }\n\n if (latest?.signature === signature) {\n this.structureRevCache[runtimeKey(domainId, instanceId)] = latest.rev\n return latest.rev\n }\n\n const rev = (latest?.rev ?? 0) + 1\n await repo.save(repo.create({ domain: { id: domainId } as any, instanceId, rev, signature, model: model as any, ...(comment ? { comment } : {}) }))\n this.structureRevCache[runtimeKey(domainId, instanceId)] = rev\n /* ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ฉด ์ฌ๊ตฌ์ฑ ์บ์๋ ์ ๊ณต์ฅ์ ๊ฒ์ด๋ค โ ๋ฒ๋ฆฐ๋ค(์ง์ฐ๋ ๊ฑด ์บ์๋ฟ, ์ฌ์ค์ ๋จ๋๋ค). */\n delete this.recovered[runtimeKey(domainId, instanceId)]\n if (latest) console.info(`[twin-engine] \"${instanceId}\" structure changed โ revision ${rev} (history kept; older events stay under revision ${latest.rev}).`)\n return rev\n }\n\n /**\n * ์ด ํธ์์ด ๊ฑฐ์ณ ์จ ๊ตฌ์กฐ๋ค โ **๋ฌด์์ด ์ธ์ ๋ฌ๋ผ์ก๋.**\n *\n * ๋ฆฌ๋น์ ์ ๊ทธ ์์ ๊ณต์ฅ์ ํต์งธ๋ก ๋ด์ง๋ง(์ฌ์์ ํ์ํ๋ค), ์ฌ๋์ด ๋ณด๊ณ ์ถ์ ๊ฒ์ ํต์งธ๊ฐ ์๋๋ผ\n * ์ฐจ์ด๋ค. ๋ชจ๋ธ์ ๋นผ๊ณ **์ฐจ์ด ์์ฝ๋ง** ๋ด๋ณด๋ธ๋ค โ 62KB ์ง๋ฆฌ ๋ณด๋๋ฅผ ํ๋ฉด์ ์ค์ด ๋ณด๋ผ ์ด์ ๊ฐ ์๋ค.\n */\n static async structureHistory(\n domainId: string,\n instanceId: string\n ): Promise<{ rev: number; createdAt?: Date; comment?: string; events: number; diff: StructureDiff }[]> {\n const revs = await getRepository(TwinStructure).find({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'ASC' } })\n if (!revs.length) return []\n\n /* ๋ฆฌ๋น์ ๋ง๋ค ๊ทธ ์๋์์ ๋ช ๊ฑด์ด ์ผ์ด๋ฌ๋ โ ์ด๋ ฅ์ ๋ฌด๊ฒ๋ฅผ ๋ณด์ฌ์ค๋ค(์งง๊ฒ ์ค์ณ๊ฐ ๊ตฌ์กฐ์ธ์ง). */\n const counts = new Map<number | null, number>()\n for (const row of await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('e.structureRev', 'rev')\n .addSelect('COUNT(1)', 'n')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .groupBy('e.structureRev')\n .getRawMany())\n counts.set(row.rev === null || row.rev === undefined ? null : Number(row.rev), Number(row.n))\n\n /* ๋ฒํธ ์๋ ์ ํ์ **๊ฐ์ฅ ์ค๋๋ ๋ฆฌ๋น์ **์ ๋ชซ์ด๋ค โ ์ฌ์์ด ๊ทธ๋ ๊ฒ ์ ์ผ๋ฏ๋ก ์ธ๋ ๊ฒ๋ ๊ฐ์์ผ ํ๋ค. */\n const oldest = revs[0].rev\n const legacy = counts.get(null) ?? 0\n\n return revs.map((r, i) => ({\n rev: r.rev,\n createdAt: r.createdAt,\n ...(r.comment ? { comment: r.comment } : {}),\n events: (counts.get(r.rev) ?? 0) + (r.rev === oldest ? legacy : 0),\n diff: diffStructures(i === 0 ? undefined : (revs[i - 1].model as any), r.model as any)\n }))\n }\n\n /** ์ง๊ธ ์ฐ์ด๋ ๊ตฌ์กฐ ๋ฆฌ๋น์ โ ์ด๋ฒคํธ์ ์ฐ์ ๋ฒํธ. ์์ง ์์ผ๋ฉด ๊ธฐ๋กํ๋ฉฐ ๋ง๋ ๋ค. */\n static async currentStructureRev(domainId: string, instanceId: string, model?: TwinModelDef): Promise<number | undefined> {\n const latest = await getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n if (latest) return latest.rev\n return model ? this.recordStructure(domainId, instanceId, model) : undefined\n }\n\n /** ๊ตฌ์กฐ ๋์ผ์ฑ ์ง๋ฌธ โ ์ขํ(layout) ๋ฑ ๋ทฐ ๊ด์ฌ์ฌ๋ ์ ์ธํ๊ณ ์ปค๋์ด ๋ณด๋ ์์ยท์ฉ๋ยท๋ฌด๋ฒ๋ง. */\n /**\n * ์ง๋ฌธ์ **64์๋ก ์ค์ธ๋ค** โ ์ปฌ๋ผ์ด varchar(64) ๋ค.\n *\n * ์๋ฌธ ์ง๋ฌธ์ ์๋ฆฌยท์ค๋น๋ฅผ ์ ๋ถ ์ด์ด ๋ถ์ธ ๋ฌธ์์ด์ด๋ผ ํฐ ๊ณต์ฅ์์๋ ์๋ง ์๊ฐ ๋๋ค. sqlite ๋\n * ๊ธธ์ด๋ฅผ ๊ฐ์ ํ์ง ์์ ๊ทธ๋ฅ ๋ค์ด๊ฐ์ง๋ง **Postgres ๋ ๊ฑฐ๊ธฐ์ ํฐ์ง๋ค** โ ๊ฐ๋ฐ์์๋ ๋ฉ์ฉกํ๊ณ \n * ์ด์์์๋ง ์ฃฝ๋ ์ข
๋ฅ์ ์คํจ๋ค. ๋น๊ต์๋ง ์ฐ๋ ๊ฐ์ด๋ฏ๋ก ํด์๋ก ์ถฉ๋ถํ๋ค.\n */\n private static structureFingerprint(model: TwinModelDef): string {\n return createHash('sha256').update(this.structureSignature(model)).digest('hex')\n }\n\n private static structureSignature(model: TwinModelDef): string {\n const locations = [...(model.locations ?? [])]\n .map(n => `${n.id}:${n.type}:${n.capacity}`)\n .sort()\n .join('|')\n const equipment = [...(model.equipment ?? [])]\n .map(m => `${m.id}:${m.kind}:${m.homeLocation}`)\n .sort()\n .join('|')\n return `N[${locations}]M[${equipment}]`\n }\n\n /** ๋ ์ง์คํธ๋ฆฌ model ๋ก ๊ธฐ๋(ํ๋ก๋น์ ๋ ์ธ์คํด์ค start). model ์ธ์ ์์ด ์ ์ฅ๋ ๊ตฌ์กฐ๋ก ์ฌ๊ธฐ๋. */\n static async startFromRegistry(domainId: string, instanceId: string, restartPolicy?: RestartPolicy): Promise<InstanceRuntime> {\n const key = runtimeKey(domainId, instanceId)\n if (this.instances[key]) return this.instances[key]\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.model) throw new Error(`instance \"${instanceId}\" not provisioned (no model)`)\n\n /*\n * โโ ์ ์ธ๋ `restartPolicy` ๊ฐ **๊ธฐ๋ ๋ฐฉ์์ ์ ํ๋ค** (2026-08-20) โโโโโโโโโโ\n *\n * ์์ ์๋ ์ด ํจ์๊ฐ ์ ์ฑ
์ **์ฝ์ด์ ๋๊ธฐ๊ธฐ๋ง** ํ๊ณ , ๊ธฐ๋์ ์ธ์ ๋ ์๋ฎฌ ๊ฒฝ๋ก์๋ค. ๊ทธ๋์ ๋ฏธ๋ฌ๋ก\n * ์ ์ธํ ํธ์์ ํ๋ฉด์์ ์์ํ๋ฉด **์๋ฎฌ๋ก ๋ด๋ค** โ ๊ทธ ํธ์์ ์ ์
์ ๋ฐ์ง ๋ชปํ๋ค(`ingestLive` ๋\n * ๋ผ์ด๋ธ๊ฐ ์๋๋ฉด 0 ์ ๋๋ ค์ค๋ค). ์ค๋ฅ๋ ๋์ง ์๊ณ , ํ๋ฉด์๋ ใrunningใ์ด๋ผ ์ ํ๋ค.\n *\n * ๋ถํ
๊ฒฝ๋ก(`resumeRow`)์๋ ๊ทธ ๊ฐ๋ฆผ์ด ์์๋๋ฐ ์ฌ๊ธฐ์๋ ์์๋ค. ์ฆ **๋ถํ
์ผ๋ก ์ด์๋ ๋ฏธ๋ฌ๋\n * ๋ฐ๊ณ , ์ฌ๋์ด ์์ํ ๋ฏธ๋ฌ๋ ๋ฐ์ง ๋ชปํ๋ค.** ๊ฐ์ ์ ์ธ์ด ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ด๋ ๊ฒ์ ๊ฒฐํจ์ด๋ค.\n *\n * ๊ฐ๋ฆผ์ ์ฌ๊ธฐ ํ ๊ณณ์ ๋๋ค โ ๋ถํ
๋ ์ด ๋ฌธ์ ์ง๋๋ค.\n *\n * โโ `reset` ์ ์ ์ธ๋๋ก **์ ๋์ ๋น์ด๋ค** (2026-08-20) โโโโโโโโโโโโโโโโโโโ\n * ใseed ์ฌํใ์ ๋ฐฑ์ง์์ ๋ค์ ์์ํ๋ค๋ ๋ป์ด๋ค. ์์ ์๋ ๊ทธ ์ ์ธ์ด ๊ตฌํ๋์ง ์์ `reset` ํธ์์ด\n * ์ฌ์ค์ ์ด์ด์ก๊ณ , ๊ทธ๋์ ใ์ด ํธ์์ ์ด๋ ฅ์ ์ ์ฌ๊ธฐ๋์ ๋๊ฒจ ๋จ์ ์๋ใ๋ฅผ ์๋ฌด๋ ์ค๋ช
ํ ์ ์์๋ค.\n *\n * ์ด๊ฒ์ **์ฌ์ค์ ์ง์ฐ๋ ๋์**์ด๋ผ ์์๋ฅผ ์ง์ผ ์ผฐ๋ค: ๋จผ์ ์ฌ๋์ด ๊ฐ ํธ์์ ์ ์ฑ
์ ๋ค์ ์ ์ธํ ๋ฌธ์\n * ๋ง๋ค๊ณ (`setTwinRestartPolicy`), ์ด๋ ฅ์ ๋๊ณ ๋ณผ ํธ์์ `resume` ์ผ๋ก ์ฎ๊ธด ๋ค์ ์ผ ๋ค. ๊ทธ ์์๋ฅผ\n * ๋ค์ง์ผ๋ฉด ์ ์ธ์ ์งํจ ๋๊ฐ๋ก ๋จ์ ์ด๋ ฅ์ ์ง์ด๋ค.\n */\n const policy = restartPolicy ?? readRestartPolicy(reg.restartPolicy, `twin \"${instanceId}\"`)\n if (policy === 'resync') {\n /* ๋ฏธ๋ฌ๋ **๊ด์ธก ๊ตฌ๋**์ผ๋ก ์ธ์ด๋ค โ ์๋ฎฌ๋ก ์ธ์ฐ๋ฉด ์๋ ์์ง์์ ์ค์ค๋ก ๋ง๋ ๋ค.\n ์๊ฐ ๊ธฐ์ค์ ๊ณต๊ฐ์ด ๊ฐ๋๋ค(๋ถํ
๊ฒฝ๋ก์ ๊ฐ์ ๊ท์น). */\n return this.startLive(instanceId, domainId, reg.kind, await this.withSpaceTimeBase(reg.model as TwinModelDef, domainId))\n }\n if (policy === 'reset') {\n /*\n * ์จ์ ์ฌํ โ ์ ๋์ ๋น์ฐ๊ณ ๋ฆฌ๋น์ 0 ๋ถํฐ ๋ค์ ์ผ๋ค. ๋ณต๊ตฌ๋ณธ๋ ํจ๊ป ๋ฒ๋ฆฐ๋ค(`resetJournal` ์ด ํ๋ค):\n * ๋จ๊ฒจ ๋๋ฉด ๋ฐฑ์ง๋ก ์์ํ ํธ์์ ์ ์ํ๊ฐ ๋์ด์๋ ใ์จ์ ์ฌํใ์ด ์๋๊ฒ ๋๋ค.\n *\n * **๋ฒค์น ์ฌ๋ณธ์ ์์ธ๋ค.** ๊ทธ๊ฒ์ ๋๊ตฐ๊ฐ ์ง์ผ๋ณด๋ ์คํ์ด๊ณ , ๊ทธ ์คํ์ ๊ธฐ๋ก์ ๊ธฐ๋์ด ์ง์ฐ๋ฉด ์คํ์ด\n * ์ฌ๋ผ์ง๋ค(๋ถํ
์ ๋ฒค์น๋ฅผ ๋์ด๋ฆฌ์ง๋ ์๋๋ค โ `resumeRow`).\n */\n if (reg.purpose !== 'bench') await this.resetJournal(domainId, instanceId)\n }\n\n /*\n * ์์คํํธ ์ฌ๋ฃ๋ฅผ **์ฌ๊ธฐ์ ํ์คํ ํ๋ณดํ๋ค.**\n * `start()` ๋ ๋๊ธฐ๋ผ ์ค์ค๋ก ์บ์๋ฅผ ์ฝ์ ์ ์์ด์ `recovered` ์ ๋ฏธ๋ฆฌ ๋ด๊ฒจ ์๊ธฐ๋ฅผ ๊ธฐ๋ํ๋๋ฐ,\n * ๊ทธ๊ฑด `bootstrap()` ์ด ๋จผ์ ๋์์ ๋๋ง ์ฐธ์ด๋ค. ๋ถํ
์์์ ๊ธฐ๋๋ฉด ์ด๋ค ๋ ์ ์ฌ๊ณ ๊ฐ ์ด์๋๊ณ \n * ์ด๋ค ๋ ์ ์กฐ์ฉํ ๋น ์ฑ๋ก ๋ฌ๋ค โ ์ฌํ๋์ง ์๋ ๊ฒฐํจ์ด ๊ฐ์ฅ ๋์๋ค.\n * ์ฒดํฌํฌ์ธํธ ์บ์ ์ฐ์ (O(1) + ๋ผ์ด๋ธ ํ์์ํ ๋ณด์กด), ์์ผ๋ฉด ์ ๋ replay ํด๋ฐฑ(๋ถํ
๊ณผ ๊ฐ์ ์์).\n */\n if (!this.recovered[key] && reg.purpose !== 'bench') {\n const cached = await this.loadSnapshot(domainId, instanceId).catch(() => null)\n if (cached?.state) {\n this.recovered[key] = { revision: cached.revision, state: cached.state }\n } else {\n const state = await this.recover(domainId, instanceId).catch(() => null)\n if (state) this.recovered[key] = { revision: state.revision, state }\n }\n }\n\n /*\n * ์ ๋์ ๋จ์ ์๋ ๋ง์ง๋ง ๋ฒํธ โ **๋ชจ๋์ ๋ฌด๊ดํ๊ฒ** ์ด๊ฒ์ ์ด์ด ์ผ๋ค.\n *\n * ์ ๋์ ์ด๊ธฐํํ๊ณ ๊ธฐ๋ํ๋ ์ ์ฑ
(`reset`)์ด๋ผ๋ฉด ์ด ๊ฐ์ด 0์ด๋ผ ์๋ฌด ์ํฅ์ด ์๋ค. ๊ท์น์\n * ๋ชจ๋๋ณ๋ก ๊ตฌ๋ถํ์ง ์๋ ์ด์ : \"์ ๋์ด ๋น์ด ์์ง ์์ผ๋ฉด ๊ทธ ๋ค๋ถํฐ\" ํ๋๋ฉด ์ด๋ ๋ชจ๋์์๋\n * ๊ฒน์น ์ ์๊ณ , ๋ชจ๋๊ฐ ๋์ด๋ ์ด ์๋ฆฌ๋ฅผ ๋ค์ ์๋ณผ ์ผ์ด ์๋ค.\n */\n const last = await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('MAX(e.revision)', 'max')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .getRawOne()\n\n return this.start(\n instanceId,\n domainId,\n /* ์ปค๋ ์ข
๋ฅยทํ์ค ์ ์ธ์ ๋ ์ง์คํธ๋ฆฌ์ ๋ฐ๋์ ์๋ค(๋ ๋ค NOT NULL). ์์ ์๋ `?? 'wms'` ๋ก\n ๋ฉ์ ๋๋ฐ, ๊ทธ๊ฑด YMS/MES ํธ์์ **์กฐ์ฉํ WMS ๋ก ๋ถํ
**์ํค๋ ๊ธธ์ด์๋ค โ ์ค๋ฅ ์์ด ๋ค๋ฅธ ๊ณต์ฅ์ด ๋ฌ๋ค. */\n reg.kind,\n reg.model as TwinModelDef,\n /* ์ ์ฅ๋ ๊ฐ์ ์์์ **์๊ฒฉํ** ์ฝ์๋ค โ ๋ชจ๋ฅด๋ ๊ฐ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ฉ์ฐ๋ฉด ๊ทธ ํธ์์ด ์กฐ์ฉํ ๋ค๋ฅด๊ฒ ์ฌ๊ธฐ๋ํ๋ค. */\n policy,\n reg.purpose,\n Number(last?.max ?? 0) || 0\n )\n }\n\n /**\n * ์ ์ธ ๊ธฐ๋ฐ ๋ถํ
(ยง0 ํ๋ ์ โ โ ๋ถํ
๊ฑฐ๋ ๋งคํ) โ ํธ์์ด ์ ์ธํ restartPolicy ์ ๋ฐ๋ผ ์ฌ๊ธฐ๋ ๋ฐฉ์์ ๊ตฌ๋ถํ๋ค.\n * ๋ถํ
๊ฒฝ๋ก๋ฅผ ํ ๊ณณ์ ๋ชจ์ \"๋ฐํ์ โ ํ์ค\" ๋ฒ์ฃผ์ค๋ฅ๋ฅผ ์ฝ๋๋ก ๊ฐ์ ํ๋ค.\n * - 'resync' : ํ์ค=์ธ๋ถ ์ค๋ฌผ โ startLive(์ฌ๋๊ธฐ). ์ด๋ฒคํธ๋ ์ด๋ํฐ ingest ๋ก ์ ์
, ์ปค๋ tick ์์.\n * - 'resume' : ์์ฑ ํ์๋ผ์ธ ์ง์ โ ์ ๋ ๋ณด์กด + resume(ํ์ค ์ด์ด๊ฐ).\n * โ GATE(ยง8 โกโข): ์ปค๋ ์ํ ์ง๋ ฌํ/์ฌ๊ฐ๊ฐ ์์ง ์์ด ์ง์ง resume ๋ถ๊ฐ โ ์ค ํ์ยท์ค๋ถํ ์ ๊ตฌํ.\n * ๊ทธ๋๊น์ง๋ ์ ๋์ ๋ณด์กดํ๋ revision ์ถฉ๋์ ํผํ๋ ค fresh ๋ก ๊ธฐ๋ํ๊ณ , ์ ์ธ๊ณผ ๊ตฌํ์ ๊ฐ๊ทน์ ํฌ๊ฒ ๊ฒฝ๊ณ ํ๋ค.\n * - 'reset' : seed ์ฌํ โ resetJournal + fresh ๊ธฐ๋(๋ฐฑ์ง ์์์ด ๋ฒ๊ทธ๊ฐ ์๋๋ผ ์ ์ธ๋ ๊ฑฐ๋).\n * ๋ฐํ: ๊ธฐ๋๋ InstanceRuntime.\n */\n static async bootDeclared(domainId: string, instanceId: string, mode: RestartPolicy): Promise<InstanceRuntime> {\n if (mode === 'resync') {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.model) throw new Error(`instance \"${instanceId}\" not provisioned (no model)`)\n return this.startLive(instanceId, domainId, reg.kind, reg.model as TwinModelDef)\n }\n if (mode === 'resume') {\n /*\n * **์ด์ด์ง๋ ํ์ค** โ ์ ๋์ ์ง์ฐ์ง ์๋๋ค.\n *\n * ์์ ์๋ ์ฌ๊ธฐ์ ์ ๋์ ์ง์ฐ๊ณ fresh ๋ก ๋์ ๋ค. resume ๊ธฐ๊ณ์ฅ์น๊ฐ ์๋ค๊ณ ๋ดค๊ธฐ ๋๋ฌธ์ธ๋ฐ,\n * ์ค์ ๋ก ์๋ ๊ฒ์ **๋ฒํธ ์ด์ด ์ธ๊ธฐ ํ๋**์๋ค: ์ํ ๋ณต์์ ์ด๋ฏธ `startFromRegistry` ๊ฐ\n * ์ ๋ ์ฌ์(๋๋ ์ฒดํฌํฌ์ธํธ)์ผ๋ก ํ๊ณ ์์๊ณ , ๋งํ ๊ฒ์ ์ปค๋์ด ๋ฆฌ๋น์ ์ 0๋ถํฐ ๋ค์ ์ธ์ด\n * ๊ธฐ์กด ํ๊ณผ ๊ฒน์น๋ ๋ฌธ์ ์๋ค. ๊ทธ ํ๋๋ฅผ `resumeRevision` ์ผ๋ก ํ์์ผ๋ฏ๋ก ์ด์ ์ด์ด ๊ฐ๋ค.\n *\n * ์์ง ์ด์ด์ง์ง ์๋ ๊ฒ(์ ์งํ๊ฒ): ์๋๋ฆฌ์ค ์์ฑ๊ธฐ์ ๋์ ํ๋ฆ์ ์ฌ๊ธฐ๋์ ์ด์ด์ง์ง ์๋๋ค โ\n * ๊ฐ์ ์จ์์์ ๋ค์ ์์ํ๋ฏ๋ก ์๊ทน์ ํจํด์ด ์ฌ๊ธฐ๋ ์ง์ ์์ ํ ๋ฒ ๋๊ธด๋ค. ์์ธ ์ฌ์ค๊ณผ\n * ์ํ๋ ์ด์ด์ง๊ณ , ์์ผ๋ก ์ผ์ด๋ ์ผ์ ๋ฌด์์ ์์๋ง ์๋ก ์์ํ๋ค.\n */\n return this.startFromRegistry(domainId, instanceId, 'resume')\n }\n // `reset`: seed ์ฌํ โ ์ ๋ ์ด๊ธฐํ ํ revision 0 ๋ถํฐ ์ฌ์คํ.\n await this.resetJournal(domainId, instanceId)\n return this.startFromRegistry(domainId, instanceId, 'reset')\n }\n\n /**\n * ์ ๋ ์ด๊ธฐํ โ ์ธ์คํด์ค ์ด๋ฒคํธ ์ ๋ purge(๋ ์ง์คํธ๋ฆฌยท์ํ๋ ์ ์ง).\n * ๋ฐ๋ชจ fresh-start ์ฉ: ๋งค ๋ถํ
seed ๋ถํฐ ์๋ก ์คํํ๋ ๋ฐ๋ชจ์์, ๋ณต๊ตฌ๋ณธ ํ๊ธฐ ํ revision 0 ๋ถํฐ ์ฌ์คํํ๋ฉด\n * ์ ๋ฐ๊ณผ revision ์ด ๊ฒน์ณ ์ ๋์ด ์ค์ผ๋๋ค โ start ์ ์ ํธ์ถํด ํ์ฌ ๋ฐ๋ง ๋จ๊ธด๋ค.\n */\n static async resetJournal(domainId: string, instanceId: string): Promise<void> {\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n delete this.recovered[runtimeKey(domainId, instanceId)]\n /*\n * โโ **์ฒดํฌํฌ์ธํธ๋ ํจ๊ป ๋ฌดํจ๋ก ๋ง๋ ๋ค** (2026-08-20) โโโโโโโโโโโโโโโโโโโโโโ\n *\n * ์ ๋๋ง ์ง์ฐ๋ฉด ์จ์ ์ฌํ์ด ๋์ง ์๋๋ค: ์์คํํธ๋ ์ฒดํฌํฌ์ธํธ๋ฅผ **๋จผ์ ** ๋ณด๊ณ , ๊ทธ๊ฒ์ด ๋จ์ ์์ผ๋ฉด\n * ๋ฐฑ์ง๋ก ์์ํ ํธ์์ ์ ์ํ๊ฐ ๋์ด์๋๋ค(์ ๋์ ๋น์๋๋ฐ ์ฌ๊ณ ๊ฐ ์๋ ํธ์์ด ๋๋ค).\n * ์๊ฐ์ฌํ์ด ๋๋ ์ฌ์ฌ ์บ์๋ ๊ฐ์ ์ด์ ๋ก ๋ฌดํจ๋ค โ ์ง์์ง ๋ฆฌ๋น์ ์ ๊ฐ๋ฆฌํค๊ฒ ๋๋ค.\n *\n * ๊ณตํต ์บ์ ์๋น์ค์๋ ์ญ์ ๊ฐ ์๋ค(get/set/clearStale ๋ฟ). ๊ทธ๋์ **ใ์์ใ์ ์ ๋๋ค** โ ๊ฐ์\n * ์ง์ด๋ด๋ ๊ฒ์ด ์๋๋ผ ใ์ฒดํฌํฌ์ธํธ๊ฐ ์๋คใ๋ ์ฌ์ค์ ์ ๋ ๊ฒ์ด๊ณ , ์ฝ๋ ์ชฝ์ ์ด๋ฏธ `cached?.state` ๋ก\n * ๊ทธ๊ฒ์ ๊ฐ๋ ค๋ธ๋ค. ๊ณตํต ๋ชจ๋์ ์ญ์ ๋ฅผ ์๋ก ๋ซ๋ ๊ฒ์ ์ด ํ ์๋ฆฌ๋ฅผ ์ํด ํ๊ธฐ์๋ ํฐ ๋ณ๊ฒฝ์ด๋ค.\n */\n await cacheService\n .setInCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId }, { revision: 0, state: null }, this.SNAPSHOT_TTL_S)\n .catch(err => twinWarn(`[twin-engine] \"${instanceId}\" checkpoint not invalidated โ a seed run may inherit old state:`, err?.message ?? err))\n await cacheService\n .setInCache(this.CHAIN_INDEX_CACHE_ID, { domainId, instanceId }, { revisions: [] }, this.SNAPSHOT_TTL_S)\n .catch(err => twinWarn(`[twin-engine] \"${instanceId}\" chain index not cleared โ time travel may point at deleted revisions:`, err?.message ?? err))\n }\n\n /** ์ญ์ โ ์ ์ง + ๋ ์ง์คํธ๋ฆฌ ์ญ์ + ์ ๋ purge(domain ์ค์ฝํ). */\n static async remove(domainId: string, instanceId: string): Promise<void> {\n await this.stop(domainId, instanceId)\n this.forgetInstance(domainId, instanceId)\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n await getRepository(TwinInstance).delete({ domain: { id: domainId } as any, instanceId })\n }\n\n /**\n * ์ด ํธ์์ ๋ํด **๋ฉ๋ชจ๋ฆฌ์ ๋จ์ ๊ฒ์ ์ ๋ถ ์๋๋ค** โ ์ง์์ ํ ์๋ฆฌ.\n *\n * ์บ์๊ฐ ๋ผ์ดํ์ฌ์ดํด๊ณผ ์ด๊ธ๋ ์์๋ค: ์ ๋ยท๋ฑ๋ก๋ถ๋ ์ง์ฐ๋ฉด์ ์ธ์คํด์ค๋ณ ์บ์๋ ๋จ๊ฒจ, ์ญ์ ๋ ํธ์์\n * ํญ๋ชฉ์ด **์๋ฒ ์ฌ๊ธฐ๋๊น์ง ์ด์ ์์๋ค.** ํญ๋ชฉ ํ๋๊ฐ ํ๋ฃจ์น KPI ๊ทธ๋ฃน์ ๋ฌผ๊ณ ์์ผ๋ฏ๋ก ์์ง ์์ผ๋ฉด\n * ์ง์ด ํธ์์ด ๊ณ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์งํ๋ค. TTL ์ ๊ฐ์ด ๋ก๋ ๊ฒ์ ๋ง์ ๋ฟ **์์ด์ง ์ฃผ์ธ์ ์ง์ฐ์ง ์๋๋ค.**\n *\n * ์์ ๊ฒ์ ์ฌ๊ธฐ ๋ชจ์ ๋๋ ์ด์ : ์บ์๋ฅผ ์๋ก ๋ง๋๋ ์ฌ๋์ด ์ง์ฐ๋ ์๋ฆฌ๋ฅผ ์ฐพ์ ํค๋งค์ง ์๊ฒ ํ๋ค.\n * ์ ์ธ์คํด์ค๋ณ ์บ์๋ฅผ ๋ง๋ค๋ฉด **์ด ํจ์์ ํ ์ค์ ๋ํ๋ค** โ ๊ทธ๋ฌ์ง ์์ผ๋ฉด ๊ฐ์ ๋์๊ฐ ๋ค์ ์๊ธด๋ค.\n */\n private static forgetInstance(domainId: string, instanceId: string): void {\n const key = runtimeKey(domainId, instanceId)\n delete this.recovered[key]\n this.measuredCache.delete(key)\n delete this.structureRevCache[key]\n }\n\n /** ๊ด๋ฆฌ ๋ชฉ๋ก โ domain ์ ๋ฑ๋ก ์ธ์คํด์ค ์ ์ฒด(๋ผ์ด๋ธ ์ฌ๋ถยท์ต์ ์ ๋ revisionยท๋
ธ๋/๋ฌด๋ฒ ์ ํฌํจ). */\n static async list(domainId: string): Promise<any[]> {\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n /*\n * **ํ์ฅ ์ด๋ฆ์ ํจ๊ป ๋ธ๋ค** โ ๋ชฉ๋ก์ด `spaceId` ๋ง ๋ด๋ณด๋ด์ ํ๋ฉด์ด ์ด๋ฆ์ ๋ฐ๋ก ์กฐํํ๊ณ ์์๋ค.\n * ๊ทธ ์กฐํ(`twinSpaces`)๋ ๊ณต๊ฐ๋ง๋ค ์นด์ดํธ ์ฟผ๋ฆฌ๋ฅผ ๋๋ N+1 ์ด๋ผ ๋๋ฆฌ๊ณ , ๊ทธ ์ฌ์ด ํ๋ฉด์ **id ๋ฅผ\n * ์ด๋ฆ์ฒ๋ผ** ๋ณด์ฌ ์ค๋ค(2026-08-13 ๊ด์ธก: ใํ์ฅ crew-probe-siteใ). ํ ๋ฒ์ ์ฝ์ด map ์ผ๋ก ๋ถ์ด๋ฉด\n * ์๋ณต๋ ์ค๊ณ ๊ทธ ๊น๋นก์๋ ์ฌ๋ผ์ง๋ค. ์ด๋ฆ์ด ์์ผ๋ฉด **๋น์ด๋ค** โ id ๋ฅผ ์ด๋ฆ์ผ๋ก ๋ฒ ๋ผ์ง ์๋๋ค.\n */\n const spaceNameOf = new Map(\n (await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name])\n )\n /*\n * **์ต์ ๋ฆฌ๋น์ ์ ํธ์๋ง๋ค ์ธ๋ฑ์ค ๋์์ ํ ํ์ฉ ์ฝ๋๋ค.**\n *\n * โโ ๊ทธ๋ฃน ์ง์๋ก ๋ฐ๊พธ์๋ค๊ฐ ๋๋๋ ธ๋ค (2026-08-22 ์ค์ธก) โโโโโโโโโโโโโโโโโโโโโ\n * ์์ ์ฃผ์์ ์ด๋ฌ๋ค: ใํธ์๋ง๋ค `findOne(order revision DESC)` ์ ๋๊ณ ์์๋ค โ 13๊ฐ๋ฉด ์ง์\n * 13๋ฒ์ด๊ณ , ํธ์์ด ๋๋ฉด ๊ทธ๋๋ก ์๋๋ค. ํ ๋ฒ์ ๊ทธ๋ฃน ์ง์๋ก ๋ฐ๊พผ๋ค.ใ\n *\n * **์ง์ ๊ฐ์๋ฅผ ์ค์์ง๋ง ์ผ์ ์์ ๋๋ ธ๋ค.**\n *\n * findOne ร 13 `(domain, instance, revision)` ์ธ๋ฑ์ค **๋์์ ํ ํ** โ ๊ฐ๊ฐ O(1)\n * GROUP BY ํ ๋ฒ ๊ทธ ๋๋ฉ์ธ์ ์ ๋์ **์ ์ ์ง๊ณ** โ O(์ ์ฒด)\n *\n * ์ ๋์ด ์์ ๋๋ ์ด๋์ด์๊ณ , ์ปค์ง๋ฉด์ ์ํด๊ฐ ๋๋ค. ์ค์ธก(์ ๋ 1,134๋ง ํ): ์ด ๊ทธ๋ฃน ์ง์๊ฐ\n * **44.7์ด**์๋ค. ๊ทธ๋ฆฌ๊ณ sqlite ๋๋ผ์ด๋ฒ๋ ์ฐ๊ฒฐ์ด ํ๋์ด๋ฏ๋ก ๊ทธ๋์ ์ฑ์ ๋ชจ๋ ์ง์๊ฐ ๊ทธ ๋ค์ ์ฐ๋ค โ\n * ๊ฐ์ ์๊ฐ 29ํ์ง๋ฆฌ `twin_instances` ์กฐํ๋ 44.7์ด๋ก ์ฐํ๋ค. ์ด ๋ชฉ๋ก์ ใํธ์ ๊ด๋ฆฌยทํ์ฅ ๊ตฌ์ฑยท\n * ์ํฐํฐ ํจ๋์ด ๋ชจ๋ ์ฝ๋ ์๋ฆฌใ์ฌ์, ํ๋ฉด์ ์ด ๋๋ง๋ค ์๋ฒ ์ ์ฒด๊ฐ ๊ทธ๋งํผ ๋ฉ์ท๋ค.\n *\n * ํธ์ ์๋ ์์ญ์ด๊ณ ์ ๋์ ์ฒ๋ง์ด๋ค. **์์ ๊ฒ์ ์ฌ๋ฌ ๋ฒ ์ฝ๋ ํธ์ด ํฐ ๊ฒ์ ํ ๋ฒ ํ๋ ๊ฒ๋ณด๋ค ์ธ๋ค.**\n * ์ง์ ๊ฐ์๊ฐ ํธ์ ์์ ๋น๋กํด ์๋ผ๋ ๊ฒ์ ์ฌ์ค์ด์ง๋ง, ๊ฐ ์ง์๊ฐ ์ธ๋ฑ์ค ๋ ํ ํ์ด๋ฏ๋ก ๊ทธ ์ฑ์ฅ์\n * ๊ฐ๋น๋๋ค โ ๊ทธ๋ฆฌ๊ณ ๋ณ๋ ฌ๋ก ๋ฌป๋๋ค.\n *\n * **๋ค์ ๊ทธ๋ฃน ์ง์๋ก ๋ฐ๊พธ์ง ๋ง ๊ฒ.** ๋ฐ๊พธ๋ ค๋ฉด ์ด ์ซ์๋ฅผ ๋จผ์ ๋ค์ ์ฌ๋ผ.\n */\n const tipOfInstance = new Map<string, number>()\n await Promise.all(\n rows.map(async r => {\n try {\n /*\n * **์ง๊ณ ํ๋๋ก ๋ฌป๋๋ค โ ํ์ ์ค์ด ์ค์ง ์๋๋ค.**\n *\n * `findOne(order revision DESC)` ๋ก ๋์๋๋ ๋ ๊ฐ์ง๊ฐ ํ๋ ธ๋ค. โ ๊ด๊ณ๋ฅผ ๊ฐ์ง ์ํฐํฐ์ ์ ๋ ฌ\n * ์กฐํ๋ TypeORM ์ด `DISTINCT` ๋ก ๊ฐ์ธ๋ฏ๋ก `select` ๋ก ์ปฌ๋ผ์ ์ขํ๋ฉด `distinctAlias.\n * TwinEvent_id` ๊ฐ ์๋ค๊ณ ํฐ์ง๋ค(์ค์ธก: ๋ชจ๋ ํธ์์์ SQLITE_ERROR). โก `select` ๋ฅผ ๋ผ๋ฉด\n * **`payload` ๊น์ง ์ค์ด ์จ๋ค** โ ์ด ๊ฐ ํ๋๋ฅผ ์๋ ค๊ณ ํฐ TEXT ๋ฅผ ์ฝ๋๋ค.\n *\n * ๊ทธ๋์ ๋จ์ผ ์ง๊ณ๋ฅผ ์ด๋ค. `(domain, instance, revision)` ์ธ๋ฑ์ค์์ instance ๊ฐ ์ ํด์ง๋ฉด\n * `MAX` ๋ ๊ทธ ๊ตฌ๊ฐ์ ๋์ด๋ฏ๋ก sqlite ๊ฐ ๋์ ์ง๋๋ค(์ค์ธก 0.007์ด ยท ๋๋ฉ์ธ ์ ์ฒด GROUP BY ๋\n * 14.5์ด). ์ด ํ์ผ์ ๋ค๋ฅธ ์๋ฆฌ๋ ๊ฐ์ ๊ท์จ์ด๋ค(ยง`timeRange` ยท ๊ธฐ๋ ์ ์ต์ข
๋ฆฌ๋น์ ).\n */\n const row = await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('MAX(e.revision)', 'revision')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId: r.instanceId })\n .getRawOne<{ revision: unknown }>()\n /* ํ์ด ์์ผ๋ฉด `null` ์ด๋ค โ ๊ทธ๋๋ ๋น์ ๋๋ค(0 ์ \"์๋ฌด ์ผ๋ ์์๋ค\" ๋ ์ฃผ์ฅ์ด๋ค). */\n if (row?.revision != null) tipOfInstance.set(String(r.instanceId), Number(row.revision) || 0)\n } catch (err: any) {\n /* ํ ํธ์์ ์กฐํ๊ฐ ์คํจํด๋ **0 ์ผ๋ก ๋ฉ์ฐ์ง ์๋๋ค** โ ๋ฆฌ๋น์ 0 ์ \"์์ง ์๋ฌด ์ผ๋ ์์๋ค\" ๋\n ์ฌ์ค ์ฃผ์ฅ์ด๋ค. ๋น์ ๋๋ฉด ์๋์์ undefined ๋ก ๋จ๊ณ , ํ๋ฉด์ ๊ทธ๊ฒ์ \"๋ชจ๋ฆ\" ์ผ๋ก ๊ทธ๋ฆฐ๋ค.\n ๊ทธ๋ฆฌ๊ณ ๊ทธ ํธ์๋ง ๋ชจ๋ฆ์ด ๋๋ค โ ์์ ์๋ ์ง๊ณ ํ๋๊ฐ ์คํจํ๋ฉด ์ ๋ถ ๋ชจ๋ฆ์ด์๋ค. */\n twinError(`[twin-engine] latest revision lookup failed \"${r.instanceId}\"`, err?.message ?? err)\n }\n })\n )\n\n const out: any[] = []\n for (const r of rows) {\n const model = (r.model as TwinModelDef) ?? { locations: [], equipment: [] }\n out.push({\n instanceId: r.instanceId,\n /*\n * **์ด๋ฆ์ ํจ๊ป ๋ธ๋ค.** ์
๋ฌดํค(`instanceId`)๋ง ๋ด๋ณด๋ด๊ณ ์์ด์ ๋ชฉ๋ก์ด `crew-two` ๋ง ๋ณด์๋ค โ\n * ์
๋ฌดํค๋ฅผ ๋๋ ๋ ์ค๊ณ์์๋ ์ด๋ฆ์ ๊ฐ์ด ์ค์ด์ผ ๊ทธ ๋๋์ด ๊ฐ์ ํ๋ค.\n * ์์ผ๋ฉด `undefined` ๋ค(id ๋ฅผ ๋ฒ ๋ผ์ง ์๋๋ค โ ํ๋ฉด์ด ์ด๋ฆ ์์์ ์์๋ณผ ์ ์์ด์ผ ํ๋ค).\n */\n name: r.name ?? undefined,\n description: r.description ?? undefined,\n kind: r.kind,\n status: r.status,\n spaceId: r.spaceId, // co-location: ๊ฐ์ spaceId ์ธ์คํด์ค๋ค์ด ํ ํ์ฅ ๊ณต์ โ ํ์ฅ๋ทฐ ์ง์ฝ ํค(G7)\n /* ์ฌ๋์ด ์ฝ๋ ํ์ฅ ์ด๋ฆ โ ์์ผ๋ฉด `undefined`(ํ๋ฉด์ด \"์ด๋ฆ ์์\" ์ ์์๋ณผ ์ ์์ด์ผ ํ๋ค). */\n spaceName: (r.spaceId ? spaceNameOf.get(r.spaceId) : undefined) || undefined,\n restartPolicy: r.restartPolicy, // ์ฌ๊ธฐ๋ ์ ์ฑ
(ADR-0029 ยง2) โ resync/resume/reset. ์ ์ธ์ด๋ฏ๋ก ๋น์ด ์์ ์ ์๋ค.\n purpose: r.purpose, // ์ด์ vs ๋ฒค์น ์ฌ๋ณธ(1๊ธ ๊ตฌ๋ณ โ ์ด๋ฆ ์ ๋์ฌ ์๋). ์ ์ฅ ์ ๊ฐ์ธ๋๋ฏ๋ก ๋น์ง ์๋๋ค.\n copyOf: r.copyOf ?? undefined,\n running: !!this.instances[runtimeKey(domainId, r.instanceId)],\n /*\n * **๊ณ์ธก์ด ๋ค์ด์ค๊ณ ์๋** โ ใ๋๋ ์คใ๊ณผ ๋ค๋ฅธ ์ฌ์ค์ด๋ค.\n *\n * ๋ฏธ๋ฌ ํธ์์ ํผ๋๊ฐ ๋จ์ด์ ธ๋ ์ปค๋์ด ๋๊ธฐ๋ง ํ๋ฉด ใ๋๋ ์คใ์ด์๋ค. ๊ทธ๋์ ์๋ฌด๊ฒ๋ ๋ฐ์ง ์๋\n * ํธ์๊ณผ ํ๋ฅด๋ ํธ์์ด ํ๋ฉด์์ ๋๊ฐ์ด ๋ณด์๋ค(์ฌ๊ธฐ๋ ๋ค ์ค์ ๋ก ๊ทธ๋ฌ๋ค). ์๋ฎฌยท์ ์ง ํธ์์๋\n * ใํด๋น ์์ใ์ด๋ค โ ์์ด์ผ ํ๋ ๊ฒ์ ๋๊ฒผ๋ค๊ณ ๋ถ๋ฅด์ง ์๋๋ค.\n */\n /* ์ค์ค๋ก ๋ฉ์ถ ์ด์ โ ์์ผ๋ฉด ๋ธ๋ค. ์ฌ๊ธฐ๋ ๋ค์๋ ์๋ค(๊ทธ๋๋ ใ๋ชจ๋ฅธ๋คใ๊ฐ ์ฌ์ค์ด๋ค). */\n stopNote: this.stopNotes.get(runtimeKey(domainId, r.instanceId)) || undefined,\n liveFeed: liveFeedStateOf({\n restartPolicy: r.restartPolicy,\n running: !!this.instances[runtimeKey(domainId, r.instanceId)],\n instanceId: r.instanceId\n }),\n revision: tipOfInstance.get(r.instanceId) ?? 0,\n /*\n * **๋ฆฌ๋๋ฅผ ๊ฑฐ์ณ ์ผ๋ค** โ ๋ณด๋ ํค๋ฅผ ์ง์ ์ฝ์ผ๋ฉด ์ ์ธ๋ ๋ชจ๋ธ์ด 0 ์ผ๋ก ๋ณด์ธ๋ค.\n *\n * ์ปค๋์ ์๋ฆฌยท์ค๋น ๋ฐฐ์ด์ **์ ์ธ๋ ํค๊น์ง ํก์ํด** ์ฝ์ด ์ฃผ๋๋ฐ, ์ด ๋ชฉ๋ก์ ์ ์ด๋ฆ๋ง ์ง์ \n * ์ธ๊ณ ์์๋ค. ๊ทธ๋์ ์ ๋ชจ๋ธ 12๊ฐ๊ฐ ํ๋ฉด์ **์๋ฆฌ 0 ยท ์ค๋น 0**\n * ์ผ๋ก ๋ด๋ค โ ์ค๋ฅ ์์ด, ๊ทธ๋ฅ ๋น ๊ณต์ฅ์ฒ๋ผ. ์ธ๋ ๊ท์น์ด ๋ ๋ฒ์ด๋ฉด ์ด๋ฐ ์์ผ๋ก ์ด๊ธ๋๋ค.\n */\n locationCount: readBoardLocations(model).length,\n equipmentCount: readBoardEquipment(model).length\n })\n }\n return out\n }\n\n /** ์ด์ ๊ณต๊ฐ ๋ชฉ๋ก(๋ฒค์น ์์ค ์ ํ๊ธฐ) โ ์ด๋ฆยท๊ท๋ชจ ํฌํจ, ๋ฒค์น ์ฌ๋ณธ ์ ์ธ. */\n static async listSpaces(domainId: string): Promise<{ spaceId: string; name: string; instances: number; locations: number; equipment: number }[]> {\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const agg = new Map<string, { spaceId: string; name: string; instances: number; locations: number; equipment: number }>()\n for (const r of insts) {\n /* ๋ฒค์น ์ ์ธ๋ **์ ์ธ์ผ๋ก๋ง** ํ๋จํ๋ค. ์์ ์๋ spaceId ์ด๋ฆ(`bench-`ยท`loadtest*`)์ผ๋ก๋ ์ถ์ธกํ๋๋ฐ,\n ๊ทธ๋ฌ๋ฉด ๊ทธ๋ ๊ฒ ์ด๋ฆ ์ง์ ์ง์ง ์ด์ ๊ณต๊ฐ์ด ๋ชฉ๋ก์์ ์กฐ์ฉํ ์ฌ๋ผ์ง๋ค. purpose ๊ฐ ์ ๋ณธ์ด๋ค. */\n if (!r.spaceId || r.purpose === 'bench') continue\n const model: any = r.model ?? {}\n const a = agg.get(r.spaceId) ?? { spaceId: r.spaceId, name: nameOf.get(r.spaceId) ?? r.spaceId, instances: 0, locations: 0, equipment: 0 }\n a.instances++\n /* ๋ชฉ๋ก๊ณผ **๊ฐ์ ๊ท์น**์ผ๋ก ์ผ๋ค โ ์ฌ๊ธฐ๋ง ์ง์ ์ธ๋ฉด ๊ณต๊ฐ ์์ฝ๊ณผ ์ธ์คํด์ค ๋ชฉ๋ก์ด ๋ค๋ฅธ ์๋ฅผ ๋งํ๋ค. */\n a.locations += readBoardLocations(model).length\n a.equipment += readBoardEquipment(model).length\n agg.set(r.spaceId, a)\n }\n return [...agg.values()]\n }\n\n /** ์ธ์คํด์ค ๋ชฉ์ ํ์(์ด์/๋ฒค์น) ์ค์ โ ๋ฒค์น ์ฌ๋ณธ์ 1๊ธ ์์ฑ์ผ๋ก ๊ตฌ๋ณ(์ด๋ฆ ์ ๋์ฌ ์๋). */\n static async setPurpose(domainId: string, instanceId: string, purpose: 'operational' | 'bench', copyOf?: string): Promise<void> {\n await getRepository(TwinInstance).update({ domain: { id: domainId } as any, instanceId }, { purpose, copyOf: copyOf ?? null } as any)\n }\n\n /**\n * ๊ณต๊ฐ ๊ตฌ์กฐ ํ๋
โ ์์ ๋ณต์ (๋ฒค์น ์ฌ๋ณธ)์ ์์ค. ์ ์ฅ๋ฌผ์ด model(์์)ยทTwinSpace.content(์น์ยทgeoยทํํ)ยทTwinArea(์์ญ)๋ก\n * ๋ถ์ฐ๋ผ ์์ผ๋ฏ๋ก ์
์ ๋ชจ์ ๋๋ ค์ค๋ค. ํธ์ถ์ธก์ด ReferenceMaster ๋ก ์ฌ๊ตฌ์ฑ โ ์ฌ์๋ณ โ ingestMaster.\n */\n static async spaceStructure(domainId: string, spaceId: string): Promise<{\n name?: string\n /** ์ค๊ณ ์ขํ๊ณ ๋ฒ์(๋ฏธํฐ)์ ์ง์ค๋ ํผ๋ฐ์ค โ ์ฌ๋ณธ์ด ์๋ณธ๊ณผ ๊ฐ์ ์๋ฆฌ์ ์๋ ค๋ฉด ํจ๊ป ๊ฐ์ผ ํ๋ค. */\n frame: { extentX?: number; extentY?: number; geo?: any; primaryRepresentationId?: string }\n areas: any[]\n instances: { instanceId: string; kind?: string; model: any }[]\n } | null> {\n const sp = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n const areas = sp\n ? (await getRepository(TwinArea).find({ where: { domain: { id: domainId } as any, space: { id: sp.id } as any } })).map(a => ({ id: a.areaId, type: a.type, name: a.name, parentId: a.parentId, layout: a.layout }))\n : []\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n if (!insts.length) return null\n return {\n name: sp?.name,\n frame: { extentX: sp?.extentX, extentY: sp?.extentY, geo: sp?.geo, primaryRepresentationId: sp?.primaryRepresentationId },\n areas,\n instances: insts.map(i => ({ instanceId: i.instanceId, kind: i.kind, model: i.model }))\n }\n }\n\n /** ๊ณต๊ฐ(+ํํยท์์ญ) ์ญ์ โ ๋ฒค์น ์ ๋ฆฌ ๋ฑ. ํธ์ถ์ธก์ด ๋ฐ์ธ๋ฉ ์ธ์คํด์ค๋ฅผ ๋จผ์ ์ ๊ฑฐํ๋ ์ ์ (๊ฐ๋ ์์). deleteTwinSpace ๋ฆฌ์กธ๋ฒ์ ๋ํ. */\n static async deleteSpace(domainId: string, spaceId: string): Promise<void> {\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (space) {\n const reps = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId }, space: { id: space.id } } })\n for (const rep of reps) await getRepository(TwinSpaceArea).delete({ domain: { id: domainId } as any, representation: { id: rep.id } as any })\n await getRepository(TwinSpaceRepresentation).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n await getRepository(TwinArea).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n }\n await getRepository(TwinSpace).delete({ domain: { id: domainId } as any, spaceId })\n }\n\n /**\n * Face2 ๋ง์คํฐ ์ธ์ ์คํธ(ADR-0018) โ ๋ ํผ๋ฐ์ค ์์คํ
(์ค ๋๋ ๊ฐ์)์ ๋ง์คํฐ๋ฅผ ์ฝ์ด ํธ์์ ์์ฑ.\n * ์ํฐํฐ๋ฅผ ์๋ฐฐ์ /๋ฐ๋ช
ํ์ง ์๊ณ ๋ง์คํฐ์์ ๋ฐ์: ๊ณต๊ฐ(Space) upsert + ์ธ์คํด์ค provision(๋ฏธ๊ธฐ๋).\n * ๋
ธ๋ํ์
์ ์ปค๋ ์นดํ๋ก๊ทธ๋ก ๊ฒ์ฆ(warning). start ๋ ํธ์ถ์ธก(bootstrap/mutation)์ด ๊ฒฐ์ .\n *\n * `into.spaceId` โ **์ด ํ์ฅ์ ๋ํ๋ค.** ํ ํ์ค์ ์ฌ๋ฌ ๋ ์ฆ(WMSยทMESยทYMS)๊ฐ ๋น์ถ๋ฏ๋ก ์ ํธ์์ด\n * ๊ธฐ์กด ๊ณต๊ฐ์ผ๋ก ๋ค์ด๊ฐ ์ ์๋ค. ์๋ ๋ณํฉ์ ์๋ ๊ทธ ๊ฒฝ์ฐ๋ฅผ ์ํด ์์๋๋ฐ(N:1) ๋ง๋๋ ํ๋ฆ์์\n * ๊ณต๊ฐ์ ๊ณ ๋ฅผ ๋ฐฉ๋ฒ์ด ์์๋ค โ ๋ง์คํฐ๊ฐ ํ์ํ id ๋ง ์ฐ์๋ค. ํ์ ์ `resolveIngestSpace`(์์).\n */\n static async ingestMaster(\n domainId: string,\n master: ReferenceMaster,\n /** ๋ง๋ค์ด์ง๋ ํธ์์ ์ฌ๊ธฐ๋ ์ ์ฑ
โ ์๋ณธ์ด ์ ํ๋ ๊ฒ์ด ์๋๋ผ **๋ง๋๋ ์ชฝ์ ์ ์ธ**์ด๋ค(ADR-0029 ยง2). */\n restartPolicy: RestartPolicy,\n into?: { spaceId?: string },\n /** ๋๊ฐ ์ธ์ ์คํธํ๋ โ ์ฌ๋์ด ์๋ ๊ฒฝ๋ก(๋ถํ
)๋ ์ฃผ์ง ์๋๋ค(๊ฐ์ฌ ๊ธฐ๋ก์ ์ง์ด๋ด์ง ์๋๋ค). */\n actor?: { id: string }\n ): Promise<{ instanceId: string; spaceId: string; warnings: IngestWarning[] }> {\n /*\n * **๊ฑฐ์ ํ ๊ฒ์ด๋ฉด ์๋ฌด๊ฒ๋ ์ฐ๊ธฐ ์ ์ ๊ฑฐ์ ํ๋ค.**\n *\n * ๊ฐ๋ ์ค ์ฌํ๋ก๋น์ ๋์ `provision` ์ด ๋ง๋๋ค. ๊ทธ๋ฐ๋ฐ ๊ทธ ํธ์ถ์ ์ด ํจ์์ **๋งจ ๋**์ด๋ผ,\n * ๊ทธ๋๊น์ง ๊ณต๊ฐยทํํยท๊ตฌ์ญ(TwinArea)์ ์ด๋ฏธ ์ ์ฅ๋ ๋ค์๋ค. ์ฌ์ฉ์์๊ฒ๋ \"์ธ์ ์คํธ ์คํจ\" ๋ก\n * ๋ณด์ด๋๋ฐ ์ค์ ๋ก๋ ์ ๋ฐ์ด ์ ์ฉ๋ ์ํ โ ์คํจ๋ผ๊ณ ๋งํ๋ฉด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พธ๋ ๊ฒ์ด ๊ฐ์ฅ ๋์๋ค.\n *\n * ๊ทธ๋์ ํ์ ์ ์์ผ๋ก ์ฎ๊ธด๋ค. ์๋ `provision` ์ ๊ฐ์ ํ์ ์ ๊ทธ๋๋ก ๋๋ค โ ์ด๊ฑด ํธ์๋ฅผ ์ํ\n * ์์ ๊ฑฐ์ ์ด๊ณ , ์ ๊ธฐ๊ฐ ์ง์ง ๋ฐฉ๋ฒฝ์ด๋ค(๋ค๋ฅธ ๊ฒฝ๋ก๊ฐ ์๊ฒจ๋ ์ง์ผ์ ธ์ผ ํ๋ค).\n *\n * **๋ฏธ๋ฌ๋ ์ฌ๊ธฐ์ ๊ฑฐ์ ํ์ง ์๋๋ค.** ๋ฏธ๋ฌ๊ฐ ๋น์ถ๋ ํ์ค์ ์ ๋ฉ์ถ๋ฏ๋ก ๋์ ์ค์ ์ ํํ๋ค\n * (์๋ `adoptStructure`). ๊ฑฐ์ ์ ์๋ฎฌ๋ ์ด์
์๋ง ๋จ๋๋ค โ ์กฐ๊ฑด์ด ๋ฐ๋ ์คํ์ ๋ค๋ฅธ ์คํ์ด๋ค.\n */\n const running = this.instances[runtimeKey(domainId, master.source)]\n if (running && running.mode !== 'live') this.assertNotRunning(domainId, master.source)\n\n const { model, spaceContent, warnings } = masterToTwin(master, DOMAIN_CATALOG)\n /*\n * โโ ํ์ฅ ์ ์ธ์ ๋ค์ ์น๋๋ค (2026-08-18) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n *\n * ์ฌ๊ธฐ๊ฐ ใ์์ฒ์์ ๋ค์ ๊ทธ๋ฆฌ๋ใ ์๋ฆฌ๋ค. ์๊ธ ๋จ๊ฐยท๊ณ์ฝ ์ ๋ณด์ฒ๋ผ **ํ์ฅ์ด ์ ํ ์**๋ ์์ฒ์ด ๋ชจ๋ฅด๋ฏ๋ก\n * ๋ค์ ๊ทธ๋ฆฌ๋ฉด ๊ทธ๋๋ก ์ฌ๋ผ์ง๋ค โ ๊ธ์ก์ด ์ฌ๋ผ์ง๊ณ , ์ฌ์ฉ์๋ ์๊ธฐ๊ฐ ๋ฃ์ ๊ฐ์ด ์ด๋๋ก ๊ฐ๋์ง ์ ์ ์๋ค.\n * ๊ทธ๋์ ๊ฒน์ผ๋ก ๋ณด๊ดํ ์ ์ธ์ ๋งค๋ฒ ๋ค์ ์น๋๋ค(`engine/local-declarations`).\n *\n * ๋์์ด ์ฌ๋ผ์ก์ผ๋ฉด(๊ตฌ์กฐ๊ฐ ๋ฐ๋์๋ค) ๊ทธ ์ฌ์ค์ ๊ฒฝ๊ณ ๋ก ๋ธ๋ค โ ๊ฐ ๊ณณ ์๋ ์ ์ธ์ ์กฐ์ฉํ ๋ฒ๋ฆฌ์ง ์๋๋ค.\n */\n const prior = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId: master.source } })\n /*\n * ๊ฒน์ด **๋**์ด๋ค โ ํ์ฅ(๊ณต๊ฐ)์ ๊ฒ๊ณผ ์ด ํธ์์ ๊ฒ. ์์๊ฐ ๊ท์จ์ด๋ค: ํ์ฅ ๋จผ์ , ํธ์์ด ๋์ค.\n * ์๊ธ์ฒ๋ผ ํ์ฅ์ด ์ ํ ์๋ ๊ทธ ํ์ฅ์ ํธ์ ์ ๋ถ๊ฐ ๊ฐ์ด ์ฝ์ด์ผ ํ๊ณ , ํ ํธ์๋ง ๋ค๋ฅด๊ฒ ๋๋ ์คํ์\n * ์ข์ ๊ฒน์ด ์ด๊ฒจ์ผ ํ๋ค(๋์ ๊ฐ์ ๊ณ ์น๋ฉด ๋๋จธ์ง ํธ์์ด ํจ๊ป ํ๋ค๋ฆฐ๋ค).\n */\n const priorSpaceId = prior?.spaceId ?? (model as any)?.spaceId\n const spaceRow = priorSpaceId\n ? await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId: priorSpaceId } })\n : null\n if (prior?.localDeclarations || spaceRow?.localDeclarations) {\n const layered = applyDeclarationLayers(model as any, spaceRow?.localDeclarations as any, prior?.localDeclarations as any)\n Object.assign(model as any, layered.model)\n /*\n * ๊ฒน์ **๋ค์ ์ ์ฅํ๋ค** โ ์ฌ๊ธฐ์ ์น์ ๊ฒ์ ์์ฒ์์ ์๋ก ๊ทธ๋ฆฐ ๋ชจ๋ธ์ด๋ฏ๋ก, ๊ทธ๋ ์ฐ๋ฆฌ๊ฐ ๋ฎ์ ๊ฐ์ด\n * ๊ณง ์ง๊ธ์ ์์ฒ ๊ฐ์ด๋ค(`replaced`). ์ ์ฅํ์ง ์์ผ๋ฉด ๊ทธ ๊ธฐ์ต์ด ๋ก์, ์ฒ ํ๊ฐ ์ ์์ฒ ๊ฐ์ผ๋ก\n * ๋๋๋ฆฐ๋ค โ ์์ฒ์ด ๊ทธ๋์ ๊ฐ์ ๊ณ ์ณค์ด๋ ์ ์ ์๋ค.\n */\n if (prior) {\n prior.localDeclarations = layered.instanceLayerApplied as any\n await getRepository(TwinInstance).save(prior)\n }\n if (spaceRow) {\n spaceRow.localDeclarations = layered.spaceLayerApplied as any\n await getRepository(TwinSpace).save(spaceRow)\n }\n /*\n * ๊ฐ ๊ณณ ์๋ ์ ์ธ์ ๊ฒฝ๊ณ ๋ก ๋ธ๋ค โ ๋ค๋ง **ํ์ฅ ๊ฒน์ ๊ฒ์ ๋บ๋ค**: ํ ํ์ฅ์๋ ์ฌ๋ฌ ์ข
๋ฅ์ ํธ์์ด\n * ์ด๊ณ (์ฐฝ๊ณ ยท์ผ๋ยท์๋์ง), ์๊ธ ์๋ฆฌ๊ฐ ์๋ ํธ์์ ์๊ธ์ด ์นํ์ง ์๋ ๊ฒ์ ์ ์์ด๋ค.\n */\n for (const t of layered.missingTargets.filter(x => x.scope === 'instance')) {\n warnings.push(unresolvedReference('localDeclaration.target', `${t.target}:${t.id}`))\n }\n }\n const repo = getRepository(TwinSpace)\n /* ํฉ์น ๊ณต๊ฐ์ ๊ณจ๋์ผ๋ฉด **์๋์ง ๋จผ์ ํ์ธํ๋ค** โ ์๋ ๊ณณ์ ์กฐ์ฉํ ์ ๊ณต๊ฐ์ ๋ง๋ค๋ฉด ์ฌ์ฉ์๋\n ํฉ์ณค๋ค๊ณ ๋ฏฟ๊ณ ํ๋ฉด์ ๋ฐ๋ก ๋
ผ๋ค. ํ์ ํจ์๊ฐ ๊ทธ ๊ฒฝ์ฐ ๊ฑฐ์ ํ๋ค. */\n const wanted = (into?.spaceId ?? '').trim()\n const wantedExists = wanted\n ? (await repo.count({ where: { domain: { id: domainId }, spaceId: wanted } })) > 0\n : false\n const choice = resolveIngestSpace(model.spaceId, wanted, wantedExists)\n const spaceId: string = choice.spaceId\n model.spaceId = spaceId // ๋ณด๋(์ปค๋ ์๋น)๋ ๊ฐ์ ๊ณต๊ฐ์ ๊ฐ๋ฆฌ์ผ์ผ ํ๋ค\n const existing = await repo.findOne({ where: { domain: { id: domainId }, spaceId } })\n if (choice.joined) {\n /* ๊ฐ์ id ์ ๊ตฌ์ญยท๋๋๋งํฌ๋ ํฉ์งํฉ์ผ๋ก ์ ํ๋ค โ ๊ตฌ๋ถํ ์ ์๋ ๊ฒ์ ๊ณ ๋ฅด์ง ์๊ณ ๋ฌด์์ด\n ํฉ์ณ์ก๋์ง ๋งํ๋ค(์ ๋นํ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ฏ๋ก ๋ง์ง ์๋๋ค). */\n }\n /*\n * ๊ณต์ ๊ณต๊ฐ(์ฌ๋ฌ ํธ์์ด ํ spaceId, N:1) โ **๋จผ์ ์ด ๊ฐ์ด ์ด๊ธด๋ค.**\n *\n * ๋ง์ง๋ง ์ธ์ ์คํธ๊ฐ ํต์งธ๋ก ๋ฎ์ด์จ ํํยท๊ตฌ์ญ์ด ์ ์ค๋๋ ๋ฌธ์ ๋ณด์ . ์ค๊ณ ์ขํ๊ณ ๋ฒ์์\n * ์ง์ค๋ ํผ๋ฐ์ค๋ ๊ณต๊ฐ์ ์ฑ์ง์ด๋ผ ํธ์๋ง๋ค ๋ค๋ฅผ ์ ์๋ค โ ๋ ๋ฒ์งธ ํธ์์ด ๋ค์ด์ค๋ฉด์ ๋ฐ๊พธ๋ฉด\n * ๋จผ์ ๋์ธ ๊ตฌ์ญ๋ค์ด ํต์งธ๋ก ์ด๊ธ๋๋ค. ๊ทธ๋์ ์ด๋ฏธ ์์ผ๋ฉด ๊ทธ๋๋ก ๋๋ค.\n */\n const cur: any = spaceContent\n const timezone = existing?.timezone || master.space.timezone\n const savedSpace = await repo.save(\n repo.create({\n ...(existing ?? {}),\n domain: { id: domainId } as any,\n spaceId,\n name: existing?.name || master.siteName,\n ...(timezone ? { timezone } : {}),\n extentX: existing?.extentX ?? cur.width,\n extentY: existing?.extentY ?? cur.depth,\n geo: existing?.geo ?? cur.geo,\n /*\n * ๋ํ ํํ ํฌ์ธํฐ๋ **ํํ์ ์ ์ฅํ ๋ค** ์ค์ ํ id ๋ก ์ฑ์ด๋ค(์๋). ์ฌ๊ธฐ์ ๋ง์คํฐ์ ๋
ผ๋ฆฌ\n * id(`r-map` ๋ฐ์)๋ฅผ ๋ฃ์ผ๋ฉด ํํ ํ์ ์์ฑ uuid ๋ฅผ ๋ฐ์ผ๋ฏ๋ก ํฌ์ธํฐ๊ฐ **์ฒ์๋ถํฐ ํ๊ณต์\n * ๊ฐ๋ฆฌํจ๋ค** โ ์ค์ ๋ก 13๊ฐ ํ์ฅ์ด ๊ทธ ์ํ์๊ณ ์ ํฉ์ฑ ์ ๊ฒ์ด ์ก์๋ค(2026-08-13). ํ๋ฉด์\n * ํ์ `isPrimary` ๋ก โ
๋ฅผ ๊ทธ๋ ค์ ์ฆ์์ด ๋ณด์ด์ง ์์๋ค(์ฌ์ค์ด ๋ ๋ฒ์ด๋ฉด ์ด๋ ๊ฒ ์กฐ์ฉํ๋ค).\n */\n primaryRepresentationId: existing?.primaryRepresentationId ?? null\n })\n )\n /*\n * ํํ์ twin_space_representations ํ
์ด๋ธ์ ์ ์ฅํ๋ค โ ๋ทฐ(twin-map-page ๋ฑ)๋ content ๊ฐ ์๋๋ผ ํ
์ด๋ธ ํํ์ ์์ฑํ๋ฏ๋ก,\n * ์ ์ฅํ์ง ์์ผ๋ฉด ์ธ์ ์คํธ ์ฌ์ดํธ์ \"๋ํ ํํ\" ์ด ์์ด ์ง๋๋ก ์์ํ์ง ๋ชปํ๋ค. rep.areas ๊ฐ ์์ผ๋ฉด TwinSpaceArea ๋ ํจ๊ป ์ ์ฅ.\n * ์ต์ด ์ธ์ ์คํธ๋ง(๊ธฐ์กด ํํ ์์ผ๋ฉด ์ฌ์ฉ์ ํธ์ง ๋ณด์กด).\n */\n const repRepo = getRepository(TwinSpaceRepresentation)\n const areaRepo = getRepository(TwinSpaceArea)\n if ((await repRepo.count({ where: { space: { id: savedSpace.id } } })) === 0) {\n const reps: any[] = (spaceContent as any).representations ?? []\n for (let i = 0; i < reps.length; i++) {\n const rep = reps[i]\n const config =\n rep.type === 'map' ? { center: rep.center, zoom: rep.zoom }\n : rep.type === 'board' ? { boardId: rep.boardId }\n : rep.type === 'image' ? { imageUrl: rep.imageUrl, width: rep.width, height: rep.height }\n : {}\n const savedRep = await repRepo.save(repRepo.create({ domain: { id: domainId } as any, space: { id: savedSpace.id } as any, type: rep.type, name: rep.name, seq: i, isPrimary: !!rep.primary || rep.id === (spaceContent as any).primaryId, config }))\n for (const area of (rep.areas ?? []) as any[]) {\n await areaRepo.save(areaRepo.create({ domain: { id: domainId } as any, representation: { id: savedRep.id } as any, name: area.name, type: area.type, geometry: area.geometry, drillTo: area.drillTo ?? null, binding: area.binding ?? null, style: area.style ?? null }))\n }\n }\n /*\n * ๋ํ๋ฅผ **์ ์ฅ๋ ํ id** ๋ก ๊ฐ๋ฆฌํจ๋ค โ ๋ง์คํฐ์ ๋
ผ๋ฆฌ id ๋ ์ ์ฅ ํค๊ฐ ์๋๋ค. ๊ณ ๋ฅธ ์์:\n * โ ๋ง์คํฐ๊ฐ primary ๋ก ํ์ํ ํํ โก ์์ผ๋ฉด ์ฒซ ํํ โข ํํ์ด ์์ผ๋ฉด ๋น์ด๋ค(์ง์ด๋ด์ง ์๋๋ค).\n */\n const saved = await repRepo.find({ where: { domain: { id: domainId } as any, space: { id: savedSpace.id } as any }, order: { seq: 'ASC' } })\n const primary = saved.find(r => r.isPrimary) ?? saved[0]\n if (primary && savedSpace.primaryRepresentationId !== primary.id) {\n await repo.save(repo.create({ ...savedSpace, primaryRepresentationId: primary.id }))\n /* ํ๋๋ง ๋ํ๋ค โ ํ ํ๋๊ทธ๋ ๊ทธ ํ๋๋ก ๋ง์ถ๋ค(๋์ด ์ผ์ ธ ์์ผ๋ฉด ํ๋ฉด์ด โ
๋ฅผ ๋ ๋ฒ ๊ทธ๋ฆฐ๋ค). */\n for (const r of saved) if (!!r.isPrimary !== (r.id === primary.id)) await repRepo.save(repRepo.create({ ...r, isPrimary: r.id === primary.id }))\n }\n }\n /*\n * area ๋จ์ผํ(space #2, P1) โ ๋
ผ๋ฆฌ ๊ตฌ์ญ์ TwinArea(์ ๊ทยทํํ๋ฌด๊ดยท๊ณต์ )์ dual-write(upsert by areaId).\n * P3: content.areas ์ ์ฅ ํ๊ธฐ โ TwinArea ๊ฐ ์ ์ผ ๊ถ์. ์์ค = masterToTwin ์ฐ์ถ spaceContent.areas(cur).\n * (์์ฒ diff ์ ๊ฑฐ[master ์์ ๋น ์ง area ์ญ์ ]๋ ์ฌ์ฉ์์ ์ area ๋ณดํธ ์ํด per-area provenance ํ์ โ ํ์.)\n */\n const twinAreaRepo = getRepository(TwinArea)\n for (const a of ((spaceContent as any).areas ?? []) as any[]) {\n if (!a?.id) continue\n const existingArea = await twinAreaRepo.findOne({ where: { domain: { id: domainId }, space: { id: savedSpace.id }, areaId: a.id } })\n await twinAreaRepo.save(\n twinAreaRepo.create({\n ...(existingArea ?? {}),\n domain: { id: domainId } as any,\n space: { id: savedSpace.id } as any,\n areaId: a.id,\n name: a.name ?? a.id,\n type: a.type,\n parentId: a.parentId ?? null,\n layout: a.x != null || a.w != null ? { x: a.x, y: a.y, w: a.w, h: a.h } : null\n })\n )\n }\n\n if (running) {\n /* ์คํ ์ค์ธ ๋ฏธ๋ฌ โ ๋ฉ์ถ์ง ์๊ณ ์ ํํ๋ค. ๋ฌด์์ด ์ฌ๋ผ์ก๋์ง๋ **๊ฒฝ๊ณ ๋ก ๋งํ๋ค**\n (๋ฉ์ท๋ค ์ธ์ฐ๋ ๋ง๋๊ฐ ์์ผ๋ฏ๋ก, ๋งํ์ง ์์ผ๋ฉด ์๋ฆฌ ํ๋๊ฐ ์กฐ์ฉํ ์์ด์ง๋ค). */\n const shift = await this.adoptStructure(domainId, master.source, model, undefined, master.origin)\n warnings.push(structureAdopted(shift.rev, shift))\n } else {\n /* ์ฌ์ดํธ ์ด๋ฆ์ด ๊ณง ํธ์์ ์ด๋ฆ์ด๋ค โ ๋ง์คํฐ๊ฐ ์ด๋ฏธ ๋งํ์ผ๋ฏ๋ก ์ง์ด๋ด์ง ์๊ณ ๊ทธ๋๋ก ์ฃ๋๋ค. */\n await this.provision(domainId, master.source, master.system, model, restartPolicy, undefined, master.origin, {\n name: master.siteName,\n description: (master as any).description,\n actor\n })\n }\n\n /*\n * ๊ตฌ์กฐ ํฌ์ โ model(์ปค๋ ์
๋ ฅ ๋ฌธ์)๋ฅผ **ํ์ค ์ํฐํฐ ํ**์ผ๋ก ํผ๋ค(ADR-0032).\n *\n * ์ธ์ ์คํธ๊ฐ ์ ์ผํ ์ฐ๊ธฐ ๊ฒฝ๋ก๋ค. ์ฌ๊ธฐ์ ์คํจํด๋ ์ธ์ ์คํธ ์์ฒด๋ ์ฑ๊ณต์ผ๋ก ๋๋ค โ\n * ํ์ **์๋ณธ์์ ์ธ์ ๋ ๋ค์ ๊ทธ๋ฆด ์ ์๋ ์บ์**์ด๊ณ , ํธ์ ์์ฒด๋ model ๋ก ์ด๋ฏธ ๋์ํ๋ค.\n * ๋ค๋ง **์กฐ์ฉํ ๋๊ธฐ์ง ์๋๋ค**: ๋ชป ์ด์ ์ฐธ์กฐ๋ ์ธ์ ์คํธ ๊ฒฝ๊ณ ๋ก ์ฌ๋ผ๊ฐ๋ค.\n */\n try {\n const projected = await projectStructure(domainId, master.source, model, master.source)\n for (const ref of projected.unresolvedHome) warnings.push(unresolvedReference('equipment.homeLocation', ref))\n for (const ref of projected.unresolvedArea) warnings.push(unresolvedReference('location.area', ref))\n /*\n * ๋ฐ์ ํ์์ **์๊ฐ**์ ์ฝ๋๋ค โ ์๊ฐ๋๋ฅผ ๋ชจ๋ฅด๋ฉด UTC ๋ก ์ฝํ๊ณ , ํ์ฅ ์ ์ค๊ฐ ์๋ ์๊ฐ์ ํผํฌ๊ฐ ์ ๋ค.\n * ์๊ฐ๋๋ฅผ ์ง์ด๋ด์ง ์๊ณ ๊ทธ ์กฐํฉ์ ๋งํ๋ค(๊ณต๊ฐ์ ์ ์ธํ๋ฉด ์ฌ๋ผ์ง๋ค).\n */\n if ((model as any)?.utcOffsetMinutes === undefined) {\n for (const e of ((model as any)?.equipment ?? []) as any[]) {\n const hasProfile = ((e?.properties ?? []) as any[]).some(p => String(p?.id) === EMS_PROPERTY.genDailyProfile && String(p?.value ?? '').trim())\n if (hasProfile) warnings.push(generationWithoutTimeZone(String((model as any)?.spaceId ?? ''), String(e.id)))\n }\n }\n } catch (err: any) {\n twinError(`[twin-engine] structure projection failed for \"${master.source}\":`, err?.message)\n warnings.push(projectionFailed(err?.message ?? 'unknown'))\n }\n\n if (warnings.length) twinWarn(`[twin-engine] ingest \"${master.source}\" warnings: ${describeWarnings(warnings)}`)\n return { instanceId: master.source, spaceId, warnings }\n }\n\n /** ๋จ๊ฑด ์์ธ โ ํ๋ก๋น์ ๋ ์๋ํฐ๊ฐ ํธ์งํ model(๊ตฌ์กฐ+layout) ํฌํจ. */\n static async detail(domainId: string, instanceId: string): Promise<any | null> {\n const r = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!r) return null\n return {\n instanceId: r.instanceId,\n kind: r.kind,\n status: r.status,\n running: !!this.instances[runtimeKey(domainId, r.instanceId)],\n restartPolicy: r.restartPolicy, // ํ์ค ์ ์ธ โ what-if ์ ์ฉ ๊ฐ๋์ฉ(mirror=์์ธก ์ ์ฉ, ์๊ทน ์ฃผ์
๋ถ๊ฐ)\n model: r.model\n }\n }\n\n /**\n * ๋ผ์ด๋ธ ๋ฐ์ธ๋ฉ ๋ธ๋ฆฌ์ง(P3, ADR-0018) โ ํธ์ ์ํฐํฐ ์ํ๋ฅผ `data(tag=์ํฐํฐid)` ์ฑ๋๋ก publish.\n * ๋ณด๋ ์ปดํฌ๋ํธ๊ฐ tag ๋ก ๊ตฌ๋
(board-ui provider)ํด `component.data` ๋ก ๋ผ์ด๋ธ ๊ฐฑ์ . delta ์์๋ง(ํฌ์).\n * tag=์ํฐํฐ id(๋ฐ๋ชจ=๋จ์ผ ์ธ์คํด์ค). ๋ฉํฐ ์ธ์คํด์ค/๋ณด๋ ์ฌ์ฌ์ฉ ์ tag ๋ค์์คํ์ด์ค๋ ํ์.\n */\n /** ๋ธ๋ก๋์บ์คํ
์คํจ ๋ก๊ทธ ์กฐ์ โ ์ฐฝ๋ง๋ค ํ ์ค(๋งํ ๊ตฌ๋
์๋ ์ด๋น ์์ญ ๋ฒ ์คํจํ๋ค). */\n private static publishDrops = new Map<string, { count: number; lastLogMs: number }>()\n private static readonly PUBLISH_DROP_LOG_MS = 10_000\n\n /**\n * ํ ๋ฒ์ ๋ธ๋ก๋์บ์คํ
โ **๊ตฌ๋
์ ํ๋๊ฐ ํธ์คํธ๋ฅผ ์ฃฝ์ด์ง ๋ชปํ๊ฒ.**\n *\n * โโ ๋ฌด์์ด ์ฃฝ์๋ (2026-08-14) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๋ฐ๋ฆฐ push ๊ฐ 1024๋ฅผ ๋์ผ๋ฉด pubsub ์ด ์ค๋ฅ๋ฅผ ๋ธ๋ค(`RepeaterOverflowError`). ๊ทธ ๋ธ๋ก๋์บ์คํ
์ ํ์ด๋จธ ์ฝ๋ฐฑ\n * ์์์ ์ผ์ด๋๋ฏ๋ก ์์ธ๊ฐ ์กํ๋ ๊ณณ ์์ด ์ฌ๋ผ๊ฐ **ํ๋ก์ธ์ค๊ฐ ๋๋ฌ๋ค** โ ํธ์ 14๊ฐ๊ฐ ๋๋ ํธ์คํธ๊ฐ\n * ์๋น๋ฅผ ๋ฉ์ถ ๊ตฌ๋
์ ํ๋ ๋๋ฌธ์ ํต์งธ๋ก.\n *\n * ๋ชป ๋ณด๋ธ ๊ฒ์ **์ฌ์ค๋ก ๋จ๊ธด๋ค**(ํ์๋ฅผ ์ธ๊ณ ์ฐฝ๋ง๋ค ํ ์ค ๋จ๊ธด๋ค). ์ผํค๋ฉด ใ๋ณด๋๋๋ฐ ํ๋ฉด์ด ๋ก์๋คใ๊ฐ\n * ๋๊ณ , ๊ทธ๊ฑด ๊ฐ์ฅ ์ฐพ๊ธฐ ์ด๋ ค์ด ๋ถ๋ฅ๋ค.\n */\n private static publishGuarded(channel: 'data' | 'twin-state', payload: any, what: string): boolean {\n try {\n pubsub.publish(channel as any, payload)\n return true\n } catch (err: any) {\n const d = this.publishDrops.get(what) ?? { count: 0, lastLogMs: 0 }\n d.count++\n const now = Date.now()\n if (now - d.lastLogMs >= this.PUBLISH_DROP_LOG_MS) {\n d.lastLogMs = now\n twinWarn(`[twin-engine] broadcast dropped on \"${what}\" (${d.count} so far) โ ${err?.message ?? err}`)\n }\n this.publishDrops.set(what, d)\n return false\n }\n }\n\n static publishEntityData(inst: InstanceRuntime): void {\n const domain = inst.domain\n if (!domain) return\n /* ์ํ ์ถ์ฒ ์ค์ โ sim: ์ปค๋ runtime, live: projector ๋ฏธ๋ฌ(+OEE ๊ณ์ฐ ์ธต ๋ณด๊ฐ). ๊ณ์ฝยทpayload ๋์ผ, ๋๋ผ์ด๋ฒ๋ง ๋ค๋ฆ. */\n const load = inst.load ?? (inst.load = newLoadMeter())\n\n /* โ ์ํ ํฌ์ โ ์ํ ํฌ๊ธฐ์ ๋น๋กํ๋ค(๋๊ท๋ชจ์์ ๊ฐ์ฅ ๋ฌด๊ฑฐ์ด ์ถ). */\n const tSnap = performance.now()\n const st: any =\n inst.mode === 'live'\n ? inst.oee\n ? withLiveOee(inst.projector?.snapshot?.(), inst.oee) // ๊ด์ธก ์ปค๋ + ๊ณ์ฐ(OEE) โ equipment payload ์ oee ํฌํจ(sim ๋ํ)\n : inst.projector?.snapshot?.()\n : inst.runtime?.resync?.()?.state\n recordPhase(load, 'snapshot', performance.now() - tSnap)\n if (!st) return\n /*\n * ๋ณํํ ์ํฐํฐ๋ง ๋ฐํ โ ์ด์ ์ delta ๋ง๋ค ์ ์ํฐํฐ(๋
ธ๋+๋ฌด๋ฒ+์ค๋)๋ฅผ ๊ฐ ๋ณํ์ ๋ฌด๊ดํ๊ฒ ์ ๋ ์ฌ๋ฐํํด\n * ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋งค์ด ๋ฐ๋ณต push ํ๊ณ ์์๋ค(์ค์ฉ). ์ต์ -์ํ ์ฑ๋์ด๋ฏ๋ก ๋ฌด๋ณํ ์ฌ๋ธ๋ก๋์บ์คํ
์ ๋ฌด์๋ฏธํ๋ค.\n * ์ํฐํฐ๋ณ ์๊ทธ๋์ฒ๋ฅผ ๋น๊ตํด ๋ฐ๋ ๊ฒ๋ง push.\n */\n const sigs = inst.entitySigs ?? (inst.entitySigs = new Map())\n const seen = new Set<string>()\n /* payload ๋งคํ์ ์์ ํจ์(buildEntityDeltas)๋ก ๋ถ๋ฆฌ โ ์ฌ๊ธฐ์ ์๊ทธ๋์ฒ dedup + ๋ฐํ๋ง.\n * ๋ณํํ ์ํฐํฐ๋ง ๋ฐํ(์ต์ -์ํ ์ฑ๋์ด๋ผ ๋ฌด๋ณํ ์ฌ๋ธ๋ก๋์บ์คํ
๋ฌด์๋ฏธ). */\n /* โก payload ๋ง๋ค๊ธฐ โ ์ํฐํฐ ์์ ๋น๋ก. โข ์๊ทธ๋์ฒ ๋น๊ต + ๋ฐํ โ ๋ฐ๋ ๊ฒ ์์ ๋น๋ก. */\n const tDelta = performance.now()\n /*\n * โโ ๋ฌผํ์ **๊ฑด๋๋ฆฐ ๊ฒ๋ง** ๋ง๋ ๋ค (2026-08-21 ์ค์ธก) โโโโโโโโโโโโโโโโโโโโโโ\n * ๋ง๋๋ payload ์ ๋๋ถ๋ถ์ด ๋ฌผํ์ด๋ค(์ํฐํฐ 3,611 ์ค 2,400). ๋ฐ๋ ๊ฒ์ด ํ๋์ฌ๋ ์ ๋ถ ๋ง๋ค์ด\n * ๋ฌธ์์ด๋ก ๋ฐ๊พผ ๋ค ใ๊ฐ๋คใ๋ฅผ ํ์ธํ๊ณ ๋ฒ๋ ธ๋ค.\n *\n * ๋ฒ์๋ ์ด ์ฐฝ์ ๋ค์ด์จ ์ฌ๊ฑด์์ ๋ชจ์๋ค(`touchedItemKeys`). **๋งํ ์ ์๋ ์ฌ๊ฑด์ด ํ๋๋ผ๋ ์์ผ๋ฉด\n * ๋ฒ์๋ ์๊ณ ์ ๋ถ ๋ง๋ ๋ค** โ ๋ฏ์ ์ดํ๊ฐ ์ค๋ฉด ์กฐ์ฉํ ๋น ๋จ๋ฆฌ๋ ๋์ ๋น์ธ๊ฒ ์์ ํ ์ชฝ์ผ๋ก ๋จ์ด์ง๋ค.\n *\n * ๊ทธ๋ฆฌ๊ณ ์ฃผ๊ธฐ๋ง๋ค ํ ๋ฒ์ **๋ฌด์กฐ๊ฑด ์ ๋ถ** ๋ง๋ ๋ค(`FULL_BROADCAST_EVERY`). ์ปค๋์ด ์ฌ๊ฑด ์์ด ๋ฌผํ์\n * ๋ฐ๊พธ๋ ์๋ฆฌ๊ฐ ์๊ธฐ๋ฉด ๊ทธ ๊ฐ์ด ํ๋ฉด์ ๋จ์ ์ ์๋๋ฐ, ๊ทธ ์ฐฝ์ ๋ช ์ด๋ก ๋ฌถ๋ ๊ทธ๋ฌผ์ด๋ค. **๋ณด์ฅ์ด ์๋๋ผ\n * ๊ทธ๋ฌผ์ด๋ค** โ ์ฌ๊ฑด ์์ด ๋ฐ๋๋ ์๋ฆฌ๋ฅผ ์ฐพ์ผ๋ฉด ๊ทธ๊ฒ์ ๊ณ ์น๋ ๊ฒ์ด ๋ต์ด๊ณ ์ด ๊ทธ๋ฌผ์ ์๊ฐ์ ๋ฒ ๋ฟ์ด๋ค.\n */\n const full = inst.fullBroadcastDue === true || !inst.dirtyItems\n const deltas = buildEntityDeltas(st, inst.id, full ? undefined : { items: inst.dirtyItems! })\n this.broadcastPasses++\n if (full) this.broadcastFullPasses++\n /* ์ด๋ฒ ์ฐฝ์ ๋ฒ์๋ ์ฌ๊ธฐ์ ๋ซ๋๋ค โ ๋ค์ ์ฐฝ์ ๋ค์ ๋ชจ์๋ค. */\n inst.dirtyItems = new Set()\n inst.fullBroadcastDue = false\n recordPhase(load, 'deltas', performance.now() - tDelta)\n\n const tPub = performance.now()\n for (const { tag, data } of deltas) {\n seen.add(tag)\n const sig = JSON.stringify(data)\n if (sigs.get(tag) === sig) continue // ๋ฌด๋ณํ โ ๋ฐํ ์๋ต\n sigs.set(tag, sig)\n /*\n * **๋ชป ๋ณด๋์ผ๋ฉด ๋ณด๋ธ ๊ฒ์ผ๋ก ์ ์ง ์๋๋ค.** ์๊ทธ๋์ฒ๋ฅผ ๋จ๊ฒจ ๋๋ฉด ๋ค์ ์ฃผ๊ธฐ์ ใ๋ฌด๋ณํใ๋ก ๊ฑด๋๋ฐ๊ณ ,\n * ๊ทธ ํ๊ทธ๋ ์์ํ ๋ก์ ๊ฐ์ ๋ณด์ฌ ์ค๋ค(์ค๋ฅ ์์ด). ๋๋๋ ค ๋๋ฉด ๋ค์ ์ฃผ๊ธฐ๊ฐ ๋ค์ ์๋ํ๋ค.\n */\n if (!this.publishGuarded('data', { data: { domain, tag, data } }, `data:${inst.id}`)) sigs.delete(tag)\n }\n recordPhase(load, 'publish', performance.now() - tPub)\n /*\n * ์ฌ๋ผ์ง ์ํฐํฐ์ ์๊ทธ๋์ฒ ์ ๋ฆฌ(๋งต ๋ฌดํ ์ฑ์ฅ ๋ฐฉ์ง) โ **์ ๋ถ ๋ง๋ ์ฐฝ์์๋ง.**\n * ๋ฒ์๋ฅผ ์ขํ ์ฐฝ์ `seen` ์๋ ๋ง๋ค์ง ์์ ์ํฐํฐ๊ฐ ์์ผ๋ฏ๋ก, ๊ทธ๋ ์ ๋ฆฌํ๋ฉด ์ด์ ์๋ ํ๊ทธ์\n * ์๊ทธ๋์ฒ๋ฅผ ์ง์ด๋ค. ๋ก์ ๊ฐ์ด ๋๊ฐ๋ ๊ฒ์ ์๋์ง๋ง(๋ค์ ์ฐฝ์ ๋ค์ ๋ง๋ค์ด ๋ณด๋ธ๋ค) ๊ฐ์ ๊ฐ์\n * ๋ํ์ด ๋ณด๋ด๊ฒ ๋์ด, ์ค์ด๋ ค๋ ๊ฒ์ ๋๋๋ฆฐ๋ค.\n */\n if (full && sigs.size > seen.size) for (const tag of sigs.keys()) if (!seen.has(tag)) sigs.delete(tag)\n }\n\n /*\n * ๋จ๊ฑด ์ ์ฅ(`persist`)์ **์์ด๋ค** (2026-08-20, ยง7.1).\n *\n * ์๋ฎฌ์ด ๋ธํ๋ง๋ค ์ด๊ฒ์ ๋ถ๋ฌ ํ ํ๋์ฉ ์ผ๊ณ , ๊ทธ๊ฒ์ด ๊ท๋ชจ์์ ํธ์คํธ๋ฅผ ๋จน์๋ค. ๋จ๊ฒจ ๋๋ฉด ๋ค์ ์ฌ๋์ด\n * ๋ค์ ๋ถ๋ฅผ ์๋ฆฌ๊ฐ ๋๋ฏ๋ก ์ง์ด๋ค โ ์ฐ๋ ๋ฌธ์ `flushJournal` ํ๋๋ค(`persistBatch`ยท`persistCarried`).\n */\n\n /**\n * ์ฌ๋ถํ
๋ณต๊ตฌ / ์๊ฐ์ฌํ โ DB ์ ๋์ replay ํด ์ํ ์ฌ๊ตฌ์ฑ.\n * model ๋ ๋ ์ง์คํธ๋ฆฌ(TwinInstance)์์, ์ด๋ฒคํธ๋ TwinEvent(revision ASC)์์.\n * ์ปค์ ๋ ์ถ(runtime-state-model ยง4): **์๊ฐ(untilTime, ์ฌ์ฉ์ ๋ชจ๊ตญ์ดยท๊ณต๊ฐ ๊ณตํต์ถ)** ์ฐ์ , ์์ผ๋ฉด ๋ฆฌ๋น์ (untilRevision, ๋ ์ฆ ๋ด๋ถ).\n * - untilTime ์ฃผ๋ฉด `eventTime โค T` ์ธ ์ด๋ฒคํธ๋ง(๊ทธ ์์ watermark) โ ๊ณต๋๋ฐฐ์น ์ฌ๋ฌ ํธ์์ ํ๋์ ์๊ฐ T๋ก ํต์ผ ํด์.\n * - ๋ ๋ค ์์ผ๋ฉด ์ต์ (๋ผ์ด๋ธ ์ธ๋ฉ๋ชจ๋ฆฌ ์ง์ค).\n * ์ด๋ฒคํธ๋ ํญ์ revision ASC(์ธ๊ณผ ์์)๋ก ์ ์ฉ โ ์๊ฐ ํํฐ๋ ์ปท์คํ ์งํฉ๋ง ์ ํ๋ค.\n */\n static async recover(domainId: string, instanceId: string, untilRevision?: number, untilTime?: string): Promise<any> {\n // ๋ผ์ด๋ธ ์ต์ (์๊ฐ์ฌํ ์๋) + ์ธ๋ฉ๋ชจ๋ฆฌ ์ธ์คํด์ค โ ๋ผ์ด๋ธ ์ปค๋ ์ค๋
์ท์ ์ง์ ์ฌ์ฉ.\n // replay(StateProjector)๋ attentionsยทack ๋ฑ ๋ผ์ด๋ธ ์ ์ฉ ํ์ ์ํ๋ฅผ ๋ด์ง ๋ชปํ๋ฏ๋ก, ์ต์ ์ ์ปค๋ ์ง์ค์ ์ด๋ค.\n if (untilRevision == null && untilTime == null) {\n const live = this.instances[runtimeKey(domainId, instanceId)]\n if (live?.kernel?.getSnapshot) return live.kernel.getSnapshot()\n // live ๋ชจ๋๋ kernel ์ด ์๊ณ projector ๋ฏธ๋ฌ โ ์ธ๋ฉ๋ชจ๋ฆฌ ์ต์ ์ค๋
์ท(projector+OEE+attentions) ์ง์ ์ฌ์ฉ.\n // (์ ๋์ด ์์ด๋ ์ต์ ์ ์ธ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ง์ค โ replay ๋ ์๊ฐ์ฌํ/๋ณต๊ตฌ ์ ์ฉ.)\n if (live?.mode === 'live' && live.projector) return this.snapshot(domainId, instanceId)\n }\n /*\n * **๋์ ์๋ ์ค๋
์ท์ด๋ฉด ์ ์ง ์๋๋ค.**\n *\n * ๋ฉ์ถ ํธ์์ ์กฐํํ ๋๋ง๋ค ์ ๋์ ์ ๋ ์ ๊ณ ์์๋ค โ ํธ์์ ํ๋๋ ์ ๋๋ ค๋ ๋ชจ๋ธ ์กฐํ๊ฐ\n * 4.6~7.7์ด์๋ ์ด์ ๋ค(crew-probe 23,731๊ฑด). ์ค๋
์ท์ ๊ฐ์ ํด๋์ ๊ฒฐ๊ณผ์ด๋ฏ๋ก, ๊ทธ ๋ค๋ก ์ด๋ฒคํธ๋\n * ๊ตฌ์กฐ ๋ณ๊ฒฝ๋ ์๋ค๋ฉด **๋ค์ ์ ์ด ๋ด์ผ ๊ฐ์ ๊ฐ**์ด๋ค.\n *\n * ์ฐ์ง ์๋ ์กฐ๊ฑด์ ์ข๊ฒ ์ก๋๋ค: ์ง๊ธ์ ๋ฌผ์์ ๋๋ง(์๊ฐ์ฌํ์ ๊ทธ ์์ ๊น์ง ์ ์ด์ผ ํ๋ค), ๋ฆฌ๋น์ ์ด\n * ๋๊ณผ ๊ฐ์ ๋๋ง, ๊ตฌ์กฐ ๋ฆฌ๋น์ ๊น์ง ๊ฐ์ ๋๋ง. ํ๋๋ผ๋ ์ด๊ธ๋๋ฉด ์ ๋๋ค โ ์บ์๊ฐ ์ฌ์ค์ ์ด๊ธฐ์ง ์๋๋ค.\n */\n const asOfNowRead = untilRevision == null && untilTime == null\n const tip = asOfNowRead ? await this.tipOf(domainId, instanceId).catch(() => null) : null\n /* ํ ๋ฒ๋ง ์ฝ๋๋ค โ ๋์ ์์ผ๋ฉด ๊ทธ๋๋ก ์ฐ๊ณ , ์๋๋ฉด ์๋์์ **์ด์ด ์ ๋ ์จ์**์ผ๋ก ์ด๋ค. */\n const cachedForResume = asOfNowRead && tip ? await this.loadSnapshot(domainId, instanceId).catch(() => null) : null\n if (cachedForResume) {\n const state = unwrapState(cachedForResume.state)\n if (state && (cachedForResume.revision ?? 0) === tip!.revision && (cachedForResume.structureRev ?? null) === tip!.structureRev)\n return state\n }\n\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.model) throw new Error(`twin instance \"${instanceId}\" not registered (no model to replay)`)\n\n /*\n * โโ ์ฌ๊ฐ์ ์์ **์ด์ด ์ ๋๋ค** (2026-08-18) โโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n *\n * ์ฐ๋ฆฌ๋ ์ด๋ฏธ ์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋จ๊ธฐ๊ณ ์๋ค(`saveFoldedSnapshot`). ๊ทธ ์ง์ ์ **์ฌ๊ฐ์ **(๋ฆฌ๋์ ๋ด๋ถ ์ํ\n * ์ ๋ถ + ๊ฐ๋ ๋์ ๊ธฐ)์ด ํจ๊ป ์์ผ๋ฉด, ๊ทธ ๋ค์ ์ผ์ด๋ ๊ฒ๋ง ์ ์ด๋ ๊ฐ์ ๋ต์ด ๋์จ๋ค โ ๊ทธ ๋์น๋\n * ์ปค๋ ์ํ์ด ์ฆ๋ช
ํ๋ค(0๋ถํฐ ์ ๊ธฐ == ์ฌ๊ฐ์ + ๊ผฌ๋ฆฌ).\n *\n * ์ฐ๋ ์กฐ๊ฑด์ ์ข๊ฒ ์ก๋๋ค: **์ง๊ธ์ ๋ฌผ์์ ๋๋ง**(์๊ฐ์ฌํ์ ๋ชฉํ ์ด์ ์ฌ๊ฐ์ ์ด ํ์ํ๋ฐ ์ง๊ธ์\n * ์ต์ ํ๋๋ง ๋จ๊ธด๋ค โ ์ฌ์ฌ์ ๋ค์ ๋จ๊ณ๋ค), ๊ตฌ์กฐ๊ฐ ๊ทธ๋๋ก์ผ ๋๋ง(๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ฉด ๊ทธ ๊ฒฝ๊ณ์์ ๊ฐ๋ผ\n * ์ ์ด์ผ ํ๋ค), ์ฌ๊ฐ์ ์ด ์ ๋ ๋๋ณด๋ค ์์ค ๋๋ง. ํ๋๋ผ๋ ์ด๊ธ๋๋ฉด 0๋ถํฐ ์ ๋๋ค โ **์บ์๊ฐ ์ฌ์ค์\n * ์ด๊ธฐ์ง ์๋๋ค.**\n */\n /*\n * ์จ์์ ๋ ์ค ํ๋๋ค: **์ง๊ธ**์ ๋ฌผ์ผ๋ฉด ์ต์ ์ฌ๊ฐ์ , **๊ณผ๊ฑฐ**๋ฅผ ๋ฌผ์ผ๋ฉด ์ฌ์ฌ์์ ๋ชฉํ ์ง์ ์ง์ .\n *\n * ๊ณผ๊ฑฐ ์จ์์ ๊ตฌ์กฐ๊ฐ ํ ๋ฒ๋ ๋ฐ๋์ง ์์ ํธ์์์๋ง ์ด๋ค โ ๊ตฌ์กฐ๊ฐ ๊ฐ๋ฆฐ ์ ๋์ ๋ง๋๋ง๋ค ๊ฐ์ ์ ์ด์ผ\n * ํ๊ณ , ๋ง๋๋ฅผ ๊ฑด๋๋ด ์จ์์ ๊ทธ ๊ฒฝ๊ณ์ ํ์ ์ ์๋๋ค(๊ทธ๋๋ 0๋ถํฐ ์ ๋ ๊ฒ์ด ์ณ๋ค).\n */\n const structureCount = asOfNowRead\n ? 0\n : await getRepository(TwinStructure).count({ where: { domain: { id: domainId }, instanceId } }).catch(() => 99)\n const pastSeed =\n !asOfNowRead && structureCount <= 1\n ? await this.chainSeedFor(domainId, instanceId, {\n ...(untilRevision != null ? { revision: untilRevision } : {}),\n ...(untilTime != null && !Number.isNaN(Date.parse(untilTime)) ? { timeMs: Date.parse(untilTime) } : {})\n }).catch(() => null)\n : null\n const resume =\n asOfNowRead && tip && cachedForResume && cachedForResume.fold && (cachedForResume.structureRev ?? null) === tip.structureRev\n ? cachedForResume\n : pastSeed\n\n /*\n * **์๋ฅผ ๊ฒ์ ์๋ฉด์ ๋ค ์ฝ์ด ์ค์ง ์๋๋ค** (2026-08-18 ์ค์ธก).\n *\n * ์ ๋์ ์ ๋ ์ฝ์ด ์จ ๋ค JS ์์ ๊ฑธ๋ ๋ค. 27๋ง ๊ฑด์ง๋ฆฌ ํธ์(order-check)์์ ํ ์๊ฐ ์ ์ํ๋ฅผ ๋ฌผ์ผ๋ฉด\n * **7.4์ด**๊ฐ ๊ฑธ๋ ธ๊ณ , ๊ทธ ๋๋ถ๋ถ์ด ใํ์ ์๋ ํ์ ์ฝ์ด ์ค๋ ์๊ฐใ์ด์๋ค. ์๊ฐยท๋ฆฌ๋น์ ์ํ์ SQL ์ด\n * ์๋ ์กฐ๊ฑด์ด๋ฏ๋ก ๊ฑฐ๊ธฐ์ ์๋ฅธ๋ค(TypeORM ๊ด์ฉ๊ตฌ๋ง โ ์์ SQL ์ 5๊ฐ ๋๋ผ์ด๋ฒ์์ ๊ฐ๋ผ์ง๋ค).\n *\n * ์๊ฐ ์ํ์๋ **๊ฒฝ๊ณ๋ฅผ ๊ทธ๋๋ก** ์ด๋ค(`<=`): ๊ทธ ์๊ฐ์ ์ผ์ด๋ ์ฌ์ค์ ๊ทธ ์๊ฐ์ ํ๋ฉด์ ์์ด์ผ ํ๋ค.\n * ์๊ฐ์ด ์๋ ๋ ๊ฑฐ์ ํ์ ๋ณด์์ ์ผ๋ก ํฌํจํด ์๋๋ฐ, SQL ๋ก ์๋ฅด๋ฉด ๊ทธ ํ๋ค์ด ๋น ์ง๋ค โ ๊ทธ๋์ ์๊ฐ\n * ์กฐ๊ฑด์ผ ๋๋ **์๊ฐ์ด ๋น์ด ์๋ ํ๋ ํจ๊ป** ๊ฐ์ ธ์ ์์ ๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ธ๋ค.\n */\n const cutoffMs = untilTime != null ? Date.parse(untilTime) : NaN\n const useTime = untilTime != null && !Number.isNaN(cutoffMs)\n const baseWhere = { domain: { id: domainId }, instanceId }\n /* ์ด์ด ์ ์ ๋๋ **๊ทธ ๋ค๋ง** ์ฝ๋๋ค โ ์ฌ๊ฐ์ ๊น์ง์ ์ฌ์ค์ ์ด๋ฏธ ์จ์ ์์ ์๋ค. */\n const from = resume ? (resume.revision ?? 0) : undefined\n /*\n * journal-fold: ์ฌ์์ ์ฌ์ค์ ํ๋์ฉ ์ ๋ ๊ฒ์ด๋ฏ๋ก ๊ทธ ๊ตฌ๊ฐ์ ํ์ด ํ์ํ๋ค. ์ปค์(`from`)์ ์๊ฐ\n * ์ํ์ด ๊ตฌ๊ฐ์ ์๋ฅด๊ณ , ์ฒดํฌํฌ์ธํธ๊ฐ ์์ชฝ์ ์จ์์ผ๋ก ๋์ ํ๋ค โ ํ ์ ์ฒด๋ฅผ ์ฝ์ง ์๋๋ค.\n */\n const rows = await getRepository(TwinEvent).find({\n where: useTime\n ? from\n ? /* ์จ์ ๋ค ยท ๋ชฉํ ์ด๋ด โ ์๊ฐ์ด ๋น ์ ํ์ ์จ์ ๋ค์ ์๋ ๊ฒ๋ง ํฌํจํ๋ค(๋ณด์์ ํฌํจ์ ์ ์ง). */\n [\n { ...baseWhere, revision: MoreThan(from), eventTime: LessThanOrEqual(new Date(cutoffMs)) },\n { ...baseWhere, revision: MoreThan(from), eventTime: IsNull() }\n ]\n : [\n { ...baseWhere, eventTime: LessThanOrEqual(new Date(cutoffMs)) },\n { ...baseWhere, eventTime: IsNull() }\n ]\n : untilRevision != null\n ? from\n ? { ...baseWhere, revision: And(MoreThan(from), LessThanOrEqual(untilRevision)) }\n : { ...baseWhere, revision: LessThanOrEqual(untilRevision) }\n : from\n ? { ...baseWhere, revision: MoreThan(from) }\n : baseWhere,\n order: { revision: 'ASC' }\n })\n const wanted = rows\n\n /*\n * **๊ทธ๋์ ๊ณต์ฅ์ผ๋ก ์ ๋๋ค.**\n *\n * ์์ ์๋ ๋ชจ๋ ์ด๋ฒคํธ๋ฅผ ์ง๊ธ ๋ฑ๋ก๋ ๋ณด๋ ํ๋๋ก ์ ์๋ค. ๊ตฌ์กฐ๊ฐ ๋ฐ๋ ์ ์์ผ๋ฉด ๋ง์ง๋ง, ๋ฐ๋\n * ๋ค์๋ ์ ์ฌ์ค์ ์ ๊ณต์ฅ์ ๋๊ณ ์ ๊ฒ ๋์ด โ ๊ทธ๋ ์๋ ์ค๋น์์ ์ผ์ด ์์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค.\n * (๊ทธ๋์ ์์ ํ๋ก๋น์ ๋์ ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ฉด ์ ๋์ ์์ ์ง์ ๋ค. ์ญ์ฌ๋ฅผ ์๊ฑฐ๋ ๊ฑฐ์ง๋ง์ ํ๊ฑฐ๋.)\n *\n * ์ด์ ์ด๋ฒคํธ๊ฐ ์๊ธฐ ๊ตฌ์กฐ๋ฅผ ๋ฌ๊ณ ์ค๋ฏ๋ก, ๋ฆฌ๋น์ ์ด ๋ฐ๋๋ ์ง์ ์์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ํ๋ฉฐ ์ด์ด ์ ๋๋ค.\n * ๋ฆฌ๋น์ ์ด ํ๋๋ฟ์ด๊ฑฐ๋(๋๋ค์) ์์ ์์ผ๋ฉด(๊ตฌ์กฐ ์ด๋ ฅ ์ด์ ) ์์ ๊ณผ ๋๊ฐ์ด ํ ๋ฒ์ ์ ๋๋ค.\n */\n const structures = await getRepository(TwinStructure).find({\n where: { domain: { id: domainId }, instanceId },\n order: { rev: 'ASC' }\n })\n const boardOf = new Map<number, TwinModelDef>(structures.map(x => [x.rev, x.model as TwinModelDef]))\n /* ์ปฌ๋ผ์ด ์๊ธฐ๊ธฐ ์ ํ์ ๋ฆฌ๋น์ ์ด ๋น์ด ์๋ค โ **๊ฐ์ฅ ์ค๋๋ ๊ตฌ์กฐ**์ ์ํ๋ค(0 ์ผ๋ก ์ฑ์ฐ์ง ์๋๋ค). */\n const oldest = structures[0]?.rev\n const revOf = (r: { structureRev?: number }): number | undefined => r.structureRev ?? oldest\n\n const segments: { model: TwinModelDef; events: any[] }[] = []\n for (const r of wanted) {\n if (!r.payload) continue\n const rev = revOf(r)\n const model = (rev !== undefined && boardOf.get(rev)) || (reg.model as TwinModelDef)\n const last = segments[segments.length - 1]\n if (last && last.model === model) last.events.push(r.payload)\n else segments.push({ model, events: [r.payload] })\n }\n /*\n * **๊ฐ์ฅ ์ ๊ตฌ์กฐ๊ฐ ์ง๊ธ์ ๊ณต์ฅ์ด๋ค** โ ๊ทธ ์๋์์ ์์ง ์๋ฌด ์ผ๋ ์์๋๋ผ๋.\n *\n * ์ฌํ๋ก๋น์ ๋ ์งํ๊ฐ ์ ํํ ๊ทธ ์ํ๋ค: ๋ถ์ค๋ฅผ ๋ท ๋๋ ธ๋๋ฐ ์ ์ด๋ฒคํธ๋ ์์ง ํ๋๋ ์๋ค. ์ด๋\n * ๋ง์ง๋ง ์ด๋ฒคํธ์ ๊ตฌ์กฐ๋ก๋ง ์ ์ผ๋ฉด ํ๋ฉด์ **์ ๊ณต์ฅ**์ ๋ณด์ฌ์ค๋ค โ ๋ฐฉ๊ธ ๋๋ฆฐ ๊ฒ์ด ์ ๋ณด์ธ๋ค.\n * ๊ทธ๋์ ๋ง๋์ ๋์ ์ง๊ธ ๊ตฌ์กฐ๋ฅผ ํ ๋ฒ ๋ ์น๋๋ค(์ด๋ฒคํธ ์๋ ๋ง๋).\n *\n * **๋ค๋ง \"์ง๊ธ\" ์ ๋ฌผ์์ ๋๋ง์ด๋ค.** ๊ณผ๊ฑฐ ์์ ์ ๋ฌผ์๋๋ฐ ์ต์ ๊ตฌ์กฐ๋ฅผ ์น์ผ๋ฉด, ๊ทธ ์์ ์ ์๋\n * ์ค๋น๊ฐ ํ๋ฉด์ ์๊ณ โ ์ด ์์
์ด ๋ง์ผ๋ ค๋ ๋ฐ๋ก ๊ทธ ๊ฑฐ์ง๋ง์ด ๋๋ค.\n */\n const asOfNow = untilRevision == null && untilTime == null\n const newest = structures[structures.length - 1]?.model as TwinModelDef | undefined\n if (asOfNow && newest && segments[segments.length - 1]?.model !== newest) segments.push({ model: newest, events: [] })\n\n /*\n * ์ ์ ์ํ์ **์ฃผ์ ์ ํธ์ ์๊ฐ์ ์ฑ์ด๋ค.**\n *\n * ๋ผ์ด๋ธยท์๋ฎฌ์ ์ปค๋์ด ์ ํธ๋ฅผ ์ค์ค๋ก ๋ด์ง๋ง, ์ ๋์ ์ ๋ ์ด ๊ฒฝ๋ก๋ ํ๋ก์ ํฐ ์ํ๋ง ๋ธ๋ค โ ์ ํธ๋\n * `nowTime` ๋ ์๋ค. ๊ทธ๋์ **๊ณผ๊ฑฐ๋ฅผ ๋ค์ ๊ณ์ฐํ๋ฉด ์ฃผ์ ๋ ์ผ์ด ํ
๋น์๊ณ **(์ง๋๋ `snap.attentions` ๋ฅผ\n * ์ฝ๋๋ค), ๊ธฐ๋๋ผ ์์ง ์์ ํธ์์ ๋ณด๋ ํ๋ฉด๋ ๊ฐ์๋ค. ์ ํธ๋ ์ํ์์ ๊ณ์ฐ๋๋ ๊ฒ์ด๋ฏ๋ก\n * ์ฌ๊ธฐ์ ๊ฐ์ ๊ณต์(`deriveAttentions`)์ผ๋ก ์ฑ์ฐ๋ฉด ๋๋ค โ ๋ ๋ฒ์ ๋์ง ์๋๋ค.\n *\n * `nowTime` ์ด ๋จผ์ ๋ค: \"๋ฆ์๋\" ํ์ ์ด ๊ทธ ๊ฐ์ ๋ณธ๋ค. ๋ค์ ๊ณ์ฐํ ์์ ์ ์ ์งํ \"์ง๊ธ\" ์ ๋ฌผ์ด๋ณธ ์๊ฐ\n * (`untilTime`)์ด๊ณ , ์์ผ๋ฉด ๋ง์ง๋ง์ผ๋ก ์ ์ฉํ ์ด๋ฒคํธ์ ์๊ฐ์ด๋ค. ๋ ๋ค ์์ผ๋ฉด ์ฑ์ฐ์ง ์๋๋ค โ\n * ๋ฒฝ์๊ณ๋ฅผ ๋ผ์ ๋ฃ์ผ๋ฉด ๊ณผ๊ฑฐ ํ๋ฉด์ด \"์ง๊ธ ๊ธฐ์ค์ผ๋ก ๋ฆ์๋ค\" ๊ณ ๋งํ๊ฒ ๋๋ค.\n */\n const lastEventTime = rows.length ? (rows[rows.length - 1]?.eventTime?.toISOString() ?? '') : ''\n\n /*\n * **๊ฐ๋ ์ด๋ ฅ๋ ๋์ด๋ฆฐ๋ค** โ ๋ค์ ๊ณ์ฐํ ํ๋ฉด์ ์ค๋น ๊ณ์ธก์ด ๋น์ด ์๋ ๊ฒ.\n *\n * OEE ๋ ์ ์์คํ
์ด ๋์ ์ ๋ณด๋ด ์ฃผ์ง ์์ ํธ์คํธ๊ฐ ์ํ ์ ์ด๋ฅผ ์ ๋ถํด ๋ง๋ ๋ค(๊ทธ๋์ ์ปค๋์ด ์๋๋ผ\n * ์ฌ๊ธฐ ์๋ค). ๊ทธ๋ฐ๋ฐ ๊ทธ ๋์ ๊ธฐ๋ **๋ผ์ด๋ธ์์๋ง** ๋์๊ณ , ์ ๋์ ์ ๋ ๊ฒฝ๋ก๋ ๊ทธ ๊ณ์ฐ์ ํ์ง ์์๋ค โ\n * ๊ณผ๊ฑฐ๋ฅผ ๋ค์ ๊ณ์ฐํ๋ฉด ๋ชจ๋ ์ค๋น๊ฐ \"๊ฐ๋ ์ด๋ ฅ์ด ์ ํ ์์\" ์ผ๋ก ๋ณด์๋ค.\n *\n * ์๋ ๊ฒ์ ๋ฐ์ดํฐ๊ฐ ์๋๋ผ ๊ณ์ฐ์ด๋ค: ์
๋ ฅ(`equipment.status` ์ ์ดยท`quality.output`)์ ์ ๋์ ๋ค\n * ์๋ค. ๊ทธ๋์ **๊ฐ์ ๋์ ๊ธฐ์ ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ํ์ด๋ค** โ ๊ท์น์ ๋ ๋ฒ ๋ง๋ค์ง ์๋๋ค.\n *\n * ์๊ฐ์ฌํ์์๋ ๋ง๋ค: ์ฌ๊ธฐ ํ์ฐ๋ ๊ฒ์ ์ด๋ฏธ ์๋ผ ๋ธ(`wanted`) ์ด๋ฒคํธ๋ฟ์ด๋ฏ๋ก, ๊ทธ ์์ ๊น์ง์\n * ๊ฐ๋ ์ด๋ ฅ์ด ๋์จ๋ค(๊ทธ ๋ค์ ์ผ์ด๋ ๊ณ ์ฅ์ด ๊ณผ๊ฑฐ ํ๋ฉด์ ์์ด์ง ์๋๋ค).\n */\n const oee = new OeeAccumulator()\n /* ์ฌ๊ฐ์ ์ด ์์ผ๋ฉด ๊ทธ ์์ ๊ผฌ๋ฆฌ๋ง ์น๋๋ค โ ์์ผ๋ฉด ๊ผฌ๋ฆฌ๋ถ๋ง ์ธ์ด ๊ฐ์ฉ๋ฅ ์ด ์กฐ์ฉํ ์์์ง๋ค. */\n if (resume?.fold?.oee) oee.restore(resume.fold.oee)\n for (const r of wanted) {\n try {\n oee.apply(r.payload as any)\n } catch {\n /* ํ ๊ฑด์ด ์ด์ํด๋ ๋๋จธ์ง ๊ณ์ธก์ ๋ฒ๋ฆฌ์ง ์๋๋ค โ ๋์ ๊ธฐ๋ ๋ชจ๋ฅด๋ ์ด๋ฒคํธ๋ฅผ ๋ฌด์ํ๋ ๊ณ์ฝ์ด๋ค. */\n }\n }\n\n const withNow = (st: any): any => {\n if (!st || typeof st !== 'object') return st\n const nowTime = st.nowTime || untilTime || lastEventTime || undefined\n const based = nowTime ? { ...st, nowTime } : st\n /* ๊ณ์ธก ์์ ์ ๊ทธ ํ๋ฉด์ \"์ง๊ธ\" ์ด๋ค โ ๋ฒฝ์๊ณ๋ก ์ฌ๋ฉด ๊ณผ๊ฑฐ ํ๋ฉด์ ๊ฐ์ฉ๋ฅ ์ด ์๊ฐ์ด ๊ฐ์๋ก ๋จ์ด์ง๋ค. */\n const nowMs = nowTime ? Date.parse(String(nowTime)) : Number.NaN\n const withMetrics = withLiveOee(based, oee, Number.isFinite(nowMs) ? nowMs : undefined)\n return withLiveAttentions(withMetrics)\n }\n\n /* ์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋จ๊ธด๋ค โ **์ง๊ธ์ ๋ฌผ์์ ๋๋ง**(์๊ฐ์ฌํ ๊ฒฐ๊ณผ๋ฅผ \"์ง๊ธ\" ์ผ๋ก ์ ์ฅํ๋ฉด ๊ฑฐ์ง์ด ๋๋ค). */\n /*\n * ์ ์ ์ง์ ์ ๋ฆฌ๋น์ โ ์ฌ์ฌ์ ์ ์ ์ด๋ฆ์ด๋ค. ๊ผฌ๋ฆฌ๋ฅผ ์ ์์ผ๋ฉด ๊ทธ ๊ผฌ๋ฆฌ์ ๋, ์๋ฌด๊ฒ๋ ์ ์ฝ์์ผ๋ฉด\n * ์จ์์ ์๋ฆฌ ๊ทธ๋๋ก๋ค(๋ชจ๋ฅด๋ฉด 0).\n */\n const foldedTo = rows.length ? (rows[rows.length - 1]?.revision ?? 0) : (from ?? 0)\n\n const keep = (st: any, fold?: { reducer: ReducerCheckpoint; oee: OeeCheckpoint }): any => {\n /* ์ฌ๊ฐ์ ์ ํจ๊ป ๋จ๊ธด๋ค โ ์ํ๋ง ๋จ๊ธฐ๋ฉด ๋ค์ ๋ฒ์ ๋ 0๋ถํฐ ์ ์ด์ผ ํ๋ค(๊ทธ๊ฒ์ด ์ด ์์
์ ์์ ์ด๋ค).\n **๊ตฌ์กฐ๊ฐ ๊ฐ๋ฆฐ ํด๋์๋ ์ฌ๊ฐ์ ์ ๋ถ์ด์ง ์๋๋ค**: ๋ง๋๋ฅผ ๊ฑด๋๋ด ์จ์์ ๊ทธ ๊ฒฝ๊ณ์ ํ์ ์ ์๋๋ค. */\n if (asOfNowRead && tip && st) {\n void this.saveFoldedSnapshot(domainId, instanceId, { revision: tip.revision, state: st, structureRev: tip.structureRev, fold })\n }\n /*\n * ์ฌ์ฌ์๋ **๊ณผ๊ฑฐ๋ฅผ ์ ์์ ๋๋** ํ ์ง์ ์ ๋จ๊ธด๋ค (2026-08-18 ์ค์ธก์ผ๋ก ๊ณ ์นจ).\n *\n * ์ฒ์์๋ ใ์ง๊ธ ์ฝ๊ธฐใ์์๋ง ๋จ๊ฒผ๋ค. ๊ทธ๋ฐ๋ฐ ๋๋ ํธ์์ ์ง๊ธ ์ฝ๊ธฐ๋ ์ปค๋ ์ค๋
์ท์ผ๋ก ์ฆ์ ๋ตํ๊ณ \n * ํด๋์ ๋ฟ์ง ์๋๋ค โ ๊ทธ๋์ ์ฌ์ฌ์ด **์์ํ ๋น์ด ์์๋ค**(์ค์ธก: ์ง์ 0๊ฐ, ์๊ฐ์ฌํ 3.7s ๊ทธ๋๋ก).\n *\n * ์ง์ ์ ใ์ง๊ธใ์ ์ฃผ์ฅํ์ง ์๋๋ค: ์๊ธฐ ๋ฆฌ๋น์ ๊ณผ ์๊ฐ์ ๋ฌ๊ณ ์์ผ๋ฏ๋ก ๊ณผ๊ฑฐ ํด๋์ ๊ฒฐ๊ณผ๋ฅผ ๋จ๊ฒจ๋\n * ๊ฑฐ์ง์ด ์๋๋ค(๊ทธ๊ฒ์ด ์ค๋
์ท๊ณผ ๋ค๋ฅธ ์ ์ด๋ค). ๊ทธ๋์ ์ฒซ ๊ณผ๊ฑฐ ์กฐํ๊ฐ ๋ค์ ๊ณผ๊ฑฐ ์กฐํ๋ฅผ ๋น ๋ฅด๊ฒ ํ๋ค.\n */\n if (fold && st) {\n const at = asOfNowRead && tip ? tip.revision : foldedTo\n if (at > 0)\n void this.keepChainPoint(domainId, instanceId, {\n revision: at,\n ...(lastEventTime ? { eventTime: lastEventTime } : {}),\n structureRev: (asOfNowRead && tip ? tip.structureRev : null) ?? null,\n fold\n }).catch(() => {})\n }\n return st\n }\n\n /*\n * ์จ์์ด ์์ผ๋ฉด **์ด์ด ์ ๋๋ค** โ ํ ๊ตฌ์กฐ ์์์๋ง(๊ตฌ์กฐ๊ฐ ๊ฐ๋ฆฌ๋ฉด ์๋ ๋ง๋ ๊ฒฝ๋ก๊ฐ ๋งก๋๋ค).\n * ์ ์ฌ๊ฐ์ ๋ ํจ๊ป ๋จ๊ธด๋ค: ๋ค์ ๋ฒ์ ๋ ๊ผฌ๋ฆฌ๋ง ์ ์ ์ ์์ด์ผ ์ด ์ง๋ฆ๊ธธ์ด ๊ณ์ ์ฐ๋ค.\n */\n if (resume?.fold?.reducer && segments.length <= 1) {\n const model = (segments[0]?.model ?? (asOfNow && newest) ?? reg.model) as TwinModelDef\n const out = replayFrom(model, resume.fold.reducer, segments[0]?.events ?? [])\n return keep(withNow(out.state), { reducer: out.checkpoint, oee: oee.serialize() })\n }\n\n if (!segments.length) {\n const model = ((asOfNow && newest) || reg.model) as TwinModelDef\n const out = replayWithCheckpoint(model, [])\n return keep(withNow(out.state), { reducer: out.checkpoint, oee: oee.serialize() })\n }\n if (segments.length === 1) {\n const out = replayWithCheckpoint(segments[0].model, segments[0].events)\n return keep(withNow(out.state), { reducer: out.checkpoint, oee: oee.serialize() })\n }\n\n /* ์ปค๋ ๊ณ์ฝ๋ `model` ์ด๋ค(0.6.14) โ ๊ฒฝ๊ณ์์ ์ดํ๋ฅผ ๋๋๋ ค ๋ด๋ ๋ธ๋ฆฟ์ง๊ฐ ์ฌ๋ผ์ก๋ค. */\n const { state, shifts } = replaySegments(segments)\n /* ๊ฒฝ๊ณ์์ ์ฌ๋ผ์ง ๊ฒ์ ์กฐ์ฉํ ๋๊ธฐ์ง ์๋๋ค โ ์๊ฐ ์ค์ด๋ ์ด์ ๋ฅผ ์ด๋๊ฐ์๋ ๋จ๊ฒจ์ผ ํ๋ค. */\n for (const sh of shifts)\n if (sh.equipmentDropped || sh.locationsDropped || sh.personsDropped || sh.assetsDropped)\n console.info(`[twin-engine] \"${instanceId}\" replay crossed a structure change โ dropped ${sh.equipmentDropped} equipment, ${sh.locationsDropped} locations, ${sh.personsDropped} persons, ${sh.assetsDropped} assets that no longer exist.`)\n return keep(withNow(state))\n }\n\n /**\n * ๊ณต๊ฐ(๊ณต๋๋ฐฐ์น) ์๊ฐ ๋ฒ์ โ ์คํฌ๋ฌ๋ฒ ์ต์ปค(runtime-state-model ยง4ยทยง6). ๊ทธ ๊ณต๊ฐ ์ ์ธ์คํด์ค ์ ๋์ min/max eventTime.\n * ๋ฐํ {minTime, maxTime}(ISO) โ ์ด๋ฒคํธ/์๊ฐ ์์ผ๋ฉด null. ํด๋ผ ํ์คํ ๋ฆฌ ์คํฌ๋ฌ๋ฒ๊ฐ ์ด ๋ฒ์๋ฅผ ์๊ฐ์ถ์ผ๋ก ๊ทธ๋ฆฐ๋ค.\n *\n * โโ ๋ ์๋ฅผ ๊ตฌํ๋ ค๊ณ ์ ๋์ ๋ค ์ฝ์ง ์๋๋ค (2026-08-20 ์ค์ธก์ผ๋ก ์ก์) โโโโโโโโ\n * ์ฌ๊ธฐ์ ์ธ์คํด์ค๋ง๋ค `find()` ๋ก **ํ์ ์ ๋ถ ์ํฐํฐ๋ก ํ์ด๋๋ ์ด์
**ํ ๋ค์ JS ์์ min/max ๋ฅผ\n * ๊ณจ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด ํจ์๋ ํ๋ฉด ์๋จ์ ์ปจํ
์คํธ ๋ ๊ฐ **4์ด๋ง๋ค** ๋ถ๋ฅธ๋ค. ์ค์ธกํ ๊ฐ๋ฐ ์๋ฒ์์\n * `order-check` ํ ํธ์์ด 275,882ํ ยท `payload` 131MB ์๋ค โ 4์ด๋ง๋ค ๊ทธ JSON ์ ์ ๋ถ ํ์ฑํ ๊ฒ์ด๋ค.\n *\n * ๊ทธ ๊ฒฐ๊ณผ๊ฐ ์ด๋ฌ๋ค: ํ๋ก์ธ์ค CPU 81~152%, ์๋ฌด ์ผ๋ ํ์ง ์๋ ์ง์๊ฐ 8~14์ด. JS ํ๋กํ์ผ์ ์์๊ฐ\n * TypeORM ์ `RelationIdLoader`ยท`RawSqlResultsToEntityTransformer`ยท`stringToSimpleJson`(= `payload`\n * ํ์ฑ)์ด๊ณ GC ๊ฐ 16.7% ์๋ค. **ํธ์ ํฑ๋ ์ ๋ ์ฐ๊ธฐ๋ ์๋๋ผ ์ด ์ฝ๊ธฐ์๋ค.**\n *\n * ์ง๊ณ๋ DB ๊ฐ ํ๋ค. `(domain, instanceId, eventTime)` ์ธ๋ฑ์ค๊ฐ ์ด๋ฏธ ์์ด(`ix_twin_event_1`)\n * ์ธ๋ฑ์ค์ **์ ๋์ ์ง๋๋ค** โ ํ์ ํ๋๋ ์ค์ด ์ค์ง ์๋๋ค.\n *\n * โโ ์ MIN ๊ณผ MAX ๋ฅผ ํ ๋ฌธ์ฅ์ ๋ฃ์ง ์๋ (์ค์ธก) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ฒ์์ `SELECT MIN(...), MAX(...) ... WHERE instanceId IN (...)` ํ ๋ฐฉ์ผ๋ก ๋์๋๋ **21ms** ์๋ค.\n * ์ง๊ณ๊ฐ **๋์ด๋ฉด** ์ตํฐ๋ง์ด์ ์ ใ์ธ๋ฑ์ค ๋์ ์ง๋ใ ์ต์ ํ๊ฐ ๊ฑธ๋ฆฌ์ง ์์ ์ธ๋ฑ์ค ๊ตฌ๊ฐ์ ํ๋๋ค โ\n * ์ฆ ๋น์ฉ์ด ์ฌ์ ํ **ํ ์์ ๋น๋ก**ํ๋ค. ํธ์๋ง๋ค ๋จ์ผ ์ง๊ณ๋ก ๋๋ ๋ฌผ์ผ๋ฉด **0.32ms**(ํธ์ 3๊ฐ ยท 6์๋ณต)\n * ์ด๊ณ , ๋น์ฉ์ด **ํธ์ ์์ ๋น๋ก**ํ๋ค. ๊ท๋ชจ ๊ธฐ์ค(์ํฐํฐ 10๋ง)์์๋ ์ด ์ฐจ์ด๊ฐ ๋ณธ์ง์ด๋ค.\n *\n * ์๋ณต์ ํธ์๋น ๋์ด์ง๋ง **ํจ๊ป ๋์ด๋ค** โ ์๊ฒฉ DB ์์ ์ง๋ ฌ๋ก ๋๋ฉด ์๋ณต ์ง์ฐ์ด ๊ทธ๋๋ก ์์ธ๋ค.\n *\n * ๋๋ผ์ด๋ฒ ๋ค์ฏ์ ๋ค ์ง๋๊ฐ์ผ ํ๋ฏ๋ก raw SQL ์ ์ฐ์ง ์๋๋ค(์ฟผ๋ฆฌ๋น๋์ MIN/MAX ๋ ์ด์๋๋ค).\n * ๋๋ ค์ฃผ๋ ๊ฐ์ **๋ชจ์์ ๋๋ผ์ด๋ฒ๋ง๋ค ๋ค๋ฅด๋ค**(๋ฌธ์์ดยทDate) โ ๋ฐ์ ๋ค์ ํ ๋ฒ ์ ๊ทํํ๋ค(`parseTime`).\n */\n static async timeRange(domainId: string, spaceId: string): Promise<{ minTime: string | null; maxTime: string | null }> {\n const regs = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n const ids = regs.map(r => r.instanceId)\n if (!ids.length) return { minTime: null, maxTime: null }\n\n /**\n * ํ ํธ์ ์ ๋์ ์๊ฐ ์ ๋ ํ๋ โ ๋จ์ผ ์ง๊ณ๋ผ ์ธ๋ฑ์ค ๋์ ์ง๋๋ค.\n *\n * ์ง๊ณ์์ **์กฐ๋ฆฝํ์ง ์๊ณ ํ์ ๋ฆฌํฐ๋ด๋ก ์ ๋๋ค.** `` `${agg}(e.eventTime)` `` ๋ก ๋ง๋ค๋ฉด ์ด ์๋ฆฌ๊ฐ\n * ์ง๊ณ๋ฅผ ์ฐ๋์ง ํ๋ ๊ฒ์ฌ(`journal-read-discipline`)๊ฐ ์ฐพ์ง ๋ชปํ๋ค โ ์ค์ ๋ก ๊ทธ๋ ๊ฒ ๋นจ๊ฐ์ก๋ค.\n * ๋ฒ์ญ ํค์์ ๊ฒช์ ๊ฒ๊ณผ ๊ฐ์ ๊ท์จ์ด๋ค: ๊ฒ์ฌ๊ฐ ์ผํ๊ฒ ๋๋ ํธ์ด ๋ซ๋ค.\n */\n const AGG_SELECT = { MIN: 'MIN(e.eventTime)', MAX: 'MAX(e.eventTime)' } as const\n const edge = async (instanceId: string, agg: 'MIN' | 'MAX'): Promise<number | null> => {\n const row = await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select(AGG_SELECT[agg], 't')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .getRawOne<{ t: unknown }>()\n return parseTime(row?.t)\n }\n\n let min = Infinity\n let max = -Infinity\n\n /*\n * ํ ๋ฒ์ ๋์ฐ๋ ์๋ฅผ ๋ฌถ๋๋ค โ ๊ณต๊ฐ์ ํธ์์ด ์๋ฐฑ์ด๋ฉด ์๋ณต ์๋ฐฑ ๊ฐ๋ฅผ ๋์์ ๋ณด๋ด ์ปค๋ฅ์
ํ์\n * ๋ง๋ ค ๋ฒ๋ฆฐ๋ค(์ด ํจ์ ํ๋ ๋๋ฌธ์ ๋ค๋ฅธ ์ง์๊ฐ ๊ธฐ๋ค๋ฆฌ๊ฒ ๋๋ค).\n */\n for (let i = 0; i < ids.length; i += TIME_RANGE_FANOUT) {\n const batch = ids.slice(i, i + TIME_RANGE_FANOUT)\n const edges = await Promise.all(batch.flatMap(id => [edge(id, 'MIN'), edge(id, 'MAX')]))\n for (let k = 0; k < edges.length; k += 2) {\n const lo = edges[k]\n const hi = edges[k + 1]\n if (lo !== null && lo < min) min = lo\n if (hi !== null && hi > max) max = hi\n }\n }\n\n if (min === Infinity) return { minTime: null, maxTime: null }\n return { minTime: new Date(min).toISOString(), maxTime: new Date(max).toISOString() }\n }\n\n /** ์ ์ง ํ
โ ์ธ์คํด์ค ์ ์ง ์ ๋ถ์์์ ์ ๋ฆฌ(์: reference-live ํผ๋ unsubscribe). ์ํ ์ํฌํธ ์์ด ๊ฒฐ์ . */\n static stopHooks: ((id: string) => void)[] = []\n static onStop(fn: (id: string) => void): void {\n this.stopHooks.push(fn)\n }\n\n static async stop(domainId: string, id: string): Promise<void> {\n const i = this.instances[runtimeKey(domainId, id)]\n if (i) {\n /*\n * **๋๊ธฐ ์ ์ ๋จ๊ธด๋ค** โ ์ง๊ธ์ด ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ง์ค์ธ ๋ง์ง๋ง ์๊ฐ์ด๋ค.\n *\n * ๋จ๊ธฐ์ง ์์ผ๋ฉด ๋ค์ ์กฐํ๊ฐ ์ ๋์ ์ ๋ ๋ค์ ์ ๋๋ค(๊ทธ ๊ฐ์ ์ด์ฐจํผ ๋ฐฉ๊ธ ๋ฉ๋ชจ๋ฆฌ์ ์๋ ๊ฒ์ด๋ค).\n * ์ฒดํฌํฌ์ธํธ ๋ฃจํ๊ฐ 20์ด๋ง๋ค ๋จ์ง๋ง ๊ทธ ์ฌ์ด์ ๋ฉ์ถ๋ฉด ๊ทธ ๊ตฌ๊ฐ์ด ํต์งธ๋ก ๋ค์ ์ ํ๋ค.\n */\n await this.persistSnapshot(domainId, id).catch(err =>\n twinError(`[twin-engine] snapshot on stop fail \"${id}\"`, err?.message ?? err)\n )\n /*\n * **๋ชจ์ ๋ ์ ๋๋ ์ง๊ธ ํ๋ฆฐ๋ค** โ ์ฃผ๊ธฐ flush ์ฌ์ด(์ต๋ `BROADCAST_COALESCE_MS`)์ ๋ฉ์ถ๋ฉด ๊ทธ ๊ตฌ๊ฐ์\n * ์ฌ์ค์ด ์ฌ๋ผ์ง๋ค. ์ค๋
์ท๋ง ๋จ๊ธฐ๋ฉด ์ํ๋ ์ด์๋ **์ ๊ทธ๋ ๊ฒ ๋๋์ง**๊ฐ ๋น๋ค(์ ๋์ด ๋ตํ๋ ๊ฒ์ด๋ค).\n * ์ฐ๊ธฐ๋ ์ด ํจ์๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์์ง๋ง(๋น์ฐจ๋จ) ๋ฒํผ๋ ์ฌ๊ธฐ์ ๋น์์ง๋ฏ๋ก ๋ค์ ๊ธฐ๋์ด ๋ ๋ฒ ์ ์ง ์๋๋ค.\n */\n await this.flushJournal(i)\n clearInterval(i.timer)\n i.unsub()\n delete this.instances[runtimeKey(domainId, id)]\n await getRepository(TwinInstance)\n .update({ domain: { id: i.domainId }, instanceId: id }, { status: 'stopped' })\n .catch(err => twinError('twin deregister fail', err))\n }\n for (const hook of this.stopHooks) { try { hook(id) } catch { /* ํ
๊ฒฉ๋ฆฌ */ } }\n }\n\n /*\n * tick ํ ๋ฒ โ **ํ ํธ์์ ์์ธ๊ฐ ์๋ฒ๋ฅผ ๋ด๋ฆฌ์ง ๋ชปํ๊ฒ** ๊ฐ์ผ๋ค.\n *\n * ์๋ชป๋ ์๋๋ฆฌ์ค๊ฐ ์ค๋ ธ์ ๋ ๋ค์ tick ์์ `rate.meanPerHour` ๋ฅผ ์ฝ๋ค ํฐ์ก๊ณ , ํ์ด๋จธ ์ฝ๋ฐฑ์\n * ์์ธ๋ ์๋ฌด๋ ๋ฐ์ง ์์ **uncaught exception ์ผ๋ก ํ๋ก์ธ์ค๊ฐ ๋ด๋ ค๊ฐ๋ค.** ํ ํ
๋ํธ์ ์๋ชป๋\n * ์ ์ธ์ด ๋ชจ๋ ํ
๋ํธ๋ฅผ ๋ฉ์ถ ์
์ด๋ค. ๋ฌธ ์์์ ๋ง๋ ๊ฒ์ด 1์ฐจ ๋ฐฉ๋ฒฝ์ด๊ณ (`validateScenario`),\n * ์ด๊ฒ์ด 2์ฐจ ๋ฐฉ๋ฒฝ์ด๋ค.\n *\n * **์กฐ์ฉํ ์ผํค์ง ์๋๋ค.** ์คํ์ ๋ฉ์ถ๊ณ ๊ทธ ์ฌ์ค์ ๋จ๊ธด๋ค โ ์์ธ๋ฅผ ๋ฌด์ํ๊ณ ๊ณ์ tick ํ๋ฉด\n * ๊ฐ์ ์ค๋ฅ๊ฐ ๋งค ์ฃผ๊ธฐ ์์์ง๊ณ , ๊ทธ ํธ์์ \"๋๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๋ฉด์\" ์๋ฌด๊ฒ๋ ์งํํ์ง ์๋๋ค.\n */\n /**\n * ๊ฐ์ ํ์ฅ ํธ์๋ค์ **์ค๋น ์ํ**๋ฅผ ์ปค๋์ ๋๊ธด๋ค โ ์ปค๋์ด ์์ฒญํ ๋๋ง.\n *\n * โโ ๊ฒฝ๊ณ (2026-08-14) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํธ์คํธ๊ฐ ์๋ ๊ฒ์ **๋๊ฐ ๊ฐ์ ํ์ฅ์ ์๋๊ฐ** ํ๋๋ค. ๋ฌด์์ ์ฝ๊ณ ๊ทธ๊ฒ์ ์ด๋ป๊ฒ ๋ถํ๋ก ๋ฐ๊ฟ์ง๋\n * ์ปค๋์ด ์ ํ๋ค(๊ณ์๋ ํธ์์ ๋ชจ๋ธ์ด ์ ์ธํ๋ค). ํธ์คํธ๊ฐ kW ๋ฅผ ๊ณ์ฐํด ์ฃผ๋ฉด ํธ์๋ง๋ค ๋ค๋ฅธ ๊ท์น์ด\n * ์๊ธฐ๊ณ , ๊ทธ ๊ท์น์ ์ด๋์๋ ์ ํ ์์ง ์๊ฒ ๋๋ค.\n *\n * ์ํ๋ง ๋๊ธด๋ค. ์ค๋
์ท์ ํต์งธ๋ก ๋๊ธฐ๋ฉด ์ํ ํฌ๊ธฐ์ ๋น๋กํ ๋น์ฉ์ ๋งค tick ์น๋ฅด๊ฒ ๋๋ค โ\n * ์ค๋น ๋ชฉ๋ก์ ๊ทธ ํธ์์ ์ปค๋์ด ์ด๋ฏธ ๋ค๊ณ ์๋ ๊ฒ์ด๋ผ ํ๋ ๊ฐ์ด ์ธ๋ค.\n */\n private static feedPeerEquipment(inst: InstanceRuntime): void {\n const kernel: any = inst.kernel\n if (typeof kernel?.observePeerEquipment !== 'function') return // ์ด์์ ์ฝ์ง ์๋ ์ปค๋\n if (!inst.spaceId) {\n kernel.observePeerEquipment([]) // ํ์ฅ์ด ์์ผ๋ฉด ์ด์๋ ์๋ค(์ ์ํ๊ฐ ๋จ์ง ์๊ฒ ๋น์ด๋ค)\n return\n }\n const peers: { id: string; status?: string }[] = []\n for (const other of Object.values(this.instances)) {\n if (other === inst || other.domainId !== inst.domainId || other.spaceId !== inst.spaceId) continue\n const eq: Map<string, any> | undefined = (other.kernel as any)?.equipment\n if (!eq || typeof eq.forEach !== 'function') continue\n eq.forEach(e => peers.push({ id: String(e?.id ?? ''), status: String(e?.status ?? '') }))\n }\n kernel.observePeerEquipment(peers)\n }\n\n private static tickGuarded(domainId: string, id: string, runtime: TwinRuntimeType): void {\n const inst = this.instances[runtimeKey(domainId, id)]\n const load = inst && (inst.load ?? (inst.load = newLoadMeter()))\n const t0 = performance.now()\n try {\n /* ์ด์์ ์ค๋น ์ํ๋ฅผ ๋จผ์ ์ฃ๋๋ค โ ์ปค๋์ด ์ด๋ฒ tick ์์ ๋ถํ๋ฅผ ๋ง๋ค ๋ ์ฝ๋๋ค. */\n if (inst) this.feedPeerEquipment(inst)\n runtime.tick(this.TICK_MS)\n\n /* ์ฌ๊ณ ๋งํ๋ค โ ์๋ฎฌ ํฑ์ ๋ฉ์ธ ์ด๋ฒคํธ ๋ฃจํ์์ ์ํ๋๋ค. ์์ฐ(๊ฐ๊ฒฉ์ ์ ๋ฐ)์ ๋๊ธฐ๋ฉด HTTPยท๊ตฌ๋
์ด\n ํจ๊ป ๋๋ ค์ง๋๋ฐ, ์์ ์๋ ๊ทธ๊ฒ์ ๋ณผ ๊ณ๊ธฐํ์ด ์์ด \"ํฐ์ง๋ฉด ์๊ณ ๋๋ ค์ง๋ฉด ๋ชฐ๋๋ค\". */\n if (load) {\n const took = performance.now() - t0\n recordPhase(load, 'tick', took)\n const j = judgeCycle(load, took, this.TICK_MS, Date.now())\n if (j.warn) twinWarn(slowTickMessage(id, took, j.budgetMs, load))\n this.guardStarvation(domainId, id, took)\n }\n } catch (err: any) {\n /*\n * ๋ฉ์ถ๋ ๊ธธ์ **ํ๋**๋ค(`stop`) โ ์์ ์๋ ํ์ด๋จธ๋ง ๊ป๋ค. ๊ทธ๋ฌ๋ฉด ๋ฑ๋ก๋ถ๋ ๊ณ์ `running` ์ด๋ผ\n * ๋งํ๊ณ (์๋ฌด ํฑ๋ ์๋ ์ฑ๋ก), ๋ถํ
์ฌ๊ฐ๋ ๊ทธ ๊ฑฐ์ง์ ๊ทผ๊ฑฐ๋ก ๋ค์ ์ธ์ด๋ค. ์ค๋
์ท ๋ณด์กดยทํผ๋ ์ ๋ฆฌยท\n * ๋ฑ๋ก๋ถ ๊ฐฑ์ ์ด ๋ชจ๋ `stop` ์์ ์๋ค.\n */\n this.stopWithNote(\n domainId,\n id,\n { code: 'tick-failed', params: { reason: String(err?.message ?? err) } },\n `[twin-engine] \"${id}\" tick failed โ this twin is stopped (other twins keep running). ` +\n `Fix the declaration and start it again. Reason: ${err?.message ?? err}`\n )\n }\n }\n\n /**\n * ํธ์คํธ๋ฅผ ๊ตถ๊ธฐ๋ ํธ์์ ๋ฉ์ถ๋ค โ **๋๋ ์ฒํ๋ ๊ฒ๋ณด๋ค ๋ฉ์ถ ๊ฒ์ด ๋ซ๋ค.**\n *\n * ๊ตถ๊น ๋ฌธํฑ์ ๋๋ ํฑ์ด ์ฐ์ `STARVE_STREAK` ๋ฒ์ด๋ฉด ๊ทธ ํธ์์ ๊ตฌ์กฐ์ ์ผ๋ก ๋ฌด๊ฒ๋ค(์ฐ์ฐ์ด ์๋๋ค).\n * ๋ฌธํฑ ์๋๋ก ํ ๋ฒ๋ง ๋ด๋ ค์๋ ์ฐ์์ ๋๋๋ค โ ๋ฌด๊ฑฐ์ด ์๊ฐ ํ๋๋ก ํธ์์ ๋ด๋ฆฌ์ง ์๋๋ค.\n */\n private static guardStarvation(domainId: string, id: string, tookMs: number): void {\n const key = runtimeKey(domainId, id)\n const starveMs = this.TICK_MS * this.STARVE_FACTOR\n if (!(tookMs >= starveMs)) {\n this.starveStreak.delete(key)\n return\n }\n const streak = (this.starveStreak.get(key) ?? 0) + 1\n this.starveStreak.set(key, streak)\n if (streak < this.STARVE_STREAK) return\n\n this.starveStreak.delete(key)\n const secs = Math.round(tookMs) / 1000\n this.stopWithNote(\n domainId,\n id,\n { code: 'starved', params: { streak, thresholdSec: starveMs / 1000, lastSec: secs } },\n `[twin-engine] \"${id}\" stopped โ ${streak} consecutive ticks over ${starveMs / 1000}s (last ${secs}s). ` +\n `A simulation tick runs on the main loop, so this twin was stalling HTTP, subscriptions and every other twin. ` +\n `Its state is checkpointed; start it again after making it lighter (fewer orders/resources) or wait for off-loop ticking.`\n )\n }\n\n /** ๋ฉ์ถ๊ณ **์ด์ ๋ฅผ ๋จ๊ธด๋ค** โ ์ด์ ์๋ ใ์ ์งใ๋ ์ฌ๋์ด ์๊ธฐ๊ฐ ๋ฉ์ถ ๊ฒ์ผ๋ก ์ฝ๋๋ค. */\n private static stopWithNote(domainId: string, id: string, note: StopNote, log: string): void {\n twinError(log)\n this.stopNotes.set(runtimeKey(domainId, id), note)\n this.stop(domainId, id).catch(err => twinError(`[twin-engine] stop after guard failed \"${id}\"`, err?.message ?? err))\n }\n\n /** ์ด ํธ์์ด ์ค์ค๋ก ๋ฉ์ถ ์ด์ (์์ผ๋ฉด) โ ํ๋ฉด์ด ์ฎ๊ฒจ ๋งํ๋ค. */\n static stopNoteOf(domainId: string, id: string): StopNote | undefined {\n return this.stopNotes.get(runtimeKey(domainId, id))\n }\n\n /**\n * ์ด ํธ์์ด **์ง๊ธ ์คํ ์ค์ธ๊ฐ** โ ํ์ ์ ์ง ํ๋.\n *\n * \"์ค๋
์ท์ด ์๋\" ๋ก๋ ๋ต์ด ๋์ง ์๋๋ค: ์์คํํธ๊ฐ ๋์ด๋ฆฐ ์ํ๊ฐ ์บ์์ ๋จ์ ์์ผ๋ฉด ๋ฉ์ถ ํธ์๋\n * ์ค๋
์ท์ ๋ธ๋ค. ๊ทธ๊ฒ์ ๊ด์ธก ์ค์ผ๋ก ์ฝ์ผ๋ฉด ํ๋ฉด์ด **๋ฉ์ถ ํธ์์ ์์
์ 0 ๊ฑด์ด๋ผ๊ณ ๋จ์ธ**ํ๋ค\n * (์ค์ ๋ก ๊ทธ๋ ๊ฒ ๋์๋ค โ ๊ด์ธก์ด ์๋ ๊ฒ๊ณผ 0 ๊ฑด์ ๋ค๋ฅด๋ค๋ ์ด ํ๋ก์ ํธ์ ๊ท์จ์ ํ๋ฉด์ด ์ด๊ฒผ๋ค).\n *\n * ๋ชฉ๋ก์ด ์ฐ๋ ๊ฒ๊ณผ **๊ฐ์ ์ ์ด**๋ค(`list()` ์ `running`) โ ๋ ๋ฒ์ด๋ฉด ์ด๊ธ๋๋ค.\n */\n static isRunning(domainId: string, id: string): boolean {\n return !!this.instances[runtimeKey(domainId, id)]\n }\n\n static runtime(domainId: string, id: string): TwinRuntimeType | undefined {\n return this.instances[runtimeKey(domainId, id)]?.runtime\n }\n\n /*\n * ์ปค๋งจ๋ ์คํ โ **ํ์ ์ `routeCommand`(์์)๊ฐ ํ๊ณ ์ฌ๊ธฐ์๋ ์คํ๋ง** ํ๋ค.\n * ํ์ ์ ์ฝ๋ ํ๊ฐ์ด๋ฐ ๋๋ฉด ์ด ๋ถ๋ฅ๋ฅผ ํ
์คํธ๋ก ๋ชป ์ก๋๋ค(์์ง์ DB ๋ฅผ ๋ฌผ๊ณ ์์ด ๋จ์ ํ
์คํธ๊ฐ\n * ๋ถ๋ฌ์ฌ ์ ์๋ค). ์์ ์๋ ๋ฆฌ์กธ๋ฒ๊ฐ `inst.runtime.dispatch` ๋ฅผ ๊ณง๋ฐ๋ก ๋ถ๋ฌ ๋ฏธ๋ฌ์์ ํฐ์ก๋ค.\n */\n static async dispatchCommand(domainId: string, instanceId: string, command: any): Promise<{ accepted: boolean; error?: string; errorCode?: string; errorParams?: Record<string, string | number> }> {\n const inst = this.instances[runtimeKey(domainId, instanceId)]\n const type = String(command?.type ?? '')\n const route = routeCommand(\n inst && { mode: inst.mode, hasRuntime: !!inst.runtime, hasKernelDispatch: typeof (inst.kernel as any)?.dispatch === 'function' },\n !!inst && inst.domainId === domainId,\n type\n )\n if (route.target === 'reject') {\n return { accepted: false, errorCode: route.errorCode, errorParams: route.errorParams, error: route.errorCode }\n }\n\n const cmd = { ...command, tenantId: domainId } // tenantId ๋ ํธ์ถ์ ๋๋ฉ์ธ์ผ๋ก ๊ฐ์ธ(๊ฐ์ฌยท๋ฌด๊ฒฐ์ฑ)\n if (route.target === 'runtime') return inst!.runtime!.dispatch(cmd)\n\n /*\n * ๋ฏธ๋ฌ โ ๊ด์ธก ์ปค๋๋ก ๋ณด๋ด๊ณ , **์ปค๋งจ๋๊ฐ ๋ธ ์ฌ์ค์ ์ ๋ ํ์ ์ค์ด** ์ฝ์ผ๋ ์๊ฐ ๋ฒํธ๋ฅผ ๋ถ์ฌํ๊ฒ ํ๋ค.\n * ๋ฏธ๋ฌ์๋ State ๊ตฌ๋
๋ฐฐ๊ด์ด ์์ด(์๋ฎฌ์ ๊ทธ ๊ฒฝ๋ก๋ก ์ ๋๋ง) ์ปค๋ ๋ฐฉ์ถ์ด ์๋ฌด ๋ฐ๋ ๋ฟ์ง ์๋๋ค.\n * ์ฌ๊ธฐ์ DB ๋ฅผ ๋ฐ๋ก ์ฝ์ด ๋ฒํธ๋ฅผ ๋งค๊ธฐ๋ฉด ์ธ๋ฉ๋ชจ๋ฆฌ ์นด์ดํฐ์ ์ด๊ธ๋ ๋ฆฌ๋น์ ์ด ๊ฒน์น๋ค(๊ฒน์นจ์ ์ค๋ฅ๋ฅผ\n * ๋ด์ง ์๊ณ ์ฌ์ ์์๋ง ์กฐ์ฉํ ๋ค์๋๋ค).\n */\n const kernel: any = inst!.kernel\n const emitted: any[] = []\n const off = kernel.onEvent?.((e: any) => emitted.push(e))\n let ack: any\n try {\n ack = kernel.dispatch(cmd)\n } finally {\n off?.()\n }\n if (ack?.accepted && emitted.length) {\n inst!.pendingJournal = [...(inst!.pendingJournal ?? []), ...emitted]\n inst!.dirty = true // ์ฝ์ผ๋ ์๊ฐ ์ด๋ฒ ์ฃผ๊ธฐ์ ๋น์ฐ๊ณ ๋ธ๋ก๋์บ์คํ
๊น์ง ํ๊ฒ ํ๋ค\n }\n return ack ?? { accepted: false, errorCode: 'unknown-command', error: 'unknown-command' }\n }\n\n /**\n * ๋๋ฉ์ธ ์์ ๊ฒ์ดํธ โ ์ธ์คํด์ค๊ฐ ์ด ๋๋ฉ์ธ ์์ ์ผ ๋๋ง true(ํ
๋ํธ ๊ฒฉ๋ฆฌ).\n * ์๊ฑฐ๋ ๋ค๋ฅธ ๋๋ฉ์ธ์ด๋ฉด false. ๋
ธ์ถ ๋ฆฌ์กธ๋ฒ(per-id metrics/attentions/state/stop/forecast)๊ฐ\n * this.instances[id] ๋ฅผ ๋ง์ง๊ธฐ ์ ์ ๋ฐ๋์ ์ด๊ฑธ๋ก ํ์ธํด์ผ ํ๋ค. ์ธ์คํด์ค id ๋ ์ถ์ธก ๊ฐ๋ฅํ๋ฏ๋ก\n * ๊ฒ์ฆ ์์ด ์ ๊ทผํ๋ฉด ํฌ๋ก์คํ
๋ํธ ์ฝ๊ธฐ/์ ์ง๊ฐ ๊ฐ๋ฅํด์ง๋ค.\n */\n /**\n * ์ด ๋ฐํ์์ **๊ด์ธก ๋ชจ๋** โ `'live'`(์ธ๋ถ ์ค๋ฌผ์ ๋ฏธ๋ฌ) ๋๋ `'sim'`(์ปค๋์ด ์คํํ๋ค). ๊ธฐ๋ ์ค์ด ์๋๋ฉด ์๋ค.\n *\n * ์๋น์ฒ๊ฐ `instances[id].mode` ๋ฅผ ์ง์ ์ฝ๋ ์๋ฆฌ๋ฅผ ๋์ ํ๋ค. ๋ ์ง์คํธ๋ฆฌ๋ฅผ ๋ฐ์ ์ด๋ฉด ๋๋ฉ์ธ ํ์ธ์ด\n * ์๋ฆฌ๋ง๋ค ์ ๊ฐ๊ฐ์ด ๋๊ณ , ์ค์ ๋ก ๊ทธ๋ ๊ฒ ๋๋ค(ํ
๋ํธ ๊ฒฉ๋ฆฌ ์ ์ ํ์ธ, 2026-08-06).\n */\n static modeOf(domainId: string, id: string): 'live' | 'sim' | undefined {\n return this.instances[runtimeKey(domainId, id)]?.mode\n }\n\n static owns(domainId: string, id: string): boolean {\n return !!this.instances[runtimeKey(domainId, id)]\n }\n\n /**\n * ์ด ํธ์์ด ์ด ํ
๋ํธ ๊ฒ์ธ๊ฐ โ **๋ ์๋ ์๋๋ .**\n *\n * `owns()` ๋ **๊ธฐ๋ ์ค์ธ** ๋ฐํ์๋ง ์๋ค. ๊ทธ๊ฒ์ ์ด๋ ฅ ์กฐํ์ ๊ด๋ฌธ์ผ๋ก ์ฐ๋ฉด, ๊บผ์ง ํธ์์ ์ ๋์\n * ์ฝ์ผ๋ ค ํ ๋ \"์ด ํ
๋ํธ์ ์๋ค\" ๋ ๋ต์ด ๋์์จ๋ค โ ๋ ๊ฐ์ง๊ฐ ํ๋ ธ๋ค. ์ฒซ์งธ, ์ ๋์ ํธ์์ด ๊บผ์ ธ\n * ์์ ๋ **๊ฐ์ฅ ํ์ํ ๊ฒ**์ด๋ค(๊ทธ๊ฒ ์ด๋ ฅ์ ์กด์ฌ ์ด์ ๋ค). ๋์งธ, ๊ทธ ๋ฌธ์ฅ์ ๋จ์ ๊ฒ์ด๋ผ๋ ๋ป์ด๋ผ\n * ์ฌ์ฉ์๊ฐ ๊ถํ ๋ฌธ์ ๋ก ์คํดํ๋ค. ์ค์ ๋ก๋ ๊ทธ๋ฅ ์คํ ์ค์ด ์๋ ๋ฟ์ด๋ค.\n *\n * ์์ ๋ **๋ฑ๋ก๋ถ**๊ฐ ์๋ค. ์ด๋ ฅยท์ง๊ณ์ฒ๋ผ ๋ฐํ์๊ณผ ๋ฌด๊ดํ ์ง๋ฌธ์ ์ด์ชฝ์ ๋ฌป๋๋ค.\n */\n static async ownsRegistered(domainId: string, instanceId: string): Promise<boolean> {\n if (this.owns(domainId, instanceId)) return true\n return !!(await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } }))\n }\n\n /**\n * **์ด ๊ณต๊ฐ์ ์ธ์คํด์ค๋ค** โ ํ ํ์ค์ ์ฌ๋ฌ ๋ ์ฆ๊ฐ ๋น์ถ๋ฏ๋ก, ๊ณต๊ฐ์ ๋ฌผ์ผ๋ฉด ๊ทธ ๋ ์ฆ ์ ๋ถ๋ฅผ ๋ตํ๋ค.\n *\n * ํ๋ฉด์ด ์ด ๊ท์น์ ์์ผ๋ก ์ง์ง ์๊ฒ ์๋ฒ๊ฐ ๋ตํ๋ค. ์์ธก ํ๋ฉด์ ๊ฐ์ ํ์ฅ์ **ํ ํ์ผ์์ ๋ ๋ฒ**\n * ๋ณต์ ํ๊ณ ์์๋ค(์ ์ฒด ๋ชฉ๋ก์ ๋ฐ์ ํด๋ผ์ด์ธํธ์์ ๊ฑธ๋ ๋ค) โ ๊ท์น์ด ํฉ์ด์ง๋ฉด ํ์ชฝ๋ง ๊ณ ์ณ์ง๋ค.\n *\n * ๋ ์์ง ์์ ๊ฒ๋ ํฌํจํ๋ค: ๊ณต๊ฐ์ ๋ฌด์์ด ์๋์ง๋ ๊ธฐ๋ ์ฌ๋ถ์ ๋ค๋ฅธ ์ฌ์ค์ด๋ค.\n */\n static async instanceIdsOfSpace(domainId: string, spaceId: string): Promise<string[]> {\n if (!spaceId) return []\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n return rows.map(r => r.instanceId).filter((x): x is string => !!x)\n }\n\n /**\n * **์ด ๊ณต๊ฐ์์ ๋ด์ผ ํ ๊ฒ** โ ๊ณต๊ฐ์ ๋ชจ๋ ๋ ์ฆ์์ ์ ํธ๋ฅผ ๋ชจ์๋ค.\n *\n * ํฉ์งํฉ์ด ๊ทธ๋๋ก ๋ป์ด ์๋ ์ ์ผํ ๋ ์ฆ๋ค(์์ธก์ ํฉ์น ์ ์๋ค โ P50 ๋ ๊ฐ๋ฅผ ๋ํ ์ ์๋ค).\n * ์ ๋ ฌยท์๋ผ๋ด๊ธฐ๋ ํ๋ฉด๊ณผ **๊ฐ์ ๊ท์น**์ ์ด๋ค(`digestAttentions`) โ ์๋ฒ๊ฐ ๊ณ ๋ฅธ ์์ N ์ด ํ๋ฉด์ด\n * ๊ณ ๋ฅผ N ๊ณผ ๋ฌ๋ผ์ง๋ฉด ๊ทธ ์ด๊ธ๋จ์ ์๋ฌด ๋ฐ์๋ ์ค๋ฅ๋ก ๋๋ฌ๋์ง ์๋๋ค.\n *\n * ์ ํธ๋ง๋ค ์ด๋ ํธ์์์ ์๋์ง(`instanceId`)๋ฅผ ๋ถ์ธ๋ค. ๊ณต๊ฐ์์ ๋ณด๋ฉด ๊ฐ์ ์๋ฆฌ id ๊ฐ ๋ ์ฆ๋ง๋ค\n * ๋ค๋ฅธ ๊ฒ์ ๊ฐ๋ฆฌํฌ ์ ์๊ณ , ์กฐ์น๋ ๊ฒฐ๊ตญ ๊ทธ ํธ์์ ๋ณด๋ด์ผ ํ๋ค.\n */\n static async attentionsOfSpace(domainId: string, spaceId: string, limit?: number): Promise<{ attentions: any[]; attentionTotal: number; severityByLocation: Record<string, string> }> {\n const ids = await this.instanceIdsOfSpace(domainId, spaceId)\n const lenses = ids\n /* ๋ ์์ง ์์ ํธ์์ **์ง๊ธ** ์ ํธ๊ฐ ์๋ค(๊ทธ ์์ ์ ํธ๋ ์๊ฐ์ฌํ์ด ๋ตํ๋ค). */\n .filter(id => this.owns(domainId, id))\n .map(id => {\n const kernel: any = this.kernel(domainId, id)\n const snap = kernel?.getSnapshot?.() ?? this.snapshot(domainId, id)\n return { instanceId: id, attentions: snap?.attentions ?? [] }\n })\n /* ๋ชจ์ผ๋ ๊ท์น(ํ๊น
ยท๊ธํ ์์ยท์๋ฆฌ ์)์ ์์ ํจ์๊ฐ ๋ค๊ณ ์๋ค โ ์ฌ๊ธฐ์ ์์ผ๋ก ์ ์ง ์๋๋ค. */\n return mergeLensAttentions(lenses, limit)\n }\n\n /** ๋ผ์ด๋ธ ์ปค๋(ForecastTwin) โ forecast/divergence ์์ธก ์ฐ์ฐ์ฉ. */\n static kernel(domainId: string, id: string): any {\n return this.instances[runtimeKey(domainId, id)]?.kernel\n }\n\n /** ๋ผ์ด๋ธ ์ฒ๋ฆฌ๋ ๊ณ์ธก ์ค๋
์ท(๋ชจ๋ํฐ, โฃ-1) โ ๋ด๋ถ ๋์ (_acc*) ์ ์ธํ ๊ณต๊ฐ ์งํ. live ์๋๋ฉด null. */\n static metrics(domainId: string, id: string): any {\n const m = this.instances[runtimeKey(domainId, id)]?.metrics\n if (!m) return null\n return {\n instanceId: id,\n ingestedTotal: m.ingestedTotal, broadcastTotal: m.broadcastTotal, journaledTotal: m.journaledTotal,\n ingestRate: m.ingestRate, broadcastRate: m.broadcastRate, journalRate: m.journalRate,\n backlog: m.backlog, broadcastCoalesceMs: this.broadcastPeriodMs,\n /* ์์
๋ณ ๋ถํ โ ๋ฌด๊ฑฐ์ด ๊ฒ๋ถํฐ. ์ฐ ์ ์ด ์์ผ๋ฉด null(0 ์ผ๋ก ์ฑ์ฐ๋ฉด \"๋น ๋ฅด๋ค\" ๋ก ์ฝํ๋ค). */\n load: loadSummary(this.instances[runtimeKey(domainId, id)]?.load, this.TICK_MS)\n }\n }\n\n /**\n * ๋ถํ ๊ณ๊ธฐํ๋ง ๋ฐ๋ก โ **์๋ฎฌ ํธ์๋ ํฌํจํ๋ค.**\n *\n * `metrics()` ๋ ๋ผ์ด๋ธ ์งํ(`inst.metrics`)๊ฐ ์์ด์ผ ๋ฌด์ธ๊ฐ๋ฅผ ๋๋ ค์ค๋ค. ๊ทธ๋ฐ๋ฐ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ์ ์ ํ๋\n * ๊ฒ์ ์ฃผ๋ก **์๋ฎฌ ํฑ**์ด๊ณ , ์๋ฎฌ ์ธ์คํด์ค์๋ ๊ทธ ์งํ๊ฐ ์์ด ํต์งธ๋ก ์ ๋ณด์๋ค.\n */\n static load(domainId: string, id: string): any {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (!inst) return null\n\n return {\n instanceId: id,\n mode: inst.mode ?? 'sim',\n domainId: inst.domainId,\n domainLabel: inst.domain?.subdomain,\n restartPolicy: inst.restartPolicy,\n tickMs: this.TICK_MS,\n running: !!inst.timer || inst.mode === 'live',\n ...(loadSummary(inst.load, this.TICK_MS) ?? { recent: null, total: null, forksCreated: 0, overBudget: 0, budgetMs: this.TICK_MS * 0.5, loadRatio: null })\n }\n }\n\n /**\n * **ํ ๊ณณ์์ ๋ณด๋ ์ ์ฒด ๋ถํ** โ ๋ช ๊ฐ๊ฐ ์คํ ์ค์ด๊ณ , ๋๊ฐ ๋ฃจํ๋ฅผ ์ ์ ํ๊ณ ์๋.\n *\n * ์๋ฎฌ ํธ์๋ ํฌํจํ๋ค(`metrics()` ๋ ๋ผ์ด๋ธ ์งํ๊ฐ ์์ด์ผ ๋ตํด์ ์๋ฎฌ์ด ํต์งธ๋ก ์ ๋ณด์๋ค).\n */\n static fleet(domainId?: string): any {\n const keys = Object.keys(this.instances).filter(key => !domainId || isOfDomain(key, domainId))\n const rows = keys.map(key => {\n const at = parseRuntimeKey(key)\n const inst = this.instances[key]\n /* ๋๋ฉ์ธ์ ํจ๊ป ๋๊ธด๋ค โ ์ด์์๊ฐ ๋จผ์ ๋ฌป๋ ๊ฒ์ \"์ด๋ ํ
๋ํธ๊ฐ ๋ฃจํ๋ฅผ ๋จน๋\" ๋ค.\n ์ฝ์ ์ ์๋ ์ด๋ฆ(subdomain)์ ๋ผ์ด๋ธ ์ธ์คํด์ค์๋ง ๋ถ์ด ์์ผ๋ฏ๋ก, ์์ผ๋ฉด ๋ฆฌ์กธ๋ฒ๊ฐ ์ฑ์ด๋ค. */\n return {\n instanceId: at.instanceId,\n mode: inst.mode ?? 'sim',\n domainId: at.domainId,\n domainLabel: inst.domain?.subdomain,\n meter: inst.load\n }\n })\n\n return {\n tickMs: this.TICK_MS,\n broadcastCoalesceMs: this.broadcastPeriodMs,\n /* ๋ธ๋ก๋์บ์คํ
์ฃผ๊ธฐ๋ฅผ ๋๋ฆฐ ํ์ โ ๋์ด๋ ์ฃผ๊ธฐ๋ง ๋ณด๋ฉด ใ์๋ ๊ทธ๋ฐ ๊ฐใ์ผ๋ก ์ฝํ๋ค. */\n broadcastBackoffs: this.broadcastBackoffs,\n /* ๋ฌผํ ๋ฒ์๋ฅผ ์ขํ์ง ๋ชปํด ์ ๋ถ ๋ง๋ ํ์ โ ์ขํ๊ธฐ๊ฐ ์ค์ ๋ก ๋ฃ๊ณ ์๋์ง๋ฅผ ์ด ๊ฐ์ผ๋ก ๋ณธ๋ค. */\n broadcastPasses: this.broadcastPasses,\n broadcastFullPasses: this.broadcastFullPasses,\n broadcastFullEvery: this.FULL_BROADCAST_EVERY,\n /* **๋ฃจํ๊ฐ ์ค์ ๋ก ์ผ๋ง๋ ๋งํ๋** โ ํธ์ ๋ถํ์ ๋๋ํ ๋๊ณ ์์ธ์ ๊ฐ๋ฆฐ๋ค(loop-lag.ts ์ฃผ์). */\n loopLag: loopLag.view(),\n ...fleetLoad(rows, this.TICK_MS),\n /* ์ค๋ง๋ค ์์ธ โ ํ๋ฉด์ด ํผ์ณ ๋ณผ ์ ์๊ฒ. ์ต๊ทผ ๋ถํ ์์๋ fleetLoad ๊ฐ ์ ํ๋ค. */\n details: keys.map(key => { const at = parseRuntimeKey(key); return this.load(at.domainId, at.instanceId) }).filter(Boolean)\n }\n }\n\n /** ์ด ํธ์์์ fork ๊ฐ ๋ง๋ค์ด์ก๋ค โ ์์ธก ํ ๋ฒ์ด ์์ญ ๊ฐ๋ฅผ ๋ง๋ ๋ค. */\n static countForks(domainId: string, id: string, count: number): void {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (inst) recordFork(inst.load ?? (inst.load = newLoadMeter()), count)\n }\n\n /** ์์ง ๋ฐ(์์ธก ์ง์ ๋ฑ)์์ ๋ฌด๊ฑฐ์ด ์์
์ ์ฐ๋ค โ ๊ฐ์ ๊ณ๊ธฐํ์ ๋ชจ์ธ๋ค. */\n static recordLoad(domainId: string, id: string, phase: LoadPhase, tookMs: number): void {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (inst) recordPhase(inst.load ?? (inst.load = newLoadMeter()), phase, tookMs)\n }\n\n /*\n * โโ ๋๊ธฐํ ๊ฑด๊ฐ ์ฅ๋ถ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n *\n * **๋ฐํ์์ด ์๋๋ผ ์์ง์ด ๋ ๋ค.** ์ธ์คํด์ค์ ๋ถ์ด๋ฉด ํธ์์ ์ฌ๊ธฐ๋ํ ๋ ์ฌ๋ผ์ง๋๋ฐ, ์ฌ๋์ด ์๊ณ ์ถ์\n * ๊ฒ์ ๋ฐ๋ก ๊ทธ ์๊ฐ์ด๋ค โ ใ๊ณ ์ณ์ ๋ค์ ๋์ ๋๋ฐ ์ด์ ํต๊ณผํ๋ใ. ํ๋ก์ธ์ค๊ฐ ์ฌ๋ ๋์ ์ด์ด์ง๋ค.\n *\n * ์ง๊ธ์ ๋ฉ๋ชจ๋ฆฌ๋ง์ด๋ค. ์ฐฝ์ด ๋ซํ ๋ ํ ํ์ฉ ์์ํ๋ ๊ฒ์ `onWindowClosed` ํ ์๋ฆฌ์ ๋ถ๋๋ค.\n */\n private static ingestLedgers: Record<string, IngestLedger> = {}\n\n /** ์ฐฝ์ด ๋ซํ ๋ ๋ถ๋ฅผ ๊ณณ โ ์์ ๊ณ์ธต์ด ๋ถํ
์์ ํ ๋ฒ ๋ฑ๋กํ๋ค(์ปค๋ ์ธต์ ๊ทธ ๊ณ์ธต์ ๋ชจ๋ฅธ๋ค). */\n private static onWindowClosed?: (at: { domainId: string; instanceId: string }, closed: IngestWindow) => void\n\n /**\n * ๋ซํ ์ฐฝ์ ๋ฐ์ ๊ณณ์ ๋ฑ๋กํ๋ค โ **์์(B)์ด ๋ถ๋ ์ ์ผํ ๋ฌธ.**\n *\n * ์ด ํจํค์ง๋ ์ ์ฅ ๊ณ์ธต์ ๋ชจ๋ฅธ๋ค. ๋ฑ๋กํ๋ ์ชฝ์ด ์๊ธฐ ๋ฐฉ์์ผ๋ก ์ด๋ค. ํ
์ด ์ค๋ฅ๋ฅผ ๋ด๋ ์ฅ๋ถ๋ ๊ณ์ ๊ตด๋ฌ๊ฐ๋ค\n * (`rollIngestWindow` ๊ฐ ๊ฐ์ผ๋ค) โ ์์์ ์งํค๋ ค๊ณ ๊ด์ธก์ ๋ฉ์ถ์ง ์๋๋ค.\n */\n static onIngestWindowClosed(\n fn: (at: { domainId: string; instanceId: string }, closed: IngestWindow) => void\n ): void {\n this.onWindowClosed = fn\n }\n\n /**\n * ํ ๋ฒ์ ์ธ์ ์คํธ ๊ฒฐ๊ณผ๋ฅผ ์ฅ๋ถ์ ์ ๋๋ค.\n *\n * `offered` ๋ **์ ์๋ ๋ ์ฝ๋ ์**๋ค(๊ฑฐ๋ถ ์ฌ๋ถ ๋ฌด๊ด). ํต๊ณผ์จ์ ์๋ก ๋ค๋ฅธ ๋ ๊ณ์๊ธฐ์์ ๋๋ ๊ณ์ฐํ๋ฉด\n * ๋ถ๋ชจ์ ๋ถ์๊ฐ ๋ค๋ฅธ ๊ฒ์ ์ธ๊ฒ ๋๋ฏ๋ก, ํ์๋ฆฌ์์ ๋ณธ ์๋ฅผ ๊ทธ๋๋ก ๋๊ธด๋ค.\n */\n static recordIngestResult(\n domainId: string,\n instanceId: string,\n offered: number,\n rejected: { record?: unknown; errors?: string[] }[] | undefined,\n nowMs = Date.now(),\n /**\n * ๋งคํ์ ํต๊ณผํ๋๋ฐ **์ปค๋์ด ๋ฐ์ง ์์** ์(`ingestLive` ์ ๋ฐํ๊ณผ ๊ฒฌ์ฃผ์ด ์ป๋๋ค).\n *\n * ใํต๊ณผใ๋ก ์ธ์ง ์๋๋ค โ ํธ์์ด ๋ฉ์ถ ์ฌ์ด ์ฌ์ค์ด ์ฌ๋ผ์ง๋๋ฐ ํ๋ฉด์ด 100% ๋ผ๊ณ ๋งํ๊ฒ ๋๋ค.\n */\n undelivered = 0\n ): void {\n const key = runtimeKey(domainId, instanceId)\n const ledger = this.ingestLedgers[key] ?? (this.ingestLedgers[key] = newIngestLedger())\n recordIngest(\n ledger,\n offered,\n rejected,\n nowMs,\n closed => this.onWindowClosed?.({ domainId, instanceId }, closed),\n undelivered\n )\n }\n\n /**\n * **์๋ณธ์ ๋ฟ์ง ๋ชปํ๋ค**๋ฅผ ์ ๋๋ค โ ใ๋ฐ์ ๊ฒ์ด ์๋คใ์ ๊ฐ๋ฅธ๋ค(ยง`recordReadFailure`).\n *\n * ์ด ๋ฌธ์ด ์๋ ๋์ ์ค ์๋ณธ์ด ๋๊ฒจ๋ ํธ์์ ์กฐํ ๊ฐ๋ฅํ ์ํ์ ๊ทธ ์ฌ์ค์ด ์์๋ค. ํ๋ฉด์ด ๋ณผ ์ ์๋\n * ๊ฒ์ ใ์ ์ฌ์ค์ด ์๋คใ๋ฟ์ด์๊ณ ๊ทธ๊ฒ์ ใ์๋ณธ์ด ์กฐ์ฉํ๋คใ์ ๊ตฌ๋ณ๋์ง ์๋๋ค โ ์ค์ฆ ์ค์ ์๋ณธ์ด\n * ๋๊ธฐ๋ฉด ์ฌ์ฉ์๊ฐ ์์ธ์ ์ฐพ์ ์ ์๋ค.\n *\n * ๋ก๊ทธ๋ก๋ ๋งํ๊ณ ์์๋ค(์ด๋ํฐ๊ฐ ์ฌ์๋๋ฅผ ๊ฒฝ๊ณ ํ๋ค). ๊ทธ๋ฌ๋ **๋ก๊ทธ๋ ์ฌ๋์ด ๋ณผ ๋๋ง ๊ฐ์ด ์๋ค** โ\n * ํ๋ฉด์ด ๋งํ๋ ค๋ฉด ์ํ์ ์์ด์ผ ํ๋ค.\n */\n static recordIngestReadFailure(domainId: string, instanceId: string, reason: string, nowMs = Date.now(), stream?: string): void {\n const key = runtimeKey(domainId, instanceId)\n const ledger = this.ingestLedgers[key] ?? (this.ingestLedgers[key] = newIngestLedger())\n recordReadFailure(ledger, reason, nowMs, stream)\n }\n\n /**\n * ์ฝ๊ธฐ๊ฐ ์ฑ๊ณตํ๋ค โ ๋จ์ ๊ธฐ๋ก์ ์ง์ด๋ค.\n *\n * **๋น ์ฝ๊ธฐ๋ ์ฑ๊ณต์ด๋ค.** ์๋ณธ์ด ใ์ ๊ฒ์ด ์๋คใ๊ณ ๋ตํ ๊ฒ์ ๋ฟ์๋ค๋ ๋ป์ด๋ฏ๋ก, ๊ทธ๋๋ ๋ถ๋ฅธ๋ค.\n * ๊ทธ ๋์ ๊ฐ๊ฒ ๋๋ฉด ์กฐ์ฉํ ์๋ณธ์ด ๋๊ธด ์๋ณธ์ผ๋ก ๋ณด์ธ๋ค.\n */\n static clearIngestReadFailure(domainId: string, instanceId: string): void {\n const ledger = this.ingestLedgers[runtimeKey(domainId, instanceId)]\n if (ledger) clearReadFailure(ledger)\n }\n\n /**\n * ์ ๋์ **์ ์ ๊ฒ**์ ๊ฐ์ ์ฅ๋ถ์ ๋จ๊ธด๋ค โ ์ ์
๊ณผ ๊ฐ์ 10๋ถ ์ฐฝ์.\n *\n * โโ ์ ์ ์
์ฅ๋ถ์ ๋ฃ๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ ์ฅ๋ถ๋ฅผ ๋ง๋ค๋ฉด ใ๋ซํ ์ฐฝ๋ง ์ต๊ทผใยทใ0 ๊ณผ ์์์ ๊ฐ๋ฅธ๋คใยท์์์ ๋ ๋ฒ ์ง์ผ์ผ ํ๊ณ , ๊ทธ์ค ํ ๋ฒ๋ง\n * ๊ณ ์ณ์ง๋ ๊ฒ์ด ๋ณดํต์ด๋ค. ์ ์
์ฐฝ์ ๊ทธ ๊ท์จ์ด ์ด๋ฏธ ๋ค์ด ์๊ณ ๋ซํ ๋ ํ์ผ๋ก ๋จ๋๋ค.\n *\n * โโ ์ด ๊ฐ์ด ์์ผ๋ฉด ๋ฌด์์ ๋ชป ๋ณด๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๊ณ๊ธฐ(`journalRate`)๋ **์ง๊ธ**๋ง ๋ตํ๋ค. ํ๋ก์ธ์ค๋ฅผ ๋ค์ ๋์ฐ๋ฉด 0 ์์ ์์ํ๋ฏ๋ก ใ์ด์ ์ด ์๊ฐ์๋\n * ์ด๋ฌ๋ใยทใ๊ณ ์น ๋ค๋ก ์ค์๋ใ๋ฅผ ๋ฌผ์ ์๋ฆฌ๊ฐ ์๋ค. 2026-08-20 ์ ๊ณ ์น ๊ฒ์ด ๋ฐ๋ก ์ฐ๊ธฐ ๊ฒฝ๋ก์ด๋ฏ๋ก,\n * ๋๋์๊ฐ๋ ๊ฒ์ ๋ณผ ์ ์์ด์ผ ํ๋ค.\n */\n static recordJournalWrite(domainId: string, instanceId: string, rows: number, nowMs = Date.now()): void {\n const key = runtimeKey(domainId, instanceId)\n const ledger = this.ingestLedgers[key] ?? (this.ingestLedgers[key] = newIngestLedger())\n recordLedgerWrite(ledger, rows, nowMs, closed => this.onWindowClosed?.({ domainId, instanceId }, closed))\n }\n\n /**\n * ใ์ด ํธ์์ด ํ์ฅ๊ณผ ๋ง์ถฐ์ง๊ณ ์๋ใ โ ํ๋ ํ์ + ์ถ์ด + ์ฌ์ + ํ๋ณธ.\n *\n * ์กฐํํ ๋ ์ฐฝ์ ํ ๋ฒ ๊ตด๋ฆฐ๋ค: ์ ์
์ด ๋ฉ์ถ๋ฉด ๋ค์ ์ธ์ ์คํธ๊ฐ ์์ด ์ฐฝ์ด ์์ํ ๋ซํ์ง ์๋๋ฐ, ๊ทธ๋ฌ๋ฉด\n * ใ์ต๊ทผใ์ด ์๊ฒ์ผ๋ก ๋จ๋๋ค. ํ์ด๋จธ๋ฅผ ๋์ง ์๋ ์ด์ ๋ ํธ์๋ง๋ค ํ์ด๋จธ๋ฅผ ๊ฑธ๋ฉด ๊ทธ ํ์ด๋จธ๋ค์ด ๋ค์\n * ๋ฉ์ธ ๋ฃจํ์ ์นํ๊ธฐ ๋๋ฌธ์ด๋ค(์ค๋ ํ์ธํ ๊ทธ ๋ถํ๋ฅผ ์ด ๊ธฐ๋ฅ์ด ๋ค์ ๋ง๋ค ์ด์ ๊ฐ ์๋ค).\n */\n /**\n * ๋๋ฉ์ธ์ ํธ์๋ง๋ค **ํ ์ค ์์ฝ** โ ๋ชฉ๋ก ํ๋ฉด๊ณผ ๋ฏธ๋ ์ถ์ด์ฉ.\n *\n * โโ ์ ์์ธ์ ๋ฐ๋ก์ธ๊ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * `ingestHealthOf` ๋ ์ฌ์ ๋ฌธ๊ตฌ์ **๋ ์ฝ๋ ์๋ฌธ ํ๋ณธ**๊น์ง ๋ธ๋ค. ๋ชฉ๋ก์ ํธ์์ด ์ค๋ฌด ๊ฐ๋ฉด ๊ทธ ์๋ฌธ์ด\n * ์ค๋ฌด ๋ฒ ์ค๋ ค ์กฐํ๊ฐ ๋ฌด๊ฑฐ์์ง๊ณ , ํ๋ฉด์ ์ด์ฐจํผ ๊ทธ๊ฒ์ ๊ทธ๋ฆฌ์ง ์๋๋ค. ๊ทธ๋์ ์ฌ๊ธฐ์๋ **์ซ์๋ง** ๋ธ๋ค.\n *\n * ์ถ์ด๋ ์ฐฝ๋น ์ซ์ ๋ท์ด๋ผ ์คํํฌ๋ผ์ธ ํ๋์ ์ถฉ๋ถํ๊ณ ๊ฐ๋ณ๋ค.\n *\n * โโ ๋ฑ๋ก๋ ํธ์์ ๊ธฐ์ค์ผ๋ก ํ๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๋๋ ํธ์๋ง ํ์ผ๋ฉด ใ๊ณ ์น๋ ค๊ณ ๋ฉ์ถฐ ๋ ํธ์ใ์ด ๋ชฉ๋ก์์ ์ฌ๋ผ์ง๋ค โ ์ฌ๋์ด ๋ฐฉ๊ธ ๋ฉ์ถ ๊ทธ๊ฒ์ ๋ณด๋ ค๊ณ \n * ๋ชฉ๋ก์ ์ฌ๋๋ฐ ์์ผ๋ฉด ๊ฒฐํจ์ผ๋ก ์ฝ๋๋ค. ๊ทธ๋์ ํธ์ถ๋ถ(๋ชฉ๋ก ํ๋ฉด)๊ฐ ์๋ instanceId ๋ค์ ๋ฐ๋๋ค.\n */\n static ingestHealthBrief(\n domainId: string,\n instanceIds: string[]\n ): { instanceId: string; verdict: string; acceptedRatio: number | null; trend: { offered: number; rejected: number; undelivered: number; rows: number }[]; lastAt: string | null }[] {\n return instanceIds.map(instanceId => {\n const full = this.ingestHealthOf(domainId, instanceId)\n return {\n instanceId,\n verdict: full.verdict,\n /* ์ต๊ทผ **๋ซํ** ์ฐฝ์ ํต๊ณผ์จ. ์ฐฝ์ด ์ ๋ซํ์ผ๋ฉด ๋น์ด๋ค โ 0 ์ด๋ 1 ๋ก ์ฑ์ฐ์ง ์๋๋ค. */\n acceptedRatio: full.recent?.acceptedRatio ?? null,\n /*\n * ์คํํฌ๋ผ์ธ์ฉ โ ์ฐฝ๋ง๋ค ์
. **๋ฏธ์ ๋ฌ์ ๋นผ๋์ผ๋ฉด ์คํํฌ๋ผ์ธ์ด ๊ฑฐ์ง์ ๊ทธ๋ฆฐ๋ค**: ๋ฒ๋ ค์ง ๊ฒ์\n * ํต๊ณผ๋ก ์ธ๋ฉด ํธ์์ด ๋ฉ์ถ ๊ตฌ๊ฐ์์๋ ์ ์ด 100% ์ ๋ถ๋๋ค.\n */\n /* ์ ํ ํ๋ ํจ๊ป โ ์๋ฎฌ ํธ์์ ์ ์
์ด 0 ์ด๋ผ ์ด ๊ฐ ์์ด๋ ์ถ์ด๊ฐ ๋น ์ ์ผ๋ก ๋ณด์ธ๋ค. */\n trend: full.trend.map(w => ({ offered: w.offered, rejected: w.rejected, undelivered: w.undelivered, rows: w.rows })),\n lastAt: full.lastAt\n }\n })\n }\n\n /**\n * ํ ํธ์์ ๋๊ธฐํ ๊ฑด๊ฐ.\n *\n * โโ ์กฐํ๊ฐ ์ฅ๋ถ๋ฅผ ์ ์ง์ํจ๋ค(์๋) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ฐฝ์ **๋ค์ ์ ์
์ด ์์ ๋** ๋ซํ๋ค. ๊ทธ๋์ ํผ๋๊ฐ ์ฃฝ์ผ๋ฉด ๋ง์ง๋ง ์ฐฝ์ด ์ด๋ฆฐ ์ฑ๋ก ๋จ์ ์์ํ ์์๋์ง\n * ์๊ณ , ์ถ์ด์๋ ๋ค์ด๊ฐ์ง ์๋๋ค. ์กฐํ ์์ ์ ํ ๋ฒ ๊ตด๋ ค ์ฃผ๋ฉด ๊ทธ ๋ง์ง๋ง ์ฐฝ์ด ๋ซํ๋ฉด์ ์์ ํ
๋ ๋ถ๋ฆฐ๋ค\n * โ ์ฆ **์ฃฝ์ ํผ๋์ ๋ง์ง๋ง ๊ตฌ๊ฐ์ ์์ง ์๊ธฐ ์ํด** ์ฝ๊ธฐ๊ฐ ๊ตด๋ฆฐ๋ค. ๋ถ์ํจ๊ณผ์ง๋ง ํ์ํ ๋ถ์ํจ๊ณผ๋ค.\n *\n * ์๊ฐ์ **ํ ๋ฒ๋ง ์ฝ์ด** ๊ตด๋ฆฌ๊ธฐ์ ํ์ ์ ๊ฐ์ ๊ฐ์ ์ด๋ค. ๋ ๋ฒ ์ฝ์ผ๋ฉด ๊ทธ ์ฌ์ด์ ์ฐฝ์ด ๋ซํ ํ์ ์ด\n * ๊ตด๋ฆฌ๊ธฐ ์ ์ํ๋ฅผ ๋ณด๋ ์ผ์ด ์๊ธด๋ค.\n */\n static ingestHealthOf(domainId: string, instanceId: string): IngestHealthView {\n const key = runtimeKey(domainId, instanceId)\n const nowMs = Date.now()\n const ledger = this.ingestLedgers[key]\n if (ledger) {\n rollIngestWindow(ledger, nowMs, undefined, closed => this.onWindowClosed?.({ domainId, instanceId }, closed))\n }\n\n const inst = this.instances[key]\n const feedState = liveFeedStateOf({\n restartPolicy: inst?.restartPolicy,\n running: !!inst,\n instanceId\n })\n return ingestHealth(ledger, feedState, undefined, nowMs)\n }\n\n /**\n * ๋๋ ์ธ์คํด์ค ์ ์ฒด์ ๊ณ์ธก(๋ชจ๋ํฐ ๋์๋ณด๋์ฉ) โ **์๋ฎฌ๊ณผ ๋ฏธ๋ฌ๋ฅผ ํจ๊ป**.\n *\n * ์์ ์๋ ์๋ฎฌ์ ๊ณ๊ธฐ๊ฐ ์์ด ์ด ๋ชฉ๋ก์์ ์กฐ์ฉํ ๋น ์ก๋ค(๊ณ๊ธฐ๊ฐ `null` ์ด๋ผ ๊ฑธ๋ฌ์ก๋ค). ๋๋ ํธ์\n * ๋๋ถ๋ถ์ด ์๋ฎฌ์ธ ์๋ฒ์์ ๊ทธ ๋ชฉ๋ก์ ใ๋ถํ๊ฐ ๊ฑฐ์ ์๋คใ๋ก ๋ณด์๋ค.\n */\n static async allMetrics(domainId?: string): Promise<any[]> {\n /* ๋๋ฉ์ธ ์์ด ๋ถ๋ฅด๋ฉด ์ ํ
๋ํธ๋ฅผ ํ๋๋ค(๋ด๋ถ ๋ชจ๋ํฐ์ฉ) โ ํค์์ ๋๋ฉ์ธ์ ๋๋๋ ค ๊ฐ์์๊ฒ ๋ฌป๋๋ค. */\n const rows = Object.keys(this.instances)\n .filter(key => !domainId || isOfDomain(key, domainId))\n .map(key => {\n const at = parseRuntimeKey(key)\n return this.metrics(at.domainId, at.instanceId)\n })\n .filter(Boolean)\n if (!rows.length || !domainId) return rows\n // ํ์ ์ด๋ฆ ๋ถ์ฌ โ ์คํ์ค ์นด๋๊ฐ id ๋ง ๋ณด์ด์ง ์๋๋ก ๊ณต๊ฐ๋ช
์ ์ค์ด์ค๋ค(๊ณต๊ฐ ์นด๋์ ๋์ผ). name=๊ณต๊ฐ๋ช
ํด๋ฐฑ spaceId ํด๋ฐฑ instanceId.\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const spaceOf = new Map(insts.map(i => [i.instanceId, i.spaceId]))\n /* ์ฉ๋ ์ ์ธ๋ ํจ๊ป ์ค์ด ๋ณด๋ธ๋ค โ ํ๋ฉด์ด ๊ณต๊ฐ ์ด๋ฆ์ผ๋ก ๋ฒค์น๋ฅผ **์ถ์ธกํ์ง ์๊ฒ** ํ๋ค.\n ์ถ์ธกํ๋ฉด `loadtest-` ๋ก ์ด๋ฆ ์ง์ ์ด์ ํธ์์ ๋ฒค์น ๋ฑ์ง๊ฐ ๋ถ๋๋ค. */\n const purposeOf = new Map(insts.map(i => [i.instanceId, i.purpose]))\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n for (const r of rows) {\n const sp = spaceOf.get(r.instanceId)\n r.spaceId = sp\n r.purpose = purposeOf.get(r.instanceId)\n r.name = (sp && nameOf.get(sp)) || sp || r.instanceId\n }\n return rows\n }\n\n /*\n * `buildForecastKernel` ์ **์ฌ๋ผ์ก๋ค**(ํตํฉ P3, 2026-08-01).\n *\n * ๋ผ์ด๋ธ๊ฐ `StateProjector` ์์ ๋๋ ์ปค๋์ด ์์ด์, ์์ธกํ๋ ค๋ฉด ๊ด์ธก ์ค๋
์ท + ์ ๋์ ์ค๋ ์๊ฐ์ผ๋ก\n * **์ผํ์ฉ ์ปค๋์ ์ธ์์ผ** ํ๋ค. ์ด์ ๋ผ์ด๋ธ ์ธ์คํด์ค๊ฐ ๊ณง ์ปค๋์ด๋ฏ๋ก(`startLive`) ๊ทธ ์๋ฆฌ์์\n * `fork` ํ๋ฉด ๋๋ค โ `TwinEngine.kernel(id)` ๊ฐ simยทlive ๋ ๋ค ๋๋ ค์ค๋ค.\n *\n * (์ค๋ ์๊ฐ์ ์ ๋์์ ๋์ฐพ๋ ์ด์ ๋ ์ฌ๋ผ์ก๋ค โ ์ํ๊ฐ requestedยทfulfilledยทlines ๋ฅผ ์งํจ๋ค.)\n */\n\n /**\n * ์์ธก์ฉ ์ปค๋์ **์์ ์๊ฐ T ๊ธฐ์ค**์ผ๋ก ์ฌ๊ตฌ์ฑ โ ๊ณผ๊ฑฐ-vantage ์์ธก(๋ฐฑํ
์คํธ)ยท\"๊ทธ๋ ์์ ๋ณธ ๋ฏธ๋\".\n * recover(untilTime)๋ก T ์์ ์ํ๋ฅผ, T ์ดํ ์ค๋ ๊ด์ธก์ ๋ชจ์ hydrate โ monteCarloForecast ๊ฐ T ์์ ์์ผ๋ก ์คํํ๋ค.\n * sim/live ๋ฌด๊ด(์ ๋ ๊ธฐ๋ฐ ์ฌ๊ตฌ์ฑ). untilTime ์๋ต ์ ์ต์ . ๋๋ฉ์ธ ์ค์ฝํ(regยทjournal ์กฐํ๊ฐ domainId).\n */\n static async buildForecastKernelAt(domainId: string, instanceId: string, untilTime?: string): Promise<any | null> {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.model) return null\n const Kernel = kernelFor(reg.kind)\n const k = new Kernel(domainId, undefined, this.productionSpecOf(reg.model as TwinModelDef))\n k.loadTwinModel(reg.model as TwinModelDef)\n this.applyOperations(k, reg.model, instanceId) // ์์ธก๋ ๊ฐ์ ๋ช
์ธ๋ก ๊ตด๋ฌ์ผ ํ๋ค(ํ๋ฉด๊ณผ ๋ค๋ฅธ ์ซ์ ๊ธ์ง)\n await this.installEstimators(k, domainId, instanceId, reg.model) // ์์ธก์ ๊ธฐ๋ค๋ฆฐ๋ค โ ์ค์ธก์ ๋์น๋ฉด ์์ธก์ด ์์๋ก ๊ณ์ฐ๋๋ค\n const state = await this.recover(domainId, instanceId, undefined, untilTime).catch(() => null)\n if (!state) return null\n const cutoff = untilTime != null ? Date.parse(untilTime) : Infinity\n /*\n * journal-fold: ์ค๋์ ๋ง์ง๋ง ์ํ๋ ๊ทธ ์ค๋์ ์ผ์ด๋ ์ฌ์ค๋ค์ ์ ์ด์ผ ๋์จ๋ค.\n *\n * **์์ด์ง ์กฐ๊ฑด** โ ์ง๊ธ ์ด ์ฝ๊ธฐ์๋ ์ํ์ด ์๊ณ `eventType` ์ ์ธ๋ฑ์ค๋ ์๋ค. ๊ทธ๋์ ์ ๋์ด ํฐ\n * ํธ์์์๋ ์ด ํ ๋ฒ์ด ๊ทธ ํธ์์ ์ ๋ ์ ์ฒด ์ฃผ์ฌ๋ค. ์ค๋ ์ํ๋ฅผ ๋ฐ๋ก ์ ์ด ๋ ํ(ํฌ์)๋ฅผ ๋๊ฑฐ๋,\n * `(domain, instanceId, eventType, revision)` ์ธ๋ฑ์ค๋ฅผ ๋ถ์ด๊ณ ์ปค์๋ฅผ ๋ฃ์ผ๋ฉด ์ด ์์ธ๋ ์ฌ๋ผ์ง๋ค.\n * ์๊ฐ ์ํ(`cutoff`)์ SQL ๋ก ๋ด๋ ค๋ ์ ๋ฐ์ ์ค๋ค.\n */\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId, eventType: OP_EVENT.order }, order: { revision: 'ASC' } })\n const latest = new Map<string, any>()\n for (const r of rows) {\n if (Number.isFinite(cutoff) && (r.eventTime?.getTime() ?? NaN) > cutoff) continue\n const d = (r.payload as any)?.data\n if (d?.orderId) latest.set(d.orderId, d)\n }\n k.hydrateObserved(state, [...latest.values()])\n return k\n }\n\n /** ํ์ฌ ์ ์ฒด ์ค๋
์ท โ ๋ผ์ด๋ธ ์ฐ์ , ์์ผ๋ฉด ์ ๋ ๋ณต๊ตฌ ์บ์. */\n static snapshot(domainId: string, id: string): any {\n const inst = this.instances[runtimeKey(domainId, id)]\n if (inst?.mode === 'live' && inst.projector) {\n /* live: **์ปค๋์ด ์ฃผ๋ชฉ ์ ํธ๋ฅผ ์ค์ค๋ก ๋ธ๋ค**(๊ด์ธก ๋ชจ๋) โ ํธ์คํธ๊ฐ ๋ง๋ถ์ด๋ withLiveAttentions ๋\n * ํ์ ์๋ค. OEE ๋ง ํธ์คํธ๊ฐ ์ฑ์ด๋ค: ์ ์์คํ
์ด ์๊ฐ ๋์ ์ ๋ณด๋ด ์ฃผ์ง ์์ ์ํ ์ ์ด๋ฅผ ์ ๋ถํด\n * ๋ง๋๋ ๊ฐ์ด๋ผ ์ปค๋์ด ๋์ ํ ์ ์๋ค(์ ํฉ์ฑ ํ๋ค์ค์ ์ ์ผํ ์์ธ). */\n const st = inst.projector.snapshot()\n return inst.oee ? withLiveOee(st, inst.oee) : st\n }\n return inst?.runtime?.resync() ?? this.recovered[runtimeKey(domainId, id)]\n }\n}\n"]}
|