@continuous-excellence/ze-great-dashboard-client 0.31.61 → 0.31.63

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-C1YurCxg.js","names":["z2","z3","overlaps","z4","z5","styles","_Fragment","storageKey","styles","styles","_Fragment","styles","styles","_Fragment","styles","styles","styles","_Fragment","styles","clamp","ease","amount","styles","_Fragment","styles","styles","_Fragment","styles","styles","useClock","formatDuration","styles","styles","_Fragment","styles","_Fragment","styles","styles","styles","_Fragment","styles","_Fragment","styles","styles","_Fragment","styles","errorMessage","DiagnosticParseFailure","failedObservation","errorMessage","styles","styles","relList","link","processPreload","mutation","mutations","node","getFetchOpts","fetchOpts","clientSecurityStateSchema","z","clientEnvSchema","clientIdentityResponseSchema","readClientEnv","result","source","DURATION_PATTERN","UNIT_MILLIS","parseDuration","match","value","rawAmount","rawUnit","amount","errorKindSchema","envelopeErrorSchema","envelopeSchema","pipelineActivitySchema","testCountSchema","testEvidenceSchema","pipelineStatusSchema","pipelineStatusPriorities","pipelineStatusPriority","status","pullRequestHealthItemSchema","pullRequestHealthSchema","pullRequestCandidateSchema","pullRequestCandidatesSchema","pullRequestWorkflowObservationSchema","pullRequestBuildObservationSchema","httpValueSchema","columnCount","rowCount","analyzeBoardLayout","issues","panels","panel","isZeroPosition","isPositionInCanvas","overlapIssues","leftIndex","left","rightIndex","right","overlaps$1","key","issue","nextIssue","position","pollingDefaults","resolvePollingSettings","duration","fallback","panelValue","board","boardValue","visibleRunningAnimations","securityDetailsResponseSchema","testHistorySampleSchema","testHistorySchema","retryAfterTime","at","now","App_module_default","projectAttention","args","label","observation","fact","reason","unreadableFactReason","unreadablePanelReason","updateHealth","envelope","type","signal","missing","Diagnostics_module_default","Diagnostics","open","setOpen","useState","useSyncExternalStore","log","count","githubConsistencyIncidents","summary","jsxs","formatWindow","jsx","Fragment","blob","updateActivity","url","first","last","browserLocalStorage","readBrowserJson","raw","storage","writeBrowserJson","removeBrowserValue","summarizeDiagnostics","sessions","clientUpdate","boardFetch","event","events","timestamps","discarded","retention","clientReleaseVersion","storageKey$1","legacyStorageKey","maximumEvents","maximumAgeMillis","diagnosticKinds","BrowserDiagnosticStore","emptyRetention","env","incident","pruned","prune","listener","supplement","parsed","isDiagnosticEvent","validRetention","validIncidents","item","cacheMetadata","metadata","header","headers","cutoff","current","discardedByAge","discardedByCount","priorRetention","dashboardFetch","init","auth","fetcher","input","response","LayoutWarning","dialogId","useEffect","closeOnEscape","boardPath","layout","downloadLayout","path","AuthBoundary_module_default","MemoryStore","createOidcManager","manager","UserManager","WebStorageStateStore","bootstrap","consumeOidcTestBootstrap","User","OidcGate","useMemo","AuthProvider","AuthScreen","useAuth","denied","setDenied","attemptedSilentSignIn","useRef","deny","useCallback","hasAuthParams","children","PanelFrame_module_default","PanelPlaceholder","wide","hint","errorPresentation","kind","HttpValuePanel_module_default","panelLayout","statusSymbols","panelTypeSymbol","panelFeature","PanelHint","className","PanelMetadata","observed","emphasis","glyph","compact","PanelEvidence","priority","anchor","PanelStatus","compactOnly","PanelValue","PanelFrame","density","typeSymbol","shallow","short","error","attentionActive","busy","field","PanelSourceLink","sourceLink","panelId","ObservedAt","TimeAge","PipelineAge","running","runStartedAt","sourceUpdatedAt","observedAt","UpdateHealth","unavailable","health","LastConfirmedAge","formatted","age","content","formatAge","formatCompactAge","milliseconds","minutes","HttpValuePanel","GroupedHttpValuePanel","presentation","HttpValueFactCell","facts","FactSourceLink","PipelineAnimationDemoPanel_module_default","FallingShapesField_module_default","FALLING_TARGET_FILL","shapes","fallingDirection","width","height","fallingGrid","direction","fieldWidth","fieldHeight","cellSize","columns","rows","shapeFits","maxX","shape","cell","maxY","overlaps","leftCell","rightCell","chooseShape","candidates","randomIndex","seed","findDestination","y","x","candidate","settled","clearPath","support","other","requireSupported","leadingEdgeCount","bestSupport","best","destination","findPlacement","index","targetCellCount","progress","occupiedCellCount","clearTrailingLine","edgeLine","occupied","lineWidth","complete","allowPartial","cleared","remaining","onLine","buildStaticField","id","pieceSeed","length","FALLING_PIECE_INTERVAL_MS","createFallingSimulation","advanceFallingSimulation","simulation","active","nextPieceAt","recycleUntil","nextId","recycling","clearingCells","target","placement","pieceInterval","nextActive","piece","startX","startY","lifecycleAmount","visibleFallingShapes","estimatedDurationMs","TICK_MS","FallingShapesField","rootRef","geometry","setGeometry","reducedMotion","setReducedMotion","view","setView","geometryRef","directionRef","progressRef","seedRef","simulationRef","startedAtRef","root","update","rect","next","observer","media","timer","overdue","pieces","FlightPathField_module_default","departure","rotation","cruiseStart","cruiseEnd","approachEnd","pointOnLine","from","to","pointOnCubic","inverse","start","controlOne","controlTwo","end","frame","world","camera","followCamera","flightPosition","indeterminate","clamped","phase","engagement","returnGround","FlightPathField","style","ReleaseTransitField_module_default","ReleaseTransitField","route","RunningField_module_default","SnowmanField_module_default","snowmanSchedule","bodyWindow","headWindow","mode","scale","clamp$1","roll","tail","hop","land","scheduleAmount","time","smoothScheduleAmount","low","high","STEP_MS","ASSEMBLY_START","HAT_AT","createSnowmanSimulation","snowmanGrid","dimensions","clamp","snowmanScenePhase","snowmanWind","random","breeze","smallVariation","elapsed","gust","snowmanMaterialCount","grid","snowmanSpawnInterval","ordinary","schedule","advanceSnowmanSimulation","previous","clone","targetElapsed","step","snowmanLoad","cells","resolvedCells","ball","resolved","rotateAround","interval","updateBalls","occupiedCells","wind","fall","nextFlakes","flake","moved","hitBall","joinBall","resting","findRestingCell","belowOwner","collectTouchedGround","compactBallCells","relaxSettledSnow","body","restingBallY","beginTopple","advanceTopple","bodyAmount","ballRadius","rollBallTo","head","seatY","settle","drop","nextY","moveToward","dx","originals","groundCoordinates","exposedGround","owner","captureRadius","canCollect","dy","distance","original","targetHeadRadius","maxHeadCount","cosine","sine","rotatedX","localX","localY","ballInteriorSlot","openBallPosition","rebalanceBallTargets","free","radius","angle","existing","minDistance","attempt","steps","i","slots","denseBallSlots","second","slot","boundary","spacing","vertical","row","offset","column","resolvedHat","interpolateSnowman","scene","mix","a","b","fraction","oldFlakes","old","ground","below","preferred","alternate","side","minimum","toppling","point","maximumStep","drawSnowmanCanvas","canvas","context","cellWidth","cellHeight","drawDot","hat","SnowmanField","canvasRef","setDimensions","overdueRef","state","paint","options","StatusWeatherField_module_default","StatusWeatherField","PhasedProgressMarker_module_default","PhasedProgressMarker","delay","anchorClassName","anchorPart","bodyClassName","bodyPart","TelemetryBloomField_module_default","TelemetryBloomField","lane","isRunningFieldAnimation","animation","RunningField","VISUAL_TICK_MS","useRunningTiming","useClock$1","startedAt","elapsedMs","hasEstimate","setNow","enabled","timingDescription","formatDuration$1","compactTiming","formatClockDuration","expected","totalSeconds","durationMs","hours","seconds","clock","RunningFieldTiming","RunningProgress_module_default","RunningProgress","timing","usesReadout","timingText","animationStyle","track","isLegacyRunningAnimation","visualSeed","hash","character","DEFAULT_RUN_DURATION_MS","ESTIMATED_DURATION_MS","DEFAULT_REVIEW_DURATION_MS","REVIEW_CYCLE_MULTIPLIER","variants","PipelineAnimationDemoPanel","useClock","fixedAnimation","runDurationMs","durationMillis","reviewDurationMs","runNumber","DemoRun","usesField","PipelinePanel_module_default","statusPresentation","passedLabel","formatPipelineActivity","activity","TestDirectionSummary_module_default","TestDirectionSummary","pinned","setPinned","setPosition","popup","useId","show","dismiss","onEscape","points","totals","total","createPortal","RunTestResults","tests","TestOutcomeSummary","allPassed","projectTestEvidence","evidence","publicTestCounts","_run","counts","PipelinePanel","rejectedPipeline","RejectedPipelinePanel","PipelineSignalPanel","rejected","defaultAnimation","setDefaultAnimation","selectDefaultRunningAnimation","previousStatusRef","wasRunning","previousAnimation","activeRun","usesLegacyProgress","testDirection","formatDuration","projectPipelineDiagnostic","base","PullRequestHealthPanel_module_default","formatCount","singular","plural","compactPullRequestHealthFacts","attentionItem","PullRequestHealthPanel","compactFacts","message","projectPullRequestDiagnostic","TestCountPanel","TestCountMessage","projectTestCountDiagnostic","readUpdateWorkflows","entry","singlePolling","basicDiagnostic","featuresByType","workflow","PanelRenderer","Renderer","SecurityDetails_module_default","SecurityDetails","setState","details","setDetails","triggerRef","dialogRef","closeRef","wasOpenRef","containFocus","focusable","dialog","PolicyDetails","SecurityNotice_module_default","authenticationGuide","SecurityNotice","UpdateActivity_module_default","updateActivityWindowMillis","projectUpdateActivity","toMillis","fromMillis","starts","lanes","schedules","paths","requestStarts","activityMarkerPosition","activityLaneLabel","cadenceLabel","relativeDue","cadence","millis","formatMillis","UpdateActivity","timeout","resetDismissal","useBoardConfig","setBoard","loadedBoardName","setLoadedBoardName","cancelled","diagnostics","errorMessage$2","DiagnosticParseFailure$1","clientUpdateIntervalMillis","clientUpdateTimeoutMillis","defaultReload","useClientUpdate","inFlight","activeController","check","controller","reload","projectPanelDiagnostic","projectHttpValueFactsDiagnostic","projected","reportedTests","pipeline","largeChange","delta","after","before","classifyTestDirection","samples","sample","latest","baseline","span","landing","changes","net","symbol","percent","descriptions","projectTestDirection","hourMillis","dayMillis","testHistoryPolicy","emptyRepair","readingKey","compareReadings","mergeTestReadings","readings","reading","incoming","projectTestReadings","partial","confirmTestObservation","testRepairEligible","hasReadings","startTestRepair","completeTestRepair","updated","failures","retryAt","storageKey","schemaVersion","historyWindowMillis","BrowserPanelMemory","identity","history","successful","sampleKey","isAtLeastAsRecent","durations","middle","lower","upper","resolvePanelMemoryIdentity","identityKey","created","sourceTimestamp","latestCompletedAt","isHistories","leftAt","rightAt","timestamp","parts","isRecord","isHistory","isDurationSample","readPanelObservation","transport","cached","failedObservation$1","errorMessage$1","supportReference","applyPipelinePresentation","isGithubLink","reconcilePipelineResponse","pipelineStatus","accepted","durationSample","pollingPanels","polling","panelProxyPath","initialPollingSchedule","knownPaths","resolveNextPoll","runningPipeline","settings","completionAt","estimatedCompletionAt","nowMillis","rollupPullRequestHealth","incomplete","workflows","observationItem","candidatesSignal","candidateSignal","buildEnvelope","observationDates","aggregateStatus","pullRequests","sorted","dates","observations","statuses","mostUrgent","TestHistoryRepair","supported","healthy","memory","usePanelSignals","testDirections","setTestDirections","testDirectionsRef","signals","setSignals","setUpdateHealth","factSignals","setFactSignals","setSchedules","rejectedPipelines","setRejectedPipelines","signalsRef","factSignalsRef","memoryRef","rendered","recordRendered","projection","publish","publishFacts","repairs","timers","abortControllers","initialSchedules","schedulesByPanelId","updateSchedule","lastEnvelope","lastConfirmedAt","recordConfirmedUpdate","recordUpdateFailure","confirmedAt","errorMessage","poll","cycle","read","DiagnosticParseFailure","components","request","componentPath","candidateResult","workflowResults","isCandidates","buildResults","rolled","parseEnvelope","failedObservation","reconciliation","App","Dashboard","diagnosticsRef","accessToken","onDenied","attentionDrivers","attentionTreatment","activeAttentionPanels","driver","ConfigError_module_default","ConfigError","container","createRoot","StrictMode"],"sources":["../../../shared/dist/browser.js","../../src/attention.ts","../../src/Diagnostics.tsx","../../src/browser-storage.ts","../../src/diagnostics-summary.ts","../../src/release-version.ts","../../src/diagnostics.ts","../../src/dashboard-fetch.ts","../../src/LayoutWarning.tsx","../../src/oidc-manager.ts","../../src/OidcGate.tsx","../../src/PanelPlaceholder.tsx","../../src/error-presentation.ts","../../src/panel-layout.ts","../../src/panel-symbols.ts","../../src/PanelFrame.tsx","../../src/TimeAge.tsx","../../src/HttpValuePanel.tsx","../../src/falling-shapes.ts","../../src/falling-simulation.ts","../../src/FallingShapesField.tsx","../../src/FlightPathField.tsx","../../src/ReleaseTransitField.tsx","../../src/snowman-timing.ts","../../src/snowman.ts","../../src/snowman-canvas.ts","../../src/SnowmanField.tsx","../../src/StatusWeatherField.tsx","../../src/PhasedProgressMarker.tsx","../../src/TelemetryBloomField.tsx","../../src/RunningField.tsx","../../src/running-timing.ts","../../src/RunningFieldTiming.tsx","../../src/RunningProgress.tsx","../../src/visual-seed.ts","../../src/PipelineAnimationDemoPanel.tsx","../../src/panel-status.ts","../../src/pipeline-activity.ts","../../src/TestDirectionSummary.tsx","../../src/TestEvidence.tsx","../../src/PipelinePanel.tsx","../../src/panel-formatting.ts","../../src/pull-request-health.ts","../../src/PullRequestHealthPanel.tsx","../../src/TestCountPanel.tsx","../../src/update-workflows.ts","../../src/panel-registry.tsx","../../src/SecurityDetails.tsx","../../src/SecurityNotice.tsx","../../src/update-activity.ts","../../src/update-activity-presentation.ts","../../src/UpdateActivity.tsx","../../src/useBoardConfig.ts","../../src/useClientUpdate.ts","../../src/panel-diagnostics.ts","../../src/test-direction.ts","../../src/test-history-model.ts","../../src/panel-memory.ts","../../src/panel-observation.ts","../../src/pipeline-reconciliation.ts","../../src/polling-panels.ts","../../src/polling-schedule.ts","../../src/pull-request-rollup.ts","../../src/test-history-repair.ts","../../src/usePanelSignals.ts","../../src/App.tsx","../../src/ConfigError.tsx","../../src/main.tsx"],"sourcesContent":["// packages/shared/src/client-env.ts\nimport { z } from \"zod\";\nvar clientSecurityStates = [\"warning\", \"blocked\"];\nvar clientSecurityStateSchema = z.enum(clientSecurityStates);\nvar clientEnvSchema = z.object({\n /** Where the immutable client assets live. The one variable that repoints the whole client. */\n assetPath: z.string().min(1),\n /** Opaque SHA-256 fingerprint of the canonical asset path, for diagnostic correlation only. */\n assetPathId: z.string().regex(/^sha256:[a-f0-9]{64}$/),\n /** Same-origin path the proxy is mounted at, so there is no CORS and no cookie problem. */\n proxyPath: z.string().min(1),\n /** Which board this is, resolved server-side so the client parses no URLs. */\n board: z.string().min(1),\n /** Omitted entirely when unauthenticated — presence is what turns auth on. */\n auth: z.object({\n issuer: z.string().min(1),\n clientId: z.string().min(1),\n audience: z.string().min(1)\n }).optional(),\n /** Public deployment posture; it contains no board, source, or credential details. */\n security: clientSecurityStateSchema.optional()\n});\nvar clientIdentityResponseSchema = clientEnvSchema.pick({ assetPath: true, assetPathId: true }).extend({ serverVersion: z.string().min(1) });\nfunction readClientEnv(source = globalThis.window?.env) {\n const result = clientEnvSchema.safeParse(source);\n if (!result.success) {\n throw new Error(\n `window.env is missing or invalid \\u2014 the server did not inject usable configuration.\n${z.prettifyError(result.error)}`\n );\n }\n return result.data;\n}\n\n// packages/shared/src/duration.ts\nimport { z as z2 } from \"zod\";\nvar DURATION_PATTERN = /^([1-9][0-9]*)(ms|s|m|h)$/;\nvar UNIT_MILLIS = {\n ms: 1,\n s: 1e3,\n m: 6e4,\n h: 36e5\n};\nfunction parseDuration(value) {\n const match = DURATION_PATTERN.exec(value);\n if (!match) return null;\n const [, rawAmount, rawUnit] = match;\n if (rawAmount === void 0 || rawUnit === void 0) return null;\n const amount = Number(rawAmount);\n if (amount <= 0) return null;\n return amount * UNIT_MILLIS[rawUnit];\n}\nvar durationSchema = z2.string().regex(/^[1-9][0-9]*(?:ms|s|m|h)$/, {\n message: 'must be a positive duration like \"30s\", \"5m\", or \"1h\"'\n}).brand();\n\n// packages/shared/src/envelope.ts\nimport { z as z3 } from \"zod\";\nvar errorKindSchema = z3.enum([\n \"unreachable\",\n \"unauthorized\",\n \"not-found\",\n \"no-runs\",\n \"upstream-error\"\n]);\nvar envelopeErrorSchema = z3.object({\n kind: errorKindSchema,\n message: z3.string()\n});\nvar envelopeSchema = z3.discriminatedUnion(\"state\", [\n z3.object({\n panelId: z3.string().min(1),\n state: z3.literal(\"ok\"),\n /** From the upstream response `Date`. A cached value must never be shown without its age. */\n observedAt: z3.iso.datetime(),\n /** Adapter-derived. The authority for this panel; the dashboard itself asserts nothing. */\n link: z3.url().nullable(),\n signal: z3.unknown()\n }),\n z3.object({\n panelId: z3.string().min(1),\n state: z3.literal(\"error\"),\n /**\n * Populated even on error: knowing *when* a failure was observed is the difference between\n * \"broken just now\" and \"broken all morning\", and a panel that can't reach its source is\n * exactly when a viewer most wants to click through.\n */\n observedAt: z3.iso.datetime(),\n link: z3.url().nullable(),\n error: envelopeErrorSchema\n })\n]);\nvar pipelineActivitySchema = z3.object({\n kind: z3.enum([\"job\", \"stage\", \"step\"]),\n name: z3.string().min(1),\n parent: z3.string().min(1).optional()\n});\nvar testCountSchema = z3.discriminatedUnion(\"status\", [\n z3.object({\n type: z3.literal(\"test-count\"),\n status: z3.literal(\"reported\"),\n total: z3.number().int().nonnegative(),\n /** Public identity for browser-local comparisons, never observation time. */\n run: z3.object({\n id: z3.string().min(1),\n attempt: z3.number().int().positive(),\n updatedAt: z3.iso.datetime()\n }).optional(),\n passed: z3.number().int().nonnegative().optional(),\n failed: z3.number().int().nonnegative().optional(),\n skipped: z3.number().int().nonnegative().optional()\n }),\n z3.object({ type: z3.literal(\"test-count\"), status: z3.literal(\"pending\") }),\n z3.object({ type: z3.literal(\"test-count\"), status: z3.literal(\"not-reported\") })\n]);\nvar testEvidenceSchema = z3.discriminatedUnion(\"state\", [\n z3.object({ state: z3.literal(\"ok\"), observedAt: z3.iso.datetime(), signal: testCountSchema }),\n z3.object({ state: z3.literal(\"error\"), observedAt: z3.iso.datetime(), error: envelopeErrorSchema })\n]);\nvar pipelineStatusSchema = z3.object({\n type: z3.literal(\"pipeline-status\"),\n status: z3.enum([\"passed\", \"failed\", \"warning\", \"running\", \"cancelled\", \"unknown\"]),\n /** The source's unmodified status/result vocabulary, for an honest display. */\n rawStatus: z3.string(),\n /** Test evidence bound to this exact run; failures do not erase build status. */\n testResults: testEvidenceSchema.optional(),\n name: z3.string().min(1),\n /** The branch represented by this status, when the upstream supplies or filters by one. */\n branch: z3.string().min(1).optional(),\n /** Elapsed execution time, supplied only after the upstream run has completed. */\n durationMs: z3.number().int().nonnegative().optional(),\n /** When an active run began, so the client can advance its elapsed display between polls. */\n runStartedAt: z3.iso.datetime().optional(),\n /** Stable source-run identity, when the adapter provides one. */\n sourceRunId: z3.string().min(1).optional(),\n /** Best-effort live work detail; adapters may describe a job, stage, or step. */\n activity: pipelineActivitySchema.optional(),\n /** Advisory duration from recent completed runs remembered by this browser. */\n estimatedDurationMs: z3.number().int().positive().optional(),\n /** When this workflow run was last updated by its source, distinct from our observation time. */\n sourceUpdatedAt: z3.iso.datetime().optional()\n});\nvar pipelineStatusPriorities = {\n passed: 0,\n cancelled: 1,\n unknown: 2,\n running: 3,\n warning: 4,\n failed: 5\n};\nfunction pipelineStatusPriority(status) {\n return pipelineStatusPriorities[status];\n}\nvar pullRequestHealthItemSchema = z3.object({\n label: z3.string().min(1),\n status: pipelineStatusSchema.shape.status,\n detail: z3.string().min(1),\n link: z3.url().nullable()\n});\nvar pullRequestHealthSchema = z3.object({\n type: z3.literal(\"pull-request-health\"),\n status: pipelineStatusSchema.shape.status,\n summary: z3.string().min(1),\n workflows: z3.array(pullRequestHealthItemSchema),\n pullRequests: z3.array(pullRequestHealthItemSchema),\n /** Missing component reads remain visible even when the evidence we did get is reassuring. */\n incompleteObservations: z3.array(z3.object({ label: z3.string().min(1), message: z3.string().min(1) })).optional(),\n /** The latest component reading, disclosed beside the oldest aggregate evidence. */\n newestObservedAt: z3.iso.datetime().optional()\n});\nvar pullRequestCandidateSchema = z3.object({\n number: z3.number().int().positive(),\n branch: z3.string().min(1),\n link: z3.url()\n});\nvar pullRequestCandidatesSchema = z3.object({\n type: z3.literal(\"pull-request-candidates\"),\n pullRequests: z3.array(pullRequestCandidateSchema),\n /** GitHub's first page is a deliberate bounded observation, not proof that no later PR exists. */\n truncated: z3.boolean().optional()\n});\nvar pullRequestWorkflowObservationSchema = z3.object({\n type: z3.literal(\"pull-request-workflow\"),\n workflow: z3.string().min(1),\n item: pullRequestHealthItemSchema\n});\nvar pullRequestBuildObservationSchema = z3.object({\n type: z3.literal(\"pull-request-build\"),\n branch: z3.string().min(1),\n item: pullRequestHealthItemSchema\n});\nvar httpValueSchema = z3.object({\n type: z3.literal(\"http-value\"),\n value: z3.union([z3.string(), z3.number(), z3.boolean()])\n});\n\n// packages/shared/src/layout.ts\nvar columnCount = 12;\nvar rowCount = 12;\nfunction analyzeBoardLayout(panels) {\n const issues = panels.flatMap((panel) => {\n if (!panel.position || isZeroPosition(panel.position) || isPositionInCanvas(panel.position))\n return [];\n return [\n {\n panelId: panel.id,\n kind: \"out-of-bounds\",\n position: panel.position,\n conflictsWith: []\n }\n ];\n });\n const overlapIssues = /* @__PURE__ */ new Map();\n for (let leftIndex = 0; leftIndex < panels.length; leftIndex++) {\n const left = panels[leftIndex];\n if (!left?.position || isZeroPosition(left.position)) continue;\n for (let rightIndex = leftIndex + 1; rightIndex < panels.length; rightIndex++) {\n const right = panels[rightIndex];\n if (!right?.position || isZeroPosition(right.position)) continue;\n if (!overlaps(left.position, right.position)) continue;\n const key = `${right.id}\\0overlap`;\n const issue = overlapIssues.get(key);\n if (issue) issue.conflictsWith.push(left.id);\n else {\n const nextIssue = {\n panelId: right.id,\n kind: \"overlap\",\n position: right.position,\n conflictsWith: [left.id]\n };\n overlapIssues.set(key, nextIssue);\n issues.push(nextIssue);\n }\n }\n }\n return { issues };\n}\nfunction normalizeBoardLayout(panels) {\n const positioned = panels.flatMap((panel) => {\n if (!panel.position || isZeroPosition(panel.position)) return [];\n return [{ ...panel.position, panelId: panel.id }];\n });\n if (positioned.length === 0) return panels.map((panel) => ({ ...panel }));\n const minX = Math.min(...positioned.map((rectangle) => rectangle.x));\n const minY = Math.min(...positioned.map((rectangle) => rectangle.y));\n const maxX = Math.max(...positioned.map((rectangle) => rectangle.x + rectangle.w));\n const maxY = Math.max(...positioned.map((rectangle) => rectangle.y + rectangle.h));\n const scaleX = maxX - minX > columnCount ? columnCount / (maxX - minX) : 1;\n const scaleY = maxY - minY > rowCount ? rowCount / (maxY - minY) : 1;\n const accepted = [];\n return panels.map((panel) => {\n const position = panel.position;\n if (!position || isZeroPosition(position)) return { ...panel };\n const desired = scaleRectangle(position, minX, minY, scaleX, scaleY);\n const legal = nearestLegalRectangle(desired, accepted);\n if (!legal) return { ...panel, position: zeroPosition };\n accepted.push({ ...legal, panelId: panel.id });\n return { ...panel, position: legal };\n });\n}\nfunction isZeroPosition(position) {\n return position?.x === 0 && position.y === 0 && position.w === 0 && position.h === 0;\n}\nvar zeroPosition = { x: 0, y: 0, w: 0, h: 0 };\nfunction isPositionInCanvas(position) {\n return !isZeroPosition(position) && position.x + position.w <= columnCount && position.y + position.h <= rowCount;\n}\nfunction overlaps(left, right) {\n return left.x < right.x + right.w && left.x + left.w > right.x && left.y < right.y + right.h && left.y + left.h > right.y;\n}\nfunction scaleRectangle(position, minX, minY, scaleX, scaleY) {\n const x = scaleCoordinate(position.x, minX, scaleX);\n const y = scaleCoordinate(position.y, minY, scaleY);\n const right = scaleCoordinate(position.x + position.w, minX, scaleX);\n const bottom = scaleCoordinate(position.y + position.h, minY, scaleY);\n return {\n x,\n y,\n w: Math.max(1, right - x),\n h: Math.max(1, bottom - y)\n };\n}\nfunction scaleCoordinate(value, origin, scale) {\n return Math.round((value - origin) * scale);\n}\nfunction nearestLegalRectangle(desired, accepted) {\n const candidates = [];\n for (let width = desired.w; width >= 1; width--) {\n for (let height = desired.h; height >= 1; height--) {\n const shrink = desired.w - width + (desired.h - height);\n for (let y = 0; y <= rowCount - height; y++) {\n for (let x = 0; x <= columnCount - width; x++) {\n const candidate2 = { x, y, w: width, h: height };\n if (accepted.some((rectangle) => overlaps(candidate2, rectangle))) continue;\n candidates.push({\n ...candidate2,\n shrink,\n distance: Math.abs(x - desired.x) + Math.abs(y - desired.y)\n });\n }\n }\n }\n }\n candidates.sort(\n (left, right) => left.shrink - right.shrink || left.distance - right.distance || left.y - right.y || left.x - right.x\n );\n const [candidate] = candidates;\n if (!candidate) return void 0;\n return { x: candidate.x, y: candidate.y, w: candidate.w, h: candidate.h };\n}\n\n// packages/shared/src/polling-policy.ts\nvar pollingDefaults = {\n refreshMillis: 6e4,\n runningRefreshMillis: 15e3,\n runningCompletionRefreshMillis: 5e3,\n runningCompletionWindowMillis: 12e4\n};\nfunction resolvePollingSettings(board, panel) {\n const duration = (value, fallback) => parseDuration(value ?? \"\") ?? fallback;\n const panelValue = (key, boardValue, fallback) => duration(panel[key], duration(board[boardValue], fallback));\n return {\n refreshMillis: panelValue(\"refresh\", \"refresh\", pollingDefaults.refreshMillis),\n runningRefreshMillis: panelValue(\n \"running_refresh\",\n \"running_refresh\",\n pollingDefaults.runningRefreshMillis\n ),\n runningCompletionRefreshMillis: panelValue(\n \"running_completion_refresh\",\n \"running_completion_refresh\",\n pollingDefaults.runningCompletionRefreshMillis\n ),\n runningCompletionWindowMillis: panelValue(\n \"running_completion_window\",\n \"running_completion_window\",\n pollingDefaults.runningCompletionWindowMillis\n )\n };\n}\n\n// packages/shared/src/running-animations.ts\nvar visibleRunningAnimations = [\n \"radial\",\n \"runway\",\n \"orbit\",\n \"signal-field\",\n \"telemetry-bloom\",\n \"release-transit\",\n \"status-weather\",\n \"falling-shapes\",\n \"snowman\",\n \"flight-path\"\n];\n\n// packages/shared/src/security-details.ts\nimport { z as z4 } from \"zod\";\nvar securityDetailsResponseSchema = z4.strictObject({\n oidc: z4.literal(true),\n policy: z4.discriminatedUnion(\"mode\", [\n z4.strictObject({ mode: z4.literal(\"authenticated\") }),\n z4.strictObject({ mode: z4.literal(\"subjects\") }),\n z4.strictObject({\n mode: z4.literal(\"claim\"),\n claim: z4.string().min(1),\n match: z4.enum([\"any\", \"all\"])\n })\n ])\n});\n\n// packages/shared/src/test-history.ts\nimport { z as z5 } from \"zod\";\nvar testHistorySampleSchema = z5.object({\n id: z5.string().min(1),\n attempt: z5.number().int().positive(),\n updatedAt: z5.iso.datetime(),\n total: z5.number().int().nonnegative()\n});\nvar testHistorySchema = z5.object({\n inspectedAt: z5.iso.datetime(),\n inspectedRuns: z5.number().int().min(0).max(8),\n complete: z5.boolean(),\n samples: z5.array(testHistorySampleSchema).max(8),\n retryAt: z5.iso.datetime().optional()\n});\nvar testHistoryHeader = \"X-Dashboard-Test-History\";\nfunction retryAfterTime(value, now) {\n if (!value) return void 0;\n const at = /^\\d+$/.test(value) ? now + Number(value) * 1e3 : Date.parse(value);\n return Number.isFinite(at) && at > now ? at : void 0;\n}\nexport {\n analyzeBoardLayout,\n clientEnvSchema,\n clientIdentityResponseSchema,\n clientSecurityStateSchema,\n clientSecurityStates,\n durationSchema,\n envelopeSchema,\n errorKindSchema,\n httpValueSchema,\n isZeroPosition,\n normalizeBoardLayout,\n parseDuration,\n pipelineActivitySchema,\n pipelineStatusPriority,\n pipelineStatusSchema,\n pollingDefaults,\n pullRequestBuildObservationSchema,\n pullRequestCandidateSchema,\n pullRequestCandidatesSchema,\n pullRequestHealthSchema,\n pullRequestWorkflowObservationSchema,\n readClientEnv,\n resolvePollingSettings,\n retryAfterTime,\n securityDetailsResponseSchema,\n testCountSchema,\n testEvidenceSchema,\n testHistoryHeader,\n testHistorySampleSchema,\n testHistorySchema,\n visibleRunningAnimations\n};\n","import {\n type Board,\n type Envelope,\n httpValueSchema,\n pipelineStatusSchema,\n pullRequestHealthSchema,\n} from '@ze-great-dashboard/shared/browser'\nimport type { HttpValueFactObservation, PanelUpdateHealth } from './panel-props.ts'\n\nexport type AttentionDriver = {\n panelId: string\n label: string\n reason: string\n factId?: string\n}\n\n/**\n * Projects only public, already-rendered evidence into the board's opt-in attention rail.\n * It intentionally never infers a source condition from loading, warning, or unknown states.\n */\nexport function projectAttention(args: {\n board: Board | undefined\n signals: Record<string, Envelope | undefined>\n updateHealth: Record<string, PanelUpdateHealth | undefined>\n factSignals: Record<string, Record<string, HttpValueFactObservation | undefined> | undefined>\n}): AttentionDriver[] {\n if (!args.board?.attention) return []\n return args.board.panels.flatMap((panel) => {\n if (!panel.attention) return []\n const label = panel.label ?? panel.id\n if (panel.type === 'http-value' && panel.facts)\n return panel.facts.flatMap((fact) => {\n const observation = args.factSignals[panel.id]?.[fact.id]\n const reason = unreadableFactReason(observation)\n return reason\n ? [{ panelId: panel.id, label, reason: `${fact.label}: ${reason}`, factId: fact.id }]\n : []\n })\n const reason = unreadablePanelReason(\n panel.type,\n args.signals[panel.id],\n args.updateHealth[panel.id],\n )\n return reason ? [{ panelId: panel.id, label, reason }] : []\n })\n}\n\nfunction unreadableFactReason(observation: HttpValueFactObservation | undefined) {\n if (observation?.failure) return `Updates unavailable — ${observation.failure}`\n if (observation?.updateHealth) return `Updates unavailable — ${observation.updateHealth.message}`\n if (!observation?.envelope) return undefined\n if (observation.envelope.state === 'error') return observation.envelope.error.message\n return httpValueSchema.safeParse(observation.envelope.signal).success\n ? undefined\n : 'Invalid value'\n}\n\nfunction unreadablePanelReason(\n type: string,\n envelope: Envelope | undefined,\n updateHealth: PanelUpdateHealth | undefined,\n) {\n if (updateHealth) return `Updates unavailable — ${updateHealth.message}`\n if (!envelope) return undefined\n if (envelope.state === 'error') return envelope.error.message\n if (type === 'pipeline-status') {\n const signal = pipelineStatusSchema.safeParse(envelope.signal)\n if (!signal.success) return 'Invalid signal'\n return signal.data.status === 'failed' ? 'Pipeline failed' : undefined\n }\n if (type === 'pull-request-health') {\n const signal = pullRequestHealthSchema.safeParse(envelope.signal)\n if (!signal.success) return 'Invalid signal'\n if (signal.data.status === 'failed') return signal.data.summary\n const missing = signal.data.incompleteObservations?.[0]\n return missing ? `${missing.label}: ${missing.message}` : undefined\n }\n if (type === 'http-value')\n return httpValueSchema.safeParse(envelope.signal).success ? undefined : 'Invalid value'\n return undefined\n}\n","import { useState, useSyncExternalStore } from 'react'\nimport styles from './Diagnostics.module.css'\nimport type { BrowserDiagnosticStore } from './diagnostics.ts'\nimport type { UpdateActivitySnapshot } from './update-activity.ts'\n\nexport function Diagnostics({\n log,\n updateActivity,\n}: {\n log: BrowserDiagnosticStore\n updateActivity?: () => UpdateActivitySnapshot\n}) {\n const [open, setOpen] = useState(false)\n useSyncExternalStore(log.subscribe, log.snapshot, log.snapshot)\n const count = log.count()\n const githubConsistencyIncidents = log.githubConsistencyIncidentCount()\n const summary = log.summary()\n const download = () => {\n const blob = new Blob(\n [\n JSON.stringify(\n log.export(updateActivity ? { updateActivity: updateActivity() } : {}),\n null,\n 2,\n ),\n ],\n { type: 'application/json' },\n )\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = `dashboard-diagnostics-${new Date().toISOString().replaceAll(':', '-')}.json`\n link.click()\n URL.revokeObjectURL(url)\n }\n const clear = () => {\n if (!window.confirm('Clear this browser’s retained dashboard diagnostics?')) return\n log.clear()\n }\n\n return (\n <section className={styles.diagnostics}>\n <button\n className={styles.button}\n type=\"button\"\n aria-expanded={open}\n onClick={() => setOpen(!open)}\n >\n Diagnostics ({count})\n {githubConsistencyIncidents > 0 && ` · GitHub consistency ${githubConsistencyIncidents}`}\n </button>\n {open && (\n <div className={styles.area}>\n <p>\n Client {log.clientVersion()} · assets {log.assetPath()}\n </p>\n <p>\n {summary.retained.eventCount} retained browser-local events across{' '}\n {summary.retained.sessionCount} session{summary.retained.sessionCount === 1 ? '' : 's'}\n {summary.retained.firstEventAt && summary.retained.lastEventAt\n ? ` (${formatWindow(summary.retained.firstEventAt, summary.retained.lastEventAt)})`\n : ''}\n . They are never uploaded.\n </p>\n {summary.retained.evidenceMayBeIncomplete && (\n <p className={styles.warning} role=\"alert\">\n Earlier evidence was pruned: {summary.retained.retention.eventsPrunedByCount} at the\n 2,000-event cap and {summary.retained.retention.eventsPrunedByAge} by the 7-day age\n limit. “No failures” applies only to the retained window.\n </p>\n )}\n <p>\n Update failures: {summary.failures.clientUpdate}; board fetch failures:{' '}\n {summary.failures.boardFetch}.\n </p>\n {log.githubConsistencyIncidentCount() > 0 && (\n <p className={styles.warning} role=\"alert\">\n GitHub API consistency incidents: {log.githubConsistencyIncidentCount()}. A response\n older than the last accepted run was rejected; download diagnostics to report it.\n </p>\n )}\n {summary.panels.length > 0 && (\n <div className={styles.panels}>\n {summary.panels.map((panel) => (\n <p key={panel.panelId}>\n <strong>{panel.panelId}</strong> — {panel.requests} requests\n {Object.keys(panel.httpStatuses).length\n ? `; HTTP ${Object.entries(panel.httpStatuses)\n .map(([status, count]) => `${status}×${count}`)\n .join(', ')}`\n : ''}\n ; parse/network failures {panel.parseFailures}/{panel.networkFailures}; visible\n changes {panel.visibleStateChanges}; latest{' '}\n {panel.latestRendered\n ? `${panel.latestRendered.state}${panel.latestRendered.status ? `/${panel.latestRendered.status}` : ''}`\n : 'not rendered'}\n .\n {panel.latestFailedObservation && (\n <>\n {' '}\n Failure: {panel.latestFailedObservation.reason}. Support reference:{' '}\n <code>\n {panel.latestFailedObservation.supportReference ?? 'not provided'}\n </code>\n .\n </>\n )}\n </p>\n ))}\n </div>\n )}\n <div className={styles.actions}>\n <button className={styles.button} type=\"button\" onClick={download}>\n Download\n </button>\n <button className={styles.button} type=\"button\" onClick={clear}>\n Clear\n </button>\n </div>\n </div>\n )}\n </section>\n )\n}\n\nfunction formatWindow(first: string, last: string) {\n return first === last ? first : `${first} to ${last}`\n}\n","export type BrowserStorageLike = Pick<Storage, 'getItem' | 'setItem'>\n\nexport function browserLocalStorage(): BrowserStorageLike | undefined {\n try {\n return window.localStorage\n } catch {\n return undefined\n }\n}\n\nexport function readBrowserJson<T>(\n storage: BrowserStorageLike | undefined,\n key: string,\n): T | undefined {\n try {\n const raw = storage?.getItem(key)\n return raw ? (JSON.parse(raw) as T) : undefined\n } catch {\n return undefined\n }\n}\n\nexport function writeBrowserJson(\n storage: BrowserStorageLike | undefined,\n key: string,\n value: unknown,\n) {\n try {\n storage?.setItem(key, JSON.stringify(value))\n } catch {\n // Browser storage is an optimization; callers retain their in-memory state.\n }\n}\n\nexport function removeBrowserValue(storage: Pick<Storage, 'removeItem'> | undefined, key: string) {\n try {\n storage?.removeItem(key)\n } catch {\n // Storage can be unavailable in private browsing or restricted frames.\n }\n}\n","import type {\n DiagnosticEvent,\n DiagnosticRetention,\n FailedObservation,\n RenderedPanelDiagnostic,\n} from './diagnostics.ts'\n\nexport type PanelDiagnosticsSummary = {\n panelId: string\n requests: number\n httpStatuses: Record<string, number>\n parseFailures: number\n networkFailures: number\n visibleStateChanges: number\n latestRendered?: RenderedPanelDiagnostic\n latestFailedObservation?: FailedObservation\n}\n\nexport type DiagnosticsSummary = {\n githubConsistencyIncidents: number\n retained: {\n eventCount: number\n firstEventAt?: string\n lastEventAt?: string\n sessionCount: number\n retention: DiagnosticRetention\n evidenceMayBeIncomplete: boolean\n }\n failures: {\n clientUpdate: number\n boardFetch: number\n }\n panels: PanelDiagnosticsSummary[]\n}\n\n/** Summarizes retained browser evidence only; omitted history is disclosed through retention. */\nexport function summarizeDiagnostics(\n events: readonly DiagnosticEvent[],\n retention: DiagnosticRetention,\n githubConsistencyIncidents = 0,\n): DiagnosticsSummary {\n const panels = new Map<string, PanelDiagnosticsSummary>()\n const sessions = new Set<string>()\n let clientUpdate = 0\n let boardFetch = 0\n\n for (const event of events) {\n sessions.add(event.sessionId)\n if (event.kind === 'client-update-failure') clientUpdate++\n if (event.kind === 'board-fetch-failure' || event.kind === 'board-fetch-parse-failure')\n boardFetch++\n if (!('panelId' in event)) continue\n\n const panel = panels.get(event.panelId) ?? {\n panelId: event.panelId,\n requests: 0,\n httpStatuses: {},\n parseFailures: 0,\n networkFailures: 0,\n visibleStateChanges: 0,\n }\n if (event.kind === 'panel-fetch-start') panel.requests++\n if (event.kind === 'panel-fetch-response') {\n if (event.status !== undefined) {\n const status = String(event.status)\n panel.httpStatuses[status] = (panel.httpStatuses[status] ?? 0) + 1\n }\n if (event.failure) panel.latestFailedObservation = event.failure\n }\n if (event.kind === 'panel-fetch-parse-failure') panel.parseFailures++\n if (event.kind === 'panel-fetch-failure') panel.networkFailures++\n if (event.kind === 'panel-rendered') {\n panel.visibleStateChanges++\n panel.latestRendered = event.rendered\n }\n panels.set(event.panelId, panel)\n }\n\n const timestamps = events.map((event) => event.at).sort()\n const discarded = retention.eventsPrunedByAge + retention.eventsPrunedByCount\n return {\n githubConsistencyIncidents,\n retained: {\n eventCount: events.length,\n firstEventAt: timestamps[0],\n lastEventAt: timestamps.at(-1),\n sessionCount: sessions.size,\n retention,\n evidenceMayBeIncomplete: discarded > 0,\n },\n failures: { clientUpdate, boardFetch },\n panels: [...panels.values()].sort((left, right) => left.panelId.localeCompare(right.panelId)),\n }\n}\n","/** Embedded in the immutable client artifact; never supplied by the server at runtime. */\nexport const clientReleaseVersion = import.meta.env.RELEASE_VERSION ?? 'dev'\n","import type { ClientEnv, Envelope } from '@ze-great-dashboard/shared/browser'\nimport {\n type BrowserStorageLike,\n browserLocalStorage,\n readBrowserJson,\n removeBrowserValue,\n writeBrowserJson,\n} from './browser-storage.ts'\nimport { type DiagnosticsSummary, summarizeDiagnostics } from './diagnostics-summary.ts'\nimport { clientReleaseVersion } from './release-version.ts'\nimport type { TestEvidenceDiagnostic } from './TestEvidence.tsx'\n\nconst storageKey = 'ze-great-dashboard.diagnostics.v2'\nconst legacyStorageKey = 'ze-great-dashboard.diagnostics.v1'\nexport const diagnosticsSchemaVersion = 2\nconst maximumEvents = 2_000\nconst maximumAgeMillis = 7 * 24 * 60 * 60 * 1_000\nconst diagnosticKinds = [\n 'session-start',\n 'client-update-check',\n 'client-update-response',\n 'client-update-failure',\n 'client-update-detected',\n 'board-fetch-start',\n 'board-fetch-response',\n 'board-fetch-parse-failure',\n 'board-fetch-failure',\n 'layout-analyzed',\n 'panel-fetch-start',\n 'panel-fetch-response',\n 'panel-fetch-parse-failure',\n 'panel-fetch-failure',\n 'panel-rendered',\n 'test-history-repair',\n] as const\n\nexport type CacheMetadata = Partial<\n Record<'cacheControl' | 'etag' | 'lastModified' | 'date' | 'age', string>\n>\n\nexport type GithubConsistencyIncident = {\n at: string\n board: string\n panelId: string\n endpoint: string\n identity: { source: string; workflow: string; branch: string }\n accepted: { sourceUpdatedAt: string; status: string; link: string | null }\n regressed: { sourceUpdatedAt: string; status: string; link: string | null }\n response: { httpStatus?: number; date?: string; etag?: string; cacheControl?: string }\n}\n\ntype EventMetadata = {\n schemaVersion: typeof diagnosticsSchemaVersion\n at: string\n sessionId: string\n board: string\n clientVersion: string\n clientAssetPath: string\n clientAssetPathId: string\n}\n\nexport type RenderedPanelDiagnostic = {\n testDirection?: ReturnType<typeof import('./test-direction.ts').projectTestDirection>\n tests?: TestEvidenceDiagnostic\n state: Envelope['state']\n status?: string\n link: string | null\n facts?: Array<{ id: string; state: 'ok' | 'error' | 'unavailable'; link: string | null }>\n}\n\nexport type FailedObservation = {\n reason: string\n supportReference?: string\n}\n\nexport type DiagnosticEventInput =\n | {\n kind: 'test-history-repair'\n panelId: string\n path: string\n outcome: 'complete' | 'partial' | 'failed'\n inspectedRuns: number\n samples: number\n }\n | { kind: 'session-start' }\n | { kind: 'client-update-check'; path: string }\n | {\n kind: 'client-update-response'\n path: string\n serverVersion: string\n assetPathIdMatches: boolean\n }\n | { kind: 'client-update-failure'; path: string; message: string }\n | {\n kind: 'client-update-detected'\n path: string\n current: { assetPath: string }\n next: { assetPath: string }\n }\n | { kind: 'board-fetch-start'; path: string }\n | {\n kind: 'board-fetch-response'\n path: string\n status?: number\n cache?: CacheMetadata\n boardSummary?: { panelCount: number; panelIds: string[] }\n }\n | { kind: 'board-fetch-parse-failure'; path: string; message: string }\n | { kind: 'board-fetch-failure'; path: string; message: string }\n | { kind: 'layout-analyzed'; issueCount: number; affectedPanelIds: string[] }\n | { kind: 'panel-fetch-start'; panelId: string; path: string }\n | {\n kind: 'panel-fetch-response'\n panelId: string\n path: string\n status?: number\n cache?: CacheMetadata\n envelope?: Envelope\n failure?: FailedObservation\n }\n | { kind: 'panel-fetch-parse-failure'; panelId: string; path: string; message: string }\n | { kind: 'panel-fetch-failure'; panelId: string; path: string; message: string }\n | {\n kind: 'panel-rendered'\n panelId: string\n path: string\n rendered: RenderedPanelDiagnostic\n }\n\nexport type DiagnosticEvent = DiagnosticEventInput extends infer Event\n ? Event extends DiagnosticEventInput\n ? Event & EventMetadata\n : never\n : never\n\n/** The only interface client features need in order to emit browser diagnostics. */\nexport interface DiagnosticSink {\n record(event: DiagnosticEventInput): void\n recordGithubConsistencyIncident(incident: Omit<GithubConsistencyIncident, 'at' | 'board'>): void\n}\n\ntype PersistedDiagnosticEvent = Omit<DiagnosticEvent, 'schemaVersion'> & { schemaVersion?: number }\nexport type DiagnosticRetention = {\n eventsPrunedByAge: number\n eventsPrunedByCount: number\n}\nexport type RetainedDiagnosticEvidence = {\n events: DiagnosticEvent[]\n retention: DiagnosticRetention\n}\n\ntype StoredDiagnostics = {\n schemaVersion: number\n events: PersistedDiagnosticEvent[]\n retention?: Partial<DiagnosticRetention>\n githubConsistencyIncidents?: GithubConsistencyIncident[]\n}\n\ntype StorageLike = BrowserStorageLike & Pick<Storage, 'removeItem'>\n\n/** Browser-local diagnostic evidence. It deliberately has no server or shared-contract counterpart. */\nexport class BrowserDiagnosticStore implements DiagnosticSink {\n private events: DiagnosticEvent[] = []\n private retention: DiagnosticRetention = emptyRetention()\n private revision = 0\n private incidents: GithubConsistencyIncident[] = []\n private readonly listeners = new Set<() => void>()\n private readonly sessionId = crypto.randomUUID?.() ?? `${Date.now()}-${Math.random()}`\n\n constructor(\n private readonly env: ClientEnv,\n private readonly storage: StorageLike | undefined = browserLocalStorage() as\n | StorageLike\n | undefined,\n private readonly now: () => Date = () => new Date(),\n ) {\n // v1 could retain upstream-provided error text. It is intentionally not migrated.\n removeBrowserValue(this.storage, legacyStorageKey)\n this.events = this.read()\n this.record({ kind: 'session-start' })\n }\n\n recordGithubConsistencyIncident(incident: Omit<GithubConsistencyIncident, 'at' | 'board'>) {\n this.incidents.push({ ...incident, at: this.now().toISOString(), board: this.env.board })\n this.persist()\n this.revision++\n this.notify()\n }\n\n githubConsistencyIncidentCount = () => this.incidents.length\n\n record(event: DiagnosticEventInput) {\n const pruned = prune(\n [\n ...this.events,\n {\n ...event,\n schemaVersion: diagnosticsSchemaVersion,\n at: this.now().toISOString(),\n sessionId: this.sessionId,\n board: this.env.board,\n clientVersion: clientReleaseVersion,\n clientAssetPath: this.env.assetPath,\n clientAssetPathId: this.env.assetPathId,\n },\n ],\n this.now(),\n this.retention,\n )\n this.events = pruned.events\n this.retention = pruned.retention\n this.persist()\n this.revision++\n this.notify()\n }\n\n count = () => {\n return this.events.length\n }\n\n clientVersion = () => clientReleaseVersion\n\n assetPath = () => this.env.assetPath\n\n snapshot = () => this.revision\n\n summary = (): DiagnosticsSummary =>\n summarizeDiagnostics(this.events, this.retention, this.incidents.length)\n\n retainedEvidence = (): RetainedDiagnosticEvidence => ({\n events: [...this.events],\n retention: { ...this.retention },\n })\n\n clear() {\n this.events = []\n this.incidents = []\n this.retention = emptyRetention()\n removeBrowserValue(this.storage, storageKey)\n this.revision++\n this.notify()\n }\n\n subscribe = (listener: () => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n export = <TSupplement extends object = object>(supplement?: TSupplement) => {\n return {\n schemaVersion: diagnosticsSchemaVersion,\n exportedAt: this.now().toISOString(),\n client: {\n version: clientReleaseVersion,\n assetPath: this.env.assetPath,\n assetPathId: this.env.assetPathId,\n board: this.env.board,\n sessionId: this.sessionId,\n },\n events: this.events,\n githubConsistencyIncidents: this.incidents,\n summary: this.summary(),\n ...supplement,\n }\n }\n\n private read(): DiagnosticEvent[] {\n const parsed = readBrowserJson<Partial<StoredDiagnostics>>(this.storage, storageKey)\n if (\n !parsed ||\n parsed.schemaVersion !== diagnosticsSchemaVersion ||\n !Array.isArray(parsed.events)\n ) {\n removeBrowserValue(this.storage, storageKey)\n return []\n }\n if (!parsed.events.every(isDiagnosticEvent)) {\n removeBrowserValue(this.storage, storageKey)\n return []\n }\n // v1 retained events predate per-event versions. Their containing store was already v1, so\n // retain them and normalize on the next write rather than discarding viewer evidence.\n const pruned = prune(\n parsed.events.map(\n (event) => ({ ...event, schemaVersion: diagnosticsSchemaVersion }) as DiagnosticEvent,\n ),\n this.now(),\n validRetention(parsed.retention),\n )\n this.retention = pruned.retention\n this.incidents = validIncidents(parsed.githubConsistencyIncidents)\n return pruned.events\n }\n\n private persist() {\n writeBrowserJson(this.storage, storageKey, {\n schemaVersion: diagnosticsSchemaVersion,\n events: this.events,\n retention: this.retention,\n githubConsistencyIncidents: this.incidents,\n })\n }\n\n private notify() {\n for (const listener of this.listeners) listener()\n }\n}\n\nfunction validIncidents(value: unknown): GithubConsistencyIncident[] {\n if (!Array.isArray(value)) return []\n return value.filter((incident): incident is GithubConsistencyIncident => {\n if (!incident || typeof incident !== 'object') return false\n const item = incident as Partial<GithubConsistencyIncident>\n return (\n typeof item.at === 'string' &&\n typeof item.board === 'string' &&\n typeof item.panelId === 'string' &&\n typeof item.endpoint === 'string' &&\n !!item.accepted &&\n !!item.regressed &&\n !!item.response\n )\n })\n}\n\nexport function cacheMetadata(headers: Headers): CacheMetadata | undefined {\n const entries = [\n ['cacheControl', 'cache-control'],\n ['etag', 'etag'],\n ['lastModified', 'last-modified'],\n ['date', 'date'],\n ['age', 'age'],\n ] as const\n const metadata = Object.fromEntries(\n entries.flatMap(([key, header]) => {\n const value = headers.get(header)\n return value ? [[key, value]] : []\n }),\n ) as CacheMetadata\n return Object.keys(metadata).length ? metadata : undefined\n}\n\nfunction emptyRetention(): DiagnosticRetention {\n return { eventsPrunedByAge: 0, eventsPrunedByCount: 0 }\n}\n\nfunction validRetention(value: unknown): DiagnosticRetention {\n if (!value || typeof value !== 'object') return emptyRetention()\n const retention = value as Partial<DiagnosticRetention>\n return {\n eventsPrunedByAge:\n typeof retention.eventsPrunedByAge === 'number' && retention.eventsPrunedByAge >= 0\n ? retention.eventsPrunedByAge\n : 0,\n eventsPrunedByCount:\n typeof retention.eventsPrunedByCount === 'number' && retention.eventsPrunedByCount >= 0\n ? retention.eventsPrunedByCount\n : 0,\n }\n}\n\nfunction prune(events: DiagnosticEvent[], now: Date, priorRetention: DiagnosticRetention) {\n const cutoff = now.valueOf() - maximumAgeMillis\n const current = events.filter(\n (event) =>\n Number.isFinite(new Date(event.at).valueOf()) && new Date(event.at).valueOf() >= cutoff,\n )\n const discardedByAge = events.length - current.length\n const discardedByCount = Math.max(0, current.length - maximumEvents)\n return {\n events: current.slice(-maximumEvents),\n retention: {\n eventsPrunedByAge: priorRetention.eventsPrunedByAge + discardedByAge,\n eventsPrunedByCount: priorRetention.eventsPrunedByCount + discardedByCount,\n },\n }\n}\n\nfunction isDiagnosticEvent(value: unknown): value is PersistedDiagnosticEvent {\n if (!value || typeof value !== 'object') return false\n const event = value as Partial<DiagnosticEvent>\n return (\n (event.schemaVersion === undefined || event.schemaVersion === diagnosticsSchemaVersion) &&\n typeof event.at === 'string' &&\n Number.isFinite(new Date(event.at).valueOf()) &&\n typeof event.sessionId === 'string' &&\n typeof event.board === 'string' &&\n diagnosticKinds.includes(event.kind as (typeof diagnosticKinds)[number])\n )\n}\n","import type { ClientEnv } from '@ze-great-dashboard/shared/browser'\nimport { clientReleaseVersion } from './release-version.ts'\n\nexport type DashboardAuth = {\n accessToken?: string\n onAuthenticationFailure?: (status: 401 | 403) => void\n}\n\n/**\n * Adds browser-supplied diagnostic claims to same-origin dashboard API requests. These headers\n * are deliberately not credentials or authorization inputs: the server treats them as untrusted\n * evidence and normalizes only safe values before logging.\n */\nexport function dashboardFetch(\n env: ClientEnv,\n input: RequestInfo | URL,\n init?: RequestInit,\n fetcher: typeof fetch = globalThis.fetch,\n auth: DashboardAuth = {},\n): Promise<Response> {\n const headers = new Headers(init?.headers)\n headers.set('X-Dashboard-Client-Version', clientReleaseVersion)\n headers.set('X-Dashboard-Client-Origin', globalThis.window.location.origin)\n headers.set('X-Dashboard-Client-Asset-Id', env.assetPathId)\n if (auth.accessToken) headers.set('authorization', `Bearer ${auth.accessToken}`)\n return fetcher(input, { ...init, headers }).then((response) => {\n if (response.status === 401 || response.status === 403)\n auth.onAuthenticationFailure?.(response.status)\n return response\n })\n}\n","import type { analyzeBoardLayout, ClientEnv } from '@ze-great-dashboard/shared/browser'\nimport { useEffect, useState } from 'react'\nimport styles from './App.module.css'\nimport type { DashboardAuth } from './dashboard-fetch.ts'\nimport { dashboardFetch } from './dashboard-fetch.ts'\n\n/** Discloses authored layout conflicts without altering the live board. */\nexport function LayoutWarning({\n board,\n layout,\n env,\n auth,\n}: {\n board: string\n layout: ReturnType<typeof analyzeBoardLayout>\n env: ClientEnv\n auth?: DashboardAuth\n}) {\n const [open, setOpen] = useState(false)\n const dialogId = `layout-warning-${board}`\n\n useEffect(() => {\n if (!open) return\n const closeOnEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setOpen(false)\n }\n window.addEventListener('keydown', closeOnEscape)\n return () => window.removeEventListener('keydown', closeOnEscape)\n }, [open])\n\n const boardPath = `${env.proxyPath}/boards/${encodeURIComponent(board)}`\n return (\n <div className={styles.layoutWarning} data-layout-warning>\n <button\n className={styles.layoutWarningButton}\n type=\"button\"\n aria-label={`Layout warnings (${layout.issues.length})`}\n aria-expanded={open}\n aria-controls={dialogId}\n onClick={() => setOpen(!open)}\n >\n <span aria-hidden=\"true\">⚠</span>\n <span>{layout.issues.length}</span>\n </button>\n {open && (\n <aside\n className={styles.layoutWarningDialog}\n id={dialogId}\n role=\"dialog\"\n aria-labelledby={`${dialogId}-title`}\n aria-modal=\"false\"\n >\n <div className={styles.layoutWarningHeading}>\n <strong id={`${dialogId}-title`}>Layout warnings</strong>\n <button\n className={styles.layoutWarningClose}\n type=\"button\"\n aria-label=\"Close layout warnings\"\n onClick={() => setOpen(false)}\n >\n ×\n </button>\n </div>\n <p>\n {layout.issues.length} layout issue{layout.issues.length === 1 ? '' : 's'} detected\n against the intended 12×12 space. The live board is unchanged: explicit overlaps remain\n overlapped and overflow continues in implicit rows.\n </p>\n <ul>\n {layout.issues.map((issue) => (\n <li key={`${issue.panelId}-${issue.kind}`}>\n <strong>{issue.panelId}</strong>: {issue.kind} at ({issue.position.x},{' '}\n {issue.position.y}), {issue.position.w}×{issue.position.h}\n {issue.conflictsWith.length ? `; overlaps ${issue.conflictsWith.join(', ')}` : ''}\n </li>\n ))}\n </ul>\n <div className={styles.layoutWarningDownloads}>\n <button\n type=\"button\"\n onClick={() => void downloadLayout(env, `${boardPath}/rendered`, auth)}\n >\n Download legal rendered layout\n </button>\n <button\n type=\"button\"\n onClick={() => void downloadLayout(env, `${boardPath}/authored`, auth)}\n >\n Download authored layout\n </button>\n </div>\n <p className={styles.layoutWarningNote}>\n The legal rendered layout normalizes the currently visible explicit area into 12×12 and\n makes the smallest deterministic adjustments needed to avoid collisions. The authored\n layout preserves the original coordinates exactly.\n </p>\n </aside>\n )}\n </div>\n )\n}\n\nasync function downloadLayout(env: ClientEnv, path: string, auth?: DashboardAuth) {\n const response = await dashboardFetch(env, path, undefined, globalThis.fetch, auth)\n if (!response.ok) throw new Error(`Layout download returned ${response.status}`)\n const link = document.createElement('a')\n link.href = URL.createObjectURL(await response.blob())\n link.download =\n response.headers.get('content-disposition')?.match(/filename=\"([^\"]+)\"/)?.[1] ?? 'layout.yaml'\n link.click()\n URL.revokeObjectURL(link.href)\n}\n","import type { ClientEnv } from '@ze-great-dashboard/shared/browser'\nimport { type StateStore, User, UserManager, WebStorageStateStore } from 'oidc-client-ts'\n\nexport type OidcTestBootstrap = {\n accessToken: string\n expiresAt: number\n scope: string\n tokenType: string\n}\n\ndeclare global {\n interface Window {\n /** Ephemeral Playwright-only pre-module input; consumed and deleted before React mounts. */\n __DASHBOARD_OIDC_TEST_BOOTSTRAP__?: OidcTestBootstrap\n }\n}\n\nclass MemoryStore implements StateStore {\n private readonly values = new Map<string, string>()\n async set(key: string, value: string) {\n this.values.set(key, value)\n }\n async get(key: string) {\n return this.values.get(key) ?? null\n }\n async remove(key: string) {\n const value = this.values.get(key) ?? null\n this.values.delete(key)\n return value\n }\n async getAllKeys() {\n return [...this.values.keys()]\n }\n}\n\n/** Creates the standards client; tokens remain in this tab's memory rather than browser storage. */\nexport function createOidcManager(auth: NonNullable<ClientEnv['auth']>) {\n const manager = new UserManager({\n authority: auth.issuer,\n client_id: auth.clientId,\n redirect_uri: `${window.location.origin}/`,\n post_logout_redirect_uri: `${window.location.origin}/`,\n response_type: 'code',\n scope: 'openid profile offline_access',\n resource: auth.audience,\n extraQueryParams: { audience: auth.audience },\n userStore: new MemoryStore(),\n // PKCE transaction data, not tokens, must survive the provider redirect.\n stateStore: new WebStorageStateStore({ store: window.sessionStorage }),\n automaticSilentRenew: true,\n })\n const bootstrap = consumeOidcTestBootstrap(window)\n if (bootstrap) {\n // MemoryStore mutates before its promise resolves, so AuthProvider's later async getUser sees\n // this user without placing a bearer anywhere durable.\n void manager.storeUser(\n new User({\n access_token: bootstrap.accessToken,\n expires_at: bootstrap.expiresAt,\n scope: bootstrap.scope,\n token_type: bootstrap.tokenType,\n // The API token has no ID-token profile. oidc-client-ts requires a profile object even\n // though this dashboard exposes only the access-token capability to its children.\n profile: {\n iss: auth.issuer,\n aud: auth.clientId,\n exp: bootstrap.expiresAt,\n iat: bootstrap.expiresAt - 1,\n sub: 'playwright-token-bootstrap',\n },\n }),\n )\n }\n return manager\n}\n\n/** Removes the test-only global before any application module can retain or expose it. */\nexport function consumeOidcTestBootstrap(source: Window = window): OidcTestBootstrap | undefined {\n const bootstrap = source.__DASHBOARD_OIDC_TEST_BOOTSTRAP__\n delete source.__DASHBOARD_OIDC_TEST_BOOTSTRAP__\n if (\n !bootstrap ||\n typeof bootstrap.accessToken !== 'string' ||\n !bootstrap.accessToken ||\n !Number.isSafeInteger(bootstrap.expiresAt) ||\n typeof bootstrap.scope !== 'string' ||\n typeof bootstrap.tokenType !== 'string'\n )\n return undefined\n return bootstrap\n}\n","import type { ClientEnv } from '@ze-great-dashboard/shared/browser'\nimport { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { AuthProvider, hasAuthParams, useAuth } from 'react-oidc-context'\nimport styles from './AuthBoundary.module.css'\nimport { createOidcManager } from './oidc-manager.ts'\n\nexport function OidcGate({\n env,\n auth,\n children,\n}: {\n env: ClientEnv\n auth: NonNullable<ClientEnv['auth']>\n children: (token: string, denied: () => void) => ReactNode\n}) {\n const manager = useMemo(() => createOidcManager(auth), [auth])\n return (\n <AuthProvider\n userManager={manager}\n onSigninCallback={() =>\n window.history.replaceState({}, document.title, window.location.pathname)\n }\n >\n <AuthScreen env={env}>{children}</AuthScreen>\n </AuthProvider>\n )\n}\n\nfunction AuthScreen({\n env,\n children,\n}: {\n env: ClientEnv\n children: (token: string, denied: () => void) => ReactNode\n}) {\n const auth = useAuth()\n const [denied, setDenied] = useState(false)\n const attemptedSilentSignIn = useRef(false)\n const deny = useCallback(() => setDenied(true), [])\n useEffect(() => {\n if (!auth.isAuthenticated) setDenied(false)\n }, [auth.isAuthenticated])\n useEffect(() => {\n if (\n attemptedSilentSignIn.current ||\n auth.isLoading ||\n auth.isAuthenticated ||\n auth.activeNavigator ||\n hasAuthParams()\n )\n return\n attemptedSilentSignIn.current = true\n // A provider session can re-establish this tab after a reload without retaining a bearer or\n // refresh token in browser storage. `login_required` is the ordinary no-session outcome.\n void auth.signinSilent()\n }, [auth])\n if (auth.isLoading)\n return (\n <main className={styles.auth} aria-live=\"polite\">\n Signing in…\n </main>\n )\n if (denied)\n return (\n <main className={styles.auth}>\n <h1>Access denied</h1>\n <p>Your authenticated identity is not permitted to view this dashboard.</p>\n </main>\n )\n if (!auth.isAuthenticated || !auth.user?.access_token)\n return (\n <main className={styles.auth}>\n <h1>{env.board}</h1>\n <p>Sign in to view the dashboard.</p>\n <button type=\"button\" onClick={() => void auth.signinRedirect()}>\n Sign in\n </button>\n </main>\n )\n return (\n <>\n <button className={styles.signout} type=\"button\" onClick={() => void auth.signoutRedirect()}>\n Sign out\n </button>\n {children(auth.user.access_token, deny)}\n </>\n )\n}\n","/**\n * A panel-shaped hole, so the grid can be looked at and argued with before any signal exists.\n * Replaced by real panels in Stage 2 — nothing here is meant to survive.\n */\nexport function PanelPlaceholder({\n label,\n hint,\n wide = false,\n}: {\n label: string\n hint: string\n wide?: boolean\n}) {\n return (\n <section\n className={`${styles.panel} ${wide ? styles.wide : ''}`}\n data-panel\n data-panel-id=\"placeholder\"\n >\n <h2 className={styles.label}>{label}</h2>\n <p className={styles.hint}>{hint}</p>\n </section>\n )\n}\n\nimport styles from './PanelFrame.module.css'\n","import type { ErrorKind } from '@ze-great-dashboard/shared/browser'\n\nexport function errorPresentation(kind: ErrorKind) {\n switch (kind) {\n case 'unauthorized':\n return { label: 'Access denied', emphasis: 'serious' as const }\n case 'not-found':\n return { label: 'Source not found', emphasis: 'serious' as const }\n case 'unreachable':\n case 'upstream-error':\n return { label: 'Source unavailable', emphasis: 'serious' as const }\n case 'no-runs':\n return { label: 'No workflow runs', emphasis: 'warning' as const }\n }\n}\n","import type { Panel } from '@ze-great-dashboard/shared/browser'\nimport type { CSSProperties } from 'react'\n\n/** Convert the advisory board position into CSS grid placement. */\nexport function panelLayout(panel: Panel): CSSProperties | undefined {\n const position = panel.position\n if (!position) return undefined\n\n return {\n '--panel-column': `${position.x + 1} / span ${position.w}`,\n '--panel-row': `${position.y + 1} / span ${position.h}`,\n } as CSSProperties\n}\n","import type { PipelineStatus } from '@ze-great-dashboard/shared/browser'\n\nimport { panelFeature, panelFeatures } from './panel-registry.tsx'\n\nexport const statusSymbols: Record<PipelineStatus['status'], { glyph: string; label: string }> = {\n passed: { glyph: '✓', label: 'Passed' },\n failed: { glyph: '✕', label: 'Failed' },\n warning: { glyph: '⚠', label: 'Warning' },\n running: { glyph: '↻', label: 'Running' },\n cancelled: { glyph: '⊘', label: 'Cancelled' },\n unknown: { glyph: '?', label: 'Unknown' },\n}\n\nexport function panelTypeSymbol(type: string) {\n return panelFeature(type)?.symbol\n}\n\n/** Every primary glyph and its single semantic meaning, useful for keeping the registry auditable. */\nexport function primarySymbolMeanings() {\n return [\n ...Object.entries(panelFeatures).map(([type, { symbol }]) => ({\n glyph: symbol.glyph,\n meaning: `panel type: ${type}`,\n })),\n ...Object.entries(statusSymbols).map(([status, symbol]) => ({\n glyph: symbol.glyph,\n meaning: `status: ${status}`,\n })),\n ]\n}\n","import type { Envelope, Panel, PipelineStatus } from '@ze-great-dashboard/shared/browser'\nimport type { ReactNode } from 'react'\nimport styles from './PanelFrame.module.css'\nimport { panelLayout } from './panel-layout.ts'\nimport { panelTypeSymbol } from './panel-symbols.ts'\n\ntype PanelStatusKind = PipelineStatus['status']\ntype CompactEvidence = { kind: 'short-value'; value: ReactNode } | { kind: 'glyph-only' }\n\nexport function PanelHint({\n children,\n className,\n title,\n}: {\n children: ReactNode\n className?: string\n title?: string\n}) {\n return (\n <p className={`${styles.hint} ${className ?? ''}`} title={title}>\n {children}\n </p>\n )\n}\n\n/** A concise metadata row with one visible glyph and the full value retained in the DOM. */\nexport function PanelMetadata({\n glyph,\n label,\n value,\n compact,\n title,\n observed = false,\n emphasis,\n className,\n}: {\n glyph: string\n label: string\n value: ReactNode\n /** A text-light visual alternative; the full value remains available to assistive technology. */\n compact?: CompactEvidence\n title?: string\n observed?: boolean\n emphasis?: 'warning' | 'serious'\n className?: string\n}) {\n return (\n <p\n className={`${styles.hint} ${observed ? styles.observed : ''} ${emphasis ? styles[emphasis] : ''} ${styles.meta} ${className ?? ''}`}\n data-panel-meta\n >\n <span aria-hidden=\"true\">{glyph}</span> <span className=\"screen-reader-only\">{label}: </span>\n <span className={styles.metaValue} title={title}>\n <span className={styles.fullValue}>{value}</span>\n {compact && (\n <span className={styles.compactValue} aria-hidden=\"true\">\n {compact.kind === 'short-value' ? compact.value : null}\n </span>\n )}\n </span>\n </p>\n )\n}\n\n/** Stable layout slot for a panel's ordinary readable evidence. */\nexport function PanelEvidence({\n children,\n className,\n priority = 'secondary',\n anchor,\n}: {\n children: ReactNode\n className?: string\n /** Evidence can be intentionally suppressed by a symbol-led compact composition. */\n priority?: 'primary' | 'secondary'\n /** Place this evidence in an opt-in PanelFrame layout slot. */\n anchor?: 'evidence'\n}) {\n return (\n <div\n className={`${styles.evidence} ${className ?? ''}`}\n data-panel-evidence\n data-panel-evidence-priority={priority}\n data-panel-anchor={anchor}\n >\n {children}\n </div>\n )\n}\n\nexport function PanelStatus({\n status,\n emphasis,\n glyph,\n label,\n compactOnly = false,\n}: {\n status?: PanelStatusKind\n emphasis?: 'warning' | 'serious'\n glyph: string\n label: string\n /** Render a compact state only in a portrait tile without changing ordinary cards. */\n compactOnly?: boolean\n}) {\n return (\n <p\n className={`${styles.status} ${status ? styles[status] : ''} ${emphasis ? styles[emphasis] : ''} ${compactOnly ? styles.compactOnlyStatus : ''}`}\n data-panel-status\n >\n {glyph && (\n <span className={styles.statusGlyph} aria-hidden=\"true\">\n {glyph}\n </span>\n )}\n {glyph && label && ' '}\n <span className={styles.statusText}>{label}</span>\n </p>\n )\n}\n\n/** A prominent fact or loading message; unlike PanelStatus, this carries no state semantics. */\nexport function PanelValue({\n children,\n emphasis,\n}: {\n children: ReactNode\n emphasis?: 'warning' | 'serious'\n}) {\n return <p className={`${styles.status} ${emphasis ? styles[emphasis] : ''}`}>{children}</p>\n}\n\nexport function PanelFrame({\n panel,\n envelope,\n sourceLink,\n busy,\n attentionActive = false,\n error = false,\n field,\n layout,\n children,\n}: {\n panel: Panel\n envelope?: Envelope\n /** Retained source evidence may supply a link without inventing an upstream envelope. */\n sourceLink?: string | null\n /** Override loading semantics for retained, readable evidence. */\n busy?: boolean\n attentionActive?: boolean\n error?: boolean\n /** Decorative active-run layer. It is intentionally a sibling of readable panel content. */\n field?: ReactNode\n /** Opt-in slots for health panels with a shared identity, state, and evidence band. */\n layout?: 'status-band'\n children: ReactNode\n}) {\n const density = panel.density ?? 'auto'\n const position = panel.position\n const typeSymbol = panelTypeSymbol(panel.type)\n const shallow = position !== undefined && position.h <= 2\n const short = position !== undefined && position.h <= 3\n return (\n <section\n className={`${styles.panel} ${styles[`density-${density}`]} ${shallow ? styles.shallow : ''} ${short ? styles.short : ''} ${error ? styles.error : ''} ${attentionActive ? styles.attentionActive : ''}`}\n id={`panel-${panel.id}`}\n style={panelLayout(panel)}\n aria-busy={busy === true ? true : envelope || busy === false ? undefined : true}\n data-panel\n data-panel-id={panel.id}\n data-panel-position={\n position ? `${position.x},${position.y},${position.w},${position.h}` : undefined\n }\n data-density={density}\n data-shallow={shallow}\n data-short={short}\n data-error={error || undefined}\n data-panel-type={panel.type}\n data-attention-active={attentionActive || undefined}\n >\n {field}\n <PanelSourceLink panelId={panel.id} link={envelope?.link ?? sourceLink} />\n <div\n className={`${styles.content} ${layout === 'status-band' ? styles.statusBand : ''}`}\n data-panel-content\n data-panel-layout={layout}\n >\n <h2 className={styles.label} data-panel-anchor=\"identity\">\n {typeSymbol && (\n <span\n className={styles.typeGlyph}\n aria-hidden=\"true\"\n title={typeSymbol.label}\n data-panel-type-glyph\n >\n {typeSymbol.glyph}\n </span>\n )}\n <span className={styles.identityText} data-panel-identity-text>\n {panel.label ?? panel.id}\n </span>\n </h2>\n {children}\n </div>\n </section>\n )\n}\n\nfunction PanelSourceLink({ panelId, link }: { panelId: string; link?: string | null }) {\n if (!link) return null\n\n return (\n <a\n className={styles.sourceAction}\n href={link}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={`View source for ${panelId} (opens in a new tab)`}\n title={`View source for ${panelId} (opens in a new tab)`}\n data-panel-action=\"source\"\n data-panel-link\n >\n <span aria-hidden=\"true\">↗</span>\n <span className=\"screen-reader-only\">View source</span>\n </a>\n )\n}\n","import { PanelMetadata } from './PanelFrame.tsx'\nimport type { PanelUpdateHealth } from './panel-props.ts'\n\nexport function ObservedAt({ value, label = 'Observed' }: { value: string; label?: string }) {\n return <TimeAge value={value} label={label} />\n}\n\nexport function PipelineAge({\n sourceUpdatedAt,\n observedAt,\n running,\n runStartedAt,\n}: {\n sourceUpdatedAt?: string\n observedAt: string\n running: boolean\n runStartedAt?: string\n}) {\n if (running && runStartedAt) return <TimeAge value={runStartedAt} label=\"Started\" />\n return (\n <TimeAge\n value={sourceUpdatedAt ?? observedAt}\n label={sourceUpdatedAt ? 'Last update' : 'Observed'}\n />\n )\n}\n\nexport function UpdateHealth({ health }: { health: PanelUpdateHealth }) {\n const unavailable = health.consecutiveFailures >= 3\n const label = unavailable ? 'Updates unavailable' : 'Updates delayed'\n return (\n <>\n <PanelMetadata\n glyph=\"⚠\"\n label={label}\n value={`${label} · ${health.message}`}\n title={health.message}\n emphasis={unavailable ? 'serious' : 'warning'}\n />\n <TimeAge value={health.lastConfirmedAt} label=\"Last confirmed\" />\n </>\n )\n}\n\nexport function LastConfirmedAge({ value }: { value: string }) {\n return <TimeAge value={value} label=\"Last confirmed\" />\n}\n\nfunction TimeAge({ value, label }: { value: string; label: string }) {\n const observed = new Date(value)\n const formatted = observed.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })\n const age = Date.now() - observed.getTime()\n const content = `${label} ${formatAge(age)}`\n return (\n <PanelMetadata\n glyph=\"◷\"\n label={label}\n value={content}\n compact={{ kind: 'short-value', value: formatCompactAge(age) }}\n title={`${label} at ${formatted}`}\n observed\n />\n )\n}\n\nexport function formatAge(milliseconds: number) {\n if (milliseconds < 60_000) return 'just now'\n const minutes = Math.floor(milliseconds / 60_000)\n if (minutes < 60) return `${minutes}m ago`\n const hours = Math.floor(minutes / 60)\n return `${hours}h ${minutes % 60}m ago`\n}\n\nfunction formatCompactAge(milliseconds: number) {\n if (milliseconds < 60_000) return 'now'\n const minutes = Math.floor(milliseconds / 60_000)\n if (minutes < 60) return `${minutes}m`\n const hours = Math.floor(minutes / 60)\n return `${hours}h ${minutes % 60}m`\n}\n","import { httpValueSchema } from '@ze-great-dashboard/shared/browser'\nimport { errorPresentation } from './error-presentation.ts'\nimport styles from './HttpValuePanel.module.css'\nimport { PanelEvidence, PanelFrame, PanelHint, PanelStatus, PanelValue } from './PanelFrame.tsx'\nimport type { HttpValueFactObservation, PanelProps } from './panel-props.ts'\nimport { ObservedAt, UpdateHealth } from './TimeAge.tsx'\n\nexport function HttpValuePanel({\n panel,\n envelope,\n attentionActive,\n updateHealth,\n facts,\n}: PanelProps) {\n if (panel.facts)\n return <GroupedHttpValuePanel panel={panel} attentionActive={attentionActive} facts={facts} />\n if (!envelope)\n return (\n <PanelFrame panel={panel} attentionActive={attentionActive}>\n <PanelEvidence>\n <PanelHint>Loading…</PanelHint>\n </PanelEvidence>\n </PanelFrame>\n )\n if (envelope.state === 'error') {\n const presentation = errorPresentation(envelope.error.kind)\n return (\n <PanelFrame panel={panel} envelope={envelope} attentionActive={attentionActive} error>\n <PanelEvidence>\n <PanelStatus glyph=\"⚠\" label={presentation.label} emphasis={presentation.emphasis} />\n <PanelHint>{envelope.error.message}</PanelHint>\n </PanelEvidence>\n </PanelFrame>\n )\n }\n const signal = httpValueSchema.safeParse(envelope.signal)\n if (!signal.success)\n return (\n <PanelFrame panel={panel} envelope={envelope} attentionActive={attentionActive} error>\n <PanelEvidence>\n <PanelStatus glyph=\"⚠\" label=\"Invalid value\" />\n </PanelEvidence>\n </PanelFrame>\n )\n return (\n <PanelFrame panel={panel} envelope={envelope} attentionActive={attentionActive}>\n <PanelEvidence className={styles.fact}>\n <PanelStatus glyph=\"✓\" label=\"Value read\" compactOnly />\n <PanelValue>{String(signal.data.value)}</PanelValue>\n <ObservedAt value={envelope.observedAt} />\n {updateHealth && <UpdateHealth health={updateHealth} />}\n </PanelEvidence>\n </PanelFrame>\n )\n}\n\nfunction GroupedHttpValuePanel({\n panel,\n attentionActive,\n facts,\n}: Pick<PanelProps, 'panel' | 'attentionActive' | 'facts'>) {\n if (!panel.facts) return null\n return (\n <PanelFrame panel={panel} attentionActive={attentionActive}>\n <PanelEvidence>\n <div className={styles.facts} data-http-value-facts>\n {panel.facts.map((fact) => (\n <HttpValueFactCell key={fact.id} label={fact.label} observation={facts?.[fact.id]} />\n ))}\n </div>\n </PanelEvidence>\n </PanelFrame>\n )\n}\n\nfunction HttpValueFactCell({\n label,\n observation,\n}: {\n label: string\n observation: HttpValueFactObservation | undefined\n}) {\n const envelope = observation?.envelope\n if (!envelope)\n return (\n <section className={styles.factCell} data-http-value-fact>\n <h3>{label}</h3>\n <PanelValue emphasis={observation?.failure ? 'serious' : undefined}>\n {observation?.failure ? '⚠ Updates unavailable' : 'Loading…'}\n </PanelValue>\n {observation?.updateHealth && <UpdateHealth health={observation.updateHealth} />}\n </section>\n )\n if (envelope.state === 'error') {\n const presentation = errorPresentation(envelope.error.kind)\n return (\n <section className={styles.factCell} data-http-value-fact data-error>\n <FactSourceLink label={label} link={envelope.link} />\n <h3>{label}</h3>\n <PanelStatus glyph=\"⚠\" label={presentation.label} emphasis={presentation.emphasis} />\n <PanelHint>{envelope.error.message}</PanelHint>\n <ObservedAt value={envelope.observedAt} />\n </section>\n )\n }\n const signal = httpValueSchema.safeParse(envelope.signal)\n if (!signal.success)\n return (\n <section className={styles.factCell} data-http-value-fact data-error>\n <FactSourceLink label={label} link={envelope.link} />\n <h3>{label}</h3>\n <PanelStatus glyph=\"⚠\" label=\"Invalid value\" emphasis=\"serious\" />\n <ObservedAt value={envelope.observedAt} />\n </section>\n )\n return (\n <section className={styles.factCell} data-http-value-fact>\n <FactSourceLink label={label} link={envelope.link} />\n <h3>{label}</h3>\n <PanelValue>{String(signal.data.value)}</PanelValue>\n <ObservedAt value={envelope.observedAt} />\n </section>\n )\n}\n\nfunction FactSourceLink({ label, link }: { label: string; link: string | null }) {\n if (!link) return null\n return (\n <a\n className={styles.factSource}\n href={link}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={`View source for ${label} (opens in a new tab)`}\n title={`View source for ${label} (opens in a new tab)`}\n >\n <span aria-hidden=\"true\">↗</span>\n <span className=\"screen-reader-only\">View source</span>\n </a>\n )\n}\n","export type FallingDirection = 'horizontal' | 'vertical'\nexport type FallingCell = { x: number; y: number }\nexport type FallingShape = {\n id: number\n bornAt: number\n cells: FallingCell[]\n x: number\n y: number\n targetX?: number\n targetY?: number\n phase: 'entry' | 'align' | 'travel' | 'settled'\n}\n\nexport const FALLING_TARGET_FILL = 0.85\n\nconst shapes: FallingCell[][] = [\n [\n { x: 0, y: 0 },\n { x: 1, y: 0 },\n ],\n [\n { x: 0, y: 0 },\n { x: 0, y: 1 },\n ],\n [\n { x: 0, y: 0 },\n { x: 1, y: 0 },\n { x: 0, y: 1 },\n ],\n [\n { x: 0, y: 0 },\n { x: 1, y: 0 },\n { x: 2, y: 0 },\n ],\n [\n { x: 0, y: 0 },\n { x: 0, y: 1 },\n { x: 1, y: 1 },\n ],\n]\n\nexport function fallingDirection(width: number, height: number): FallingDirection {\n return width > height ? 'horizontal' : 'vertical'\n}\n\nexport function fallingGrid(\n direction: FallingDirection,\n width = direction === 'horizontal' ? 12 : 3,\n height = direction === 'horizontal' ? 3 : 12,\n): { columns: number; rows: number } {\n const fieldWidth = Math.max(1, width * 0.8)\n const fieldHeight = Math.max(1, height * 0.8)\n const cellSize = Math.max(24, Math.min(42, Math.min(fieldWidth, fieldHeight) / 4))\n const columns = Math.max(3, Math.min(24, Math.round(fieldWidth / cellSize)))\n const rows = Math.max(3, Math.min(16, Math.round(fieldHeight / cellSize)))\n return direction === 'horizontal'\n ? { columns: Math.max(columns, rows), rows }\n : { columns, rows: Math.max(rows, columns) }\n}\n\nexport function shapeFits(shape: FallingCell[], columns: number, rows: number): boolean {\n const maxX = Math.max(...shape.map((cell) => cell.x))\n const maxY = Math.max(...shape.map((cell) => cell.y))\n return maxX < columns && maxY < rows\n}\n\nexport function overlaps(left: FallingShape, right: FallingShape): boolean {\n return left.cells.some((leftCell) =>\n right.cells.some(\n (rightCell) =>\n left.x + leftCell.x === right.x + rightCell.x &&\n left.y + leftCell.y === right.y + rightCell.y,\n ),\n )\n}\n\nexport function chooseShape(seed: number, columns: number, rows: number): FallingCell[] {\n const candidates = shapes.filter((shape) => shapeFits(shape, columns, rows))\n return candidates[randomIndex(seed, candidates.length)] ?? [{ x: 0, y: 0 }]\n}\n\nexport function findDestination(\n shape: FallingCell[],\n direction: FallingDirection,\n columns: number,\n rows: number,\n settled: readonly FallingShape[],\n seed = 0,\n requireSupported = false,\n): { x: number; y: number } | undefined {\n const width = Math.max(...shape.map((cell) => cell.x)) + 1\n const height = Math.max(...shape.map((cell) => cell.y)) + 1\n const candidates: Array<{ x: number; y: number; support: number }> = []\n for (let y = 0; y <= rows - height; y++) {\n for (let x = 0; x <= columns - width; x++) {\n const candidate = { id: -1, bornAt: 0, cells: shape, x, y, phase: 'settled' as const }\n if (settled.some((item) => overlaps(candidate, item))) continue\n if (!clearPath(shape, direction, columns, rows, candidate, settled)) continue\n const support =\n direction === 'vertical'\n ? shape.filter(\n (cell) =>\n y + cell.y === rows - 1 ||\n settled.some((item) =>\n item.cells.some(\n (other) =>\n item.x + other.x === x + cell.x && item.y + other.y === y + cell.y + 1,\n ),\n ),\n ).length\n : shape.filter(\n (cell) =>\n x + cell.x === 0 ||\n settled.some((item) =>\n item.cells.some(\n (other) =>\n item.x + other.x === x + cell.x - 1 && item.y + other.y === y + cell.y,\n ),\n ),\n ).length\n if (requireSupported && support < leadingEdgeCount(shape, direction)) continue\n candidates.push({ x, y, support })\n }\n }\n candidates.sort(\n (left, right) =>\n right.support - left.support ||\n (direction === 'vertical'\n ? right.y - left.y || left.x - right.x\n : left.x - right.x || left.y - right.y),\n )\n const bestSupport = candidates[0]?.support\n const best = candidates.filter((candidate) => candidate.support === bestSupport)\n const destination = best[randomIndex(seed, best.length)]\n return destination ? { x: destination.x, y: destination.y } : undefined\n}\n\nexport function findPlacement(\n direction: FallingDirection,\n columns: number,\n rows: number,\n settled: readonly FallingShape[],\n seed: number,\n requireSupported: boolean,\n): { shape: FallingCell[]; destination: { x: number; y: number } } | undefined {\n const candidates = shapes.flatMap((shape, index) => {\n if (!shapeFits(shape, columns, rows)) return []\n const destination = findDestination(\n shape,\n direction,\n columns,\n rows,\n settled,\n seed + index * 31,\n requireSupported,\n )\n return destination ? [{ shape, destination }] : []\n })\n if (candidates.length === 0) return undefined\n return candidates[randomIndex(seed, candidates.length)]\n}\n\nexport function targetCellCount(columns: number, rows: number, progress: number): number {\n return Math.ceil(columns * rows * FALLING_TARGET_FILL * Math.min(1, Math.max(0, progress)))\n}\n\nexport function occupiedCellCount(shapes: readonly FallingShape[]): number {\n return shapes.reduce((count, shape) => count + shape.cells.length, 0)\n}\n\nexport type LineClear = {\n shapes: FallingShape[]\n cleared: FallingCell[]\n complete: boolean\n}\n\n/** Clears only cells in the trailing edge line and slides the surviving field into it. */\nexport function clearTrailingLine(\n direction: FallingDirection,\n columns: number,\n rows: number,\n settled: readonly FallingShape[],\n allowPartial: boolean,\n): LineClear | undefined {\n const edgeLine = direction === 'vertical' ? rows - 1 : 0\n const occupied = new Set(\n settled.flatMap((item) =>\n item.cells\n .filter((cell) =>\n direction === 'vertical' ? item.y + cell.y === edgeLine : item.x + cell.x === edgeLine,\n )\n .map((cell) => (direction === 'vertical' ? item.x + cell.x : item.y + cell.y)),\n ),\n )\n const lineWidth = direction === 'vertical' ? columns : rows\n const complete = occupied.size === lineWidth\n if (!complete && !allowPartial) return undefined\n if (occupied.size === 0) return undefined\n\n const cleared: FallingCell[] = []\n const shapes = settled.flatMap((item) => {\n const remaining = item.cells.filter((cell) => {\n const onLine =\n direction === 'vertical' ? item.y + cell.y === edgeLine : item.x + cell.x === edgeLine\n if (onLine) {\n cleared.push({ x: item.x + cell.x, y: item.y + cell.y })\n }\n return !onLine\n })\n if (remaining.length === 0) return []\n return [\n {\n ...item,\n cells: remaining,\n y: direction === 'vertical' ? item.y + 1 : item.y,\n x: direction === 'horizontal' ? item.x - 1 : item.x,\n },\n ]\n })\n return { shapes, cleared, complete }\n}\n\nexport function buildStaticField(\n direction: FallingDirection,\n columns: number,\n rows: number,\n seed: number,\n count: number,\n): FallingShape[] {\n const settled: FallingShape[] = []\n for (let id = 0; id < count; id += 1) {\n const pieceSeed = seed + id * 17\n const shape = chooseShape(pieceSeed, columns, rows)\n const destination = findDestination(shape, direction, columns, rows, settled, pieceSeed + 1)\n if (!destination) break\n settled.push({\n id,\n bornAt: 0,\n cells: shape,\n x: destination.x,\n y: destination.y,\n phase: 'settled',\n })\n }\n return settled\n}\n\nfunction leadingEdgeCount(shape: FallingCell[], direction: FallingDirection): number {\n if (direction === 'vertical') {\n return new Set(shape.map((cell) => cell.x)).size\n }\n return new Set(shape.map((cell) => cell.y)).size\n}\n\nfunction clearPath(\n shape: FallingCell[],\n direction: FallingDirection,\n columns: number,\n rows: number,\n destination: FallingShape,\n settled: readonly FallingShape[],\n): boolean {\n const width = Math.max(...shape.map((cell) => cell.x)) + 1\n const height = Math.max(...shape.map((cell) => cell.y)) + 1\n if (direction === 'vertical') {\n for (let y = 0; y <= destination.y; y += 1) {\n if (settled.some((item) => overlaps({ ...destination, y }, item))) return false\n }\n return destination.y + height <= rows\n }\n for (let x = columns - width; x >= destination.x; x -= 1) {\n if (settled.some((item) => overlaps({ ...destination, x }, item))) return false\n }\n return destination.x + width <= columns\n}\n\nfunction randomIndex(seed: number, length: number): number {\n if (length <= 1) return 0\n const value = Math.sin(seed * 12.9898 + 78.233) * 43_758.5453\n return Math.floor((value - Math.floor(value)) * length)\n}\n","import {\n clearTrailingLine,\n type FallingCell,\n type FallingDirection,\n type FallingShape,\n findPlacement,\n occupiedCellCount,\n targetCellCount,\n} from './falling-shapes.ts'\n\nexport const FALLING_ENTRY_MS = 250\nexport const FALLING_TRAVEL_MS = 850\nexport const FALLING_RECYCLE_MS = 500\nexport const FALLING_PIECE_INTERVAL_MS = 1_250\n\nexport type FallingSimulation = {\n settled: FallingShape[]\n active: FallingShape[]\n nextPieceAt: number\n recycleUntil: number\n nextId: number\n recycling: boolean\n clearingCells: FallingCell[]\n}\n\ntype SimulationInput = {\n elapsed: number\n direction: FallingDirection\n columns: number\n rows: number\n progress: number\n estimatedDurationMs?: number\n overdue: boolean\n seed: number\n}\n\nexport function createFallingSimulation(): FallingSimulation {\n return {\n settled: [],\n active: [],\n nextPieceAt: FALLING_PIECE_INTERVAL_MS,\n recycleUntil: 0,\n nextId: 0,\n recycling: false,\n clearingCells: [],\n }\n}\n\nexport function advanceFallingSimulation(\n simulation: FallingSimulation,\n input: SimulationInput,\n): FallingSimulation {\n if (input.elapsed < simulation.recycleUntil) return simulation\n let settled = simulation.settled\n let active = simulation.active\n let nextPieceAt = simulation.nextPieceAt\n const recycleUntil = simulation.recycleUntil\n let nextId = simulation.nextId\n let recycling = simulation.recycling\n let clearingCells = simulation.clearingCells\n\n if (recycling) {\n recycling = false\n clearingCells = []\n }\n if (input.elapsed >= nextPieceAt && active.length === 0) {\n const target = targetCellCount(input.columns, input.rows, input.progress)\n if (input.progress < 1 && occupiedCellCount(settled) >= target)\n return { ...simulation, recycling, clearingCells }\n const placement = findPlacement(\n input.direction,\n input.columns,\n input.rows,\n settled,\n input.seed + nextId * 17 + 1,\n !input.overdue,\n )\n if (!placement && (input.progress >= 1 || input.estimatedDurationMs === undefined)) {\n const cleared = clearTrailingLine(input.direction, input.columns, input.rows, settled, true)\n if (cleared) {\n return {\n ...simulation,\n settled: cleared.shapes,\n recycleUntil: input.elapsed + FALLING_RECYCLE_MS,\n nextPieceAt: input.elapsed + FALLING_RECYCLE_MS,\n recycling: true,\n clearingCells: cleared.cleared,\n }\n }\n }\n if (placement) {\n const height = Math.max(...placement.shape.map((cell) => cell.y)) + 1\n active = [\n {\n id: nextId,\n bornAt: input.elapsed,\n cells: placement.shape,\n x:\n input.direction === 'horizontal'\n ? input.columns - Math.max(...placement.shape.map((cell) => cell.x)) - 0.5\n : placement.destination.x,\n y: input.direction === 'vertical' ? -height + 0.5 : placement.destination.y,\n targetX: placement.destination.x,\n targetY: placement.destination.y,\n phase: 'entry',\n },\n ]\n nextId += 1\n nextPieceAt += pieceInterval(input.estimatedDurationMs, input.columns, input.rows)\n }\n }\n const nextActive: FallingShape[] = []\n for (const piece of active) {\n const age = input.elapsed - piece.bornAt\n const amount = Math.min(1, Math.max(0, (age - FALLING_ENTRY_MS) / FALLING_TRAVEL_MS))\n if (amount >= 1 && piece.targetX !== undefined && piece.targetY !== undefined) {\n settled = [...settled, { ...piece, x: piece.targetX, y: piece.targetY, phase: 'settled' }]\n continue\n }\n const startX =\n input.direction === 'horizontal'\n ? input.columns - Math.max(...piece.cells.map((cell) => cell.x)) - 1\n : (piece.targetX ?? piece.x)\n const startY = input.direction === 'vertical' ? 0 : (piece.targetY ?? piece.y)\n const lifecycleAmount = Math.min(1, Math.max(0, age / (FALLING_ENTRY_MS + FALLING_TRAVEL_MS)))\n nextActive.push({\n ...piece,\n x:\n input.direction === 'horizontal'\n ? startX + ((piece.targetX ?? startX) - startX) * amount\n : startX,\n y:\n input.direction === 'vertical'\n ? startY + ((piece.targetY ?? startY) - startY) * amount\n : startY,\n phase: age < FALLING_ENTRY_MS ? 'entry' : lifecycleAmount < 0.35 ? 'align' : 'travel',\n })\n }\n return {\n settled,\n active: nextActive,\n nextPieceAt,\n recycleUntil,\n nextId,\n recycling,\n clearingCells,\n }\n}\n\nexport function visibleFallingShapes(simulation: FallingSimulation) {\n return [...simulation.settled, ...simulation.active]\n}\n\nfunction pieceInterval(estimatedDurationMs: number | undefined, columns: number, rows: number) {\n const target = Math.ceil(columns * rows * 0.85)\n return estimatedDurationMs === undefined || target <= 0\n ? FALLING_PIECE_INTERVAL_MS\n : Math.max(400, estimatedDurationMs / Math.max(1, Math.ceil(target / 3)))\n}\n","import type { CSSProperties } from 'react'\nimport { useEffect, useRef, useState } from 'react'\nimport styles from './FallingShapesField.module.css'\nimport {\n buildStaticField,\n type FallingDirection,\n fallingDirection,\n fallingGrid,\n} from './falling-shapes.ts'\nimport {\n advanceFallingSimulation,\n createFallingSimulation,\n visibleFallingShapes,\n} from './falling-simulation.ts'\n\nconst TICK_MS = 50\ntype Geometry = { columns: number; rows: number; direction: FallingDirection }\n\nexport function FallingShapesField({\n progress,\n estimatedDurationMs,\n overdue,\n seed = 0,\n}: {\n progress: number\n estimatedDurationMs?: number\n overdue: boolean\n seed?: number\n}) {\n const rootRef = useRef<HTMLDivElement>(null)\n const [geometry, setGeometry] = useState<Geometry>({\n ...fallingGrid('vertical'),\n direction: 'vertical',\n })\n const [reducedMotion, setReducedMotion] = useState(false)\n const [view, setView] = useState(createFallingSimulation)\n const geometryRef = useRef(geometry)\n const directionRef = useRef<FallingDirection | undefined>(undefined)\n const progressRef = useRef(progress)\n const seedRef = useRef(seed)\n const simulationRef = useRef(createFallingSimulation())\n const startedAtRef = useRef(Date.now())\n\n useEffect(() => {\n progressRef.current = progress\n seedRef.current = seed\n }, [progress, seed])\n useEffect(() => {\n const root = rootRef.current\n if (!root) return\n const update = () => {\n const rect = root.getBoundingClientRect()\n if (rect.width === 0 || rect.height === 0) return\n const direction = directionRef.current ?? fallingDirection(rect.width, rect.height)\n directionRef.current = direction\n const next = { ...fallingGrid(direction, rect.width, rect.height), direction }\n geometryRef.current = next\n setGeometry(next)\n }\n update()\n if (typeof ResizeObserver === 'undefined') return\n const observer = new ResizeObserver(update)\n observer.observe(root)\n return () => observer.disconnect()\n }, [])\n useEffect(() => {\n const media = window.matchMedia('(prefers-reduced-motion: reduce)')\n const update = () => setReducedMotion(media.matches)\n update()\n media.addEventListener?.('change', update)\n return () => media.removeEventListener?.('change', update)\n }, [])\n useEffect(() => {\n simulationRef.current = createFallingSimulation()\n startedAtRef.current = Date.now()\n if (reducedMotion) {\n const settled = buildStaticField(\n geometry.direction,\n geometry.columns,\n geometry.rows,\n seedRef.current,\n Math.max(1, Math.floor(progressRef.current * 6)),\n )\n setView({ ...createFallingSimulation(), settled })\n return\n }\n setView(simulationRef.current)\n }, [geometry, reducedMotion])\n useEffect(() => {\n if (reducedMotion) return\n const timer = window.setInterval(() => {\n const next = advanceFallingSimulation(simulationRef.current, {\n elapsed: Date.now() - startedAtRef.current,\n ...geometryRef.current,\n progress: progressRef.current,\n estimatedDurationMs,\n overdue,\n seed: seedRef.current,\n })\n simulationRef.current = next\n setView(next)\n }, TICK_MS)\n return () => window.clearInterval(timer)\n }, [estimatedDurationMs, overdue, reducedMotion])\n const pieces = visibleFallingShapes(view)\n return (\n <div\n ref={rootRef}\n className={styles.field}\n data-running-part=\"falling-shapes-field\"\n data-overdue={overdue || undefined}\n data-direction={geometry.direction}\n data-recycling={view.recycling || undefined}\n style={\n { '--shape-columns': geometry.columns, '--shape-rows': geometry.rows } as CSSProperties\n }\n >\n <div className={styles.grid}>\n {view.clearingCells.map((cell) => (\n <span\n key={`${cell.x}-${cell.y}`}\n className={styles.clearingCell}\n style={{ '--clear-x': cell.x, '--clear-y': cell.y } as CSSProperties}\n />\n ))}\n {pieces.map((piece) => (\n <div\n key={piece.id}\n className={styles.piece}\n data-piece={piece.id}\n data-piece-phase={piece.phase}\n style={\n {\n '--piece-x': piece.x,\n '--piece-y': piece.y,\n '--piece-width': Math.max(...piece.cells.map((cell) => cell.x)) + 1,\n '--piece-height': Math.max(...piece.cells.map((cell) => cell.y)) + 1,\n } as CSSProperties\n }\n >\n {piece.cells.map((cell) => (\n <span\n key={`${cell.x}-${cell.y}`}\n className={styles.cell}\n style={{ '--cell-x': cell.x, '--cell-y': cell.y } as CSSProperties}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n )\n}\n","import type { CSSProperties } from 'react'\nimport styles from './FlightPathField.module.css'\n\nexport type FlightStage = 'rollout' | 'climb' | 'cruise' | 'approach' | 'holding'\n\nexport type FlightPosition = {\n /** Position in the decorative world, before the camera follows the aircraft. */\n worldX: number\n worldY: number\n /** Camera displacement in field percentages. */\n cameraX: number\n cameraY: number\n /** Aircraft position in the clipped field after camera displacement. */\n x: number\n y: number\n /** Deliberate aircraft attitude, not the tangent of its world journey. */\n pitch: number\n /** Extra downward displacement that lets the ground leave during cruise and return on approach. */\n groundOffsetY: number\n stage: FlightStage\n}\n\ntype Point = { x: number; y: number }\n\nconst departure: Point = { x: 8, y: 74 }\nconst rotation: Point = { x: 22, y: 74 }\nconst cruiseStart: Point = { x: 38, y: 30 }\nconst cruiseEnd: Point = { x: 65, y: 30 }\n// The final frame is still well above the ground: an active run has not arrived.\nconst approachEnd: Point = { x: 88, y: 48 }\n\nfunction pointOnLine(from: Point, to: Point, progress: number): Point {\n return { x: from.x + (to.x - from.x) * progress, y: from.y + (to.y - from.y) * progress }\n}\n\nfunction pointOnCubic(\n start: Point,\n controlOne: Point,\n controlTwo: Point,\n end: Point,\n progress: number,\n): Point {\n const inverse = 1 - progress\n return {\n x:\n inverse ** 3 * start.x +\n 3 * inverse ** 2 * progress * controlOne.x +\n 3 * inverse * progress ** 2 * controlTwo.x +\n progress ** 3 * end.x,\n y:\n inverse ** 3 * start.y +\n 3 * inverse ** 2 * progress * controlOne.y +\n 3 * inverse * progress ** 2 * controlTwo.y +\n progress ** 3 * end.y,\n }\n}\n\nfunction frame(\n world: Point,\n camera: Point,\n pitch: number,\n stage: FlightStage,\n groundOffsetY = 0,\n): FlightPosition {\n return {\n worldX: world.x,\n worldY: world.y,\n cameraX: camera.x,\n cameraY: camera.y,\n x: world.x - camera.x,\n y: world.y - camera.y,\n pitch,\n groundOffsetY,\n stage,\n }\n}\n\nfunction followCamera(world: Point): Point {\n return { x: world.x - 50, y: world.y - 50 }\n}\n\n/**\n * Maps estimated elapsed progress to world movement, a deliberately lagged camera, and restrained\n * aircraft attitude. Keeping those concerns separate makes the field read as a tracked flight,\n * rather than as a route diagram.\n */\nexport function flightPosition(progress: number, indeterminate: boolean): FlightPosition {\n if (indeterminate) {\n const world = { x: 50, y: 30 }\n return frame(world, followCamera(world), 0, 'holding', 20)\n }\n const clamped = Math.min(1, Math.max(0, progress))\n if (clamped < 0.18)\n return frame(pointOnLine(departure, rotation, clamped / 0.18), { x: 0, y: 0 }, 0, 'rollout')\n if (clamped < 0.35) {\n const phase = (clamped - 0.18) / 0.17\n const world = pointOnCubic(rotation, { x: 28, y: 74 }, { x: 32, y: 30 }, cruiseStart, phase)\n // The camera takes a moment to catch up after rotation instead of snapping the plane center.\n const engagement = phase * phase * (3 - 2 * phase)\n const target = followCamera(world)\n return frame(\n world,\n { x: target.x * engagement, y: target.y * engagement },\n -7,\n 'climb',\n 20 * engagement,\n )\n }\n if (clamped < 0.7) {\n const world = pointOnLine(cruiseStart, cruiseEnd, (clamped - 0.35) / 0.35)\n return frame(world, followCamera(world), 0, 'cruise', 20)\n }\n const phase = (clamped - 0.7) / 0.3\n const world = pointOnCubic(cruiseEnd, { x: 72, y: 30 }, { x: 80, y: 47 }, approachEnd, phase)\n // Reintroduce the ground only during approach; cruise should read as open air.\n const returnGround = phase * phase * (3 - 2 * phase)\n return frame(world, followCamera(world), 4, 'approach', 20 * (1 - returnGround))\n}\n\n/** Decorative estimated-flight progress, framed as a camera-following aircraft shot. */\nexport function FlightPathField({\n progress,\n indeterminate,\n}: {\n progress: number\n indeterminate: boolean\n}) {\n const position = flightPosition(progress, indeterminate)\n const style = {\n '--flight-x': `${position.x}%`,\n '--flight-y': `${position.y}%`,\n '--flight-camera-x': `${position.cameraX}%`,\n '--flight-camera-y': `${position.cameraY}%`,\n '--flight-ground-x': `${-position.cameraX}%`,\n '--flight-ground-y': `${-position.cameraY + position.groundOffsetY}%`,\n '--flight-cloud-x': `${-position.cameraX * 0.45}%`,\n '--flight-cloud-y': `${-position.cameraY * 0.32}%`,\n '--flight-pitch': `${position.pitch}deg`,\n } as CSSProperties\n return (\n <span\n className={styles.scene}\n data-running-part=\"flight-path\"\n data-flight-stage={position.stage}\n style={style}\n >\n <span className={styles.ground} data-running-part=\"flight-ground\">\n <span className={styles.groundGlow} />\n <span className={styles.groundTerrain} data-running-part=\"flight-ground-terrain\" />\n <span\n className={styles.groundTerrainOverdrive}\n data-running-part=\"flight-ground-overdrive\"\n />\n <span className={styles.groundRunway} data-running-part=\"flight-ground-runway\" />\n </span>\n <span\n className={`${styles.cloudLayer} ${styles.cloudLayerFar}`}\n data-running-part=\"flight-cloud-layer\"\n data-flight-depth=\"far\"\n >\n <span className={`${styles.cloud} ${styles.cloudOne}`} data-running-part=\"flight-cloud\" />\n <span className={`${styles.cloud} ${styles.cloudTwo}`} data-running-part=\"flight-cloud\" />\n <span className={`${styles.cloud} ${styles.cloudThree}`} data-running-part=\"flight-cloud\" />\n <span className={`${styles.cloud} ${styles.cloudFour}`} data-running-part=\"flight-cloud\" />\n </span>\n <span className={styles.plane} data-running-part=\"flight-plane\">\n <svg className={styles.aircraft} viewBox=\"0 0 72 40\" aria-hidden=\"true\">\n <path\n data-running-part=\"flight-fuselage\"\n d=\"M3 21c5-4 12-6 23-6h27c8 0 13 2 16 5-3 3-8 5-16 5H26C15 25 8 24 3 21Z\"\n />\n <path data-running-part=\"flight-wing\" d=\"m33 23 17 11h-12L23 24Z\" />\n <path data-running-part=\"flight-tail\" d=\"m13 17 5-11h7l-1 11Z\" />\n <path className={styles.windows} d=\"M25 18h4v2h-4zm7 0h4v2h-4zm7 0h4v2h-4z\" />\n </svg>\n </span>\n <span\n className={`${styles.cloudLayer} ${styles.cloudLayerNear}`}\n data-running-part=\"flight-cloud-layer\"\n data-flight-depth=\"near\"\n >\n <span className={`${styles.cloud} ${styles.cloudFive}`} data-running-part=\"flight-cloud\" />\n <span className={`${styles.cloud} ${styles.cloudSix}`} data-running-part=\"flight-cloud\" />\n <span className={`${styles.cloud} ${styles.cloudSeven}`} data-running-part=\"flight-cloud\" />\n <span className={`${styles.cloud} ${styles.cloudEight}`} data-running-part=\"flight-cloud\" />\n </span>\n </span>\n )\n}\n","import styles from './ReleaseTransitField.module.css'\n\nexport function ReleaseTransitField() {\n return (\n <>\n <span className={styles.frontier} data-running-part=\"frontier\" />\n <span className={styles.now} data-running-part=\"transit-now\" />\n <span className={styles.routes} data-running-part=\"transit-routes\">\n {[0, 1, 2].map((route) => (\n <span className={styles.route} key={route} />\n ))}\n </span>\n <span className={styles.trail} data-running-part=\"transit-trail\" />\n <span className={styles.packet} data-running-part=\"transit-packet\" />\n </>\n )\n}\n","export type SnowmanScheduleMode = 'snowfall' | 'arrival' | 'hop' | 'full'\n\nexport type SnowmanSchedule = {\n mode: SnowmanScheduleMode\n bodyStart: number\n bodyEnd: number\n headStart: number\n hopStart: number\n land: number\n settleEnd: number\n end: number\n}\n\n/** Derive one deterministic choreography from the complete expected run duration. */\nexport function snowmanSchedule(duration: number): SnowmanSchedule {\n const bodyWindow = duration * 0.25\n const headWindow = duration * 0.2\n const mode: SnowmanScheduleMode =\n bodyWindow < 700 || headWindow < 350\n ? 'snowfall'\n : headWindow < 530\n ? 'arrival'\n : headWindow < 1030\n ? 'hop'\n : 'full'\n const scale = clamp(\n (headWindow - (mode === 'full' ? 1030 : 530)) / (mode === 'full' ? 1620 : 620),\n 0,\n 1,\n )\n const roll = mode === 'full' ? 500 + 1000 * scale : 0\n const tail = mode === 'arrival' ? 0 : 180 + 70 * scale\n const hop = mode === 'arrival' ? Math.min(900, headWindow) : 350 + 550 * scale\n const end = duration * 0.95\n const land = end - tail\n return {\n mode,\n bodyStart: duration * 0.75 - Math.min(2500, bodyWindow),\n bodyEnd: duration * 0.75,\n headStart: land - hop - roll,\n hopStart: land - hop,\n land,\n settleEnd: land + (tail ? 120 + 60 * scale : 0),\n end,\n }\n}\n\nexport function scheduleAmount(time: number, start: number, end: number) {\n return end === start ? Number(time >= end) : clamp((time - start) / (end - start), 0, 1)\n}\n\nexport function smoothScheduleAmount(value: number) {\n return value * value * (3 - 2 * value)\n}\n\nfunction clamp(value: number, low: number, high: number) {\n return Math.max(low, Math.min(high, value))\n}\n","export type SnowmanPhase = 'drift' | 'snowing' | 'assembling' | 'complete' | 'overdue'\nexport type SnowCellOwner = 'ground' | 'body' | 'head' | 'snowman'\nexport type SnowmanDimensions = { width: number; height: number }\n\nexport type SnowCell = {\n id: number\n x: number\n y: number\n owner: SnowCellOwner\n /** Coordinates relative to a rolling ball. Ground and accumulated snow omit these. */\n localX?: number\n localY?: number\n targetLocalX?: number\n targetLocalY?: number\n packed?: boolean\n}\nexport type AirborneFlake = { id: number; x: number; y: number; bornAt: number }\nexport type Snowball = {\n kind: 'body' | 'head'\n x: number\n y: number\n radius: number\n angle: number\n /** A placed ball no longer follows the relaxing terrain beneath it. */\n locked: boolean\n /** The final support position captured when the body locks. */\n supportY?: number\n launch?: { x: number; y: number }\n}\nexport type SnowmanSimulation = {\n nextAt: number\n id: number\n lastElapsed: number\n grid: { columns: number; rows: number }\n flakes: AirborneFlake[]\n cells: SnowCell[]\n body?: Snowball\n head?: Snowball\n toppling?: { startedAt: number; angle: number; pivotX: number; pivotY: number }\n toppled: boolean\n hat?: { x: number; y: number; angle: number }\n}\n\nexport { snowmanSchedule } from './snowman-timing.ts'\n\nimport {\n scheduleAmount as amount,\n smoothScheduleAmount as ease,\n snowmanSchedule,\n} from './snowman-timing.ts'\n\nconst STEP_MS = 25\nconst ASSEMBLY_START = 0.5\nconst HAT_AT = 0.95\n/** Attached snowfall at which the completed decorative figure falls and stays down. */\nexport const SNOWMAN_TOPPLE_LOAD = 60\n\nexport function createSnowmanSimulation(\n dimensions: SnowmanDimensions = { width: 360, height: 180 },\n): SnowmanSimulation {\n return {\n nextAt: 0,\n id: 0,\n lastElapsed: 0,\n grid: snowmanGrid(dimensions),\n flakes: [],\n cells: [],\n toppled: false,\n }\n}\n\nexport function snowmanGrid(dimensions: SnowmanDimensions) {\n // Four device-independent pixels gives fine grain without making a compact field expensive.\n const columns = clamp(Math.round(dimensions.width / 4), 48, 180)\n const rows = clamp(Math.round(dimensions.height / 4), 28, 100)\n return { columns, rows }\n}\n\nexport function snowmanScenePhase(\n progress: number,\n estimatedDurationMs: number | undefined,\n overdue: boolean,\n): SnowmanPhase {\n if (overdue) return 'overdue'\n if (estimatedDurationMs === undefined) return 'snowing'\n if (snowmanSchedule(estimatedDurationMs).mode === 'snowfall') return 'snowing'\n if (progress >= HAT_AT) return 'complete'\n if (progress >= ASSEMBLY_START) return 'assembling'\n return 'drift'\n}\n\n/** A permanent slight breeze plus seed-stable, visibly stronger intermittent gusts. */\nexport function snowmanWind(seed: number, elapsed: number) {\n const direction = random(seed + 41) < 0.5 ? -1 : 1\n const breeze = direction * (0.72 + random(seed + 43) * 0.45)\n const smallVariation = Math.sin(elapsed / 1_600 + random(seed + 47) * Math.PI * 2) * 0.4\n const gustWave = Math.max(0, Math.sin(elapsed / 3_100 + random(seed + 53) * Math.PI * 2))\n const gust = direction * gustWave ** 7 * (3.2 + random(seed + 59) * 1.8)\n return breeze + smallVariation + gust\n}\n\nexport function snowmanMaterialCount(dimensions: SnowmanDimensions) {\n const grid = snowmanGrid(dimensions)\n return Math.round(grid.columns * grid.rows * 0.18)\n}\n\nexport function snowmanSpawnInterval(\n estimatedDurationMs: number | undefined,\n dimensions: SnowmanDimensions,\n overdue = false,\n elapsed = 0,\n) {\n if (estimatedDurationMs === undefined) return overdue ? 30 : 60\n const ordinary = (estimatedDurationMs * HAT_AT) / snowmanMaterialCount(dimensions)\n if (overdue) return ordinary / 2\n const schedule = snowmanSchedule(estimatedDurationMs)\n if (schedule.mode !== 'snowfall' && elapsed >= Math.max(0, schedule.bodyStart - 500)) {\n return ordinary * 4\n }\n return ordinary\n}\n\n/** Advances a fixed-step cellular snow simulation without reading the DOM or a browser clock. */\nexport function advanceSnowmanSimulation(\n previous: SnowmanSimulation,\n {\n elapsed,\n progress,\n estimatedDurationMs,\n overdue,\n seed,\n dimensions,\n }: {\n elapsed: number\n progress: number\n estimatedDurationMs?: number\n overdue: boolean\n seed: number\n dimensions: SnowmanDimensions\n },\n): SnowmanSimulation {\n const grid = snowmanGrid(dimensions)\n let simulation =\n previous.grid.columns === grid.columns && previous.grid.rows === grid.rows\n ? clone(previous)\n : createSnowmanSimulation(dimensions)\n const targetElapsed = Math.max(simulation.lastElapsed, elapsed)\n for (let time = simulation.lastElapsed + STEP_MS; time <= targetElapsed; time += STEP_MS) {\n simulation = step(\n simulation,\n time,\n estimatedDurationMs === undefined ? progress : time / estimatedDurationMs,\n estimatedDurationMs,\n overdue && (estimatedDurationMs === undefined || time >= estimatedDurationMs),\n seed,\n dimensions,\n )\n simulation.lastElapsed = time\n }\n return simulation\n}\n\nexport function snowmanLoad(cells: readonly SnowCell[]) {\n return cells.filter((cell) => cell.owner === 'snowman').length\n}\n\nexport function resolvedCells(simulation: SnowmanSimulation) {\n return simulation.cells.map((cell) => {\n const ball =\n cell.owner === 'body' ? simulation.body : cell.owner === 'head' ? simulation.head : undefined\n const resolved =\n ball && cell.localX !== undefined && cell.localY !== undefined\n ? {\n ...cell,\n x: ball.x + cell.localX * Math.cos(ball.angle) - cell.localY * Math.sin(ball.angle),\n y: ball.y + cell.localX * Math.sin(ball.angle) + cell.localY * Math.cos(ball.angle),\n }\n : cell\n return simulation.toppling && resolved.owner !== 'ground'\n ? rotateAround(resolved, simulation.toppling)\n : resolved\n })\n}\n\nexport function resolvedBallCenter(simulation: SnowmanSimulation, ball: Snowball) {\n return simulation.toppling ? rotateAround(ball, simulation.toppling) : ball\n}\n\nfunction step(\n simulation: SnowmanSimulation,\n elapsed: number,\n progress: number,\n estimatedDurationMs: number | undefined,\n overdue: boolean,\n seed: number,\n dimensions: SnowmanDimensions,\n) {\n const phase = snowmanScenePhase(progress, estimatedDurationMs, overdue)\n const interval = snowmanSpawnInterval(estimatedDurationMs, dimensions, overdue, elapsed)\n while (elapsed >= simulation.nextAt) {\n simulation.flakes.push({\n id: simulation.id++,\n x: random(seed + simulation.id * 17) * simulation.grid.columns,\n y: -1 - random(seed + simulation.id * 23) * 6,\n bornAt: simulation.nextAt,\n })\n simulation.nextAt += interval\n }\n\n updateBalls(simulation, progress, estimatedDurationMs, overdue)\n const occupied = occupiedCells(simulation)\n const wind = snowmanWind(seed, elapsed) * (STEP_MS / 1_000)\n const fall =\n estimatedDurationMs === undefined\n ? 0.52\n : Math.max(0.52, ((simulation.grid.rows + 7) * STEP_MS) / (estimatedDurationMs * 0.25))\n const nextFlakes: AirborneFlake[] = []\n for (const flake of simulation.flakes) {\n const moved = { ...flake, x: flake.x + wind, y: flake.y + fall }\n const ball = hitBall(simulation, moved)\n if (ball) {\n joinBall(simulation, ball, flake.id, moved.x - ball.x, moved.y - ball.y)\n continue\n }\n const resting = findRestingCell(moved, occupied, simulation.grid, wind, seed)\n if (!resting) {\n nextFlakes.push({ ...moved, x: clamp(moved.x, 0, simulation.grid.columns - 1) })\n continue\n }\n const belowOwner = occupied.get(key(resting.x, resting.y + 1))\n simulation.cells.push({\n id: flake.id,\n x: resting.x,\n y: resting.y,\n owner:\n belowOwner === 'body' || belowOwner === 'head' || belowOwner === 'snowman'\n ? 'snowman'\n : 'ground',\n })\n occupied.set(key(resting.x, resting.y), simulation.cells.at(-1)?.owner ?? 'ground')\n }\n simulation.flakes = nextFlakes\n if (estimatedDurationMs !== undefined && phase !== 'drift' && phase !== 'snowing')\n collectTouchedGround(simulation)\n compactBallCells(simulation)\n // A small cascade closes a swept gap promptly without making the whole bank flow at once.\n relaxSettledSnow(simulation, seed, elapsed)\n relaxSettledSnow(simulation, seed, elapsed + STEP_MS / 2)\n const body = simulation.body\n if (body?.locked) {\n body.supportY ??= restingBallY(simulation, body.x, body.radius, body.y + body.radius)\n body.y = body.supportY\n }\n if (\n overdue &&\n !simulation.toppling &&\n !simulation.toppled &&\n snowmanLoad(simulation.cells) >= SNOWMAN_TOPPLE_LOAD\n )\n beginTopple(simulation, elapsed)\n advanceTopple(simulation, elapsed)\n return simulation\n}\n\nfunction updateBalls(\n simulation: SnowmanSimulation,\n progress: number,\n estimatedDurationMs: number | undefined,\n _overdue: boolean,\n) {\n if (estimatedDurationMs === undefined) return\n const schedule = snowmanSchedule(estimatedDurationMs)\n if (schedule.mode === 'snowfall') return\n const time = progress * estimatedDurationMs\n const { columns, rows } = simulation.grid\n const bodyAmount = ease(amount(time, schedule.bodyStart, schedule.bodyEnd))\n if (time >= schedule.bodyStart && !simulation.body) {\n const x = columns * 0.14\n simulation.body = {\n kind: 'body',\n x,\n y: restingBallY(simulation, x, 2, rows - 1),\n radius: 2,\n angle: 0,\n locked: false,\n }\n }\n const body = simulation.body\n if (body && !body.locked) {\n body.radius = Math.max(body.radius, ballRadius(simulation, 'body', 2))\n const x = columns * (0.14 + 0.38 * bodyAmount)\n rollBallTo(body, x, restingBallY(simulation, x, body.radius, rows - 1))\n body.locked = time >= schedule.bodyEnd\n }\n if (time >= schedule.headStart && !simulation.head) {\n const x = columns * (schedule.mode === 'full' ? 0.88 : 0.66)\n simulation.head = {\n kind: 'head',\n x,\n y: restingBallY(simulation, x, 1.7, rows - 1),\n radius: 1.7,\n angle: 0,\n locked: false,\n }\n collectTouchedGround(simulation)\n }\n const head = simulation.head\n if (head && body && !head.locked) {\n head.radius = Math.max(head.radius, ballRadius(simulation, 'head', 1.7))\n if (time < schedule.hopStart) {\n const rolling = ease(amount(time, schedule.headStart, schedule.hopStart))\n const x = columns * (0.88 - 0.22 * rolling)\n rollBallTo(head, x, restingBallY(simulation, x, head.radius, rows - 1))\n } else {\n head.launch ??= { x: head.x, y: head.y }\n const hop = amount(time, schedule.hopStart, schedule.land)\n const seatY = body.y - body.radius - head.radius + 0.5\n head.x = head.launch.x + (body.x - head.launch.x) * ease(hop)\n head.y =\n head.launch.y +\n (seatY - head.launch.y) * ease(hop) -\n Math.sin(Math.PI * hop) * Math.max(5, body.radius * 1.5)\n if (time >= schedule.land) {\n const settle = amount(time, schedule.land, schedule.settleEnd)\n head.y += Math.sin(Math.PI * settle) * 0.45\n }\n head.locked = time >= schedule.settleEnd\n }\n }\n if (head && time >= schedule.land) {\n const drop = amount(time, schedule.land, schedule.end)\n simulation.hat = {\n x: head.x,\n y: head.y - head.radius - 1 - 5 * (1 - drop * drop),\n angle: (1 - ease(drop)) * -0.22,\n }\n }\n}\n\nfunction rollBallTo(ball: Snowball, x: number, y: number) {\n const nextY = moveToward(ball.y, y, 0.16)\n const dx = x - ball.x\n ball.angle += (Math.sign(dx) * Math.hypot(dx, nextY - ball.y)) / Math.max(ball.radius, 1)\n ball.x = x\n ball.y = nextY\n}\n\nfunction collectTouchedGround(simulation: SnowmanSimulation) {\n const resolved = resolvedCells(simulation)\n const originals = new Map(simulation.cells.map((cell) => [cell.id, cell]))\n const groundCoordinates = new Set(\n resolved\n .filter((cell) => cell.owner === 'ground')\n .map((cell) => key(Math.round(cell.x), Math.round(cell.y))),\n )\n const exposedGround = new Set(\n resolved\n .filter((cell) => cell.owner === 'ground')\n .filter((cell) => !groundCoordinates.has(key(Math.round(cell.x), Math.round(cell.y) - 1)))\n .map((cell) => cell.id),\n )\n for (const ball of [simulation.body, simulation.head]) {\n if (!ball || ball.locked) continue\n const owner = ball.kind\n const captureRadius = ball.radius + 0.75\n for (const cell of resolved) {\n if (!canCollect(simulation, ball)) break\n if (cell.owner !== 'ground') continue\n const dx = cell.x - ball.x\n const dy = cell.y - ball.y\n const distance = Math.hypot(dx, dy)\n // The roller takes only exposed grains on its lower, leading contact arc. Capturing buried\n // cells makes the ball appear to hook loose snow into the air behind it.\n if (!exposedGround.has(cell.id) || distance > captureRadius || dy < -ball.radius * 0.2)\n continue\n const original = originals.get(cell.id)\n if (!original) continue\n joinBall(simulation, ball, original.id, dx, dy)\n }\n ball.radius = Math.max(\n ball.radius,\n ballRadius(simulation, owner, ball.kind === 'body' ? 2 : 1.7),\n )\n }\n}\n\nfunction canCollect(simulation: SnowmanSimulation, ball: Snowball) {\n if (ball.kind === 'body' || !simulation.body) return true\n const bodyRadius = simulation.body.radius\n const targetHeadRadius = bodyRadius * 0.72\n const maxHeadCount = Math.max(\n 12,\n Math.round(Math.PI * (Math.max(0, targetHeadRadius - 1.7) / 0.6) ** 2),\n )\n return simulation.cells.filter((cell) => cell.owner === 'head').length < maxHeadCount\n}\n\nfunction hitBall(simulation: SnowmanSimulation, flake: AirborneFlake) {\n const candidates = [simulation.body, simulation.head].filter(\n (ball): ball is Snowball => ball !== undefined && !ball.locked,\n )\n return candidates.find(\n (ball) =>\n canCollect(simulation, ball) && Math.hypot(flake.x - ball.x, flake.y - ball.y) <= ball.radius,\n )\n}\n\nfunction joinBall(\n simulation: SnowmanSimulation,\n ball: Snowball,\n id: number,\n localX: number,\n localY: number,\n) {\n const cosine = Math.cos(-ball.angle)\n const sine = Math.sin(-ball.angle)\n const rotatedX = localX * cosine - localY * sine\n localY = localX * sine + localY * cosine\n localX = rotatedX\n const cell = simulation.cells.find((candidate) => candidate.id === id)\n const target = ballInteriorSlot(simulation, ball, id)\n const start = openBallPosition(simulation, ball, localX, localY, id)\n const next = {\n id,\n x: ball.x + start.x,\n y: ball.y + start.y,\n owner: ball.kind,\n localX: start.x,\n localY: start.y,\n targetLocalX: target.x,\n targetLocalY: target.y,\n }\n if (cell) Object.assign(cell, next)\n else simulation.cells.push(next)\n ball.radius = Math.max(\n ball.radius,\n ballRadius(simulation, ball.kind, ball.kind === 'body' ? 2 : 1.7),\n )\n rebalanceBallTargets(simulation, ball)\n}\n\nfunction openBallPosition(\n simulation: SnowmanSimulation,\n ball: Snowball,\n localX: number,\n localY: number,\n id: number,\n) {\n const cells = simulation.cells.filter((cell) => cell.id !== id && cell.owner === ball.kind)\n const free = (x: number, y: number) =>\n cells.every((cell) => Math.hypot((cell.localX ?? 0) - x, (cell.localY ?? 0) - y) >= 0.75)\n if (free(localX, localY)) return { x: localX, y: localY }\n // Search outward from the contact, retaining already packed grains in their material frame.\n for (let radius = 0.75; ; radius += 0.75) {\n for (let i = 0; i < 32; i++) {\n const angle = (i * Math.PI) / 16\n const x = localX + Math.cos(angle) * radius\n const y = localY + Math.sin(angle) * radius\n if ((Math.hypot(x, y) <= ball.radius + 0.75 || radius > ball.radius * 2) && free(x, y)) {\n ball.radius = Math.max(ball.radius, Math.hypot(x, y) - 0.5)\n return { x, y }\n }\n }\n }\n}\n\nfunction ballInteriorSlot(simulation: SnowmanSimulation, ball: Snowball, id: number) {\n const existing = simulation.cells.filter(\n (cell) =>\n cell.owner === ball.kind &&\n cell.targetLocalX !== undefined &&\n cell.targetLocalY !== undefined,\n )\n const free = (x: number, y: number, minDistance = 0.72) =>\n existing.every(\n (cell) =>\n Math.hypot((cell.targetLocalX ?? 0) - x, (cell.targetLocalY ?? 0) - y) >= minDistance,\n )\n for (let attempt = 0; attempt < 64; attempt += 1) {\n const angle = random(id * 31 + attempt * 17) * Math.PI * 2\n const distance = Math.sqrt(random(id * 37 + attempt * 19)) * Math.max(0.4, ball.radius - 0.35)\n const x = Math.cos(angle) * distance\n const y = Math.sin(angle) * distance\n if (free(x, y)) return { x, y }\n }\n for (let radius = 0.4; radius <= ball.radius - 0.35; radius += 0.5) {\n const steps = Math.max(6, Math.round((2 * Math.PI * radius) / 0.72))\n for (let i = 0; i < steps; i++) {\n const angle = (i * Math.PI * 2) / steps + random(id * 13)\n const x = Math.cos(angle) * radius\n const y = Math.sin(angle) * radius\n if (free(x, y, 0.6)) return { x, y }\n }\n }\n return { x: 0, y: 0 }\n}\n\nfunction compactBallCells(simulation: SnowmanSimulation) {\n for (const cell of simulation.cells) {\n if (\n cell.packed ||\n cell.localX === undefined ||\n cell.localY === undefined ||\n cell.targetLocalX === undefined ||\n cell.targetLocalY === undefined\n )\n continue\n const x = moveToward(cell.localX, cell.targetLocalX, 0.25)\n const y = moveToward(cell.localY, cell.targetLocalY, 0.25)\n cell.localX = x\n cell.localY = y\n cell.packed = x === cell.targetLocalX && y === cell.targetLocalY\n }\n}\n\n/** Reassigns the material to a dense lattice so newly collected snow compresses older grains. */\nfunction rebalanceBallTargets(simulation: SnowmanSimulation, ball: Snowball) {\n const cells = simulation.cells.filter(\n (cell) => cell.owner === ball.kind && cell.localX !== undefined && cell.localY !== undefined,\n )\n const slots = denseBallSlots(ball.radius, cells.length)\n cells.sort((first, second) => first.id - second.id)\n for (const [index, cell] of cells.entries()) {\n const slot = slots[index]\n if (!slot) break\n cell.targetLocalX = slot.x\n cell.targetLocalY = slot.y\n cell.packed = false\n }\n}\n\nfunction denseBallSlots(radius: number, count: number) {\n const boundary = Math.max(0.2, radius - 0.1)\n const candidates: Array<{ x: number; y: number }> = []\n const spacing = 0.9\n const vertical = (spacing * Math.sqrt(3)) / 2\n for (let row = -Math.ceil(boundary / vertical); row <= Math.ceil(boundary / vertical); row += 1) {\n const y = row * vertical\n const offset = (row & 1) === 0 ? 0 : spacing / 2\n for (\n let column = -Math.ceil(boundary / spacing);\n column <= Math.ceil(boundary / spacing);\n column += 1\n ) {\n const x = column * spacing + offset\n if (Math.hypot(x, y) <= boundary) candidates.push({ x, y })\n }\n }\n candidates.sort((first, second) => Math.hypot(first.x, first.y) - Math.hypot(second.x, second.y))\n const slots: Array<{ x: number; y: number }> = []\n for (const candidate of candidates) {\n if (slots.every((slot) => Math.hypot(slot.x - candidate.x, slot.y - candidate.y) >= 0.82))\n slots.push(candidate)\n if (slots.length === count) break\n }\n return slots\n}\n\nexport function resolvedHat(simulation: SnowmanSimulation) {\n if (!simulation.hat) return undefined\n return simulation.toppling\n ? {\n ...rotateAround(simulation.hat, simulation.toppling),\n angle: simulation.hat.angle + simulation.toppling.angle,\n }\n : simulation.hat\n}\n\n/** Interpolate presentation only; particle identities and physics remain on the fixed clock. */\nexport function interpolateSnowman(\n previous: SnowmanSimulation,\n next: SnowmanSimulation,\n fraction: number,\n) {\n const scene = clone(next)\n const mix = (a: number, b: number) => a + (b - a) * clamp(fraction, 0, 1)\n for (const kind of ['body', 'head'] as const) {\n const a = previous[kind],\n b = scene[kind]\n if (a && b) {\n b.x = mix(a.x, b.x)\n b.y = mix(a.y, b.y)\n b.angle = mix(a.angle, b.angle)\n }\n }\n const oldFlakes = new Map(previous.flakes.map((flake) => [flake.id, flake]))\n for (const flake of scene.flakes) {\n const old = oldFlakes.get(flake.id)\n if (old) {\n flake.x = mix(old.x, flake.x)\n flake.y = mix(old.y, flake.y)\n }\n }\n if (scene.toppling && previous.toppling)\n scene.toppling.angle = mix(previous.toppling.angle, scene.toppling.angle)\n if (scene.hat && previous.hat)\n scene.hat = {\n x: mix(previous.hat.x, scene.hat.x),\n y: mix(previous.hat.y, scene.hat.y),\n angle: mix(previous.hat.angle, scene.hat.angle),\n }\n return scene\n}\n\nfunction occupiedCells(simulation: SnowmanSimulation) {\n const occupied = new Map<string, SnowCellOwner>()\n for (const cell of resolvedCells(simulation))\n occupied.set(key(Math.round(cell.x), Math.round(cell.y)), cell.owner)\n return occupied\n}\n\n/** Lets a settled bank creep into a newly cleared trench instead of preserving impossible voids. */\nfunction relaxSettledSnow(simulation: SnowmanSimulation, seed: number, elapsed: number) {\n const occupied = occupiedCells(simulation)\n const ground = simulation.cells\n .filter((cell) => cell.owner === 'ground')\n .sort((first, second) => second.y - first.y || first.x - second.x)\n for (const cell of ground) {\n const below = key(cell.x, cell.y + 1)\n if (cell.y < simulation.grid.rows - 1 && !occupied.has(below)) {\n occupied.delete(key(cell.x, cell.y))\n cell.y += 1\n occupied.set(key(cell.x, cell.y), cell.owner)\n continue\n }\n const preferred = random(seed + cell.id * 29 + elapsed) < 0.5 ? -1 : 1\n for (const direction of [preferred, -preferred]) {\n const x = cell.x + direction\n if (\n x < 0 ||\n x >= simulation.grid.columns ||\n cell.y >= simulation.grid.rows - 1 ||\n occupied.has(key(x, cell.y)) ||\n occupied.has(key(x, cell.y + 1))\n )\n continue\n occupied.delete(key(cell.x, cell.y))\n cell.x = x\n cell.y += 1\n occupied.set(key(cell.x, cell.y), cell.owner)\n break\n }\n }\n}\n\nfunction findRestingCell(\n flake: AirborneFlake,\n occupied: Map<string, SnowCellOwner>,\n grid: SnowmanSimulation['grid'],\n wind: number,\n seed: number,\n) {\n const x = Math.round(flake.x)\n const y = Math.round(flake.y)\n if (y < 0) return undefined\n if (y >= grid.rows - 1) return { x, y: grid.rows - 1 }\n if (!occupied.has(key(x, y + 1))) return undefined\n const preferred = wind >= 0 ? 1 : -1\n const alternate = random(seed + flake.id * 71 + y) > 0.5 ? preferred : -preferred\n for (const offset of [alternate, -alternate]) {\n const side = x + offset\n if (\n side >= 0 &&\n side < grid.columns &&\n !occupied.has(key(side, y + 1)) &&\n !occupied.has(key(side, y))\n )\n return { x: side, y: y + 1 }\n }\n return occupied.has(key(x, y)) ? { x, y: Math.max(0, y - 1) } : { x, y }\n}\n\nfunction restingBallY(simulation: SnowmanSimulation, x: number, radius: number, fallback: number) {\n const cells = resolvedCells(simulation).filter(\n (cell) => cell.owner === 'ground' && Math.abs(cell.x - x) <= radius,\n )\n const surface = cells.length ? Math.min(...cells.map((cell) => cell.y)) : fallback\n return surface - radius\n}\nfunction ballRadius(simulation: SnowmanSimulation, owner: 'body' | 'head', minimum: number) {\n const count = simulation.cells.filter((cell) => cell.owner === owner).length\n return minimum + Math.sqrt(count / Math.PI) * 0.5\n}\nfunction beginTopple(simulation: SnowmanSimulation, elapsed: number) {\n const body = simulation.body\n if (!body) return\n simulation.toppling = {\n startedAt: elapsed,\n angle: 0,\n pivotX: body.x,\n pivotY: body.y + body.radius * 0.72,\n }\n}\n\nfunction advanceTopple(simulation: SnowmanSimulation, elapsed: number) {\n const toppling = simulation.toppling\n if (!toppling) return\n const progress = clamp((elapsed - toppling.startedAt) / 750, 0, 1)\n // Ease-in keeps the initial loss of balance readable; ease-out lets the body settle rather than snap.\n toppling.angle = (1 - (1 - progress) ** 3) * (Math.PI / 2)\n if (progress === 1) simulation.toppled = true\n}\n\nfunction rotateAround<T extends { x: number; y: number }>(\n point: T,\n toppling: NonNullable<SnowmanSimulation['toppling']>,\n) {\n const cosine = Math.cos(toppling.angle)\n const sine = Math.sin(toppling.angle)\n const x = point.x - toppling.pivotX\n const y = point.y - toppling.pivotY\n return {\n ...point,\n x: toppling.pivotX + x * cosine - y * sine,\n y: toppling.pivotY + x * sine + y * cosine,\n }\n}\nfunction clone(simulation: SnowmanSimulation): SnowmanSimulation {\n return {\n ...simulation,\n grid: { ...simulation.grid },\n hat: simulation.hat && { ...simulation.hat },\n flakes: simulation.flakes.map((flake) => ({ ...flake })),\n cells: simulation.cells.map((cell) => ({ ...cell })),\n body: simulation.body && { ...simulation.body },\n head: simulation.head && { ...simulation.head },\n toppling: simulation.toppling && { ...simulation.toppling },\n }\n}\nfunction key(x: number, y: number) {\n return `${x}:${y}`\n}\nfunction clamp(value: number, low: number, high: number) {\n return Math.max(low, Math.min(high, value))\n}\nfunction moveToward(current: number, target: number, maximumStep: number) {\n if (Math.abs(target - current) <= maximumStep) return target\n return current + Math.sign(target - current) * maximumStep\n}\nfunction random(value: number) {\n const sine = Math.sin(value * 12.9898) * 43758.5453\n return sine - Math.floor(sine)\n}\n","import { resolvedCells, resolvedHat, type SnowmanSimulation } from './snowman.ts'\n\nexport function drawSnowmanCanvas(\n canvas: HTMLCanvasElement | null,\n simulation: SnowmanSimulation,\n dimensions: { width: number; height: number },\n) {\n if (!canvas) return\n const context = canvas.getContext('2d')\n if (!context) return\n const scale = window.devicePixelRatio || 1\n const width = Math.max(1, Math.round(dimensions.width))\n const height = Math.max(1, Math.round(dimensions.height))\n if (canvas.width !== width * scale || canvas.height !== height * scale) {\n canvas.width = width * scale\n canvas.height = height * scale\n canvas.style.width = `${width}px`\n canvas.style.height = `${height}px`\n }\n context.setTransform(scale, 0, 0, scale, 0, 0)\n context.clearRect(0, 0, width, height)\n const cellWidth = width / simulation.grid.columns\n const cellHeight = height / simulation.grid.rows\n context.fillStyle = 'rgba(244, 241, 223, 0.52)'\n for (const cell of resolvedCells(simulation))\n drawDot(context, (cell.x + 0.5) * cellWidth, (cell.y + 0.5) * cellHeight, cellWidth, cellHeight)\n context.fillStyle = 'rgba(244, 241, 223, 0.76)'\n for (const flake of simulation.flakes)\n drawDot(\n context,\n (flake.x + 0.5) * cellWidth,\n (flake.y + 0.5) * cellHeight,\n cellWidth * 0.72,\n cellHeight * 0.72,\n )\n const hat = resolvedHat(simulation)\n if (hat && simulation.head) {\n const radius = simulation.head.radius\n context.save()\n context.translate(hat.x * cellWidth, hat.y * cellHeight)\n context.scale(cellWidth, cellHeight)\n context.rotate(hat.angle)\n context.fillStyle = 'rgba(27, 31, 24, 0.78)'\n context.fillRect(-radius * 0.65, -2, radius * 1.3, 2)\n context.fillRect(-radius, -0.3, radius * 2, 0.45)\n context.restore()\n }\n}\n\nfunction drawDot(\n context: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number,\n) {\n context.beginPath()\n context.arc(x, y, Math.max(0.8, Math.min(width, height) * 0.42), 0, Math.PI * 2)\n context.fill()\n}\n","import { useEffect, useRef, useState } from 'react'\nimport styles from './SnowmanField.module.css'\nimport {\n advanceSnowmanSimulation,\n createSnowmanSimulation,\n interpolateSnowman,\n snowmanScenePhase,\n} from './snowman.ts'\nimport { drawSnowmanCanvas } from './snowman-canvas.ts'\n\n/** A dense, seeded canvas snow scene. It remains decorative and never holds panel data. */\nexport function SnowmanField({\n progress,\n estimatedDurationMs,\n overdue,\n seed = 0,\n}: {\n progress: number\n estimatedDurationMs?: number\n overdue: boolean\n seed?: number\n}) {\n const rootRef = useRef<HTMLDivElement>(null)\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const [dimensions, setDimensions] = useState({ width: 360, height: 180 })\n const [reducedMotion, setReducedMotion] = useState(\n () => window.matchMedia('(prefers-reduced-motion: reduce)').matches,\n )\n\n const progressRef = useRef(progress)\n const overdueRef = useRef(overdue)\n const state = useRef({\n startedAt: Date.now(),\n progressAt: Date.now(),\n progress,\n simulation: createSnowmanSimulation(),\n })\n\n useEffect(() => {\n progressRef.current = progress\n state.current.progressAt = Date.now()\n state.current.progress = progress\n }, [progress])\n useEffect(() => {\n overdueRef.current = overdue\n }, [overdue])\n useEffect(() => {\n const media = window.matchMedia('(prefers-reduced-motion: reduce)')\n const update = () => setReducedMotion(media.matches)\n update()\n media.addEventListener?.('change', update)\n return () => media.removeEventListener?.('change', update)\n }, [])\n useEffect(() => {\n const root = rootRef.current\n if (!root) return\n const update = () => {\n const rect = root.getBoundingClientRect()\n if (rect.width > 0 && rect.height > 0)\n setDimensions({ width: rect.width, height: rect.height })\n }\n update()\n if (typeof ResizeObserver === 'undefined') return\n const observer = new ResizeObserver(update)\n observer.observe(root)\n return () => observer.disconnect()\n }, [])\n useEffect(() => {\n if (reducedMotion) return\n state.current.simulation = createSnowmanSimulation(dimensions)\n let frame = 0\n const paint = () => {\n const current = state.current\n const elapsed =\n estimatedDurationMs === undefined\n ? Date.now() - current.startedAt\n : current.progress * estimatedDurationMs + (Date.now() - current.progressAt)\n const options = {\n progress: progressRef.current,\n estimatedDurationMs,\n overdue: overdueRef.current,\n seed,\n dimensions,\n }\n const next = advanceSnowmanSimulation(current.simulation, { ...options, elapsed })\n current.simulation = next\n const future = advanceSnowmanSimulation(next, { ...options, elapsed: next.lastElapsed + 25 })\n const scene = interpolateSnowman(next, future, (elapsed - next.lastElapsed) / 25)\n drawSnowmanCanvas(canvasRef.current, scene, dimensions)\n const root = rootRef.current\n if (root) {\n root.dataset.snowCellCount = String(next.cells.length)\n root.dataset.snowDensity = next.grid.columns < 65 ? 'compact' : 'full'\n if (next.toppled) root.dataset.snowmanToppled = 'true'\n else delete root.dataset.snowmanToppled\n }\n if (!reducedMotion) frame = window.requestAnimationFrame(paint)\n }\n frame = window.requestAnimationFrame(paint)\n return () => window.cancelAnimationFrame(frame)\n }, [dimensions, estimatedDurationMs, reducedMotion, seed])\n useEffect(() => {\n if (!reducedMotion) return\n const scene = advanceSnowmanSimulation(createSnowmanSimulation(dimensions), {\n elapsed: estimatedDurationMs === undefined ? 4800 : progress * estimatedDurationMs,\n progress,\n estimatedDurationMs,\n overdue,\n seed,\n dimensions,\n })\n drawSnowmanCanvas(canvasRef.current, scene, dimensions)\n if (rootRef.current) {\n rootRef.current.dataset.snowCellCount = String(scene.cells.length)\n if (scene.toppled) rootRef.current.dataset.snowmanToppled = 'true'\n else delete rootRef.current.dataset.snowmanToppled\n }\n }, [dimensions, estimatedDurationMs, overdue, progress, reducedMotion, seed])\n const phase = snowmanScenePhase(progress, estimatedDurationMs, overdue)\n return (\n <div\n ref={rootRef}\n className={styles.field}\n data-running-part=\"snowman-field\"\n data-snowman-phase={phase}\n data-reduced-motion={reducedMotion || undefined}\n >\n <canvas ref={canvasRef} className={styles.canvas} data-running-part=\"snowman-canvas\" />\n </div>\n )\n}\n","import styles from './StatusWeatherField.module.css'\n\nexport function StatusWeatherField() {\n return (\n <>\n <span className={styles.haze} data-running-part=\"weather-haze\" />\n <span className={styles.pressure} data-running-part=\"weather-pressure\" />\n <span className={`${styles.band} ${styles.bandOne}`} />\n <span className={`${styles.band} ${styles.bandTwo}`} />\n <span className={`${styles.band} ${styles.bandThree}`} />\n <span className={`${styles.drift} ${styles.driftOne}`} />\n <span className={`${styles.drift} ${styles.driftTwo}`} />\n <span className={`${styles.drift} ${styles.driftThree}`} />\n <span className={`${styles.drift} ${styles.driftFour}`} />\n <span className={`${styles.drift} ${styles.driftFive}`} />\n </>\n )\n}\n","import type { CSSProperties } from 'react'\nimport styles from './PhasedProgressMarker.module.css'\n\n/**\n * A progress-anchored decorative marker. The anchor owns live progress geometry; the body owns\n * its independent phase animation, so a timing render cannot replace its transform.\n */\nexport function PhasedProgressMarker({\n anchorClassName,\n bodyClassName,\n delay,\n anchorPart,\n bodyPart,\n}: {\n anchorClassName: string | undefined\n bodyClassName: string | undefined\n delay?: string\n anchorPart?: string\n bodyPart: string\n}) {\n const style = delay ? ({ '--phased-marker-delay': delay } as CSSProperties) : undefined\n return (\n <span className={`${styles.anchor} ${anchorClassName ?? ''}`} data-running-part={anchorPart}>\n <span\n className={`${styles.body} ${bodyClassName ?? ''}`}\n data-running-part={bodyPart}\n style={style}\n />\n </span>\n )\n}\n","import { PhasedProgressMarker } from './PhasedProgressMarker.tsx'\nimport styles from './TelemetryBloomField.module.css'\n\nexport function TelemetryBloomField() {\n return (\n <>\n <span className={styles.frontier} data-running-part=\"frontier\" />\n <span className={styles.flare} data-running-part=\"bloom-flare\" />\n <span className={styles.lanes} data-running-part=\"bloom-lanes\">\n {[0, 1, 2, 3].map((lane) => (\n <span className={styles.lane} key={lane} data-running-part=\"bloom-lane\">\n <PhasedProgressMarker\n anchorClassName={styles.markerAnchor}\n bodyClassName={styles.markerBody}\n delay={[undefined, '-0.8s', '-1.7s', '-2.4s'][lane]}\n anchorPart=\"bloom-marker-anchor\"\n bodyPart=\"bloom-marker\"\n />\n </span>\n ))}\n </span>\n </>\n )\n}\n","import type { RunningAnimation } from '@ze-great-dashboard/shared/browser'\nimport type { CSSProperties } from 'react'\nimport { FallingShapesField } from './FallingShapesField.tsx'\nimport { FlightPathField } from './FlightPathField.tsx'\nimport { ReleaseTransitField } from './ReleaseTransitField.tsx'\nimport styles from './RunningField.module.css'\nimport { SnowmanField } from './SnowmanField.tsx'\nimport { StatusWeatherField } from './StatusWeatherField.tsx'\nimport { TelemetryBloomField } from './TelemetryBloomField.tsx'\n\nexport type RunningFieldAnimation = Extract<\n RunningAnimation,\n | 'telemetry-bloom'\n | 'release-transit'\n | 'status-weather'\n | 'falling-shapes'\n | 'snowman'\n | 'flight-path'\n>\n\nexport function isRunningFieldAnimation(\n animation: Exclude<RunningAnimation, 'off'>,\n): animation is RunningFieldAnimation {\n return [\n 'telemetry-bloom',\n 'release-transit',\n 'status-weather',\n 'falling-shapes',\n 'snowman',\n 'flight-path',\n ].includes(animation)\n}\n\nexport function RunningField({\n animation,\n progress,\n estimatedDurationMs,\n overdue,\n indeterminate,\n seed,\n}: {\n animation: RunningFieldAnimation\n progress: number\n estimatedDurationMs?: number\n overdue: boolean\n indeterminate: boolean\n seed?: number\n}) {\n const style = {\n '--running-progress': `${progress * 100}%`,\n } as CSSProperties\n return (\n <div\n className={`${styles.field} ${overdue ? styles.overdue : ''}`}\n data-animation={animation}\n data-running-field\n data-overdue={overdue || undefined}\n data-indeterminate={indeterminate || undefined}\n aria-hidden=\"true\"\n style={style}\n >\n {animation === 'telemetry-bloom' && <TelemetryBloomField />}\n {animation === 'release-transit' && <ReleaseTransitField />}\n {animation === 'status-weather' && <StatusWeatherField />}\n {animation === 'falling-shapes' && (\n <FallingShapesField\n progress={progress}\n estimatedDurationMs={estimatedDurationMs}\n overdue={overdue}\n seed={seed}\n />\n )}\n {animation === 'snowman' && (\n <SnowmanField\n progress={progress}\n estimatedDurationMs={estimatedDurationMs}\n overdue={overdue}\n seed={seed}\n />\n )}\n {animation === 'flight-path' && (\n <FlightPathField progress={progress} indeterminate={indeterminate} />\n )}\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\n\nconst VISUAL_TICK_MS = 20\n\nexport type RunningTiming = {\n elapsedMs: number | undefined\n estimatedDurationMs: number | undefined\n hasEstimate: boolean\n overdue: boolean\n progress: number\n}\n\nexport function useRunningTiming(\n runStartedAt?: string,\n estimatedDurationMs?: number,\n): RunningTiming {\n const now = useClock(Boolean(runStartedAt))\n const startedAt = runStartedAt ? new Date(runStartedAt).valueOf() : Number.NaN\n const elapsedMs = Number.isFinite(startedAt) ? Math.max(0, now - startedAt) : undefined\n const hasEstimate = elapsedMs !== undefined && estimatedDurationMs !== undefined\n const overdue = hasEstimate && elapsedMs > estimatedDurationMs\n const progress = hasEstimate ? Math.min(elapsedMs / estimatedDurationMs, 1) : 0\n return { elapsedMs, estimatedDurationMs, hasEstimate, overdue, progress }\n}\n\nfunction useClock(enabled: boolean) {\n const [now, setNow] = useState(() => Date.now())\n useEffect(() => {\n if (!enabled) return\n setNow(Date.now())\n // The timing text rounds to seconds, but progress gets display-cadence intermediate positions.\n // This avoids the visible sawtooth created by a coarse timer and CSS transition.\n const interval = window.setInterval(() => setNow(Date.now()), VISUAL_TICK_MS)\n return () => window.clearInterval(interval)\n }, [enabled])\n return now\n}\n\nexport function timingDescription(\n elapsedMs: number | undefined,\n estimatedDurationMs: number | undefined,\n overdue: boolean,\n) {\n const elapsed =\n elapsedMs === undefined ? 'Run in progress' : `Elapsed ${formatDuration(elapsedMs)}`\n const expected =\n estimatedDurationMs === undefined\n ? 'Expected duration unavailable'\n : `Expected ≈ ${formatDuration(estimatedDurationMs)}`\n return `${elapsed} · ${expected}${overdue ? ' · Over estimate' : ''}`\n}\n\nexport function compactTiming(\n elapsedMs: number | undefined,\n estimatedDurationMs: number | undefined,\n overdue: boolean,\n) {\n const elapsed = elapsedMs === undefined ? '—' : formatClockDuration(elapsedMs)\n const expected =\n estimatedDurationMs === undefined ? '?' : `~${formatClockDuration(estimatedDurationMs)}`\n return `${overdue ? '⚠' : '\\u00a0'}${elapsed}/${expected}`\n}\n\nfunction formatDuration(durationMs: number) {\n const totalSeconds = Math.floor(durationMs / 1_000)\n const hours = Math.floor(totalSeconds / 3_600)\n const minutes = Math.floor((totalSeconds % 3_600) / 60)\n const seconds = totalSeconds % 60\n if (hours > 0) return `${hours}h ${minutes}m`\n if (minutes > 0) return `${minutes}m ${seconds}s`\n return `${seconds}s`\n}\n\nfunction formatClockDuration(durationMs: number) {\n const totalSeconds = Math.floor(durationMs / 1_000)\n const hours = Math.floor(totalSeconds / 3_600)\n const minutes = Math.floor((totalSeconds % 3_600) / 60)\n const seconds = totalSeconds % 60\n const clock = `${minutes}:${String(seconds).padStart(2, '0')}`\n return hours > 0 ? `${hours}:${clock.padStart(5, '0')}` : clock\n}\n","import styles from './RunningField.module.css'\nimport { compactTiming, timingDescription } from './running-timing.ts'\n\n/** The sole readable timing projection for panel-scale decorative fields. */\nexport function RunningFieldTiming({\n elapsedMs,\n estimatedDurationMs,\n overdue,\n}: {\n elapsedMs: number | undefined\n estimatedDurationMs: number | undefined\n overdue: boolean\n}) {\n return (\n <p className={`${styles.timing} ${overdue ? styles.timingOverdue : ''}`}>\n <span className=\"screen-reader-only\">\n {timingDescription(elapsedMs, estimatedDurationMs, overdue)}\n </span>\n <span aria-hidden=\"true\">{compactTiming(elapsedMs, estimatedDurationMs, overdue)}</span>\n </p>\n )\n}\n","import type { RunningAnimation } from '@ze-great-dashboard/shared/browser'\nimport type { CSSProperties } from 'react'\nimport { PhasedProgressMarker } from './PhasedProgressMarker.tsx'\nimport styles from './RunningProgress.module.css'\nimport { compactTiming, type RunningTiming, timingDescription } from './running-timing.ts'\n\nexport function RunningProgress({\n animation,\n timing,\n}: {\n animation: LegacyRunningAnimation\n timing: RunningTiming\n}) {\n const { elapsedMs, estimatedDurationMs, hasEstimate, overdue, progress } = timing\n const usesReadout = animation === 'runway' || animation === 'signal-field'\n const timingText = timingDescription(elapsedMs, estimatedDurationMs, overdue)\n const style = {\n '--running-progress': `${progress * 100}%`,\n '--running-degrees': `${progress * 360}deg`,\n } as CSSProperties\n const animationStyle = animation === 'signal-field' ? styles.signalField : styles[animation]\n\n return (\n <div\n className={`${styles.progress} ${animationStyle} ${overdue ? styles.overdue : ''} ${hasEstimate ? '' : styles.indeterminate}`}\n style={style}\n data-running-progress={animation}\n data-overdue={overdue || undefined}\n data-indeterminate={!hasEstimate || undefined}\n >\n <div className={styles.visual} aria-hidden=\"true\" data-running-visual>\n {animation === 'radial' && <span className={styles.radialCore} />}\n {animation === 'runway' && (\n <>\n <span className={styles.spark} data-running-part=\"runway-spark\" />\n <span\n className={`${styles.spark} ${styles.sparkTwo}`}\n data-running-part=\"runway-spark-two\"\n />\n </>\n )}\n {animation === 'orbit' && (\n <>\n <span className={styles.orbitCore} />\n <span className={styles.particle} />\n <span className={`${styles.particle} ${styles.particleTwo}`} />\n </>\n )}\n {animation === 'signal-field' && (\n <>\n <span className={styles.rail} />\n <span className={styles.lead} />\n <span className={styles.pulse} />\n <span className={`${styles.pulse} ${styles.pulseTwo}`} />\n <span className={styles.tracks} data-running-part=\"signal-tracks\">\n {[0, 1, 2, 3, 4].map((track) => (\n <span className={styles.track} key={track} data-running-part=\"signal-track\">\n <PhasedProgressMarker\n anchorClassName={styles.markerAnchor}\n bodyClassName={styles.markerBody}\n delay={[undefined, '-0.8s', '-1.7s', '-2.4s', '-0.35s'][track]}\n anchorPart=\"signal-marker-anchor\"\n bodyPart=\"signal-marker\"\n />\n </span>\n ))}\n </span>\n </>\n )}\n </div>\n <p className={`${styles.timing} ${usesReadout ? styles.readout : ''}`}>\n {usesReadout ? (\n <>\n <span className=\"screen-reader-only\">{timingText}</span>\n <span aria-hidden=\"true\">{compactTiming(elapsedMs, estimatedDurationMs, overdue)}</span>\n </>\n ) : (\n timingText\n )}\n </p>\n </div>\n )\n}\n\n/** The compact, inline treatments retained for existing boards. */\nexport type LegacyRunningAnimation = Extract<\n RunningAnimation,\n 'radial' | 'runway' | 'orbit' | 'signal-field'\n>\n\nexport function isLegacyRunningAnimation(\n animation: RunningAnimation,\n): animation is LegacyRunningAnimation {\n return ['radial', 'runway', 'orbit', 'signal-field'].includes(animation)\n}\n","/** A stable numeric variation seed for decorative fields keyed by a panel's public id. */\nexport function visualSeed(value: string): number {\n return Array.from(value).reduce(\n (hash, character) => (hash * 31 + character.charCodeAt(0)) >>> 0,\n 7,\n )\n}\n","import { type Panel, parseDuration } from '@ze-great-dashboard/shared/browser'\nimport { useEffect, useState } from 'react'\nimport { PanelEvidence, PanelFrame, PanelStatus } from './PanelFrame.tsx'\nimport styles from './PipelineAnimationDemoPanel.module.css'\nimport { isRunningFieldAnimation, RunningField } from './RunningField.tsx'\nimport { RunningFieldTiming } from './RunningFieldTiming.tsx'\nimport { RunningProgress } from './RunningProgress.tsx'\nimport { useRunningTiming } from './running-timing.ts'\nimport { visualSeed } from './visual-seed.ts'\n\nconst DEFAULT_RUN_DURATION_MS = 20_000\nconst ESTIMATED_DURATION_MS = 15_000\nconst DEFAULT_REVIEW_DURATION_MS = 300_000\nconst REVIEW_CYCLE_MULTIPLIER = 1.25\nconst variants = [\n 'radial',\n 'runway',\n 'orbit',\n 'signal-field',\n 'telemetry-bloom',\n 'release-transit',\n 'status-weather',\n 'falling-shapes',\n 'snowman',\n 'flight-path',\n] as const\n\n/**\n * A local comparison aid for the active-run treatments. It deliberately creates no signal or\n * diagnostic evidence: its state is derived only from the wall clock and repeats forever.\n */\nexport function PipelineAnimationDemoPanel({ panel }: { panel: Panel }) {\n const now = useClock()\n // A configured visible treatment turns the local comparison aid into a stable review panel.\n // `off` retains the rotating default: the demo exists to render a treatment.\n const fixedAnimation =\n panel.running_animation === undefined || panel.running_animation === 'off'\n ? undefined\n : panel.running_animation\n const runDurationMs = durationMillis(panel.demo_run_duration, DEFAULT_RUN_DURATION_MS)\n const reviewDurationMs = durationMillis(panel.demo_review_duration, DEFAULT_REVIEW_DURATION_MS)\n const durationMs = fixedAnimation\n ? Math.ceil(reviewDurationMs * REVIEW_CYCLE_MULTIPLIER)\n : runDurationMs\n const runNumber = Math.floor(now / durationMs)\n const animation = fixedAnimation ?? variants[runNumber % variants.length] ?? 'radial'\n const runStartedAt = runNumber * durationMs\n\n return (\n <DemoRun\n panel={panel}\n animation={animation}\n runStartedAt={runStartedAt}\n estimatedDurationMs={fixedAnimation ? reviewDurationMs : ESTIMATED_DURATION_MS}\n />\n )\n}\n\nfunction durationMillis(value: Panel['demo_run_duration'], fallback: number): number {\n if (!value) return fallback\n return parseDuration(value) ?? fallback\n}\n\nfunction DemoRun({\n panel,\n animation,\n runStartedAt,\n estimatedDurationMs,\n}: {\n panel: Panel\n animation: (typeof variants)[number]\n runStartedAt: number\n estimatedDurationMs: number\n}) {\n const startedAt = new Date(runStartedAt).toISOString()\n const timing = useRunningTiming(startedAt, estimatedDurationMs)\n const usesField = isRunningFieldAnimation(animation)\n return (\n <PanelFrame\n panel={panel}\n field={\n usesField ? (\n <RunningField\n key={`${animation}-${runStartedAt}`}\n animation={animation}\n progress={timing.progress}\n estimatedDurationMs={timing.estimatedDurationMs}\n overdue={timing.overdue}\n indeterminate={!timing.hasEstimate}\n seed={visualSeed(panel.id)}\n />\n ) : undefined\n }\n >\n <PanelEvidence>\n <PanelStatus status=\"running\" glyph=\"↻\" label=\"Running\" />\n <p className={styles.variant}>\n <span className={styles.variantPrefix}>Demo treatment · </span>\n {animation}\n </p>\n {usesField ? (\n <RunningFieldTiming\n elapsedMs={timing.elapsedMs}\n estimatedDurationMs={estimatedDurationMs}\n overdue={timing.overdue}\n />\n ) : (\n <RunningProgress animation={animation} timing={timing} />\n )}\n </PanelEvidence>\n </PanelFrame>\n )\n}\n\nfunction useClock() {\n const [now, setNow] = useState(() => Date.now())\n useEffect(() => {\n const interval = window.setInterval(() => setNow(Date.now()), 1_000)\n return () => window.clearInterval(interval)\n }, [])\n return now\n}\n","import type { PipelineStatus } from '@ze-great-dashboard/shared/browser'\nimport { statusSymbols } from './panel-symbols.ts'\n\nexport type PanelStatusKind = PipelineStatus['status']\n\nexport function statusPresentation(status: PanelStatusKind, passedLabel = 'Passed') {\n const presentation = statusSymbols[status]\n return status === 'passed' ? { ...presentation, label: passedLabel } : presentation\n}\n","import type { PipelineActivity } from '@ze-great-dashboard/shared/browser'\n\nexport function formatPipelineActivity(activity: PipelineActivity | undefined) {\n if (!activity) return 'Activity unavailable'\n return activity.parent ? `${activity.parent} › ${activity.name}` : activity.name\n}\n","import { type ReactNode, useEffect, useId, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport styles from './TestDirectionSummary.module.css'\nimport type { TestDirection } from './test-direction.ts'\n\nexport function TestDirectionSummary({\n direction,\n children,\n}: {\n direction?: TestDirection\n children: ReactNode\n}) {\n const [open, setOpen] = useState(false)\n const [pinned, setPinned] = useState(false)\n const [position, setPosition] = useState({ left: 0, top: 0 })\n const target = useRef<HTMLButtonElement>(null)\n const popup = useRef<HTMLSpanElement>(null)\n const id = useId()\n const show = () => {\n const rect = target.current?.getBoundingClientRect()\n if (rect)\n setPosition({\n left: Math.max(8, Math.min(rect.left, window.innerWidth - 328)),\n top: Math.max(8, Math.min(rect.bottom, window.innerHeight - 180)),\n })\n setOpen(true)\n }\n useEffect(() => {\n if (!direction) {\n setOpen(false)\n setPinned(false)\n }\n }, [direction])\n useEffect(() => {\n if (!open) return\n const dismiss = (event: PointerEvent) => {\n if (\n event.target instanceof Node &&\n !target.current?.contains(event.target) &&\n !popup.current?.contains(event.target)\n ) {\n setOpen(false)\n setPinned(false)\n }\n }\n const onEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpen(false)\n setPinned(false)\n }\n }\n document.addEventListener('pointerdown', dismiss)\n document.addEventListener('keydown', onEscape)\n return () => {\n document.removeEventListener('pointerdown', dismiss)\n document.removeEventListener('keydown', onEscape)\n }\n }, [open])\n if (!direction) return <>{children}</>\n const points = direction.totals\n .map(\n (total, index, totals) =>\n `${totals.length === 1 ? 48 : (index * 48) / (totals.length - 1)},${16 - (total / Math.max(1, ...totals)) * 14}`,\n )\n .join(' ')\n return (\n <>\n <button\n ref={target}\n type=\"button\"\n className={styles.summary}\n aria-describedby={open ? id : undefined}\n aria-expanded={open}\n onMouseEnter={show}\n onMouseLeave={(event) => {\n if (\n !pinned &&\n !(event.relatedTarget instanceof Node && popup.current?.contains(event.relatedTarget))\n )\n setOpen(false)\n }}\n onFocus={show}\n onBlur={() => {\n setOpen(false)\n setPinned(false)\n }}\n onClick={() => {\n if (pinned) {\n setPinned(false)\n setOpen(false)\n } else {\n setPinned(true)\n show()\n }\n }}\n >\n {children}\n {direction.mode !== 'quiet' && (\n <span\n className={`${styles.delta} ${direction.emphasized ? styles.emphasized : ''}`}\n aria-hidden=\"true\"\n >\n {direction.symbol} {direction.delta > 0 ? '+' : direction.delta < 0 ? '−' : ''}\n {Math.abs(direction.delta).toLocaleString()}\n </span>\n )}\n {direction.totals.length > 1 && (\n <svg className={styles.sparkline} viewBox=\"0 0 48 18\" aria-hidden=\"true\">\n <polyline points={points} />\n </svg>\n )}\n </button>\n {open &&\n createPortal(\n <span\n ref={popup}\n id={id}\n role=\"tooltip\"\n className={styles.explanation}\n style={{ ...position, maxHeight: Math.max(40, window.innerHeight - position.top - 8) }}\n onMouseLeave={(event) => {\n if (\n !pinned &&\n !(\n event.relatedTarget instanceof Node &&\n target.current?.contains(event.relatedTarget)\n )\n )\n setOpen(false)\n }}\n >\n {direction.explanation}\n </span>,\n document.body,\n )}\n </>\n )\n}\n","import type { TestCount, TestEvidence } from '@ze-great-dashboard/shared/browser'\nimport styles from './PanelFrame.module.css'\nimport { PanelMetadata } from './PanelFrame.tsx'\nimport { TestDirectionSummary } from './TestDirectionSummary.tsx'\nimport type { TestDirection } from './test-direction.ts'\n\nexport function RunTestResults({\n envelope,\n direction,\n}: {\n envelope: TestEvidence\n direction?: TestDirection\n}) {\n if (envelope.state === 'error')\n return (\n <PanelMetadata\n glyph=\"⚠\"\n label=\"Tests\"\n value={`Test results unavailable: ${envelope.error.message}`}\n />\n )\n const tests = envelope.signal\n if (tests.status !== 'reported')\n return (\n <PanelMetadata\n glyph=\"≡\"\n label=\"Tests\"\n value={tests.status === 'pending' ? 'Tests pending' : 'No test results published'}\n />\n )\n return (\n <PanelMetadata\n glyph=\"≡\"\n label=\"Tests\"\n value={<TestOutcomeSummary tests={tests} direction={direction} />}\n />\n )\n}\n\n/** The same reported evidence in both standalone panels and workflow runs. */\nexport function TestOutcomeSummary({\n tests,\n direction,\n}: {\n tests: Extract<TestCount, { status: 'reported' }>\n direction?: TestDirection\n}) {\n const allPassed = tests.total > 0 && tests.passed === tests.total\n return (\n <TestDirectionSummary direction={direction}>\n {allPassed ? (\n <span className={styles.passed}>✓ {tests.total.toLocaleString()} passed</span>\n ) : (\n `${tests.total.toLocaleString()} tests`\n )}\n {!!tests.failed && (\n <span className={styles.failed}> · ✕ {tests.failed.toLocaleString()} failed</span>\n )}\n {!!tests.skipped && (\n <span className={styles.warning}> · ↷ {tests.skipped.toLocaleString()} skipped</span>\n )}\n </TestDirectionSummary>\n )\n}\n\n/** Only compact public evidence; observation timestamps do not constitute a visible change. */\nexport function projectTestEvidence(evidence: TestEvidence) {\n return evidence.state === 'error'\n ? { state: evidence.state, kind: evidence.error.kind, message: evidence.error.message }\n : { state: evidence.state, ...publicTestCounts(evidence.signal) }\n}\nexport type TestEvidenceDiagnostic = ReturnType<typeof projectTestEvidence>\n\nfunction publicTestCounts(signal: TestCount) {\n if (signal.status !== 'reported') return signal\n const { run: _run, ...counts } = signal\n return counts\n}\n","import {\n type Envelope,\n type Panel,\n type PipelineStatus,\n pipelineStatusSchema,\n type RunningAnimation,\n visibleRunningAnimations,\n} from '@ze-great-dashboard/shared/browser'\nimport { useRef, useState } from 'react'\nimport type { RenderedPanelDiagnostic } from './diagnostics.ts'\nimport { errorPresentation } from './error-presentation.ts'\nimport { PanelEvidence, PanelFrame, PanelHint, PanelMetadata, PanelStatus } from './PanelFrame.tsx'\nimport styles from './PipelinePanel.module.css'\nimport type { PanelProps } from './panel-props.ts'\nimport { statusPresentation } from './panel-status.ts'\nimport { formatPipelineActivity } from './pipeline-activity.ts'\nimport { isRunningFieldAnimation, RunningField } from './RunningField.tsx'\nimport { RunningFieldTiming } from './RunningFieldTiming.tsx'\nimport { isLegacyRunningAnimation, RunningProgress } from './RunningProgress.tsx'\nimport { useRunningTiming } from './running-timing.ts'\nimport { projectTestEvidence, RunTestResults } from './TestEvidence.tsx'\nimport { LastConfirmedAge, PipelineAge, UpdateHealth } from './TimeAge.tsx'\nimport { visualSeed } from './visual-seed.ts'\n\nexport function PipelinePanel({\n panel,\n envelope,\n attentionActive,\n updateHealth,\n rejectedPipeline,\n testDirection,\n}: PanelProps) {\n if (!envelope && rejectedPipeline)\n return <RejectedPipelinePanel panel={panel} rejected={rejectedPipeline} />\n if (!envelope)\n return (\n <PanelFrame panel={panel} attentionActive={attentionActive}>\n <PanelEvidence>\n <PanelHint>Loading…</PanelHint>\n </PanelEvidence>\n </PanelFrame>\n )\n if (envelope.state === 'error') {\n const presentation = errorPresentation(envelope.error.kind)\n return (\n <PanelFrame\n panel={panel}\n envelope={envelope}\n attentionActive={attentionActive}\n error\n layout=\"status-band\"\n >\n <div data-panel-anchor=\"status\">\n <PanelStatus glyph=\"⚠\" label={presentation.label} emphasis={presentation.emphasis} />\n </div>\n <PanelEvidence anchor=\"evidence\">\n <PanelHint>{envelope.error.message}</PanelHint>\n </PanelEvidence>\n </PanelFrame>\n )\n }\n\n const signal = pipelineStatusSchema.safeParse(envelope.signal)\n if (!signal.success)\n return (\n <PanelFrame\n panel={panel}\n envelope={envelope}\n attentionActive={attentionActive}\n error\n layout=\"status-band\"\n >\n <div data-panel-anchor=\"status\">\n <PanelStatus glyph=\"⚠\" label=\"Invalid signal\" />\n </div>\n <PanelEvidence anchor=\"evidence\">\n <PanelHint>The received pipeline status could not be read.</PanelHint>\n </PanelEvidence>\n </PanelFrame>\n )\n return (\n <PipelineSignalPanel\n panel={panel}\n envelope={envelope}\n signal={signal.data}\n testDirection={testDirection}\n updateHealth={updateHealth}\n attentionActive={attentionActive}\n />\n )\n}\n\nfunction RejectedPipelinePanel({\n panel,\n rejected,\n}: {\n panel: Panel\n rejected: NonNullable<PanelProps['rejectedPipeline']>\n}) {\n const presentation = statusPresentation(rejected.status)\n return (\n <PanelFrame panel={panel} sourceLink={rejected.link} busy={false} layout=\"status-band\">\n <div data-panel-anchor=\"status\">\n <PanelStatus\n status={rejected.status}\n glyph={presentation.glyph}\n label={presentation.label}\n />\n </div>\n <PanelEvidence className={styles.details} anchor=\"evidence\">\n <PanelHint>\n {rejected.github ? 'GitHub' : 'The source'} returned an older result; checking again\n {rejected.github && (\n <>\n {' · '}\n <a\n href=\"https://github.com/orgs/community/discussions/206725\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n GitHub API report\n </a>\n </>\n )}\n </PanelHint>\n <LastConfirmedAge value={rejected.sourceUpdatedAt} />\n </PanelEvidence>\n </PanelFrame>\n )\n}\n\nfunction PipelineSignalPanel({\n panel,\n envelope,\n signal,\n updateHealth,\n attentionActive,\n testDirection,\n}: {\n panel: Panel\n envelope: Envelope\n signal: PipelineStatus\n testDirection?: PanelProps['testDirection']\n updateHealth?: PanelProps['updateHealth']\n attentionActive?: boolean\n}) {\n const presentation = statusPresentation(signal.status)\n const [defaultAnimation, setDefaultAnimation] = useState<RunningAnimation | undefined>(() =>\n signal.status === 'running' ? selectDefaultRunningAnimation() : undefined,\n )\n const previousStatusRef = useRef(signal.status)\n if (signal.status !== previousStatusRef.current) {\n const wasRunning = previousStatusRef.current === 'running'\n previousStatusRef.current = signal.status\n if (panel.running_animation === undefined && !wasRunning && signal.status === 'running') {\n setDefaultAnimation((previousAnimation) => selectDefaultRunningAnimation(previousAnimation))\n }\n }\n const animation = panel.running_animation ?? defaultAnimation ?? 'off'\n const activeRun = signal.status === 'running' && animation !== 'off'\n const timing = useRunningTiming(signal.runStartedAt, signal.estimatedDurationMs)\n const usesField = activeRun && isRunningFieldAnimation(animation)\n const usesLegacyProgress = activeRun && isLegacyRunningAnimation(animation)\n return (\n <PanelFrame\n panel={panel}\n envelope={envelope}\n attentionActive={attentionActive}\n layout={usesField || usesLegacyProgress ? undefined : 'status-band'}\n field={\n usesField ? (\n <RunningField\n animation={animation}\n progress={timing.progress}\n estimatedDurationMs={timing.estimatedDurationMs}\n overdue={timing.overdue}\n indeterminate={!timing.hasEstimate}\n seed={visualSeed(panel.id)}\n />\n ) : undefined\n }\n >\n <div data-panel-anchor=\"status\">\n <PanelStatus status={signal.status} glyph={presentation.glyph} label={presentation.label} />\n </div>\n <PanelEvidence className={styles.details} anchor=\"evidence\">\n {signal.status === 'running' && (\n <PanelMetadata\n glyph=\"⚙\"\n label=\"Activity\"\n value={formatPipelineActivity(signal.activity)}\n compact={{ kind: 'glyph-only' }}\n title={`Activity: ${formatPipelineActivity(signal.activity)}`}\n className={styles.activity}\n />\n )}\n {signal.testResults && (\n <RunTestResults envelope={signal.testResults} direction={testDirection} />\n )}\n {signal.branch && (\n <PanelMetadata\n glyph=\"⎇\"\n label=\"Branch\"\n value={<span className={styles.branch}>{signal.branch}</span>}\n compact={{\n kind: 'short-value',\n value: <span className={styles.branch}>{signal.branch}</span>,\n }}\n title={`Branch: ${signal.branch}`}\n />\n )}\n {usesField && (\n <RunningFieldTiming\n elapsedMs={timing.elapsedMs}\n estimatedDurationMs={signal.estimatedDurationMs}\n overdue={timing.overdue}\n />\n )}\n {usesLegacyProgress && <RunningProgress animation={animation} timing={timing} />}\n {signal.status !== 'running' && signal.durationMs !== undefined && (\n <PanelMetadata\n glyph=\"◷\"\n label=\"Duration\"\n value={`Took ${formatDuration(signal.durationMs)}`}\n compact={{ kind: 'short-value', value: formatDuration(signal.durationMs) }}\n title={`Duration: Took ${formatDuration(signal.durationMs)}`}\n className={styles.duration}\n />\n )}\n <PipelineAge\n sourceUpdatedAt={signal.sourceUpdatedAt}\n observedAt={envelope.observedAt}\n running={signal.status === 'running'}\n runStartedAt={signal.runStartedAt}\n />\n {updateHealth && <UpdateHealth health={updateHealth} />}\n </PanelEvidence>\n </PanelFrame>\n )\n}\n\nfunction selectDefaultRunningAnimation(previousAnimation?: RunningAnimation) {\n const candidates = visibleRunningAnimations.filter((animation) => animation !== previousAnimation)\n return candidates[Math.floor(Math.random() * candidates.length)] ?? 'telemetry-bloom'\n}\n\nfunction formatDuration(durationMs: number) {\n const totalSeconds = Math.floor(durationMs / 1_000)\n const hours = Math.floor(totalSeconds / 3_600)\n const minutes = Math.floor((totalSeconds % 3_600) / 60)\n const seconds = totalSeconds % 60\n\n if (hours > 0) return `${hours}h ${minutes}m`\n if (minutes > 0) return `${minutes}m ${seconds}s`\n return `${seconds}s`\n}\n\nexport function projectPipelineDiagnostic(envelope: Envelope): RenderedPanelDiagnostic {\n const base = { state: envelope.state, link: envelope.link }\n if (envelope.state === 'error') return base\n const signal = pipelineStatusSchema.safeParse(envelope.signal)\n return {\n ...base,\n status: signal.success ? signal.data.status : undefined,\n ...(signal.success && signal.data.testResults\n ? { tests: projectTestEvidence(signal.data.testResults) }\n : {}),\n }\n}\n","export function formatCount(count: number, singular: string, plural = `${singular}s`) {\n return `${count} ${count === 1 ? singular : plural}`\n}\n","import type { PullRequestHealth } from '@ze-great-dashboard/shared/browser'\nimport { formatCount } from './panel-formatting.ts'\n\nexport type PullRequestHealthCompactFacts = {\n workflow: string\n pullRequests: string\n primary: string\n secondary: string\n primaryDetail?: string\n primaryKind?: 'failed' | 'warning'\n title: string\n}\n\n/**\n * Keep the wall-facing version of this aggregate signal short without making the\n * server's prose summary part of the client contract.\n */\nexport function compactPullRequestHealthFacts(\n signal: PullRequestHealth,\n): PullRequestHealthCompactFacts {\n const attentionItem = [...signal.workflows, ...signal.pullRequests].find(\n (item) => item.status === 'failed' || item.status === 'warning',\n )\n\n if (attentionItem) {\n return {\n workflow: formatCount(signal.workflows.length, 'workflow'),\n pullRequests: formatCount(signal.pullRequests.length, 'open PR'),\n primary: `${attentionItem.label} ${attentionItem.status}`,\n secondary: `${formatCount(signal.workflows.length, 'workflow')} · ${formatCount(signal.pullRequests.length, 'open PR')}`,\n primaryDetail: attentionItem.detail,\n primaryKind: attentionItem.status === 'warning' ? 'warning' : 'failed',\n title: `${signal.summary} — ${attentionItem.label}: ${attentionItem.detail}`,\n }\n }\n\n return {\n workflow: formatCount(signal.workflows.length, 'workflow'),\n pullRequests: formatCount(signal.pullRequests.length, 'open PR'),\n primary: formatCount(signal.workflows.length, 'workflow'),\n secondary: formatCount(signal.pullRequests.length, 'open PR'),\n title: signal.summary,\n }\n}\n","import type { Envelope } from '@ze-great-dashboard/shared/browser'\nimport { pullRequestHealthSchema } from '@ze-great-dashboard/shared/browser'\nimport type { RenderedPanelDiagnostic } from './diagnostics.ts'\nimport { errorPresentation } from './error-presentation.ts'\nimport { PanelEvidence, PanelFrame, PanelHint, PanelMetadata, PanelStatus } from './PanelFrame.tsx'\nimport styles from './PullRequestHealthPanel.module.css'\nimport type { PanelProps } from './panel-props.ts'\nimport { statusPresentation } from './panel-status.ts'\nimport { compactPullRequestHealthFacts } from './pull-request-health.ts'\nimport { ObservedAt, UpdateHealth } from './TimeAge.tsx'\n\nexport function PullRequestHealthPanel({\n panel,\n envelope,\n attentionActive,\n updateHealth,\n}: PanelProps) {\n if (!envelope)\n return (\n <PanelFrame panel={panel} attentionActive={attentionActive}>\n <PanelEvidence>\n <PanelHint>Loading…</PanelHint>\n </PanelEvidence>\n </PanelFrame>\n )\n if (envelope.state === 'error') {\n const presentation = errorPresentation(envelope.error.kind)\n return (\n <PanelFrame\n panel={panel}\n envelope={envelope}\n attentionActive={attentionActive}\n error\n layout=\"status-band\"\n >\n <div data-panel-anchor=\"status\">\n <PanelStatus glyph=\"⚠\" label={presentation.label} emphasis={presentation.emphasis} />\n </div>\n <PanelEvidence anchor=\"evidence\">\n <PanelHint>{envelope.error.message}</PanelHint>\n </PanelEvidence>\n </PanelFrame>\n )\n }\n const signal = pullRequestHealthSchema.safeParse(envelope.signal)\n if (!signal.success)\n return (\n <PanelFrame\n panel={panel}\n envelope={envelope}\n attentionActive={attentionActive}\n error\n layout=\"status-band\"\n >\n <div data-panel-anchor=\"status\">\n <PanelStatus glyph=\"⚠\" label=\"Invalid signal\" />\n </div>\n <PanelEvidence anchor=\"evidence\">\n <PanelHint>The received pull-request health status could not be read.</PanelHint>\n </PanelEvidence>\n </PanelFrame>\n )\n const presentation = statusPresentation(signal.data.status, 'Healthy')\n const compactFacts = compactPullRequestHealthFacts(signal.data)\n return (\n <PanelFrame\n panel={panel}\n envelope={envelope}\n attentionActive={attentionActive}\n layout=\"status-band\"\n >\n <div className={styles.statusAnchor} data-panel-anchor=\"status\">\n <PanelStatus\n status={signal.data.status}\n glyph={presentation.glyph}\n label={presentation.label}\n />\n </div>\n <div\n className={styles.evidence}\n data-panel-anchor=\"evidence\"\n data-panel-evidence-priority=\"secondary\"\n >\n <PanelHint className={styles.fullSummary} title={signal.data.summary}>\n {signal.data.summary}\n </PanelHint>\n <div className={styles.compactFacts} title={compactFacts.title} data-compact-facts>\n {compactFacts.primaryDetail && (\n <p className={styles.failedItem} title={compactFacts.primaryDetail}>\n <span aria-hidden=\"true\">⚠</span>{' '}\n <span className=\"screen-reader-only\">\n {compactFacts.primaryKind === 'warning' ? 'Warning' : 'Failed'} item:{' '}\n </span>\n {compactFacts.primary}\n <span className=\"screen-reader-only\">. Detail: {compactFacts.primaryDetail}</span>\n </p>\n )}\n <PanelMetadata\n glyph=\"⚙\"\n label=\"Update workflows\"\n value={compactFacts.workflow}\n compact={{ kind: 'short-value', value: signal.data.workflows.length }}\n title={`Update workflows: ${compactFacts.workflow}`}\n className={styles.compactFact}\n />\n <PanelMetadata\n glyph=\"⎇\"\n label=\"Open update pull requests\"\n value={compactFacts.pullRequests}\n compact={{ kind: 'short-value', value: signal.data.pullRequests.length }}\n title={`Open update pull requests: ${compactFacts.pullRequests}`}\n className={styles.compactFact}\n />\n </div>\n <div className={styles.freshness}>\n <ObservedAt value={envelope.observedAt} label=\"Observed (oldest evidence)\" />\n {signal.data.newestObservedAt && (\n <span className=\"screen-reader-only\">\n Newest evidence observed {signal.data.newestObservedAt}.\n </span>\n )}\n {updateHealth && <UpdateHealth health={updateHealth} />}\n </div>\n {signal.data.incompleteObservations && (\n <div role=\"status\">\n <PanelHint className={styles.incomplete}>\n ⚠ Incomplete observations:{' '}\n {signal.data.incompleteObservations\n .map(({ label, message }) => `${label}: ${message}`)\n .join(' · ')}\n </PanelHint>\n </div>\n )}\n </div>\n </PanelFrame>\n )\n}\n\nexport function projectPullRequestDiagnostic(envelope: Envelope): RenderedPanelDiagnostic {\n const base = { state: envelope.state, link: envelope.link }\n if (envelope.state === 'error') return base\n const signal = pullRequestHealthSchema.safeParse(envelope.signal)\n return { ...base, status: signal.success ? signal.data.status : undefined }\n}\n","import {\n type Envelope,\n testCountSchema,\n testEvidenceSchema,\n} from '@ze-great-dashboard/shared/browser'\nimport type { RenderedPanelDiagnostic } from './diagnostics.ts'\nimport { errorPresentation } from './error-presentation.ts'\nimport { PanelEvidence, PanelFrame, PanelHint, PanelStatus, PanelValue } from './PanelFrame.tsx'\nimport type { PanelProps } from './panel-props.ts'\nimport { projectTestEvidence, TestOutcomeSummary } from './TestEvidence.tsx'\nimport { ObservedAt, UpdateHealth } from './TimeAge.tsx'\n\n/** Renders one workflow run's declared aggregate test evidence. */\nexport function TestCountPanel({\n panel,\n envelope,\n attentionActive,\n updateHealth,\n testDirection,\n}: PanelProps) {\n if (!envelope)\n return (\n <PanelFrame panel={panel} attentionActive={attentionActive}>\n <PanelEvidence>\n <PanelHint>Loading…</PanelHint>\n </PanelEvidence>\n </PanelFrame>\n )\n if (envelope.state === 'error') {\n const presentation = errorPresentation(envelope.error.kind)\n return (\n <PanelFrame panel={panel} envelope={envelope} attentionActive={attentionActive} error>\n <PanelEvidence>\n <PanelStatus glyph=\"⚠\" label={presentation.label} emphasis={presentation.emphasis} />\n <PanelHint>{envelope.error.message}</PanelHint>\n </PanelEvidence>\n </PanelFrame>\n )\n }\n const parsed = testCountSchema.safeParse(envelope.signal)\n if (!parsed.success)\n return (\n <PanelFrame panel={panel} envelope={envelope} attentionActive={attentionActive} error>\n <PanelEvidence>\n <PanelStatus glyph=\"⚠\" label=\"Invalid test result\" />\n </PanelEvidence>\n </PanelFrame>\n )\n const signal = parsed.data\n if (signal.status === 'pending')\n return (\n <TestCountMessage\n panel={panel}\n envelope={envelope}\n attentionActive={attentionActive}\n label=\"Pending\"\n hint=\"The selected workflow run is still in progress.\"\n />\n )\n if (signal.status === 'not-reported')\n return (\n <TestCountMessage\n panel={panel}\n envelope={envelope}\n attentionActive={attentionActive}\n label=\"No test results published\"\n hint=\"This completed workflow did not publish the configured test summary.\"\n />\n )\n return (\n <PanelFrame panel={panel} envelope={envelope} attentionActive={attentionActive}>\n <PanelEvidence>\n <PanelStatus glyph=\"✓\" label=\"Test results reported\" compactOnly />\n <PanelValue>\n <TestOutcomeSummary tests={signal} direction={testDirection} />\n </PanelValue>\n <ObservedAt value={envelope.observedAt} />\n {updateHealth && <UpdateHealth health={updateHealth} />}\n </PanelEvidence>\n </PanelFrame>\n )\n}\n\nfunction TestCountMessage({\n panel,\n envelope,\n attentionActive,\n label,\n hint,\n}: {\n panel: PanelProps['panel']\n envelope: NonNullable<PanelProps['envelope']>\n attentionActive?: boolean\n label: string\n hint: string\n}) {\n return (\n <PanelFrame panel={panel} envelope={envelope} attentionActive={attentionActive}>\n <PanelEvidence>\n <PanelStatus glyph=\"◌\" label={label} />\n <PanelHint>{hint}</PanelHint>\n <ObservedAt value={envelope.observedAt} />\n </PanelEvidence>\n </PanelFrame>\n )\n}\n\nexport function projectTestCountDiagnostic(envelope: Envelope): RenderedPanelDiagnostic {\n const evidence = testEvidenceSchema.safeParse(envelope)\n return {\n state: envelope.state,\n link: envelope.link,\n ...(evidence.success ? { tests: projectTestEvidence(evidence.data) } : {}),\n }\n}\n","export function readUpdateWorkflows(panel: unknown) {\n const value =\n typeof panel === 'object' && panel !== null\n ? (panel as { update_workflows?: unknown }).update_workflows\n : undefined\n if (!Array.isArray(value)) return []\n return value.flatMap((entry) =>\n typeof entry === 'object' &&\n entry !== null &&\n typeof (entry as { workflow?: unknown }).workflow === 'string'\n ? [{ workflow: (entry as { workflow: string }).workflow }]\n : [],\n )\n}\n","import { HttpValuePanel } from './HttpValuePanel.tsx'\nimport { PanelPlaceholder } from './PanelPlaceholder.tsx'\nimport { PipelineAnimationDemoPanel } from './PipelineAnimationDemoPanel.tsx'\nimport { PipelinePanel, projectPipelineDiagnostic } from './PipelinePanel.tsx'\nimport { PullRequestHealthPanel, projectPullRequestDiagnostic } from './PullRequestHealthPanel.tsx'\nimport type { PanelFeature } from './panel-feature.ts'\nimport type { PanelProps } from './panel-props.ts'\nimport { projectTestCountDiagnostic, TestCountPanel } from './TestCountPanel.tsx'\nimport { readUpdateWorkflows } from './update-workflows.ts'\n\ntype PanelRendererProps = PanelProps\n\nconst singlePolling = {\n kind: 'single',\n initialPaths: (_panel, root) => [root],\n} satisfies PanelFeature['polling']\nconst basicDiagnostic: PanelFeature['projectDiagnostic'] = (envelope) => ({\n state: envelope.state,\n link: envelope.link,\n})\n\n/** Exhaustive feature contracts: a renderer cannot be registered without polling and diagnostics. */\nexport const panelFeatures = {\n 'pipeline-status': {\n testHistory: true,\n symbol: { glyph: '▣', label: 'Pipeline status' },\n Renderer: PipelinePanel,\n polling: singlePolling,\n projectDiagnostic: projectPipelineDiagnostic,\n },\n 'pull-request-health': {\n symbol: { glyph: '⌘', label: 'Pull request health' },\n Renderer: PullRequestHealthPanel,\n polling: {\n kind: 'pull-request-health',\n initialPaths: (panel, root) => [\n `${root}/pull-requests`,\n ...readUpdateWorkflows(panel).map(\n ({ workflow }) => `${root}/update-workflow/${encodeURIComponent(workflow)}`,\n ),\n ],\n },\n projectDiagnostic: projectPullRequestDiagnostic,\n },\n 'http-value': {\n symbol: { glyph: '◌', label: 'HTTP value' },\n Renderer: HttpValuePanel,\n polling: {\n kind: 'facts',\n initialPaths: (panel, root) =>\n panel.facts\n ? panel.facts.map((fact) => `${root}/facts/${encodeURIComponent(fact.id)}`)\n : [root],\n },\n projectDiagnostic: basicDiagnostic,\n },\n 'test-count': {\n testHistory: true,\n symbol: { glyph: '≡', label: 'Test count' },\n Renderer: TestCountPanel,\n polling: singlePolling,\n projectDiagnostic: projectTestCountDiagnostic,\n },\n 'pipeline-animation-demo': {\n symbol: { glyph: '✦', label: 'Pipeline animation demo' },\n Renderer: PipelineAnimationDemoPanel,\n polling: { kind: 'local' },\n projectDiagnostic: basicDiagnostic,\n },\n} satisfies Record<string, PanelFeature>\n\nexport type RenderablePanelType = keyof typeof panelFeatures\n\nconst featuresByType = new Map<string, PanelFeature>(Object.entries(panelFeatures))\nexport function panelFeature(type: string) {\n return featuresByType.get(type)\n}\n\nexport function PanelRenderer({\n panel,\n envelope,\n attentionActive,\n updateHealth,\n rejectedPipeline,\n facts,\n testDirection,\n}: PanelRendererProps) {\n const Renderer = panelFeature(panel.type)?.Renderer\n return Renderer ? (\n <Renderer\n panel={panel}\n envelope={envelope}\n attentionActive={attentionActive}\n updateHealth={updateHealth}\n rejectedPipeline={rejectedPipeline}\n facts={facts}\n testDirection={testDirection}\n />\n ) : (\n <PanelPlaceholder label={panel.type} hint=\"Not wired yet\" wide />\n )\n}\n","import {\n type ClientEnv,\n type SecurityDetailsResponse,\n securityDetailsResponseSchema,\n} from '@ze-great-dashboard/shared/browser'\nimport { useEffect, useRef, useState } from 'react'\nimport type { DashboardAuth } from './dashboard-fetch.ts'\nimport { dashboardFetch } from './dashboard-fetch.ts'\nimport styles from './SecurityDetails.module.css'\n\n/** Safe policy metadata for an already admitted viewer; values and identity claims stay server-side. */\nexport function SecurityDetails({ env, auth }: { env: ClientEnv; auth: DashboardAuth }) {\n const [open, setOpen] = useState(false)\n const [state, setState] = useState<'idle' | 'loading' | 'error'>('idle')\n const [details, setDetails] = useState<SecurityDetailsResponse>()\n const triggerRef = useRef<HTMLButtonElement>(null)\n const dialogRef = useRef<HTMLElement>(null)\n const closeRef = useRef<HTMLButtonElement>(null)\n const wasOpenRef = useRef(false)\n\n useEffect(() => {\n if (!open) {\n if (wasOpenRef.current) triggerRef.current?.focus()\n wasOpenRef.current = false\n return\n }\n wasOpenRef.current = true\n const dismiss = () => setOpen(false)\n const closeOnEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') dismiss()\n }\n const containFocus = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return\n const focusable = [\n ...(dialogRef.current?.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ) ?? []),\n ]\n const first = focusable.at(0)\n const last = focusable.at(-1)\n if (!first || !last) return\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n }\n const dialog = dialogRef.current\n dialog?.addEventListener('keydown', containFocus)\n window.addEventListener('keydown', closeOnEscape)\n closeRef.current?.focus()\n return () => {\n dialog?.removeEventListener('keydown', containFocus)\n window.removeEventListener('keydown', closeOnEscape)\n }\n }, [open])\n\n async function show() {\n setOpen(true)\n setState('loading')\n setDetails(undefined)\n try {\n const response = await dashboardFetch(\n env,\n `${env.proxyPath}/boards/${encodeURIComponent(env.board)}/security`,\n undefined,\n globalThis.fetch,\n auth,\n )\n if (!response.ok) throw new Error(`Security details returned ${response.status}`)\n const result = securityDetailsResponseSchema.safeParse(await response.json())\n if (!result.success) throw new Error('Security details were malformed')\n setDetails(result.data)\n setState('idle')\n } catch {\n setState('error')\n }\n }\n\n return (\n <>\n <button\n ref={triggerRef}\n className={styles.control}\n type=\"button\"\n aria-expanded={open}\n aria-controls=\"security-details-dialog\"\n onClick={() => void show()}\n >\n Security\n </button>\n {open && (\n <div className={styles.backdrop} role=\"presentation\">\n <section\n ref={dialogRef}\n className={styles.dialog}\n id=\"security-details-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"security-title\"\n >\n <h2 id=\"security-title\">Security details</h2>\n {state === 'loading' && <p aria-live=\"polite\">Loading security details…</p>}\n {state === 'error' && <p role=\"alert\">Security details are unavailable.</p>}\n {details && <PolicyDetails details={details} />}\n <button ref={closeRef} type=\"button\" onClick={() => setOpen(false)}>\n Close\n </button>\n </section>\n </div>\n )}\n </>\n )\n}\n\nfunction PolicyDetails({ details }: { details: SecurityDetailsResponse }) {\n if (details.policy.mode === 'claim')\n return (\n <p>\n OIDC is enabled. Access uses the <code>{details.policy.claim}</code> claim with a{' '}\n <strong>{details.policy.match}</strong> match policy.\n </p>\n )\n return details.policy.mode === 'authenticated' ? (\n <p>OIDC is enabled. Any verified API access token with a subject may view this board.</p>\n ) : (\n <p>OIDC is enabled. Access is limited to a server-held subject policy.</p>\n )\n}\n","import type { ClientSecurityState } from '@ze-great-dashboard/shared/browser'\nimport styles from './SecurityNotice.module.css'\n\nconst authenticationGuide =\n 'https://github.com/robertfmurdock/ze-great-dashboard/blob/main/docs/oidc-authentication.md'\n\n/** Deployment-level posture, intentionally separate from panel health and diagnostics. */\nexport function SecurityNotice({ mode }: { mode: ClientSecurityState }) {\n if (mode === 'blocked')\n return (\n <main className={styles.blocked} role=\"alert\">\n <h1>⚠ Authentication configuration required</h1>\n <p>\n This dashboard is blocked because authentication is required but has not been configured.\n </p>\n <p>No dashboard data was loaded.</p>\n <p>\n <a href={authenticationGuide}>Read the authentication setup guide</a>.\n </p>\n </main>\n )\n return (\n <aside className={styles.notice} role=\"alert\" aria-label=\"Unauthenticated deployment warning\">\n <span aria-hidden=\"true\">⚠</span>\n <span>\n <strong>This deployment has no authentication.</strong> If this is reachable on a public\n network and reveals important information, take it down now. Configure the board’s{' '}\n <code>auth</code> block and <code>security: required</code>, or set{' '}\n <code>security: unsecured</code> to explicitly acknowledge intentional public access.{' '}\n <a href={authenticationGuide}>Read the authentication setup guide</a>.\n </span>\n </aside>\n )\n}\n","import type { DiagnosticEvent, DiagnosticRetention } from './diagnostics.ts'\nimport type { PollingScheduleSnapshot } from './polling-schedule.ts'\n\nexport const updateActivityWindowMillis = 10 * 60 * 1_000\n\nexport type UpdateActivitySnapshot = {\n capturedAt: string\n window: { from: string; to: string }\n schedules: PollingScheduleSnapshot[]\n}\n\nexport type UpdateActivityLane = PollingScheduleSnapshot & {\n observed: Array<{ path: string; starts: string[] }>\n hasRetainedEvidence: boolean\n}\n\nexport function projectUpdateActivity({\n schedules,\n events,\n retention,\n now = new Date(),\n}: {\n schedules: PollingScheduleSnapshot[]\n events: DiagnosticEvent[]\n retention: DiagnosticRetention\n now?: Date\n}): UpdateActivitySnapshot & {\n lanes: UpdateActivityLane[]\n evidenceMayBeIncomplete: boolean\n} {\n const toMillis = now.valueOf()\n const fromMillis = toMillis - updateActivityWindowMillis\n const starts = events.filter(\n (event): event is Extract<DiagnosticEvent, { kind: 'panel-fetch-start' }> =>\n event.kind === 'panel-fetch-start' &&\n Number.isFinite(Date.parse(event.at)) &&\n Date.parse(event.at) >= fromMillis &&\n Date.parse(event.at) <= toMillis,\n )\n const lanes = schedules.map((schedule) => {\n const paths = new Map<string, string[]>()\n for (const event of starts) {\n if (event.panelId !== schedule.panelId) continue\n const observed = paths.get(event.path) ?? []\n observed.push(event.at)\n paths.set(event.path, observed)\n }\n return {\n ...schedule,\n observed: [...paths.entries()].map(([path, requestStarts]) => ({\n path,\n starts: requestStarts,\n })),\n hasRetainedEvidence: paths.size > 0,\n }\n })\n return {\n capturedAt: now.toISOString(),\n window: { from: new Date(fromMillis).toISOString(), to: now.toISOString() },\n schedules,\n lanes,\n evidenceMayBeIncomplete: retention.eventsPrunedByAge > 0 || retention.eventsPrunedByCount > 0,\n }\n}\n","import type { PollingScheduleSnapshot } from './polling-schedule.ts'\nimport { type UpdateActivityLane, updateActivityWindowMillis } from './update-activity.ts'\n\nexport function activityMarkerPosition(at: string, now: Date) {\n return Math.max(\n 0,\n Math.min(\n 100,\n ((Date.parse(at) - (now.valueOf() - updateActivityWindowMillis)) /\n updateActivityWindowMillis) *\n 100,\n ),\n )\n}\n\nexport function activityLaneLabel(lane: UpdateActivityLane, now: Date) {\n return `${lane.label}, panel ${lane.panelId}; ${cadenceLabel(lane.cadence)} cadence; ${lane.inFlight ? 'request in flight' : lane.nextDueAt ? relativeDue(lane.nextDueAt, now) : 'awaiting first request'}; ${lane.observed.length ? `${lane.observed.length} observed proxy path${lane.observed.length === 1 ? '' : 's'}` : 'no retained requests in the last 10 minutes'}`\n}\n\nfunction cadenceLabel(cadence: PollingScheduleSnapshot['cadence']) {\n return cadence === 'completion-window'\n ? 'Completion-window'\n : cadence === 'running'\n ? 'Running'\n : 'Normal'\n}\n\nfunction relativeDue(at: string, now: Date) {\n const millis = Date.parse(at) - now.valueOf()\n return millis < 0 ? `Overdue by ${formatMillis(-millis)}` : `Next poll in ${formatMillis(millis)}`\n}\n\nfunction formatMillis(millis: number) {\n return millis % 60_000 === 0\n ? `${Math.round(millis / 60_000)}m`\n : `${Math.max(1, Math.round(millis / 1_000))}s`\n}\n","import type { Board } from '@ze-great-dashboard/shared/browser'\nimport { useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'\nimport type { BrowserDiagnosticStore } from './diagnostics.ts'\nimport type { PollingScheduleSnapshot } from './polling-schedule.ts'\nimport styles from './UpdateActivity.module.css'\nimport { projectUpdateActivity } from './update-activity.ts'\nimport { activityLaneLabel, activityMarkerPosition } from './update-activity-presentation.ts'\n\n/** A browser-local polling timeline, available on demand. Diagnostics retains the exportable detail. */\nexport function UpdateActivity({\n board,\n schedules,\n log,\n}: {\n board: Board | undefined\n schedules: PollingScheduleSnapshot[]\n log: BrowserDiagnosticStore\n}) {\n const [now, setNow] = useState(() => new Date())\n const [open, setOpen] = useState(false)\n const triggerRef = useRef<HTMLButtonElement>(null)\n const dialogRef = useRef<HTMLElement>(null)\n const closeRef = useRef<HTMLButtonElement>(null)\n const wasOpenRef = useRef(false)\n useSyncExternalStore(log.subscribe, log.snapshot, log.snapshot)\n useEffect(() => {\n if (!open) return\n const interval = window.setInterval(() => setNow(new Date()), 1_000)\n return () => window.clearInterval(interval)\n }, [open])\n const activity = useMemo(\n () => projectUpdateActivity({ schedules, ...log.retainedEvidence(), now }),\n [log, now, schedules],\n )\n\n useEffect(() => {\n if (!open) {\n if (wasOpenRef.current) triggerRef.current?.focus()\n wasOpenRef.current = false\n return\n }\n\n wasOpenRef.current = true\n const dismiss = () => setOpen(false)\n let timeout = window.setTimeout(dismiss, 60_000)\n const resetDismissal = () => {\n window.clearTimeout(timeout)\n timeout = window.setTimeout(dismiss, 60_000)\n }\n const closeOnEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') dismiss()\n }\n const containFocus = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return\n const focusable = [\n ...(dialogRef.current?.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ) ?? []),\n ]\n const first = focusable.at(0)\n const last = focusable.at(-1)\n if (!first || !last) return\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last?.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n }\n const dialog = dialogRef.current\n dialog?.addEventListener('pointerdown', resetDismissal)\n dialog?.addEventListener('keydown', resetDismissal)\n dialog?.addEventListener('focusin', resetDismissal)\n dialog?.addEventListener('keydown', containFocus)\n window.addEventListener('keydown', closeOnEscape)\n closeRef.current?.focus()\n return () => {\n window.clearTimeout(timeout)\n dialog?.removeEventListener('pointerdown', resetDismissal)\n dialog?.removeEventListener('keydown', resetDismissal)\n dialog?.removeEventListener('focusin', resetDismissal)\n dialog?.removeEventListener('keydown', containFocus)\n window.removeEventListener('keydown', closeOnEscape)\n }\n }, [open])\n\n return (\n <>\n <button\n ref={triggerRef}\n className={styles.trigger}\n type=\"button\"\n aria-expanded={open}\n aria-controls=\"update-activity-dialog\"\n onClick={() => {\n setNow(new Date())\n setOpen(true)\n }}\n >\n Update activity\n </button>\n {open && (\n <section\n ref={dialogRef}\n className={styles.dialog}\n data-update-activity\n id=\"update-activity-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"update-activity-title\"\n >\n <div className={styles.dialogHeader}>\n <div>\n <h2 id=\"update-activity-title\">Update activity</h2>\n <p>\n Browser-local proxy reads from the last 10 minutes. Panels schedule independently.\n </p>\n </div>\n <button\n ref={closeRef}\n className={styles.close}\n type=\"button\"\n onClick={() => setOpen(false)}\n >\n Close\n </button>\n </div>\n <div className={styles.body}>\n <span className={styles.legend}>● observed · ◇ expected</span>\n {board && activity.lanes.length === 0 && (\n <p className={styles.empty}>No visible polling panels are configured.</p>\n )}\n {activity.lanes.length > 0 && (\n <>\n <div className={styles.axis} aria-hidden=\"true\">\n <span>10m ago</span>\n <span>now</span>\n </div>\n <div className={styles.lanes}>\n {activity.lanes.map((lane) => (\n <div className={styles.lane} data-update-activity-lane key={lane.panelId}>\n <span className={styles.laneLabel}>{lane.label}</span>\n <span\n className={styles.track}\n role=\"img\"\n aria-label={activityLaneLabel(lane, now)}\n >\n {lane.observed.flatMap(({ path, starts }) =>\n starts.map((start) => (\n <i\n className={styles.observed}\n key={`${path}-${start}`}\n style={{ left: `${activityMarkerPosition(start, now)}%` }}\n title={`Observed request: ${path}`}\n />\n )),\n )}\n {lane.nextDueAt && (\n <i\n className={styles.expected}\n style={{ left: `${activityMarkerPosition(lane.nextDueAt, now)}%` }}\n title=\"Expected next poll\"\n />\n )}\n </span>\n </div>\n ))}\n </div>\n </>\n )}\n {activity.evidenceMayBeIncomplete && (\n <p className={styles.note}>\n Older browser evidence was pruned, so an empty lane only means no retained request\n in this window.\n </p>\n )}\n <p className={styles.note}>\n Observed markers are requests this browser started; the outlined marker is the current\n expected next poll, not an observed request.\n </p>\n </div>\n </section>\n )}\n </>\n )\n}\n","import type { Board, ClientEnv } from '@ze-great-dashboard/shared/browser'\nimport { useEffect, useState } from 'react'\nimport type { DashboardAuth } from './dashboard-fetch.ts'\nimport { dashboardFetch } from './dashboard-fetch.ts'\nimport { cacheMetadata, type DiagnosticSink } from './diagnostics.ts'\n\n/** Fetches the board configuration and records the evidence that led to its rendered shape. */\nexport function useBoardConfig({\n env,\n diagnostics,\n auth,\n}: {\n env: ClientEnv\n diagnostics: DiagnosticSink\n auth?: DashboardAuth\n}) {\n const [board, setBoard] = useState<Board>()\n const [loadedBoardName, setLoadedBoardName] = useState<string>()\n\n useEffect(() => {\n let cancelled = false\n setBoard(undefined)\n setLoadedBoardName(undefined)\n const path = `${env.proxyPath}/boards/${encodeURIComponent(env.board)}`\n diagnostics.record({ kind: 'board-fetch-start', path })\n dashboardFetch(env, path, undefined, globalThis.fetch, auth)\n .then(async (response) => {\n diagnostics.record({\n kind: 'board-fetch-response',\n path,\n status: response.status,\n cache: cacheMetadata(response.headers),\n })\n if (!response.ok) throw new Error(`Board configuration returned ${response.status}`)\n try {\n return await response.json()\n } catch (error) {\n diagnostics.record({\n kind: 'board-fetch-parse-failure',\n path,\n message: errorMessage(error),\n })\n throw new DiagnosticParseFailure(error)\n }\n })\n .then((value: unknown) => {\n if (cancelled) return\n setBoard(value as Board)\n setLoadedBoardName(env.board)\n const panels = Array.isArray((value as { panels?: unknown }).panels)\n ? (value as { panels: Array<{ id?: unknown }> }).panels\n : []\n diagnostics.record({\n kind: 'board-fetch-response',\n path,\n boardSummary: {\n panelCount: panels.length,\n panelIds: panels.flatMap((panel) => (typeof panel.id === 'string' ? [panel.id] : [])),\n },\n })\n })\n .catch((error) => {\n if (!(error instanceof DiagnosticParseFailure))\n diagnostics.record({ kind: 'board-fetch-failure', path, message: errorMessage(error) })\n if (!cancelled) {\n setBoard({ panels: [] })\n setLoadedBoardName(env.board)\n }\n })\n return () => {\n cancelled = true\n }\n }, [auth, diagnostics, env])\n\n return { board, loadedBoardName }\n}\n\nfunction errorMessage(error: unknown) {\n return error instanceof Error ? error.message : String(error)\n}\n\nclass DiagnosticParseFailure extends Error {\n constructor(error: unknown) {\n super(errorMessage(error))\n }\n}\n","import { type ClientEnv, clientIdentityResponseSchema } from '@ze-great-dashboard/shared/browser'\nimport { useEffect } from 'react'\nimport type { DashboardAuth } from './dashboard-fetch.ts'\nimport { dashboardFetch } from './dashboard-fetch.ts'\nimport type { DiagnosticSink } from './diagnostics.ts'\n\nconst clientUpdateIntervalMillis = 60_000\nconst clientUpdateTimeoutMillis = 10_000\nconst defaultReload = () => globalThis.window.location.reload()\n\nexport function useClientUpdate({\n env,\n diagnostics,\n fetcher,\n reload = defaultReload,\n auth,\n}: {\n env: ClientEnv\n diagnostics: DiagnosticSink\n fetcher?: typeof fetch\n reload?: () => void\n auth?: DashboardAuth\n}) {\n useEffect(() => {\n let cancelled = false\n let inFlight = false\n let activeController: AbortController | undefined\n const path = `${env.proxyPath}/client`\n\n const check = async () => {\n if (cancelled || inFlight) return\n inFlight = true\n const controller = new AbortController()\n activeController = controller\n const timeout = globalThis.setTimeout(() => controller.abort(), clientUpdateTimeoutMillis)\n diagnostics.record({ kind: 'client-update-check', path })\n try {\n const response = await dashboardFetch(\n env,\n path,\n {\n cache: 'no-store',\n signal: controller.signal,\n },\n fetcher ?? globalThis.fetch,\n auth,\n )\n if (!response.ok) throw new Error(`Client identity returned ${response.status}`)\n const parsed = clientIdentityResponseSchema.safeParse(await response.json())\n if (!parsed.success) throw new Error('Client identity response was invalid')\n if (cancelled) return\n diagnostics.record({\n kind: 'client-update-response',\n path,\n serverVersion: parsed.data.serverVersion,\n assetPathIdMatches: parsed.data.assetPathId === env.assetPathId,\n })\n if (parsed.data.assetPath !== env.assetPath) {\n diagnostics.record({\n kind: 'client-update-detected',\n path,\n current: { assetPath: env.assetPath },\n next: parsed.data,\n })\n reload()\n }\n } catch (error) {\n if (!cancelled && !(error instanceof DOMException && error.name === 'AbortError')) {\n diagnostics.record({\n kind: 'client-update-failure',\n path,\n message: error instanceof Error ? error.message : String(error),\n })\n }\n } finally {\n globalThis.clearTimeout(timeout)\n inFlight = false\n if (activeController === controller) activeController = undefined\n if (!cancelled) globalThis.setTimeout(() => void check(), clientUpdateIntervalMillis)\n }\n }\n\n void check()\n return () => {\n cancelled = true\n activeController?.abort()\n }\n }, [auth, diagnostics, env, fetcher, reload])\n}\n","import type { Envelope, Panel } from '@ze-great-dashboard/shared/browser'\nimport type { RenderedPanelDiagnostic } from './diagnostics.ts'\nimport type { HttpValueFactObservation } from './panel-props.ts'\nimport { panelFeature } from './panel-registry.tsx'\n\n/**\n * The compact public fact a viewer saw. Keep new panel projections here beside their\n * presentation boundary; this is intentionally not a source or server event contract.\n */\nexport function projectPanelDiagnostic(panel: Panel, envelope: Envelope): RenderedPanelDiagnostic {\n return (\n panelFeature(panel.type)?.projectDiagnostic(envelope) ?? {\n state: envelope.state,\n link: envelope.link,\n }\n )\n}\n\nexport function panelDiagnosticChanged(\n previous: Envelope | undefined,\n panel: Panel,\n next: Envelope,\n) {\n if (!previous) return true\n const before = projectPanelDiagnostic(panel, previous)\n const after = projectPanelDiagnostic(panel, next)\n return JSON.stringify(before) !== JSON.stringify(after)\n}\n\n/** Public evidence for a visual group whose sources were observed independently. */\nexport function projectHttpValueFactsDiagnostic(\n facts: Record<string, HttpValueFactObservation | undefined>,\n): RenderedPanelDiagnostic {\n const projected = Object.entries(facts).map(([id, observation]) => {\n if (!observation?.envelope) return { id, state: 'unavailable' as const, link: null }\n return { id, state: observation.envelope.state, link: observation.envelope.link }\n })\n return {\n state: projected.some((fact) => fact.state === 'ok') ? 'ok' : 'error',\n link: null,\n facts: projected,\n }\n}\n\nexport function httpValueFactsDiagnosticChanged(\n previous: Record<string, HttpValueFactObservation | undefined> | undefined,\n next: Record<string, HttpValueFactObservation | undefined>,\n) {\n return (\n JSON.stringify(previous && projectHttpValueFactsDiagnostic(previous)) !==\n JSON.stringify(projectHttpValueFactsDiagnostic(next))\n )\n}\n","import type { Envelope, TestCount, TestHistorySample } from '@ze-great-dashboard/shared/browser'\nimport { pipelineStatusSchema, testCountSchema } from '@ze-great-dashboard/shared/browser'\n\nexport type TestSample = TestHistorySample\nexport type TestDirection = {\n mode: 'zero' | 'jump' | 'holding' | 'trend' | 'change' | 'quiet'\n symbol: string\n delta: number\n emphasized: boolean\n totals: number[]\n explanation: string\n}\n\nexport function reportedTests(\n envelope: Envelope,\n): Extract<TestCount, { status: 'reported' }> | undefined {\n if (envelope.state !== 'ok') return\n const pipeline = pipelineStatusSchema.safeParse(envelope.signal)\n if (pipeline.success) {\n if (pipeline.data.status === 'running' || pipeline.data.testResults?.state !== 'ok') return\n const tests = pipeline.data.testResults.signal\n return tests.status === 'reported' ? tests : undefined\n }\n const tests = testCountSchema.safeParse(envelope.signal)\n return tests.success && tests.data.status === 'reported' ? tests.data : undefined\n}\n\nfunction largeChange(before: number, after: number) {\n const delta = Math.abs(after - before)\n return delta >= 20 && (before === 0 || delta / before >= 0.2)\n}\n\n/** Input is unique, chronologically ordered completed runs, not polls. */\nexport function classifyTestDirection(samples: readonly TestSample[]): TestDirection | undefined {\n const totals = samples.slice(-8).map((sample) => sample.total)\n const latest = totals.at(-1)\n if (latest === undefined) return\n const previous = totals.at(-2)\n let mode: TestDirection['mode'] = 'quiet'\n let baseline = previous ?? latest\n let span = Math.min(2, totals.length)\n if (previous !== undefined && latest === 0 && previous > 0) mode = 'zero'\n else if (previous !== undefined && largeChange(previous, latest)) mode = 'jump'\n else {\n for (let landing = totals.length - 3; landing >= 1; landing--) {\n const before = totals[landing - 1]\n const count = totals[landing]\n if (before === undefined || count === undefined) continue\n if (\n largeChange(before, count) &&\n totals\n .slice(landing + 1)\n .every((total) => Math.abs(total - count) <= Math.max(2, count * 0.02))\n ) {\n mode = 'holding'\n baseline = before\n span = totals.length - landing + 1\n break\n }\n }\n if (mode === 'quiet') {\n const changes = totals\n .slice(1)\n .map((total, index) => total - (totals[index] ?? total))\n .filter((delta) => delta !== 0)\n const net = latest - (totals[0] ?? latest)\n if (\n changes.length >= 3 &&\n Math.abs(net) >= 5 &&\n changes.every((delta) => Math.sign(delta) === Math.sign(net))\n ) {\n mode = 'trend'\n baseline = totals[0] ?? latest\n span = totals.length\n } else if (previous !== undefined && latest !== previous) mode = 'change'\n }\n }\n const delta = latest - baseline\n const symbol =\n mode === 'quiet'\n ? ''\n : mode === 'zero'\n ? '⚠ ↓'\n : mode === 'holding'\n ? '→'\n : mode === 'trend'\n ? delta > 0\n ? '↗'\n : '↘'\n : delta > 0\n ? '↑'\n : '↓'\n const percent =\n baseline > 0 ? ` (${delta > 0 ? '+' : ''}${((delta / baseline) * 100).toFixed(1)}%)` : ''\n const descriptions = {\n zero: `Reported zero tests; previously ${baseline.toLocaleString()}.`,\n jump: `Large jump: ${baseline.toLocaleString()} → ${latest.toLocaleString()} tests${percent}.`,\n holding: `Holding a new level: ${latest.toLocaleString()} tests, previously ${baseline.toLocaleString()}${percent}.`,\n trend: `Sustained ${delta > 0 ? 'increase' : 'decrease'}: ${baseline.toLocaleString()} → ${latest.toLocaleString()} tests${percent}.`,\n change: `Latest change: ${baseline.toLocaleString()} → ${latest.toLocaleString()} tests${percent}.`,\n quiet: `No clear count change. Latest: ${latest.toLocaleString()} tests.`,\n }\n return {\n mode,\n symbol,\n delta,\n emphasized: mode === 'zero' || mode === 'jump',\n totals,\n explanation: `${descriptions[mode]} Comparison: ${span} retained run reading${span === 1 ? '' : 's'}. History: ${totals.join(' → ')}. Source readings retained by this browser are included; this is not complete CI history or a measure of test quality.`,\n }\n}\n\nexport function projectTestDirection(direction?: TestDirection) {\n if (!direction) return undefined\n return { mode: direction.mode, delta: direction.delta, totals: direction.totals }\n}\n","import type { TestHistory, TestHistorySample } from '@ze-great-dashboard/shared/browser'\nimport { classifyTestDirection } from './test-direction.ts'\n\nconst hourMillis = 60 * 60 * 1000\nconst dayMillis = 24 * hourMillis\nexport const testHistoryPolicy = {\n retentionMillis: 14 * dayMillis,\n retainedReadings: 32,\n refreshMillis: dayMillis,\n gapMillis: hourMillis,\n minimumAttemptMillis: hourMillis,\n retryDelaysMillis: [hourMillis, 6 * hourMillis, dayMillis],\n} as const\n\nexport type TestRepairState = {\n lastConfirmedAt?: number\n lastCompleteAt?: number\n lastAttemptAt?: number\n nextAttemptAt?: number\n failures: number\n gapPending: boolean\n partial?: boolean\n hadSamples?: boolean\n}\nconst emptyRepair: TestRepairState = { failures: 0, gapPending: false }\n\nfunction readingKey(sample: TestHistorySample) {\n return JSON.stringify([sample.id, sample.attempt])\n}\nfunction compareReadings(left: TestHistorySample, right: TestHistorySample) {\n return (\n Date.parse(left.updatedAt) - Date.parse(right.updatedAt) ||\n left.id.localeCompare(right.id, 'en', { numeric: true }) ||\n left.attempt - right.attempt\n )\n}\n\n/** Live observations and historical inspections are readings of the same source. */\nexport function mergeTestReadings(\n existing: readonly TestHistorySample[],\n incoming: readonly TestHistorySample[],\n now: number,\n) {\n const readings = new Map(existing.map((reading) => [readingKey(reading), reading]))\n for (const reading of incoming) {\n const previous = readings.get(readingKey(reading))\n // For the same source timestamp, prefer the latest inspection (including corrected totals).\n if (!previous || Date.parse(reading.updatedAt) >= Date.parse(previous.updatedAt))\n readings.set(readingKey(reading), reading)\n }\n return [...readings.values()]\n .filter((reading) => Date.parse(reading.updatedAt) >= now - testHistoryPolicy.retentionMillis)\n .sort(compareReadings)\n .slice(-testHistoryPolicy.retainedReadings)\n}\n\nexport function projectTestReadings(\n readings: readonly TestHistorySample[],\n current: TestHistorySample,\n partial = false,\n) {\n const anchor = readings.findIndex((reading) => readingKey(reading) === readingKey(current))\n if (anchor < 0) return undefined\n const direction = classifyTestDirection([...readings.slice(0, anchor), current])\n return direction && partial\n ? {\n ...direction,\n explanation: `${direction.explanation} Recent source-history inspection was incomplete.`,\n }\n : direction\n}\n\nexport function confirmTestObservation(\n state: TestRepairState = emptyRepair,\n now: number,\n): TestRepairState {\n return {\n ...state,\n lastConfirmedAt: now,\n gapPending:\n state.gapPending ||\n (state.lastConfirmedAt !== undefined &&\n now - state.lastConfirmedAt >= testHistoryPolicy.gapMillis),\n }\n}\n\nexport function testRepairEligible(\n state: TestRepairState = emptyRepair,\n hasReadings: boolean,\n now: number,\n) {\n return (\n now >= (state.nextAttemptAt ?? 0) &&\n (state.lastCompleteAt === undefined ||\n now - state.lastCompleteAt >= testHistoryPolicy.refreshMillis ||\n state.gapPending ||\n (state.hadSamples === true && !hasReadings))\n )\n}\n\nexport function startTestRepair(\n state: TestRepairState = emptyRepair,\n now: number,\n): TestRepairState {\n return {\n ...state,\n lastAttemptAt: now,\n nextAttemptAt: now + testHistoryPolicy.minimumAttemptMillis,\n }\n}\n\nexport function completeTestRepair(\n state: TestRepairState = emptyRepair,\n result: TestHistory | undefined,\n hasReadings: boolean,\n now: number,\n retryAt = 0,\n): TestRepairState {\n const updated = {\n ...state,\n hadSamples: hasReadings,\n partial: !result?.complete || result.samples.length < result.inspectedRuns,\n }\n if (result?.complete)\n return {\n ...updated,\n lastCompleteAt: now,\n failures: 0,\n gapPending: false,\n nextAttemptAt: now + testHistoryPolicy.minimumAttemptMillis,\n }\n const failures = state.failures + 1\n const delay =\n testHistoryPolicy.retryDelaysMillis[\n Math.min(failures - 1, testHistoryPolicy.retryDelaysMillis.length - 1)\n ] ?? testHistoryPolicy.refreshMillis\n return {\n ...updated,\n failures,\n nextAttemptAt: Math.max(now + delay, retryAt, result?.retryAt ? Date.parse(result.retryAt) : 0),\n }\n}\n","import type {\n Envelope,\n Panel,\n PipelineStatus,\n TestHistory,\n} from '@ze-great-dashboard/shared/browser'\nimport { browserLocalStorage, readBrowserJson, writeBrowserJson } from './browser-storage.ts'\nimport { reportedTests, type TestSample } from './test-direction.ts'\nimport {\n completeTestRepair,\n confirmTestObservation,\n mergeTestReadings,\n projectTestReadings,\n startTestRepair,\n type TestRepairState,\n testRepairEligible,\n} from './test-history-model.ts'\n\nconst storageKey = 'ze-great-dashboard.panel-memory.v1'\nconst schemaVersion = 1\nconst historyWindowMillis = 14 * 24 * 60 * 60 * 1_000\n\nexport type PanelMemoryIdentity = {\n board: string\n panelId: string\n source: string\n workflow: string\n branch: string\n testArtifact?: string\n}\n\nexport type AcceptedPipeline = {\n sourceUpdatedAt: string\n status: PipelineStatus['status']\n link: string | null\n}\n\nexport type DurationSample = {\n link: string | null\n sourceRunId?: string\n durationMs: number\n sourceUpdatedAt: string\n}\ntype History = {\n repair?: TestRepairState\n tests?: TestSample[]\n latest?: AcceptedPipeline\n durations: Record<string, DurationSample>\n latestCompleted?: DurationSample\n}\ntype StoredMemory = { schemaVersion: number; histories: Record<string, History> }\ntype StorageLike = Pick<Storage, 'getItem' | 'setItem'>\n\nexport class BrowserPanelMemory {\n private histories: Record<string, History>\n private readonly storage: StorageLike | undefined\n\n constructor(\n storage: StorageLike | undefined = browserLocalStorage(),\n private readonly now: () => Date = () => new Date(),\n ) {\n this.storage = storage\n this.histories = this.read()\n this.pruneAll()\n }\n\n latest(identity: PanelMemoryIdentity): AcceptedPipeline | undefined {\n return this.history(identity).latest\n }\n\n rememberLatest(identity: PanelMemoryIdentity, latest: AcceptedPipeline) {\n this.history(identity).latest = latest\n this.persist()\n }\n\n recordRun(identity: PanelMemoryIdentity, sample: DurationSample, successful = false) {\n const history = this.history(identity)\n if (successful) history.durations[sampleKey(sample)] = sample\n const previous = history.latestCompleted\n if (!previous || isAtLeastAsRecent(sample.sourceUpdatedAt, previous.sourceUpdatedAt)) {\n history.latestCompleted = sample\n }\n this.pruneHistory(history)\n this.persist()\n }\n\n recordSuccessfulRun(identity: PanelMemoryIdentity, sample: DurationSample) {\n this.recordRun(identity, sample, true)\n }\n\n recordCompletedRun(identity: PanelMemoryIdentity, sample: DurationSample) {\n this.recordRun(identity, sample)\n }\n\n medianDuration(identity: PanelMemoryIdentity): number | undefined {\n const history = this.history(identity)\n this.pruneHistory(history)\n const durations = Object.values(history.durations)\n .map(({ durationMs }) => durationMs)\n .sort((left, right) => left - right)\n if (durations.length === 0) return undefined\n const middle = Math.floor(durations.length / 2)\n if (durations.length % 2 === 1) return durations[middle]\n const lower = durations[middle - 1]\n const upper = durations[middle]\n return lower === undefined || upper === undefined ? undefined : Math.floor((lower + upper) / 2)\n }\n\n resolveEstimatedDuration(identity: PanelMemoryIdentity): number | undefined {\n const successful = this.medianDuration(identity)\n if (successful !== undefined) return successful\n\n const history = this.history(identity)\n this.pruneHistory(history)\n return history.latestCompleted?.durationMs\n }\n\n observeTests(board: string, panel: Panel, envelope: Envelope) {\n const tests = reportedTests(envelope)\n if (!tests?.run) return undefined\n const history = this.testHistory(board, panel)\n const current: TestSample = { ...tests.run, total: tests.total }\n history.tests = mergeTestReadings(history.tests ?? [], [current], this.now().valueOf())\n if (history.repair)\n history.repair = { ...history.repair, hadSamples: Boolean(history.tests.length) }\n this.persist()\n return projectTestReadings(history.tests, current, history.repair?.partial)\n }\n\n testDirection(board: string, panel: Panel, envelope: Envelope) {\n const tests = reportedTests(envelope)\n if (!tests?.run) return undefined\n const history = this.testHistory(board, panel)\n this.pruneHistory(history)\n return projectTestReadings(\n history.tests ?? [],\n { ...tests.run, total: tests.total },\n history.repair?.partial,\n )\n }\n\n confirmTestPoll(board: string, panel: Panel) {\n const history = this.testHistory(board, panel)\n history.repair = confirmTestObservation(history.repair, this.now().valueOf())\n this.persist()\n }\n\n testRepairDue(board: string, panel: Panel) {\n const history = this.testHistory(board, panel)\n this.pruneHistory(history)\n return testRepairEligible(history.repair, Boolean(history.tests?.length), this.now().valueOf())\n }\n\n beginTestRepair(board: string, panel: Panel) {\n const history = this.testHistory(board, panel)\n history.repair = startTestRepair(history.repair, this.now().valueOf())\n this.persist()\n }\n\n finishTestRepair(board: string, panel: Panel, result?: TestHistory, retryAt?: number) {\n const history = this.testHistory(board, panel)\n const now = this.now().valueOf()\n history.tests = mergeTestReadings(history.tests ?? [], result?.samples ?? [], now)\n history.repair = completeTestRepair(\n history.repair,\n result,\n Boolean(history.tests.length),\n now,\n retryAt,\n )\n this.persist()\n }\n\n private testHistory(board: string, panel: Panel) {\n return this.history({\n ...resolvePanelMemoryIdentity(board, panel),\n testArtifact: JSON.stringify(panel.test_results ?? null),\n })\n }\n\n private history(identity: PanelMemoryIdentity) {\n const key = identityKey(identity)\n const existing = this.histories[key]\n if (existing) return existing\n const created: History = { durations: {} }\n this.histories[key] = created\n return created\n }\n\n private pruneAll() {\n for (const history of Object.values(this.histories)) this.pruneHistory(history)\n this.persist()\n }\n\n private pruneHistory(history: History) {\n const cutoff = this.now().valueOf() - historyWindowMillis\n if (history.tests) history.tests = mergeTestReadings(history.tests, [], this.now().valueOf())\n for (const [link, sample] of Object.entries(history.durations)) {\n const at = sourceTimestamp(sample.sourceUpdatedAt)\n if (at === undefined || at < cutoff) delete history.durations[link]\n }\n const latestCompletedAt = history.latestCompleted\n ? sourceTimestamp(history.latestCompleted.sourceUpdatedAt)\n : undefined\n if (\n history.latestCompleted &&\n (latestCompletedAt === undefined || latestCompletedAt < cutoff)\n ) {\n delete history.latestCompleted\n }\n }\n\n private read(): Record<string, History> {\n const parsed = readBrowserJson<Partial<StoredMemory>>(this.storage, storageKey)\n if (parsed?.schemaVersion !== schemaVersion || !parsed.histories) return {}\n return isHistories(parsed.histories) ? parsed.histories : {}\n }\n\n private persist() {\n writeBrowserJson(this.storage, storageKey, { schemaVersion, histories: this.histories })\n }\n}\n\nfunction sampleKey(sample: DurationSample) {\n return sample.sourceRunId ?? sample.link ?? sample.sourceUpdatedAt\n}\n\nfunction isAtLeastAsRecent(left: string, right: string) {\n const leftAt = sourceTimestamp(left)\n const rightAt = sourceTimestamp(right)\n return leftAt !== undefined && (rightAt === undefined || leftAt >= rightAt)\n}\n\nfunction sourceTimestamp(value: string) {\n const timestamp = Date.parse(value)\n return Number.isFinite(timestamp) ? timestamp : undefined\n}\n\nexport function resolvePanelMemoryIdentity(board: string, panel: Panel): PanelMemoryIdentity {\n return {\n board,\n panelId: panel.id,\n source: panel.source ?? '',\n workflow:\n typeof panel.pipeline === 'string' || typeof panel.pipeline === 'number'\n ? String(panel.pipeline)\n : '',\n branch: panel.branch ?? '',\n }\n}\n\nfunction identityKey(identity: PanelMemoryIdentity) {\n const parts = [\n identity.board,\n identity.panelId,\n identity.source,\n identity.workflow,\n identity.branch,\n ]\n if (identity.testArtifact !== undefined) parts.push(identity.testArtifact)\n return JSON.stringify(parts)\n}\n\nfunction isHistories(value: unknown): value is Record<string, History> {\n if (!isRecord(value)) return false\n return Object.values(value).every(isHistory)\n}\n\nfunction isHistory(value: unknown): value is History {\n if (!isRecord(value) || !isRecord(value.durations)) return false\n if (!Object.values(value.durations).every(isDurationSample)) return false\n if (value.repair !== undefined) {\n if (\n !isRecord(value.repair) ||\n !Number.isInteger(value.repair.failures) ||\n Number(value.repair.failures) < 0 ||\n typeof value.repair.gapPending !== 'boolean'\n )\n return false\n for (const key of ['lastConfirmedAt', 'lastCompleteAt', 'lastAttemptAt', 'nextAttemptAt']) {\n const at = value.repair[key]\n if (at !== undefined && (typeof at !== 'number' || !Number.isFinite(at) || at < 0))\n return false\n }\n if (value.repair.partial !== undefined && typeof value.repair.partial !== 'boolean')\n return false\n if (value.repair.hadSamples !== undefined && typeof value.repair.hadSamples !== 'boolean')\n return false\n }\n if (\n value.tests !== undefined &&\n (!Array.isArray(value.tests) ||\n !value.tests.every(\n (sample) =>\n isRecord(sample) &&\n typeof sample.id === 'string' &&\n sample.id.length > 0 &&\n Number.isInteger(sample.attempt) &&\n Number(sample.attempt) > 0 &&\n typeof sample.updatedAt === 'string' &&\n Number.isFinite(Date.parse(sample.updatedAt)) &&\n Number.isInteger(sample.total) &&\n Number(sample.total) >= 0,\n ))\n )\n return false\n return value.latestCompleted === undefined || isDurationSample(value.latestCompleted)\n}\n\nfunction isDurationSample(value: unknown): value is DurationSample {\n if (!isRecord(value)) return false\n return (\n (typeof value.link === 'string' || value.link === null) &&\n (value.sourceRunId === undefined || typeof value.sourceRunId === 'string') &&\n typeof value.durationMs === 'number' &&\n Number.isInteger(value.durationMs) &&\n value.durationMs >= 0 &&\n typeof value.sourceUpdatedAt === 'string' &&\n sourceTimestamp(value.sourceUpdatedAt) !== undefined\n )\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n}\n","import { type Envelope, envelopeSchema } from '@ze-great-dashboard/shared/browser'\nimport { cacheMetadata, type DiagnosticSink } from './diagnostics.ts'\n\nexport type ComponentObservation = { envelope?: Envelope; error?: string }\n\n/**\n * Reads one bounded panel component while retaining its browser cache conversation and public\n * diagnostics. Composite panels use this instead of inventing an aggregate source response.\n */\nexport async function readPanelObservation(args: {\n diagnostics: DiagnosticSink\n panelId: string\n path: string\n signal?: AbortSignal\n cache: Map<string, Envelope>\n fetcher: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>\n}): Promise<ComponentObservation> {\n args.diagnostics.record({ kind: 'panel-fetch-start', panelId: args.panelId, path: args.path })\n try {\n const response = await args.fetcher(args.path, { signal: args.signal })\n const transport = {\n kind: 'panel-fetch-response' as const,\n panelId: args.panelId,\n path: args.path,\n status: response.status,\n cache: cacheMetadata(response.headers),\n }\n if (response.status === 304) {\n args.diagnostics.record(transport)\n const cached = args.cache.get(args.path)\n return cached\n ? { envelope: cached }\n : { error: 'Source returned not modified before an initial observation.' }\n }\n const parsed = envelopeSchema.safeParse(await response.json())\n if (!parsed.success) {\n args.diagnostics.record(transport)\n args.diagnostics.record({\n kind: 'panel-fetch-parse-failure',\n panelId: args.panelId,\n path: args.path,\n message: 'Response was not a valid signal envelope.',\n })\n return { error: 'Response was not a valid signal envelope.' }\n }\n const envelope = parsed.data\n args.diagnostics.record({\n ...transport,\n envelope,\n ...(envelope.state === 'error' ? { failure: failedObservation(envelope, response) } : {}),\n })\n if (envelope.state === 'ok') args.cache.set(args.path, envelope)\n return { envelope }\n } catch (error) {\n if (!args.signal?.aborted)\n args.diagnostics.record({\n kind: 'panel-fetch-failure',\n panelId: args.panelId,\n path: args.path,\n message: errorMessage(error),\n })\n return { error: errorMessage(error) }\n }\n}\n\nfunction failedObservation(envelope: Extract<Envelope, { state: 'error' }>, response: Response) {\n const supportReference = response.headers.get('x-dashboard-request-id')\n return {\n reason: envelope.error.message,\n ...(supportReference ? { supportReference } : {}),\n }\n}\n\nfunction errorMessage(error: unknown) {\n return error instanceof Error ? error.message : String(error)\n}\n","import type { Envelope, PipelineStatus } from '@ze-great-dashboard/shared/browser'\nimport { pipelineStatusSchema } from '@ze-great-dashboard/shared/browser'\nimport type { AcceptedPipeline } from './panel-memory.ts'\nimport type { RejectedPipelinePresentation } from './panel-props.ts'\n\nexport type PipelineDurationSample = {\n link: string | null\n sourceRunId?: string\n durationMs: number\n sourceUpdatedAt: string\n}\n\nexport type PipelineReconciliation =\n | { kind: 'not-pipeline'; envelope: Envelope }\n | {\n kind: 'rejected'\n envelope: Extract<Envelope, { state: 'ok' }>\n signal: PipelineStatus & { sourceUpdatedAt: string }\n }\n | {\n kind: 'accepted'\n envelope: Envelope\n signal: PipelineStatus\n accepted?: AcceptedPipeline\n durationSample?: PipelineDurationSample\n }\n\n/** The client display state after applying a newly observed pipeline response. */\nexport type PipelinePresentation = {\n envelope: Envelope | undefined\n rejected?: RejectedPipelinePresentation\n}\n\n/**\n * Preserve a current envelope on rejection, or make persisted accepted evidence readable when\n * there is no envelope after a reload. An accepted result always ends the historical disclosure.\n */\nexport function applyPipelinePresentation(args: {\n current: Envelope | undefined\n reconciliation: PipelineReconciliation\n accepted?: AcceptedPipeline\n}): PipelinePresentation {\n if (args.reconciliation.kind === 'rejected' && args.accepted) {\n return {\n envelope: args.current,\n rejected: {\n status: args.accepted.status,\n sourceUpdatedAt: args.accepted.sourceUpdatedAt,\n link: args.accepted.link,\n github: isGithubLink(args.reconciliation.envelope.link),\n },\n }\n }\n return { envelope: args.reconciliation.envelope }\n}\n\nexport function reconcilePipelineResponse(args: {\n envelope: Envelope\n accepted?: AcceptedPipeline\n estimatedDurationMs?: number\n}): PipelineReconciliation {\n const signal = pipelineStatus(args.envelope)\n if (!signal) return { kind: 'not-pipeline', envelope: args.envelope }\n if (\n args.accepted &&\n signal.sourceUpdatedAt &&\n Date.parse(signal.sourceUpdatedAt) < Date.parse(args.accepted.sourceUpdatedAt)\n ) {\n if (args.envelope.state !== 'ok' || !signal.sourceUpdatedAt)\n return { kind: 'not-pipeline', envelope: args.envelope }\n return {\n kind: 'rejected',\n envelope: args.envelope,\n signal: { ...signal, sourceUpdatedAt: signal.sourceUpdatedAt },\n }\n }\n\n const accepted = signal.sourceUpdatedAt\n ? { sourceUpdatedAt: signal.sourceUpdatedAt, status: signal.status, link: args.envelope.link }\n : undefined\n const durationSample =\n signal.status !== 'running' &&\n signal.durationMs !== undefined &&\n signal.sourceUpdatedAt &&\n Number.isFinite(Date.parse(signal.sourceUpdatedAt))\n ? {\n link: args.envelope.link,\n ...(signal.sourceRunId ? { sourceRunId: signal.sourceRunId } : {}),\n durationMs: signal.durationMs,\n sourceUpdatedAt: signal.sourceUpdatedAt,\n }\n : undefined\n const envelope =\n signal.status === 'running' &&\n args.estimatedDurationMs !== undefined &&\n args.envelope.state === 'ok'\n ? { ...args.envelope, signal: { ...signal, estimatedDurationMs: args.estimatedDurationMs } }\n : args.envelope\n return { kind: 'accepted', envelope, signal, accepted, durationSample }\n}\n\nexport function pipelineStatus(envelope: Envelope): PipelineStatus | undefined {\n if (envelope.state !== 'ok') return undefined\n const result = pipelineStatusSchema.safeParse(envelope.signal)\n return result.success ? result.data : undefined\n}\n\nfunction isGithubLink(link: string | null) {\n if (!link) return false\n try {\n return new URL(link).hostname === 'github.com'\n } catch {\n return false\n }\n}\n","import type { Panel } from '@ze-great-dashboard/shared/browser'\nimport {\n type Board,\n type ClientEnv,\n isZeroPosition,\n resolvePollingSettings,\n} from '@ze-great-dashboard/shared/browser'\nimport type { RemotePanelPolling } from './panel-feature.ts'\nimport { panelFeature } from './panel-registry.tsx'\nimport type { PollingScheduleSnapshot } from './polling-schedule.ts'\n\nexport { readUpdateWorkflows } from './update-workflows.ts'\n\nexport type PollingPanel = { panel: Panel; polling: RemotePanelPolling }\n\n/** Visible remote features carry their registered polling behavior into the lifecycle. */\nexport function pollingPanels(board: Board): PollingPanel[] {\n return board.panels.flatMap((panel) => {\n if (isZeroPosition(panel.position)) return []\n const polling = panelFeature(panel.type)?.polling\n return polling && polling.kind !== 'local' ? [{ panel, polling }] : []\n })\n}\n\nexport function panelProxyPath(env: ClientEnv, panelId: string) {\n return `${env.proxyPath}/panel/${encodeURIComponent(env.board)}/${encodeURIComponent(panelId)}`\n}\n\n/** Build the initial schedule without claiming branch-dependent fan-out before it is observed. */\nexport function initialPollingSchedule(\n board: Board,\n env: ClientEnv,\n { panel, polling }: PollingPanel,\n): PollingScheduleSnapshot {\n const path = panelProxyPath(env, panel.id)\n const knownPaths = polling.initialPaths(panel, path)\n return {\n panelId: panel.id,\n label: panel.label ?? panel.id,\n settings: resolvePollingSettings(board, panel),\n cadence: 'normal',\n inFlight: false,\n knownPaths,\n }\n}\n","import {\n type Envelope,\n type PipelineStatus,\n type PollingSettings,\n pipelineStatusSchema,\n} from '@ze-great-dashboard/shared/browser'\n\n/** Ephemeral scheduling state; polling owns it and views may project it. */\nexport type PollingScheduleSnapshot = {\n panelId: string\n label: string\n settings: PollingSettings\n cadence: PollingCadence\n inFlight: boolean\n lastRequestStartedAt?: string\n nextDueAt?: string\n /** Paths known before this cycle; dynamic fan-out is disclosed only once observed. */\n knownPaths: string[]\n}\n\n/** Return the next delay for a panel, keeping active runs responsive without polling forever at burst speed. */\nexport function nextPollDelayMillis(\n envelope: Envelope | undefined,\n nowMillis: number,\n settings: PollingSettings,\n): number {\n return resolveNextPoll(envelope, nowMillis, settings).delayMillis\n}\n\nexport type PollingCadence = 'normal' | 'running' | 'completion-window'\n\n/** The scheduler and activity view share this resolved cadence; neither infers it from history. */\nexport function resolveNextPoll(\n envelope: Envelope | undefined,\n nowMillis: number,\n settings: PollingSettings,\n): { delayMillis: number; cadence: PollingCadence } {\n const pipeline = runningPipeline(envelope)\n if (!pipeline) return { delayMillis: settings.refreshMillis, cadence: 'normal' }\n\n const completionAt = estimatedCompletionAt(pipeline)\n if (completionAt === undefined)\n return { delayMillis: settings.runningRefreshMillis, cadence: 'running' }\n\n if (nowMillis < completionAt) {\n return {\n delayMillis: Math.min(settings.runningRefreshMillis, completionAt - nowMillis),\n cadence: 'running',\n }\n }\n if (nowMillis < completionAt + settings.runningCompletionWindowMillis) {\n return { delayMillis: settings.runningCompletionRefreshMillis, cadence: 'completion-window' }\n }\n return { delayMillis: settings.runningRefreshMillis, cadence: 'running' }\n}\n\nfunction runningPipeline(envelope: Envelope | undefined): PipelineStatus | undefined {\n if (envelope?.state !== 'ok') return undefined\n const result = pipelineStatusSchema.safeParse(envelope.signal)\n return result.success && result.data.status === 'running' ? result.data : undefined\n}\n\nfunction estimatedCompletionAt(signal: PipelineStatus): number | undefined {\n if (!signal.runStartedAt || signal.estimatedDurationMs === undefined) return undefined\n const startedAt = Date.parse(signal.runStartedAt)\n return Number.isFinite(startedAt) ? startedAt + signal.estimatedDurationMs : undefined\n}\n","import type {\n Envelope,\n PipelineStatus,\n PullRequestCandidate,\n PullRequestHealth,\n} from '@ze-great-dashboard/shared/browser'\nimport {\n pipelineStatusPriority,\n pullRequestBuildObservationSchema,\n pullRequestCandidatesSchema,\n pullRequestWorkflowObservationSchema,\n} from '@ze-great-dashboard/shared/browser'\n\ntype Observation = { envelope?: Envelope; error?: string }\n\n/** Purely combines normalized, public component observations; it never constructs source URLs. */\nexport function rollupPullRequestHealth(args: {\n panelId: string\n link: string | null\n workflows: Array<{ workflow: string; observation: Observation }>\n candidates: Observation\n builds: Map<string, Observation>\n}): Envelope | undefined {\n const incomplete: Array<{ label: string; message: string }> = []\n const workflows = args.workflows.map(({ workflow, observation }) => {\n const signal = observationItem(observation.envelope, 'pull-request-workflow')\n if (signal) return signal.item as PullRequestHealth['workflows'][number]\n const message = observation.error ?? 'No usable observation is available.'\n incomplete.push({ label: `Update workflow ${workflow}`, message })\n return {\n label: workflow,\n status: 'unknown' as const,\n detail: `Update workflow ${workflow} · Unavailable: ${message}`,\n link: null,\n }\n })\n const candidatesSignal = candidateSignal(args.candidates.envelope)\n if (!candidatesSignal) {\n const message = args.candidates.error ?? 'No usable observation is available.'\n incomplete.push({ label: 'Open update PR candidates', message })\n if (workflows.every((item) => item.status === 'unknown')) return undefined\n return buildEnvelope(\n args,\n workflows,\n [],\n incomplete,\n observationDates(args.workflows.map(({ observation }) => observation)),\n )\n }\n if (candidatesSignal.truncated)\n incomplete.push({\n label: 'Open update PR candidates',\n message: 'The first 100 candidates were observed; additional open update PRs may exist.',\n })\n const pullRequests = candidatesSignal.pullRequests.map((candidate: PullRequestCandidate) => {\n const observation = args.builds.get(candidate.branch)\n const signal = observationItem(observation?.envelope, 'pull-request-build')\n if (signal)\n return {\n ...signal.item,\n label: `PR #${candidate.number}`,\n detail: signal.item.detail,\n link: candidate.link,\n }\n const message = observation?.error ?? 'No usable observation is available.'\n incomplete.push({ label: `PR #${candidate.number}`, message })\n return {\n label: `PR #${candidate.number}`,\n status: 'unknown' as const,\n detail: `${candidate.branch} · Unavailable: ${message}`,\n link: candidate.link,\n }\n })\n return buildEnvelope(\n args,\n workflows,\n pullRequests,\n incomplete,\n observationDates([\n ...args.workflows.map(({ observation }) => observation),\n args.candidates,\n ...args.builds.values(),\n ]),\n )\n}\n\nfunction buildEnvelope(\n args: Parameters<typeof rollupPullRequestHealth>[0],\n workflows: PullRequestHealth['workflows'],\n pullRequests: PullRequestHealth['pullRequests'],\n incomplete: Array<{ label: string; message: string }>,\n dates: string[],\n) {\n const status = aggregateStatus([...workflows, ...pullRequests].map((item) => item.status))\n const attentionItem = [...workflows, ...pullRequests].find((item) => item.status === status)\n const summary =\n status !== 'passed' && attentionItem\n ? `${attentionItem.label}: ${attentionItem.detail}`\n : pullRequests.length === 0\n ? `${workflows.length} update workflow${workflows.length === 1 ? '' : 's'} · No open update PRs`\n : `${workflows.length} update workflow${workflows.length === 1 ? '' : 's'} · ${pullRequests.length} open update PR${pullRequests.length === 1 ? '' : 's'}`\n const sorted = dates.sort()\n return {\n panelId: args.panelId,\n state: 'ok' as const,\n observedAt: sorted[0] ?? new Date().toISOString(),\n link: args.link,\n signal: {\n type: 'pull-request-health' as const,\n status,\n summary,\n workflows,\n pullRequests,\n ...(incomplete.length ? { incompleteObservations: incomplete } : {}),\n ...(sorted.length > 1 ? { newestObservedAt: sorted.at(-1) } : {}),\n } satisfies PullRequestHealth,\n }\n}\n\nfunction observationItem(\n envelope: Envelope | undefined,\n type: 'pull-request-workflow' | 'pull-request-build',\n): { item: PullRequestHealth['workflows'][number] } | undefined {\n if (envelope?.state !== 'ok') return undefined\n const schema =\n type === 'pull-request-workflow'\n ? pullRequestWorkflowObservationSchema\n : pullRequestBuildObservationSchema\n const result = schema.safeParse(envelope.signal)\n return result.success ? { item: result.data.item } : undefined\n}\nfunction candidateSignal(\n envelope: Envelope | undefined,\n): { pullRequests: PullRequestCandidate[]; truncated?: boolean } | undefined {\n if (envelope?.state !== 'ok') return undefined\n const result = pullRequestCandidatesSchema.safeParse(envelope.signal)\n return result.success ? result.data : undefined\n}\nfunction observationDates(observations: Observation[]) {\n return observations.flatMap(({ envelope }) =>\n envelope?.state === 'ok' ? [envelope.observedAt] : [],\n )\n}\nfunction aggregateStatus(statuses: PipelineStatus['status'][]): PipelineStatus['status'] {\n return statuses.reduce(\n (mostUrgent, status) =>\n pipelineStatusPriority(status) > pipelineStatusPriority(mostUrgent) ? status : mostUrgent,\n 'passed' as const,\n )\n}\n","import { type Panel, retryAfterTime, testHistorySchema } from '@ze-great-dashboard/shared/browser'\nimport type { DiagnosticSink } from './diagnostics.ts'\nimport type { BrowserPanelMemory } from './panel-memory.ts'\n\ntype Candidate = { panel: Panel; path: string }\n\n/** Idle work is driven by settled current polls, never by its own recurring timer. */\nexport class TestHistoryRepair {\n private readonly pending = new Map<string, Candidate>()\n private readonly activePolls = new Set<string>()\n private readonly healthy = new Set<string>()\n private controller?: AbortController\n private disposed = false\n\n constructor(\n private readonly options: {\n board: string\n memory: BrowserPanelMemory\n fetcher: typeof fetch\n diagnostics: DiagnosticSink\n onMerged: (panel: Panel) => void\n visible?: () => boolean\n },\n ) {}\n\n currentStarted(panelId: string) {\n this.activePolls.add(panelId)\n }\n\n currentSettled(panel: Panel, path: string, healthy: boolean, supported: boolean) {\n if (this.disposed) return\n this.activePolls.delete(panel.id)\n if (!supported) this.pending.delete(panel.id)\n if (healthy) this.healthy.add(panel.id)\n else this.healthy.delete(panel.id)\n if (healthy && supported) {\n this.options.memory.confirmTestPoll(this.options.board, panel)\n if (this.options.memory.testRepairDue(this.options.board, panel))\n this.pending.set(panel.id, { panel, path: `${path}/test-history` })\n }\n this.drain()\n }\n\n dispose() {\n this.disposed = true\n this.pending.clear()\n this.controller?.abort()\n }\n\n private drain() {\n if (\n this.disposed ||\n this.controller ||\n this.activePolls.size ||\n !(this.options.visible?.() ?? document.visibilityState === 'visible')\n )\n return\n for (const [id, candidate] of this.pending) {\n this.pending.delete(id)\n if (\n !this.healthy.has(id) ||\n !this.options.memory.testRepairDue(this.options.board, candidate.panel)\n )\n continue\n this.controller = new AbortController()\n void this.run(candidate, this.controller)\n return\n }\n }\n\n private async run({ panel, path }: Candidate, controller: AbortController) {\n const { board, memory, diagnostics } = this.options\n memory.beginTestRepair(board, panel)\n let result: ReturnType<typeof testHistorySchema.parse> | undefined\n let retryAt: number | undefined\n try {\n const response = await this.options.fetcher(path, { signal: controller.signal })\n retryAt = retryAfterTime(response.headers.get('retry-after'), Date.now())\n if (response.ok) result = testHistorySchema.parse(await response.json())\n } catch {\n // Repair is optional context; failure never changes current polling health.\n }\n if (!this.disposed && !controller.signal.aborted) {\n memory.finishTestRepair(board, panel, result, retryAt)\n diagnostics.record({\n kind: 'test-history-repair',\n panelId: panel.id,\n path,\n outcome: result?.complete ? 'complete' : result ? 'partial' : 'failed',\n inspectedRuns: result?.inspectedRuns ?? 0,\n samples: result?.samples.length ?? 0,\n })\n this.options.onMerged(panel)\n }\n this.controller = undefined\n this.drain()\n }\n}\n","import {\n type Board,\n type ClientEnv,\n type Envelope,\n envelopeSchema,\n testHistoryHeader,\n} from '@ze-great-dashboard/shared/browser'\nimport { useEffect, useRef, useState } from 'react'\nimport type { DashboardAuth } from './dashboard-fetch.ts'\nimport { dashboardFetch } from './dashboard-fetch.ts'\nimport { cacheMetadata, type DiagnosticSink, type RenderedPanelDiagnostic } from './diagnostics.ts'\nimport { projectHttpValueFactsDiagnostic, projectPanelDiagnostic } from './panel-diagnostics.ts'\nimport { BrowserPanelMemory, resolvePanelMemoryIdentity } from './panel-memory.ts'\nimport { readPanelObservation } from './panel-observation.ts'\nimport type {\n HttpValueFactObservation,\n PanelUpdateHealth,\n RejectedPipelinePresentation,\n} from './panel-props.ts'\nimport { panelFeature } from './panel-registry.tsx'\nimport { applyPipelinePresentation, reconcilePipelineResponse } from './pipeline-reconciliation.ts'\nimport {\n initialPollingSchedule,\n panelProxyPath,\n pollingPanels,\n readUpdateWorkflows,\n} from './polling-panels.ts'\nimport { type PollingScheduleSnapshot, resolveNextPoll } from './polling-schedule.ts'\nimport { rollupPullRequestHealth } from './pull-request-rollup.ts'\nimport { projectTestDirection, type TestDirection } from './test-direction.ts'\nimport { TestHistoryRepair } from './test-history-repair.ts'\n\nexport function usePanelSignals({\n board,\n env,\n diagnostics,\n memory,\n auth,\n}: {\n board: Board | undefined\n env: ClientEnv\n diagnostics: DiagnosticSink\n memory?: BrowserPanelMemory\n auth?: DashboardAuth\n}) {\n const [testDirections, setTestDirections] = useState<Record<string, TestDirection | undefined>>(\n {},\n )\n const testDirectionsRef = useRef<Record<string, TestDirection | undefined>>({})\n const [signals, setSignals] = useState<Record<string, Envelope | undefined>>({})\n const [updateHealth, setUpdateHealth] = useState<Record<string, PanelUpdateHealth | undefined>>(\n {},\n )\n const [factSignals, setFactSignals] = useState<\n Record<string, Record<string, HttpValueFactObservation | undefined> | undefined>\n >({})\n const [schedules, setSchedules] = useState<PollingScheduleSnapshot[]>([])\n const [rejectedPipelines, setRejectedPipelines] = useState<\n Record<string, RejectedPipelinePresentation | undefined>\n >({})\n const signalsRef = useRef<Record<string, Envelope | undefined>>({})\n const factSignalsRef = useRef<\n Record<string, Record<string, HttpValueFactObservation | undefined> | undefined>\n >({})\n const memoryRef = useRef<BrowserPanelMemory | null>(null)\n if (!memoryRef.current) memoryRef.current = memory ?? new BrowserPanelMemory()\n\n useEffect(() => {\n signalsRef.current = {}\n factSignalsRef.current = {}\n setSignals({})\n setTestDirections({})\n testDirectionsRef.current = {}\n setUpdateHealth({})\n setFactSignals({})\n setSchedules([])\n setRejectedPipelines({})\n if (!board) return\n\n let cancelled = false\n const memory = memoryRef.current\n if (!memory) return\n const rendered = new Map<string, RenderedPanelDiagnostic>()\n const recordRendered = (\n panel: Board['panels'][number],\n projection: RenderedPanelDiagnostic,\n ) => {\n if (JSON.stringify(rendered.get(panel.id)) === JSON.stringify(projection)) return\n rendered.set(panel.id, projection)\n diagnostics.record({\n kind: 'panel-rendered',\n panelId: panel.id,\n path: panelProxyPath(env, panel.id),\n rendered: projection,\n })\n }\n const publish = (panel: Board['panels'][number], envelope: Envelope) => {\n if (cancelled) return\n const direction = panelFeature(panel.type)?.testHistory\n ? memory.testDirection(env.board, panel, envelope)\n : undefined\n const projected = projectTestDirection(direction)\n recordRendered(panel, {\n ...projectPanelDiagnostic(panel, envelope),\n ...(projected ? { testDirection: projected } : {}),\n })\n testDirectionsRef.current = { ...testDirectionsRef.current, [panel.id]: direction }\n setTestDirections(testDirectionsRef.current)\n signalsRef.current = { ...signalsRef.current, [panel.id]: envelope }\n setSignals(signalsRef.current)\n }\n const publishFacts = (\n panel: Board['panels'][number],\n facts: Record<string, HttpValueFactObservation | undefined>,\n ) => {\n if (cancelled) return\n recordRendered(panel, projectHttpValueFactsDiagnostic(facts))\n factSignalsRef.current = { ...factSignalsRef.current, [panel.id]: facts }\n setFactSignals(factSignalsRef.current)\n }\n const repairs = new TestHistoryRepair({\n board: env.board,\n memory,\n diagnostics,\n fetcher: (input, init) => dashboardFetch(env, input, init, globalThis.fetch, auth),\n onMerged: (panel) => {\n const envelope = signalsRef.current[panel.id]\n if (envelope) publish(panel, envelope)\n },\n })\n const timers = new Set<number>()\n const abortControllers = new Set<AbortController>()\n const panels = pollingPanels(board)\n const initialSchedules = panels.map((panel) => initialPollingSchedule(board, env, panel))\n const schedulesByPanelId = new Map(\n initialSchedules.map((schedule) => [schedule.panelId, schedule]),\n )\n setSchedules(initialSchedules)\n const updateSchedule = (panelId: string, update: Partial<PollingScheduleSnapshot>) => {\n if (cancelled) return\n setSchedules((current) =>\n current.map((schedule) =>\n schedule.panelId === panelId ? { ...schedule, ...update } : schedule,\n ),\n )\n }\n for (const { panel, polling } of panels) {\n let inFlight = false\n const memory = memoryRef.current\n if (!memory) return\n const schedule = schedulesByPanelId.get(panel.id)\n if (!schedule) continue\n const { settings } = schedule\n const path = panelProxyPath(env, panel.id)\n let lastEnvelope: Envelope | undefined\n let lastConfirmedAt: string | undefined\n const recordConfirmedUpdate = () => {\n lastConfirmedAt = new Date().toISOString()\n if (!cancelled)\n setUpdateHealth((current) => {\n if (!current[panel.id]) return current\n const next = { ...current }\n delete next[panel.id]\n return next\n })\n }\n const recordUpdateFailure = (error: unknown) => {\n const confirmedAt = lastConfirmedAt\n if (cancelled || !confirmedAt) return\n const message = errorMessage(error)\n setUpdateHealth((current) => {\n const previous = current[panel.id]\n return {\n ...current,\n [panel.id]: {\n consecutiveFailures: (previous?.consecutiveFailures ?? 0) + 1,\n message,\n lastConfirmedAt: confirmedAt,\n },\n }\n })\n }\n type CurrentPoll = { signal: AbortSignal; healthy: boolean; historySupported: boolean }\n const poll = async (read: (cycle: CurrentPoll) => Promise<void>) => {\n if (cancelled || inFlight) return\n inFlight = true\n const controller = new AbortController()\n const cycle: CurrentPoll = {\n signal: controller.signal,\n healthy: false,\n historySupported: false,\n }\n abortControllers.add(controller)\n repairs.currentStarted(panel.id)\n updateSchedule(panel.id, {\n inFlight: true,\n lastRequestStartedAt: new Date().toISOString(),\n nextDueAt: undefined,\n })\n try {\n await read(cycle)\n } catch (error) {\n if (!cancelled && !cycle.signal.aborted) {\n recordUpdateFailure(error)\n if (!(error instanceof DiagnosticParseFailure))\n diagnostics.record({\n kind: 'panel-fetch-failure',\n panelId: panel.id,\n path,\n message: errorMessage(error),\n })\n }\n } finally {\n inFlight = false\n abortControllers.delete(controller)\n if (!cancelled && !cycle.signal.aborted) {\n const next = resolveNextPoll(lastEnvelope, Date.now(), settings)\n updateSchedule(panel.id, {\n inFlight: false,\n cadence: next.cadence,\n nextDueAt: new Date(Date.now() + next.delayMillis).toISOString(),\n })\n const timer = window.setTimeout(() => {\n timers.delete(timer)\n void poll(read)\n }, next.delayMillis)\n timers.add(timer)\n }\n repairs.currentSettled(panel, path, cycle.healthy, cycle.historySupported)\n }\n }\n switch (polling.kind) {\n case 'facts': {\n if (!panel.facts) break\n const facts = panel.facts\n const components = new Map<string, Envelope>()\n void poll(async ({ signal }) => {\n const observations = await Promise.all(\n facts.map(async (fact) => {\n const result = await readPanelObservation({\n diagnostics,\n panelId: panel.id,\n path: `${path}/facts/${encodeURIComponent(fact.id)}`,\n signal,\n cache: components,\n fetcher: (input, init) =>\n dashboardFetch(env, input, init, globalThis.fetch, auth),\n })\n return [fact.id, result.error ? { failure: result.error } : result] as const\n }),\n )\n if (!signal.aborted) publishFacts(panel, Object.fromEntries(observations))\n })\n continue\n }\n case 'pull-request-health': {\n const workflows = readUpdateWorkflows(panel)\n const components = new Map<string, Envelope>()\n void poll(async ({ signal }) => {\n const request = async (componentPath: string) => {\n const result = await readPanelObservation({\n diagnostics,\n panelId: panel.id,\n path: componentPath,\n signal,\n cache: components,\n fetcher: (input, init) => dashboardFetch(env, input, init, globalThis.fetch, auth),\n })\n return result.envelope?.state === 'error'\n ? { error: result.envelope.error.message }\n : result\n }\n const [candidateResult, ...workflowResults] = await Promise.all([\n request(`${path}/pull-requests`),\n ...workflows.map(({ workflow }) =>\n request(`${path}/update-workflow/${encodeURIComponent(workflow)}`),\n ),\n ])\n if (cancelled || signal.aborted) return\n const candidates =\n candidateResult.envelope?.state === 'ok' &&\n isCandidates(candidateResult.envelope.signal)\n ? candidateResult.envelope.signal.pullRequests\n : []\n const buildResults = await Promise.all(\n candidates.map(\n async (candidate) =>\n [\n candidate.branch,\n await request(\n `${path}/pull-request-build?branch=${encodeURIComponent(candidate.branch)}`,\n ),\n ] as const,\n ),\n )\n if (cancelled || signal.aborted) return\n const rolled = rollupPullRequestHealth({\n panelId: panel.id,\n link: candidateResult.envelope?.link ?? null,\n workflows: workflows.map(({ workflow }, index) => ({\n workflow,\n observation: workflowResults[index] ?? { error: 'Missing workflow result.' },\n })),\n candidates: candidateResult,\n builds: new Map(buildResults),\n })\n if (rolled) {\n lastEnvelope = rolled\n recordConfirmedUpdate()\n publish(panel, rolled)\n } else recordUpdateFailure('No usable pull-request observations.')\n })\n continue\n }\n case 'single':\n break\n default:\n polling satisfies never\n }\n void poll(async (cycle) => {\n diagnostics.record({ kind: 'panel-fetch-start', panelId: panel.id, path })\n const response = await dashboardFetch(\n env,\n path,\n { signal: cycle.signal },\n globalThis.fetch,\n auth,\n )\n cycle.historySupported =\n panelFeature(panel.type)?.testHistory === true &&\n response.headers.get(testHistoryHeader) === 'supported'\n const transport = {\n kind: 'panel-fetch-response' as const,\n panelId: panel.id,\n path,\n status: response.status,\n cache: cacheMetadata(response.headers),\n }\n if (response.status === 304) {\n cycle.healthy = lastEnvelope?.state === 'ok'\n diagnostics.record(transport)\n recordConfirmedUpdate()\n return\n }\n let envelope: Envelope\n try {\n const parsed = parseEnvelope(await response.json())\n if (!parsed) {\n diagnostics.record(transport)\n diagnostics.record({\n kind: 'panel-fetch-parse-failure',\n panelId: panel.id,\n path,\n message: 'Response was not a valid signal envelope.',\n })\n recordUpdateFailure('Response was not a valid signal envelope.')\n return\n }\n envelope = parsed\n diagnostics.record({\n ...transport,\n envelope,\n ...(envelope.state === 'error'\n ? { failure: failedObservation(envelope, response) }\n : {}),\n })\n cycle.healthy = envelope.state === 'ok'\n recordConfirmedUpdate()\n } catch (error) {\n diagnostics.record(transport)\n diagnostics.record({\n kind: 'panel-fetch-parse-failure',\n panelId: panel.id,\n path,\n message: errorMessage(error),\n })\n throw new DiagnosticParseFailure(error)\n }\n if (cancelled || cycle.signal.aborted) return\n const result = { status: response.status, cache: transport.cache }\n if (panel.type === 'pipeline-status') {\n const identity = resolvePanelMemoryIdentity(env.board, panel)\n const accepted = memory.latest(identity)\n const reconciliation = reconcilePipelineResponse({\n envelope,\n accepted,\n estimatedDurationMs: memory.resolveEstimatedDuration(identity),\n })\n const presentation = applyPipelinePresentation({\n current: signalsRef.current[panel.id],\n reconciliation,\n accepted,\n })\n if (reconciliation.kind === 'rejected' && accepted) {\n const signal = reconciliation.signal\n diagnostics.recordGithubConsistencyIncident({\n panelId: panel.id,\n endpoint: path,\n identity: {\n source: identity.source,\n workflow: identity.workflow,\n branch: identity.branch,\n },\n accepted,\n regressed: {\n sourceUpdatedAt: signal.sourceUpdatedAt,\n status: signal.status,\n link: envelope.link,\n },\n response: {\n httpStatus: result.status,\n date: result.cache?.date,\n etag: result.cache?.etag,\n cacheControl: result.cache?.cacheControl,\n },\n })\n if (!cancelled)\n setRejectedPipelines((current) => ({\n ...current,\n [panel.id]: presentation.rejected,\n }))\n return\n }\n if (reconciliation.kind === 'accepted') {\n envelope = reconciliation.envelope\n if (!cancelled && presentation.rejected === undefined)\n setRejectedPipelines((current) => {\n if (!current[panel.id]) return current\n const next = { ...current }\n delete next[panel.id]\n return next\n })\n if (reconciliation.accepted) memory.rememberLatest(identity, reconciliation.accepted)\n if (reconciliation.durationSample) {\n const sample = {\n link: reconciliation.durationSample.link,\n ...(reconciliation.durationSample.sourceRunId\n ? { sourceRunId: reconciliation.durationSample.sourceRunId }\n : {}),\n durationMs: reconciliation.durationSample.durationMs,\n sourceUpdatedAt: reconciliation.durationSample.sourceUpdatedAt,\n }\n memory.recordRun(identity, sample, reconciliation.signal.status === 'passed')\n }\n }\n }\n lastEnvelope = envelope\n if (panelFeature(panel.type)?.testHistory) memory.observeTests(env.board, panel, envelope)\n publish(panel, envelope)\n })\n }\n\n return () => {\n cancelled = true\n repairs.dispose()\n for (const controller of abortControllers) controller.abort()\n for (const timer of timers) window.clearTimeout(timer)\n }\n }, [auth, board, diagnostics, env])\n\n return { signals, updateHealth, factSignals, schedules, rejectedPipelines, testDirections }\n}\n\nfunction failedObservation(envelope: Extract<Envelope, { state: 'error' }>, response: Response) {\n const supportReference = response.headers.get('x-dashboard-request-id')\n return {\n reason: envelope.error.message,\n ...(supportReference ? { supportReference } : {}),\n }\n}\n\nfunction isCandidates(\n value: unknown,\n): value is { type: 'pull-request-candidates'; pullRequests: Array<{ branch: string }> } {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { type?: unknown }).type === 'pull-request-candidates' &&\n Array.isArray((value as { pullRequests?: unknown }).pullRequests)\n )\n}\n\nfunction errorMessage(error: unknown) {\n return error instanceof Error ? error.message : String(error)\n}\n\nclass DiagnosticParseFailure extends Error {\n constructor(error: unknown) {\n super(errorMessage(error))\n }\n}\n\nfunction parseEnvelope(value: unknown): Envelope | undefined {\n const result = envelopeSchema.safeParse(value)\n return result.success ? result.data : undefined\n}\n","import {\n analyzeBoardLayout,\n type ClientEnv,\n isZeroPosition,\n} from '@ze-great-dashboard/shared/browser'\nimport { useEffect, useMemo, useRef } from 'react'\nimport styles from './App.module.css'\nimport { projectAttention } from './attention.ts'\nimport { Diagnostics } from './Diagnostics.tsx'\nimport type { DashboardAuth } from './dashboard-fetch.ts'\nimport { BrowserDiagnosticStore } from './diagnostics.ts'\nimport { LayoutWarning } from './LayoutWarning.tsx'\nimport { OidcGate } from './OidcGate.tsx'\nimport { PanelPlaceholder } from './PanelPlaceholder.tsx'\nimport { PanelRenderer } from './panel-registry.tsx'\nimport { SecurityDetails } from './SecurityDetails.tsx'\nimport { SecurityNotice } from './SecurityNotice.tsx'\nimport { UpdateActivity } from './UpdateActivity.tsx'\nimport { projectUpdateActivity } from './update-activity.ts'\nimport { useBoardConfig } from './useBoardConfig.ts'\nimport { useClientUpdate } from './useClientUpdate.ts'\nimport { usePanelSignals } from './usePanelSignals.ts'\n\n/**\n * The board shell.\n *\n * Stage 1 has no data: there is no proxy endpoint to poll yet. What this proves is the plumbing —\n * that the client was handed its configuration by the server and knows which version of itself it\n * is. The version readout is what makes two published versions visibly different, which is the\n * whole point of the Stage 1 exit criterion.\n */\nexport function App({ env }: { env: ClientEnv }) {\n if (env.security === 'blocked') return <SecurityNotice mode=\"blocked\" />\n return env.auth ? (\n <OidcGate env={env} auth={env.auth}>\n {(accessToken, denied) => <Dashboard env={env} accessToken={accessToken} onDenied={denied} />}\n </OidcGate>\n ) : (\n <Dashboard env={env} />\n )\n}\n\nfunction Dashboard({\n env,\n accessToken,\n onDenied,\n}: {\n env: ClientEnv\n accessToken?: string\n onDenied?: () => void\n}) {\n const diagnosticsRef = useRef<BrowserDiagnosticStore | null>(null)\n if (!diagnosticsRef.current) diagnosticsRef.current = new BrowserDiagnosticStore(env)\n const diagnostics = diagnosticsRef.current\n const auth = useMemo<DashboardAuth | undefined>(\n () =>\n accessToken\n ? { accessToken, onAuthenticationFailure: (status) => status === 403 && onDenied?.() }\n : undefined,\n [accessToken, onDenied],\n )\n useClientUpdate({ env, diagnostics, auth })\n const { board, loadedBoardName } = useBoardConfig({ env, diagnostics, auth })\n const { signals, updateHealth, factSignals, schedules, rejectedPipelines, testDirections } =\n usePanelSignals({\n board: loadedBoardName === env.board ? board : undefined,\n env,\n diagnostics,\n auth,\n })\n const layout = useMemo(() => (board ? analyzeBoardLayout(board.panels) : undefined), [board])\n const attentionDrivers = useMemo(\n () => projectAttention({ board, signals, updateHealth, factSignals }),\n [board, factSignals, signals, updateHealth],\n )\n const attentionTreatment = attentionDrivers.length ? board?.attention?.treatment : undefined\n const activeAttentionPanels = new Set(attentionDrivers.map((driver) => driver.panelId))\n\n useEffect(() => {\n if (!layout || layout.issues.length === 0) return\n diagnostics.record({\n kind: 'layout-analyzed',\n issueCount: layout.issues.length,\n affectedPanelIds: layout.issues.map((issue) => issue.panelId),\n })\n }, [diagnostics, layout])\n\n return (\n <div\n className={`${styles.board} ${attentionTreatment ? styles[`attention-${attentionTreatment}`] : ''}`}\n data-attention-treatment={attentionTreatment}\n data-attention-active={attentionDrivers.length || undefined}\n >\n <header className={styles.header}>\n <h1 className={styles.title}>{env.board}</h1>\n {env.security === 'warning' && <SecurityNotice mode=\"warning\" />}\n {attentionDrivers.length > 0 && (\n <aside\n className={styles.attentionRail}\n role=\"alert\"\n aria-label=\"Important panel attention\"\n >\n <span className={styles.attentionGlyph} aria-hidden=\"true\">\n ⚠\n </span>\n <ul>\n {attentionDrivers.map((driver) => (\n <li key={`${driver.panelId}-${driver.factId ?? 'panel'}-${driver.reason}`}>\n <a href={`#panel-${driver.panelId}`}>\n <strong>{driver.label}</strong>: {driver.reason}\n </a>\n </li>\n ))}\n </ul>\n </aside>\n )}\n </header>\n <main className={styles.grid}>\n {!board && <PanelPlaceholder label=\"board\" hint=\"Loading configuration…\" wide />}\n {board?.panels\n .filter((panel) => !isZeroPosition(panel.position))\n .map((panel) => (\n <PanelRenderer\n key={panel.id}\n panel={panel}\n envelope={signals[panel.id]}\n attentionActive={activeAttentionPanels.has(panel.id)}\n updateHealth={updateHealth[panel.id]}\n rejectedPipeline={rejectedPipelines[panel.id]}\n facts={factSignals[panel.id]}\n testDirection={testDirections[panel.id]}\n />\n ))}\n </main>\n\n <footer className={styles.footer} data-board-footer>\n <span>Signals are read live from their configured authorities.</span>\n <div className={styles.footerTools}>\n {auth && <SecurityDetails env={env} auth={auth} />}\n {layout && layout.issues.length > 0 && (\n <LayoutWarning board={env.board} layout={layout} env={env} auth={auth} />\n )}\n <Diagnostics\n log={diagnostics}\n updateActivity={() => {\n const evidence = diagnostics.retainedEvidence()\n const projected = projectUpdateActivity({\n schedules,\n ...evidence,\n })\n return {\n capturedAt: projected.capturedAt,\n window: projected.window,\n schedules: projected.schedules,\n }\n }}\n />\n <UpdateActivity board={board} schedules={schedules} log={diagnostics} />\n </div>\n </footer>\n </div>\n )\n}\n","import styles from './ConfigError.module.css'\n\nexport function ConfigError({ message }: { message: string }) {\n return (\n <div className={styles.error} role=\"alert\">\n <h1>⚠️ Dashboard misconfigured</h1>\n <p>The page loaded, but the server did not hand it usable configuration.</p>\n <pre>{message}</pre>\n </div>\n )\n}\n","import { readClientEnv } from '@ze-great-dashboard/shared/browser'\nimport { StrictMode } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport { App } from './App.tsx'\nimport { ConfigError } from './ConfigError.tsx'\nimport './styles.css'\n\nconst container = document.getElementById('root')\nif (!container) {\n throw new Error('No #root element in the document — the template is not the one we expect.')\n}\n\nconst root = createRoot(container)\n\ntry {\n root.render(\n <StrictMode>\n <App env={readClientEnv()} />\n </StrictMode>,\n )\n} catch (error) {\n // A radiator that fails silently is worse than one that says what's wrong. If configuration\n // never arrived, say so on screen rather than rendering an empty board.\n root.render(<ConfigError message={error instanceof Error ? error.message : String(error)} />)\n}\n"],"mappings":"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"}