2sagaco48 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/diagnostics.mjs +141 -0
- package/dist/compute.worker-j5ahIpF-.js +1 -0
- package/dist/graph.worker-DG6iGCB9.js +1 -0
- package/dist/index.html +2314 -0
- package/flatten-guide.md +248 -0
- package/index.html +12 -0
- package/package.json +38 -0
- package/src/App.orig.tsx +204 -0
- package/src/App.orig1.tsx +27 -0
- package/src/App.orig2.tsx +25 -0
- package/src/App.tsx +3 -0
- package/src/BaseApp.tsx +18 -0
- package/src/INTEGRATION_LEDGER.md +22 -0
- package/src/PERSIST_CANARY.orig.txt +1 -0
- package/src/PERSIST_CANARY.txt +1 -0
- package/src/REGRESSION_LEDGER.md +651 -0
- package/src/TEMPLATE_PIPELINE_AUDIT.md +208 -0
- package/src/WILLIAMS_PERSONA_GUIDE.md +62 -0
- package/src/chat/VeritasChat.tsx +69 -0
- package/src/chat/synthesis.ts +31 -0
- package/src/chat/tier.ts +45 -0
- package/src/components/AdaptersPage.orig.tsx +99 -0
- package/src/components/AdaptersPage.tsx +3 -0
- package/src/components/AdversarialPanel.tsx +136 -0
- package/src/components/AnchorBaselinePanel.tsx +75 -0
- package/src/components/AnswerPanel.tsx +60 -0
- package/src/components/ArtifactPanel.tsx +43 -0
- package/src/components/ChatApp.orig.tsx +1582 -0
- package/src/components/ChatApp.orig1.tsx +722 -0
- package/src/components/ChatApp.tsx +95 -0
- package/src/components/ChatAugmentPanels.tsx +73 -0
- package/src/components/CitationLedgerPanel.tsx +313 -0
- package/src/components/ComputeSandboxPanel.tsx +130 -0
- package/src/components/ConfigPanel.tsx +110 -0
- package/src/components/ControlPlanePage.tsx +195 -0
- package/src/components/CreativeTreeLifePage.tsx +234 -0
- package/src/components/CreativeTreeOfLifePanel.tsx +149 -0
- package/src/components/DebugTracePanel.tsx +137 -0
- package/src/components/DeepReasoningTrace.tsx +48 -0
- package/src/components/EntitySheetPanel.tsx +51 -0
- package/src/components/FailureModesPanel.tsx +104 -0
- package/src/components/GBSDashboard.tsx +239 -0
- package/src/components/GraphView.tsx +116 -0
- package/src/components/HUD.tsx +125 -0
- package/src/components/HypothesisPanel.tsx +67 -0
- package/src/components/InnovationGenomeEngine.tsx +792 -0
- package/src/components/InnovationPersonaGuide.tsx +348 -0
- package/src/components/InnovationPersonaPanel.tsx +289 -0
- package/src/components/LiveResourceHUD.tsx +109 -0
- package/src/components/LongWriterPanel.tsx +112 -0
- package/src/components/MainPipelineV10Bridge.tsx +72 -0
- package/src/components/MarkdownLite.tsx +63 -0
- package/src/components/MemoryInspector.tsx +38 -0
- package/src/components/MemoryMonitor.tsx +52 -0
- package/src/components/MemoryStressPanel.tsx +176 -0
- package/src/components/ModulesPage.tsx +171 -0
- package/src/components/PipelineDebugConsole.orig.tsx +1856 -0
- package/src/components/PipelineDebugConsole.tsx +3 -0
- package/src/components/PreFlightHUD.tsx +67 -0
- package/src/components/PrismaFetchTracePanel.tsx +87 -0
- package/src/components/ReportOSPanel.tsx +165 -0
- package/src/components/ResourceEstimatorPage.tsx +327 -0
- package/src/components/RichText.tsx +181 -0
- package/src/components/SagaOsPanel.tsx +605 -0
- package/src/components/SagaOsReference.tsx +421 -0
- package/src/components/SagaOsV2Panel.tsx +594 -0
- package/src/components/SagaStyleTab.tsx +382 -0
- package/src/components/SageBlueprintPanel.tsx +416 -0
- package/src/components/SharedChatInput.tsx +77 -0
- package/src/components/StatFinancePanel.tsx +190 -0
- package/src/components/StylePersonaPanel.tsx +128 -0
- package/src/components/TemplatesPage.tsx +300 -0
- package/src/components/TestPanel.tsx +63 -0
- package/src/components/TraceLog.tsx +89 -0
- package/src/components/V15CalibrationAugment.tsx +1134 -0
- package/src/components/V15CalibrationDialog.tsx +1871 -0
- package/src/components/V15Overlay.orig.tsx +120 -0
- package/src/components/V15Overlay.tsx +4 -0
- package/src/components/V15OverlayWrapper.tsx +362 -0
- package/src/components/V15Toggle.tsx +34 -0
- package/src/console/DiagnosticRecoveryPanel.tsx +358 -0
- package/src/console/EngineeringConsole.tsx +103 -0
- package/src/console/FictionSystemPanels.tsx +882 -0
- package/src/console/InspectorPanels.tsx +254 -0
- package/src/console/ManuscriptGraderPanel.tsx +182 -0
- package/src/console/RecursiveReviserPanel.tsx +245 -0
- package/src/console/SeedControlPanel.tsx +135 -0
- package/src/console/StoryControllerPanel.tsx +443 -0
- package/src/console/engineBridge.ts +258 -0
- package/src/console/gemini.ts +106 -0
- package/src/console/grading.ts +250 -0
- package/src/console/util.ts +45 -0
- package/src/fiction/continuity.ts +372 -0
- package/src/fiction/crash-protection.ts +111 -0
- package/src/fiction/diagnostics.ts +208 -0
- package/src/fiction/diff.ts +74 -0
- package/src/fiction/entity-state-machine.ts +214 -0
- package/src/fiction/nive-engine.ts +404 -0
- package/src/fiction/pipeline-selftest.ts +132 -0
- package/src/fiction/seed-control.ts +193 -0
- package/src/fiction/story-engine.ts +326 -0
- package/src/fiction/types.ts +68 -0
- package/src/flatten-guide.md +379 -0
- package/src/index.css +14 -0
- package/src/index.orig.css +13 -0
- package/src/lib/academic-sources.base.ts +188 -0
- package/src/lib/academic-sources.orig.ts +28 -0
- package/src/lib/academic-sources.ts +10 -0
- package/src/lib/advanced-math.ts +119 -0
- package/src/lib/adversarial-engine.base.ts +409 -0
- package/src/lib/adversarial-engine.ts +82 -0
- package/src/lib/ai-revision.ts +623 -0
- package/src/lib/app-state.tsx +426 -0
- package/src/lib/artifact-registry.ts +97 -0
- package/src/lib/artifacts.ts +180 -0
- package/src/lib/atlas-dr.ts +167 -0
- package/src/lib/browser-mtls.ts +127 -0
- package/src/lib/browser-queue.ts +221 -0
- package/src/lib/browser-search-scraper.base.ts +382 -0
- package/src/lib/browser-search-scraper.orig.ts +90 -0
- package/src/lib/browser-search-scraper.ts +10 -0
- package/src/lib/calc-interceptor.ts +82 -0
- package/src/lib/citation-lane-tap.ts +78 -0
- package/src/lib/citation-ledger-store.ts +369 -0
- package/src/lib/citation-ledger.ts +203 -0
- package/src/lib/compute-sandbox.ts +215 -0
- package/src/lib/compute.worker.ts +153 -0
- package/src/lib/connectors/gemini.ts +120 -0
- package/src/lib/connectors/jina.ts +233 -0
- package/src/lib/connectors/marketdata.ts +51 -0
- package/src/lib/connectors/prismafetch.base.ts +175 -0
- package/src/lib/connectors/prismafetch.ts +1 -0
- package/src/lib/connectors/serpapi.ts +65 -0
- package/src/lib/connectors/wikidata.ts +44 -0
- package/src/lib/constraints.ts +331 -0
- package/src/lib/continuation-detector.base.ts +153 -0
- package/src/lib/continuation-detector.ts +48 -0
- package/src/lib/contradraft.ts +168 -0
- package/src/lib/cors-proxy.ts +120 -0
- package/src/lib/coverage.ts +81 -0
- package/src/lib/debug/architecture-prescription.ts +556 -0
- package/src/lib/debug/covea-repair.ts +543 -0
- package/src/lib/debug/helios-ground.ts +319 -0
- package/src/lib/debug/intent-decomposer.ts +281 -0
- package/src/lib/debug/intent-lattice.ts +349 -0
- package/src/lib/debug/pipeline-diagnosis.ts +1149 -0
- package/src/lib/debug/pipeline-trace-bus.ts +424 -0
- package/src/lib/debug/prompt-forge.ts +678 -0
- package/src/lib/debug/repair-sites.ts +513 -0
- package/src/lib/debug/research-phase.ts +266 -0
- package/src/lib/debug/retrieval-context.ts +76 -0
- package/src/lib/debug/retrieval-hardener.ts +142 -0
- package/src/lib/debug/scraper-debug-runner.ts +576 -0
- package/src/lib/debug/scraper-forensics.ts +418 -0
- package/src/lib/debug/scraper-lane-roadmap.ts +136 -0
- package/src/lib/debug/self-test.ts +415 -0
- package/src/lib/debug/step-attribution.ts +211 -0
- package/src/lib/debug/template-rubric.ts +301 -0
- package/src/lib/debug/unified-innovation.ts +126 -0
- package/src/lib/debug/veritas-hybrid-scraper.ts +335 -0
- package/src/lib/defense-registry.ts +104 -0
- package/src/lib/defenses.ts +162 -0
- package/src/lib/deterministic-citation-ledger.ts +174 -0
- package/src/lib/elo-registry.base.ts +117 -0
- package/src/lib/elo-registry.ts +1 -0
- package/src/lib/entity-resolver.ts +291 -0
- package/src/lib/failure-modes.ts +267 -0
- package/src/lib/feature-registry.ts +69 -0
- package/src/lib/flaw-registry.ts +143 -0
- package/src/lib/flaws/_template.ts +52 -0
- package/src/lib/flaws/builtins.ts +63 -0
- package/src/lib/flaws/finance.ts +169 -0
- package/src/lib/flaws/fixers.ts +10 -0
- package/src/lib/flaws/index.ts +32 -0
- package/src/lib/flaws/legal.ts +157 -0
- package/src/lib/flaws/medical.ts +188 -0
- package/src/lib/flaws/original-defenses-pack.ts +81 -0
- package/src/lib/flaws/sample-declarative-pack.json +38 -0
- package/src/lib/flaws/selftest.ts +201 -0
- package/src/lib/flaws/software-extended.ts +125 -0
- package/src/lib/flaws/software-rn-webgl.ts +182 -0
- package/src/lib/flaws/statistics-advanced.ts +46 -0
- package/src/lib/flaws/statistics.ts +61 -0
- package/src/lib/gbse/config.ts +20 -0
- package/src/lib/gbse/engine.ts +226 -0
- package/src/lib/gbse/graph.ts +118 -0
- package/src/lib/gbse/graph.worker.ts +21 -0
- package/src/lib/gbse/tests.ts +117 -0
- package/src/lib/gbse/tiers.ts +65 -0
- package/src/lib/gbse/types.ts +94 -0
- package/src/lib/innovation-genome-engine-v2.orig.ts +1001 -0
- package/src/lib/innovation-genome-engine-v2.ts +3 -0
- package/src/lib/innovation-genome-engine.orig.ts +330 -0
- package/src/lib/innovation-genome-engine.ts +3 -0
- package/src/lib/innovation-genome-v10.orig.ts +314 -0
- package/src/lib/innovation-genome-v10.ts +2 -0
- package/src/lib/innovation-genome-v3.orig.ts +2015 -0
- package/src/lib/innovation-genome-v3.ts +2 -0
- package/src/lib/innovation-genome-v4.orig.ts +1959 -0
- package/src/lib/innovation-genome-v4.ts +2 -0
- package/src/lib/innovation-genome-v5.orig.ts +1210 -0
- package/src/lib/innovation-genome-v5.ts +2 -0
- package/src/lib/innovation-genome-v7.orig.ts +2549 -0
- package/src/lib/innovation-genome-v7.ts +2 -0
- package/src/lib/innovation-genome-v8.orig.ts +1485 -0
- package/src/lib/innovation-genome-v8.ts +2 -0
- package/src/lib/innovation-genome-v9.orig.ts +643 -0
- package/src/lib/innovation-genome-v9.ts +2 -0
- package/src/lib/jina.base.ts +293 -0
- package/src/lib/jina.ts +1 -0
- package/src/lib/live-telemetry.ts +61 -0
- package/src/lib/longwriter.ts +84 -0
- package/src/lib/manuscript-grade-v2.ts +298 -0
- package/src/lib/memory-governor.ts +173 -0
- package/src/lib/memory-stress-tests.ts +248 -0
- package/src/lib/model-intelligence.ts +48 -0
- package/src/lib/model-rotator.ts +75 -0
- package/src/lib/models.orig.ts +513 -0
- package/src/lib/models.ts +151 -0
- package/src/lib/n-deep.base.ts +592 -0
- package/src/lib/n-deep.ts +51 -0
- package/src/lib/nih-simulator.ts +56 -0
- package/src/lib/nih-vulnerability-fixes.ts +460 -0
- package/src/lib/omega-templates.base.ts +294 -0
- package/src/lib/omega-templates.ts +225 -0
- package/src/lib/omni-nexus.ts +64 -0
- package/src/lib/oracle-adapters.ts +67 -0
- package/src/lib/oracle-registry.ts +163 -0
- package/src/lib/orchestrator.ts +357 -0
- package/src/lib/output-boundary.ts +235 -0
- package/src/lib/overrides/vite-native-chaos-harness.ts +154 -0
- package/src/lib/overrides/vite-native-contract-plane.ts +245 -0
- package/src/lib/overrides/vite-native-doctor-plane.ts +208 -0
- package/src/lib/overrides/vite-native-knowledge-store.ts +267 -0
- package/src/lib/overrides/vite-native-policy-plane.ts +190 -0
- package/src/lib/overrides/vite-native-replay-plane.ts +197 -0
- package/src/lib/overrides/vite-native-runtime-plane.ts +106 -0
- package/src/lib/overrides/vite-native-scraper.ts +848 -0
- package/src/lib/overrides/vite-native-selftest-functional.ts +217 -0
- package/src/lib/overrides/vite-native-selftest.ts +183 -0
- package/src/lib/overrides/vite-native-snapshot-plane.ts +123 -0
- package/src/lib/philosophy-toolkit.ts +75 -0
- package/src/lib/pipeline.orig.ts +659 -0
- package/src/lib/pipeline.ts +42 -0
- package/src/lib/precache.ts +128 -0
- package/src/lib/py-sandbox.ts +205 -0
- package/src/lib/quality-score.ts +96 -0
- package/src/lib/quant-engine.ts +231 -0
- package/src/lib/quant-lib.ts +80 -0
- package/src/lib/reportos.ts +175 -0
- package/src/lib/research-os.ts +306 -0
- package/src/lib/resource-estimator.ts +114 -0
- package/src/lib/rpm-governor.ts +93 -0
- package/src/lib/runtime-estimator.ts +135 -0
- package/src/lib/sage/empty-space-v6.ts +560 -0
- package/src/lib/sage/empty-space-v7.ts +222 -0
- package/src/lib/sage/empty-space.ts +733 -0
- package/src/lib/sage/engine.ts +786 -0
- package/src/lib/sage/index.ts +17 -0
- package/src/lib/sage/judge.ts +246 -0
- package/src/lib/sage/prng.ts +53 -0
- package/src/lib/sage/reality-grounding.ts +380 -0
- package/src/lib/sage/repetition.ts +151 -0
- package/src/lib/sage/saga-os-v2-engines.ts +1870 -0
- package/src/lib/sage/saga-os-v2.ts +274 -0
- package/src/lib/sage/saga-os-v3-core.ts +1491 -0
- package/src/lib/sage/saga-os-v3-release.ts +739 -0
- package/src/lib/sage/saga-os-v4-aureate.ts +1161 -0
- package/src/lib/sage/saga-os-v4.ts +212 -0
- package/src/lib/sage/saga-os-v5.ts +205 -0
- package/src/lib/sage/saga-os-v6.ts +346 -0
- package/src/lib/sage/saga-os-v7.ts +314 -0
- package/src/lib/sage/saga-os-v8.ts +505 -0
- package/src/lib/sage/saga-os.ts +329 -0
- package/src/lib/sage/taxonomy.ts +403 -0
- package/src/lib/sage/unified-roll.ts +524 -0
- package/src/lib/sage/worked-sketches.ts +44 -0
- package/src/lib/sage.ts +166 -0
- package/src/lib/scraper-debug-bus.ts +53 -0
- package/src/lib/scraper-enhanced.orig.ts +153 -0
- package/src/lib/scraper-enhanced.ts +10 -0
- package/src/lib/scraper-hardener.base.orig.ts +155 -0
- package/src/lib/scraper-hardener.base.ts +317 -0
- package/src/lib/scraper-hardener.ts +1 -0
- package/src/lib/scraper-palisade/palisade-adjudicator.orig.ts +419 -0
- package/src/lib/scraper-palisade/palisade-adjudicator.ts +13 -0
- package/src/lib/scraper-vnext/arbiter-omega.orig.ts +688 -0
- package/src/lib/scraper-vnext/arbiter-omega.ts +13 -0
- package/src/lib/scraper-vnext/canonical-portfolio-augments.ts +479 -0
- package/src/lib/scraper-vnext/canonical-portfolio-orchestrator.orig.ts +1529 -0
- package/src/lib/scraper-vnext/canonical-portfolio-orchestrator.ts +13 -0
- package/src/lib/scraper-vnext/conclave-omega.ts +1830 -0
- package/src/lib/scraper-vnext/content-extractor-v2.ts +226 -0
- package/src/lib/scraper-vnext/diagnostics-suite.ts +36 -0
- package/src/lib/scraper-vnext/epistemic-packer.ts +97 -0
- package/src/lib/scraper-vnext/fusion-v2.ts +65 -0
- package/src/lib/scraper-vnext/hydra-reader.orig.ts +1216 -0
- package/src/lib/scraper-vnext/hydra-reader.ts +13 -0
- package/src/lib/scraper-vnext/native-scraper-browser-vnext.orig.ts +91 -0
- package/src/lib/scraper-vnext/native-scraper-browser-vnext.ts +13 -0
- package/src/lib/scraper-vnext/nexus-consensus.orig.ts +905 -0
- package/src/lib/scraper-vnext/nexus-consensus.ts +13 -0
- package/src/lib/scraper-vnext/portfolio-consensus-adjudicator.ts +804 -0
- package/src/lib/scraper-vnext/portfolio-consensus-memory.ts +377 -0
- package/src/lib/scraper-vnext/portfolio-terminal-governor.ts +548 -0
- package/src/lib/scraper-vnext/query-strategist.orig.ts +224 -0
- package/src/lib/scraper-vnext/query-strategist.ts +423 -0
- package/src/lib/scraper-vnext/retrieval-accelerator.ts +708 -0
- package/src/lib/scraper-vnext/retrieval-audit-augments.ts +477 -0
- package/src/lib/scraper-vnext/retrieval-control-plane.ts +904 -0
- package/src/lib/scraper-vnext/retrieval-policy-augments.ts +358 -0
- package/src/lib/scraper-vnext/safe-fetch-v2.ts +157 -0
- package/src/lib/scraper-vnext/sentinel-omega.ts +56 -0
- package/src/lib/scraper-vnext/sentinel-orchestrator.ts +69 -0
- package/src/lib/scraper-vnext/sibyl-oracle.orig.ts +413 -0
- package/src/lib/scraper-vnext/sibyl-oracle.ts +13 -0
- package/src/lib/scraper-vnext/smart-read-v2.ts +55 -0
- package/src/lib/scraper-vnext/spa-rescue-bridge.ts +608 -0
- package/src/lib/scraper-vnext/strata-engine.orig.ts +2666 -0
- package/src/lib/scraper-vnext/strata-engine.ts +13 -0
- package/src/lib/scraper-vnext/structured-source-adapter.orig.ts +369 -0
- package/src/lib/scraper-vnext/structured-source-adapter.ts +34 -0
- package/src/lib/scraper-vnext/terminal-complete.ts +224 -0
- package/src/lib/scraper-vnext/terminal-final.ts +277 -0
- package/src/lib/scraper-vnext/terminal-saturation.ts +345 -0
- package/src/lib/scraper-vnext/terminal-wire.ts +425 -0
- package/src/lib/scraper-vnext/vanguard-titanium.orig.ts +467 -0
- package/src/lib/scraper-vnext/vanguard-titanium.ts +17 -0
- package/src/lib/search-cache.ts +138 -0
- package/src/lib/sloop-runner.base.ts +223 -0
- package/src/lib/sloop-runner.ts +104 -0
- package/src/lib/sloop.ts +114 -0
- package/src/lib/small-model-adapters.ts +82 -0
- package/src/lib/sscp.ts +86 -0
- package/src/lib/system-map.ts +54 -0
- package/src/lib/uni-node.ts +86 -0
- package/src/lib/universal-rigor-guard.ts +433 -0
- package/src/lib/v15-gate-testbed.ts +274 -0
- package/src/lib/v15-gemini.base.ts +89 -0
- package/src/lib/v15-gemini.ts +1 -0
- package/src/lib/v15-grounding.orig.ts +241 -0
- package/src/lib/v15-grounding.ts +79 -0
- package/src/lib/v15-pipeline.base.ts +769 -0
- package/src/lib/v15-pipeline.orig.ts +1154 -0
- package/src/lib/v15-pipeline.ts +674 -0
- package/src/lib/v15-questions.ts +64 -0
- package/src/lib/v15-rate-limiter.orig.ts +91 -0
- package/src/lib/v15-rate-limiter.ts +48 -0
- package/src/lib/v15-state.base.ts +87 -0
- package/src/lib/v15-state.ts +28 -0
- package/src/lib/visual-table-generator.tsx +207 -0
- package/src/lib/wasm-runtime.ts +133 -0
- package/src/lib/williams-persona-guide.ts +265 -0
- package/src/lib/williams-style.base.ts +464 -0
- package/src/lib/williams-style.ts +59 -0
- package/src/lib/worker-pool.ts +96 -0
- package/src/lib/writing-tiers.ts +125 -0
- package/src/main.orig.tsx +10 -0
- package/src/main.tsx +10 -0
- package/src/utils/cn.orig.ts +6 -0
- package/src/utils/cn.ts +6 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +31 -0
- package/unify.mjs +537 -0
- package/vite.config.ts +18 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* V15 Calibration Question Bank — 24 questions across 8 domains.
|
|
3
|
+
* A shuffled subset is used per calibration run.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface CalibQuestion {
|
|
7
|
+
id: string;
|
|
8
|
+
domain: string;
|
|
9
|
+
text: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const QUESTION_BANK: CalibQuestion[] = [
|
|
13
|
+
// General knowledge / factual
|
|
14
|
+
{ id: "gen1", domain: "general", text: "What is the boiling point of water at sea level, in both Celsius and Fahrenheit? Provide the pressure assumption." },
|
|
15
|
+
{ id: "gen2", domain: "general", text: "Name three renewable energy sources and one key limitation of each. Be concrete." },
|
|
16
|
+
{ id: "gen3", domain: "general", text: "Explain photosynthesis in one paragraph suitable for a high-school student. Include reactants and products." },
|
|
17
|
+
|
|
18
|
+
// Numeric / computation
|
|
19
|
+
{ id: "num1", domain: "numeric", text: "If a car travels 60 mph for 2 hours 30 minutes, how far does it go? Show the calculation with units." },
|
|
20
|
+
{ id: "num2", domain: "numeric", text: "Calculate the compound interest on $10,000 at 5% annual rate over 3 years, compounded annually. Show the formula." },
|
|
21
|
+
{ id: "num3", domain: "numeric", text: "What is 15% tip on a $47.80 bill, rounded to the nearest cent? Include the total after tip." },
|
|
22
|
+
|
|
23
|
+
// Medical (should trigger clinician caveat)
|
|
24
|
+
{ id: "med1", domain: "medical", text: "What are the common causes of chest pain in adults, and when should someone seek emergency care?" },
|
|
25
|
+
{ id: "med2", domain: "medical", text: "Explain the difference between type 1 and type 2 diabetes for a lay reader." },
|
|
26
|
+
{ id: "med3", domain: "medical", text: "What is a normal resting heart rate range for a healthy adult, and what factors can affect it?" },
|
|
27
|
+
|
|
28
|
+
// Legal (should trigger attorney caveat / jurisdiction)
|
|
29
|
+
{ id: "leg1", domain: "legal", text: "What is the general concept of statute of limitations in U.S. civil cases? Give an example." },
|
|
30
|
+
{ id: "leg2", domain: "legal", text: "What is the difference between a copyright and a trademark under U.S. law?" },
|
|
31
|
+
{ id: "leg3", domain: "legal", text: "Briefly explain what 'consideration' means in contract law." },
|
|
32
|
+
|
|
33
|
+
// Finance (should trigger adviser caveat)
|
|
34
|
+
{ id: "fin1", domain: "finance", text: "Explain the difference between a Roth IRA and a Traditional IRA in the U.S. tax system." },
|
|
35
|
+
{ id: "fin2", domain: "finance", text: "What is the Sharpe ratio and how is it computed? Give one caveat about its use." },
|
|
36
|
+
{ id: "fin3", domain: "finance", text: "What does 'dollar cost averaging' mean and what is one advantage and one disadvantage?" },
|
|
37
|
+
|
|
38
|
+
// Statistics (should catch misinterpretation)
|
|
39
|
+
{ id: "sta1", domain: "statistics", text: "What does a p-value of 0.03 mean in a two-sample t-test comparing means? Include one common misinterpretation." },
|
|
40
|
+
{ id: "sta2", domain: "statistics", text: "Explain the difference between correlation and causation with one concrete example." },
|
|
41
|
+
{ id: "sta3", domain: "statistics", text: "What is the difference between standard deviation and standard error of the mean?" },
|
|
42
|
+
|
|
43
|
+
// Software (may catch code failure modes)
|
|
44
|
+
{ id: "soft1", domain: "software", text: "Give a short TypeScript example that shows how to safely parse JSON from an untrusted API response. Explain the validation." },
|
|
45
|
+
{ id: "soft2", domain: "software", text: "What are three common causes of memory leaks in a React application, and one fix for each?" },
|
|
46
|
+
{ id: "soft3", domain: "software", text: "Explain what an ORM is and give one advantage and one disadvantage compared to raw SQL." },
|
|
47
|
+
|
|
48
|
+
// Scientific reasoning
|
|
49
|
+
{ id: "sci1", domain: "science", text: "How does a nuclear reactor generate electricity? Trace the energy flow from fission to grid." },
|
|
50
|
+
{ id: "sci2", domain: "science", text: "What is the greenhouse effect and how do CO2 emissions amplify it?" },
|
|
51
|
+
{ id: "sci3", domain: "science", text: "Explain why the sky appears blue during the day, and red/orange at sunset." },
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
/** Fisher-Yates shuffle a copy of the bank. */
|
|
55
|
+
export function shuffleQuestions(seed?: number): CalibQuestion[] {
|
|
56
|
+
const arr = [...QUESTION_BANK];
|
|
57
|
+
let s = seed ?? Date.now();
|
|
58
|
+
const rnd = () => { s = (s * 9301 + 49297) % 233280; return s / 233280; };
|
|
59
|
+
for (let i = arr.length - 1; i > 0; i--) {
|
|
60
|
+
const j = Math.floor(rnd() * (i + 1));
|
|
61
|
+
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
62
|
+
}
|
|
63
|
+
return arr;
|
|
64
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export interface ModelLimit {
|
|
2
|
+
rpm: number;
|
|
3
|
+
rpd: number;
|
|
4
|
+
tpm?: number;
|
|
5
|
+
category?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const MODEL_LIMITS: Record<string, ModelLimit> = {
|
|
9
|
+
"gemini-3-flash-preview": { rpm: 5, rpd: 7, tpm: 26370, category: "Text" },
|
|
10
|
+
"gemini-3.5-flash": { rpm: 3, rpd: 5, tpm: 4230, category: "Text" },
|
|
11
|
+
"gemini-2.5-flash": { rpm: 1, rpd: 1, tpm: 2000, category: "Text" },
|
|
12
|
+
"gemini-3.1-flash-lite": { rpm: 2, rpd: 4, tpm: 1590, category: "Text" },
|
|
13
|
+
"gemini-2.5-flash-lite": { rpm: 1, rpd: 2, tpm: 2960, category: "Text" },
|
|
14
|
+
"gemma-4-31b-it": { rpm: 1, rpd: 1, tpm: 846, category: "Other" },
|
|
15
|
+
"gemma-4-26b-it": { rpm: 0, rpd: 0, tpm: 0, category: "Other" },
|
|
16
|
+
"gemma-3-27b-it": { rpm: 5, rpd: 20, tpm: 30000, category: "Other" },
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const DEFAULT_LIMIT: ModelLimit = { rpm: 2, rpd: 10, tpm: 10000 };
|
|
20
|
+
|
|
21
|
+
interface UsageBook { minute: number[]; day: number[]; inflight: number }
|
|
22
|
+
const usage = new Map<string, UsageBook>();
|
|
23
|
+
|
|
24
|
+
function book(model: string): UsageBook {
|
|
25
|
+
let u = usage.get(model);
|
|
26
|
+
if (!u) { u = { minute: [], day: [], inflight: 0 }; usage.set(model, u); }
|
|
27
|
+
return u;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function prune(u: UsageBook, now: number) {
|
|
31
|
+
u.minute = u.minute.filter(t => now - t < 60000);
|
|
32
|
+
u.day = u.day.filter(t => now - t < 86400000);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getLimit(model: string): ModelLimit { return MODEL_LIMITS[model] ?? DEFAULT_LIMIT; }
|
|
36
|
+
|
|
37
|
+
export interface UsageSnapshot {
|
|
38
|
+
model: string;
|
|
39
|
+
rpmUsed: number; rpmMax: number; rpmRemaining: number;
|
|
40
|
+
rpdUsed: number; rpdMax: number; rpdRemaining: number;
|
|
41
|
+
inflight: number; msUntilNextSlot: number; throttled: boolean;
|
|
42
|
+
warning?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function snapshotUsage(model: string): UsageSnapshot {
|
|
46
|
+
const now = Date.now();
|
|
47
|
+
const u = book(model);
|
|
48
|
+
prune(u, now);
|
|
49
|
+
const lim = getLimit(model);
|
|
50
|
+
const rpmUsed = u.minute.length + u.inflight;
|
|
51
|
+
const rpdUsed = u.day.length + u.inflight;
|
|
52
|
+
const rpmRemaining = Math.max(0, lim.rpm - rpmUsed);
|
|
53
|
+
const rpdRemaining = Math.max(0, lim.rpd - rpdUsed);
|
|
54
|
+
const throttled = rpmRemaining <= 0 || rpdRemaining <= 0;
|
|
55
|
+
const oldest = u.minute.length ? Math.min(...u.minute) : now;
|
|
56
|
+
const msUntilNextSlot = rpmRemaining <= 0 ? Math.max(0, 60000 - (now - oldest)) : 0;
|
|
57
|
+
const nearRpm = lim.rpm > 0 && rpmRemaining <= Math.max(1, Math.ceil(lim.rpm * 0.1));
|
|
58
|
+
const nearRpd = lim.rpd > 0 && rpdRemaining < 2;
|
|
59
|
+
const warning = nearRpm || nearRpd
|
|
60
|
+
? `Rate warning: ${model} RPM ${rpmUsed}/${lim.rpm}, RPD ${rpdUsed}/${lim.rpd}`
|
|
61
|
+
: undefined;
|
|
62
|
+
return { model, rpmUsed, rpmMax: lim.rpm, rpmRemaining, rpdUsed, rpdMax: lim.rpd, rpdRemaining, inflight: u.inflight, msUntilNextSlot, throttled, warning };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function snapshotAllUsage(): UsageSnapshot[] { return Object.keys(MODEL_LIMITS).map(snapshotUsage); }
|
|
66
|
+
|
|
67
|
+
export function getRateLimitWarnings() { return snapshotAllUsage().filter(s => s.warning); }
|
|
68
|
+
|
|
69
|
+
export async function tryAcquire(model: string, waitIfShort = true): Promise<boolean> {
|
|
70
|
+
let snap = snapshotUsage(model);
|
|
71
|
+
if (!snap.throttled) { book(model).inflight++; return true; }
|
|
72
|
+
if (waitIfShort && snap.rpdRemaining > 0 && snap.msUntilNextSlot > 0 && snap.msUntilNextSlot <= 3000) {
|
|
73
|
+
await new Promise(r => setTimeout(r, snap.msUntilNextSlot + 50));
|
|
74
|
+
snap = snapshotUsage(model);
|
|
75
|
+
if (!snap.throttled) { book(model).inflight++; return true; }
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function recordResult(model: string, ok: boolean): void {
|
|
81
|
+
const u = book(model);
|
|
82
|
+
u.inflight = Math.max(0, u.inflight - 1);
|
|
83
|
+
if (ok) { const now = Date.now(); u.minute.push(now); u.day.push(now); prune(u, now); }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function pickLeastLoaded(pool: string[]): string | null {
|
|
87
|
+
const free = pool.map(snapshotUsage).filter(s => !s.throttled);
|
|
88
|
+
if (!free.length) return null;
|
|
89
|
+
free.sort((a, b) => (b.rpmRemaining / Math.max(1, b.rpmMax) + b.rpdRemaining / Math.max(1, b.rpdMax)) - (a.rpmRemaining / Math.max(1, a.rpmMax) + a.rpdRemaining / Math.max(1, a.rpdMax)));
|
|
90
|
+
return free[0].model;
|
|
91
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v15-rate-limiter.ts — Workspace Override
|
|
3
|
+
* ============================================================================
|
|
4
|
+
* Persistently expands `MODEL_LIMITS` to the FULL user-specified roster
|
|
5
|
+
* (all 9 models: Gemini 2.5 / 3 / 3.1 / 3.5 / 3.6 Flash + Lites, Gemma 4-26B,
|
|
6
|
+
* Gemma 4-31B) with the exact RPM / TPM / RPD limits, so the model rotator
|
|
7
|
+
* (`pickLeastLoaded` and `snapshotAllUsage`) considers every model in
|
|
8
|
+
* round-robin and honors each rate cap.
|
|
9
|
+
*
|
|
10
|
+
* Additive strategy: we re-use the package's usage bookkeeping (which reads
|
|
11
|
+
* `MODEL_LIMITS` via the exported binding by reference) by MUTATING the same
|
|
12
|
+
* object at module load. This preserves every existing package function
|
|
13
|
+
* (`tryAcquire`, `snapshotUsage`, `snapshotAllUsage`, `recordResult`, etc.)
|
|
14
|
+
* while ensuring the roster is complete.
|
|
15
|
+
*
|
|
16
|
+
* User-supplied roster (RPM / TPM / RPD):
|
|
17
|
+
* Gemini 2.5 Flash → 1 / 2.08K / 4
|
|
18
|
+
* Gemini 2.5 Flash Lite → 2 / 5.99K / 8
|
|
19
|
+
* Gemini 3 Flash → 4 / 13.88K / 8
|
|
20
|
+
* Gemini 3.1 Flash Lite → 4 / 21.64K / 14
|
|
21
|
+
* Gemini 3.5 Flash → 3 / 9.79K / 11
|
|
22
|
+
* Gemini 3.5 Flash Lite → 15 / 250K / 500 (max headroom from spec)
|
|
23
|
+
* Gemini 3.6 Flash → 5 / 250K / 20 (max headroom from spec)
|
|
24
|
+
* Gemma 4 26B → 30 / 16K / 14400
|
|
25
|
+
* Gemma 4 31B → 30 / 16K / 14400 (per user cap "0/30 → 30")
|
|
26
|
+
* ============================================================================ */
|
|
27
|
+
|
|
28
|
+
import { MODEL_LIMITS, type ModelLimit } from "./v15-rate-limiter.orig";
|
|
29
|
+
|
|
30
|
+
export * from "./v15-rate-limiter.orig";
|
|
31
|
+
|
|
32
|
+
const FULL_ROSTER: Record<string, ModelLimit> = {
|
|
33
|
+
"gemini-2.5-flash": { rpm: 5, rpd: 20, tpm: 250_000, category: "Text" },
|
|
34
|
+
"gemini-2.5-flash-lite": { rpm: 10, rpd: 20, tpm: 250_000, category: "Text" },
|
|
35
|
+
"gemini-3-flash": { rpm: 5, rpd: 20, tpm: 250_000, category: "Text" },
|
|
36
|
+
"gemini-3.1-flash-lite": { rpm: 15, rpd: 500, tpm: 250_000, category: "Text" },
|
|
37
|
+
"gemini-3.5-flash": { rpm: 5, rpd: 20, tpm: 250_000, category: "Text" },
|
|
38
|
+
"gemini-3.5-flash-lite": { rpm: 15, rpd: 500, tpm: 250_000, category: "Text" },
|
|
39
|
+
"gemini-3.6-flash": { rpm: 5, rpd: 20, tpm: 250_000, category: "Text" },
|
|
40
|
+
"gemma-4-26b-it": { rpm: 30, rpd: 14400, tpm: 16_000, category: "Other" },
|
|
41
|
+
"gemma-4-31b-it": { rpm: 30, rpd: 14400, tpm: 16_000, category: "Other" },
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
for (const [model, limit] of Object.entries(FULL_ROSTER)) {
|
|
45
|
+
MODEL_LIMITS[model] = limit;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const VERITAS_FULL_LLM_ROSTER: readonly string[] = Object.keys(FULL_ROSTER);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* V15 Pipeline state — isolated from npm package's app-state.
|
|
3
|
+
* Uses localStorage + event dispatch for cross-component sync.
|
|
4
|
+
*
|
|
5
|
+
* Namespace 'veritas.v15.*' avoids ANY collision with the npm package's
|
|
6
|
+
* 'veritas.*' keys. The V15 toggle default is FALSE — the original app runs
|
|
7
|
+
* unchanged unless the engineer explicitly enables V15.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const K_ENABLED = "veritas.v15.enabled";
|
|
11
|
+
const K_KEYS = "veritas.keys.v3"; // Same key the npm package uses — read-only
|
|
12
|
+
const EVT = "veritas:v15:change";
|
|
13
|
+
|
|
14
|
+
export function getV15Enabled(): boolean {
|
|
15
|
+
try { return localStorage.getItem(K_ENABLED) === "true"; } catch { return false; }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function setV15Enabled(on: boolean): void {
|
|
19
|
+
try { localStorage.setItem(K_ENABLED, String(on)); } catch { /* ignore */ }
|
|
20
|
+
try { window.dispatchEvent(new CustomEvent(EVT, { detail: { enabled: on } })); } catch { /* ignore */ }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function subscribeV15(cb: (on: boolean) => void): () => void {
|
|
24
|
+
const handler = () => cb(getV15Enabled());
|
|
25
|
+
window.addEventListener(EVT, handler);
|
|
26
|
+
window.addEventListener("storage", handler);
|
|
27
|
+
return () => {
|
|
28
|
+
window.removeEventListener(EVT, handler);
|
|
29
|
+
window.removeEventListener("storage", handler);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
import { registerApiKey } from "./v15-gemini";
|
|
34
|
+
|
|
35
|
+
/** Read the Gemini API key the npm package stored (never overwrite it). */
|
|
36
|
+
export function getGeminiKey(): string {
|
|
37
|
+
try {
|
|
38
|
+
const raw = localStorage.getItem(K_KEYS);
|
|
39
|
+
if (!raw) return "";
|
|
40
|
+
const parsed = JSON.parse(raw);
|
|
41
|
+
const primary = typeof parsed?.gemini === "string" ? parsed.gemini : "";
|
|
42
|
+
if (primary) registerApiKey("gemini", primary);
|
|
43
|
+
return primary;
|
|
44
|
+
} catch { return ""; }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const K_ROTATION_KEYS = "veritas.v15.rotationKeys";
|
|
48
|
+
|
|
49
|
+
export function getAuxiliaryGeminiKeys(): string[] {
|
|
50
|
+
try {
|
|
51
|
+
const raw = localStorage.getItem(K_ROTATION_KEYS);
|
|
52
|
+
return raw ? JSON.parse(raw) : [];
|
|
53
|
+
} catch { return []; }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function saveAuxiliaryGeminiKeys(keys: string[]): void {
|
|
57
|
+
try {
|
|
58
|
+
localStorage.setItem(K_ROTATION_KEYS, JSON.stringify(keys));
|
|
59
|
+
// Eagerly register keys to the active pool
|
|
60
|
+
keys.forEach(k => registerApiKey("gemini", k));
|
|
61
|
+
const primary = getGeminiKey();
|
|
62
|
+
if (primary) registerApiKey("gemini", primary);
|
|
63
|
+
} catch { /* ignore */ }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Auto-register keys at module load
|
|
67
|
+
try {
|
|
68
|
+
getAuxiliaryGeminiKeys().forEach(k => registerApiKey("gemini", k));
|
|
69
|
+
const primary = getGeminiKey();
|
|
70
|
+
if (primary) registerApiKey("gemini", primary);
|
|
71
|
+
} catch { /* ignore */ }
|
|
72
|
+
|
|
73
|
+
const K_ALLOWED_MODELS = "veritas.v15.allowedModels";
|
|
74
|
+
|
|
75
|
+
export function getAllowedModels(): string[] {
|
|
76
|
+
try {
|
|
77
|
+
const raw = localStorage.getItem(K_ALLOWED_MODELS);
|
|
78
|
+
if (!raw) return []; // Empty means ALL allowed by default
|
|
79
|
+
return JSON.parse(raw);
|
|
80
|
+
} catch { return []; }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function saveAllowedModels(models: string[]): void {
|
|
84
|
+
try {
|
|
85
|
+
localStorage.setItem(K_ALLOWED_MODELS, JSON.stringify(models));
|
|
86
|
+
} catch { /* ignore */ }
|
|
87
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Persistent V15 state override: default ON unless explicitly disabled. */
|
|
2
|
+
export * from "./v15-state.base";
|
|
3
|
+
import { setV15Enabled as baseSetV15Enabled } from "./v15-state.base";
|
|
4
|
+
|
|
5
|
+
const K_ENABLED = "veritas.v15.enabled";
|
|
6
|
+
const EVT = "veritas:v15:change";
|
|
7
|
+
|
|
8
|
+
export function getV15Enabled(): boolean {
|
|
9
|
+
try {
|
|
10
|
+
const value = localStorage.getItem(K_ENABLED);
|
|
11
|
+
return value === null ? true : value === "true";
|
|
12
|
+
} catch { return true; }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function setV15Enabled(on: boolean): void { baseSetV15Enabled(on); }
|
|
16
|
+
|
|
17
|
+
export function subscribeV15(cb: (on: boolean) => void): () => void {
|
|
18
|
+
const handler = () => cb(getV15Enabled());
|
|
19
|
+
window.addEventListener(EVT, handler);
|
|
20
|
+
window.addEventListener("storage", handler);
|
|
21
|
+
return () => {
|
|
22
|
+
window.removeEventListener(EVT, handler);
|
|
23
|
+
window.removeEventListener("storage", handler);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// [unify.mjs] Emergency mocks for symbols lost from package/wrapper
|
|
28
|
+
export function getGeminiKey(): string { return ""; }
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visual Table & Diagram Generation System
|
|
3
|
+
* Generates clean, publication-ready tables and diagrams for NIH grants.
|
|
4
|
+
* Replaces markdown tables with semantic React components.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from "react";
|
|
8
|
+
|
|
9
|
+
export interface TableColumn {
|
|
10
|
+
header: string;
|
|
11
|
+
key: string;
|
|
12
|
+
width?: string;
|
|
13
|
+
align?: "left" | "center" | "right";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface TableRow {
|
|
17
|
+
[key: string]: string | number | React.ReactNode;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface TableProps {
|
|
21
|
+
columns: TableColumn[];
|
|
22
|
+
rows: TableRow[];
|
|
23
|
+
caption?: string;
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Renders a clean, NIH-compliant table with proper formatting.
|
|
29
|
+
*/
|
|
30
|
+
export function generateNIHTable({ columns, rows, caption, className = "" }: TableProps): React.ReactElement {
|
|
31
|
+
return (
|
|
32
|
+
<div className={`overflow-x-auto my-4 ${className}`}>
|
|
33
|
+
<table className="min-w-full border-collapse border border-zinc-300 text-sm">
|
|
34
|
+
{caption && (
|
|
35
|
+
<caption className="caption-top text-xs font-semibold text-zinc-700 mb-2">
|
|
36
|
+
{caption}
|
|
37
|
+
</caption>
|
|
38
|
+
)}
|
|
39
|
+
<thead>
|
|
40
|
+
<tr className="bg-zinc-100">
|
|
41
|
+
{columns.map((col) => (
|
|
42
|
+
<th
|
|
43
|
+
key={col.key}
|
|
44
|
+
className={`border border-zinc-300 px-3 py-2 font-semibold text-zinc-900 ${
|
|
45
|
+
col.align === "center" ? "text-center" : col.align === "right" ? "text-right" : "text-left"
|
|
46
|
+
}`}
|
|
47
|
+
>
|
|
48
|
+
{col.header}
|
|
49
|
+
</th>
|
|
50
|
+
))}
|
|
51
|
+
</tr>
|
|
52
|
+
</thead>
|
|
53
|
+
<tbody>
|
|
54
|
+
{rows.map((row, rowIndex) => (
|
|
55
|
+
<tr key={rowIndex} className={rowIndex % 2 === 0 ? "bg-white" : "bg-zinc-50"}>
|
|
56
|
+
{columns.map((col) => (
|
|
57
|
+
<td
|
|
58
|
+
key={col.key}
|
|
59
|
+
className={`border border-zinc-300 px-3 py-2 ${
|
|
60
|
+
col.align === "center" ? "text-center" : col.align === "right" ? "text-right" : "text-left"
|
|
61
|
+
}`}
|
|
62
|
+
>
|
|
63
|
+
{row[col.key]}
|
|
64
|
+
</td>
|
|
65
|
+
))}
|
|
66
|
+
</tr>
|
|
67
|
+
))}
|
|
68
|
+
</tbody>
|
|
69
|
+
</table>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Generates an NIH-style Specific Aims table.
|
|
76
|
+
*/
|
|
77
|
+
export function generateSpecificAimsTable(aims: Array<{
|
|
78
|
+
aim: string;
|
|
79
|
+
metric: string;
|
|
80
|
+
expectedResult: string;
|
|
81
|
+
statisticalTarget: string;
|
|
82
|
+
}>): React.ReactElement {
|
|
83
|
+
const columns: TableColumn[] = [
|
|
84
|
+
{ header: "Aim", key: "aim", width: "25%" },
|
|
85
|
+
{ header: "Metric", key: "metric", width: "25%" },
|
|
86
|
+
{ header: "Expected Result", key: "expectedResult", width: "25%" },
|
|
87
|
+
{ header: "Statistical Target", key: "statisticalTarget", width: "25%" },
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
const rows: TableRow[] = aims.map((aim, i) => ({
|
|
91
|
+
aim: `Aim ${i + 1}: ${aim.aim}`,
|
|
92
|
+
metric: aim.metric,
|
|
93
|
+
expectedResult: aim.expectedResult,
|
|
94
|
+
statisticalTarget: aim.statisticalTarget,
|
|
95
|
+
}));
|
|
96
|
+
|
|
97
|
+
return generateNIHTable({
|
|
98
|
+
columns,
|
|
99
|
+
rows,
|
|
100
|
+
caption: "Table 1. Specific Aims with Metrics and Statistical Targets",
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Generates a power analysis table with ICC adjustment.
|
|
106
|
+
*/
|
|
107
|
+
export function generatePowerAnalysisTable(scenarios: Array<{
|
|
108
|
+
scenario: string;
|
|
109
|
+
totalN: number;
|
|
110
|
+
clusterSize: number;
|
|
111
|
+
icc: number;
|
|
112
|
+
effectiveN: number;
|
|
113
|
+
designEffect: number;
|
|
114
|
+
adequate: boolean;
|
|
115
|
+
}>): React.ReactElement {
|
|
116
|
+
const columns: TableColumn[] = [
|
|
117
|
+
{ header: "Scenario", key: "scenario", width: "20%" },
|
|
118
|
+
{ header: "Total N", key: "totalN", width: "12%" },
|
|
119
|
+
{ header: "Cluster Size", key: "clusterSize", width: "12%" },
|
|
120
|
+
{ header: "ICC (ρ)", key: "icc", width: "10%" },
|
|
121
|
+
{ header: "Design Effect", key: "designEffect", width: "12%" },
|
|
122
|
+
{ header: "Effective N", key: "effectiveN", width: "12%" },
|
|
123
|
+
{ header: "Adequate?", key: "adequate", width: "10%" },
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
const rows: TableRow[] = scenarios.map((scenario) => ({
|
|
127
|
+
scenario: scenario.scenario,
|
|
128
|
+
totalN: scenario.totalN.toLocaleString(),
|
|
129
|
+
clusterSize: scenario.clusterSize,
|
|
130
|
+
icc: scenario.icc.toFixed(3),
|
|
131
|
+
designEffect: scenario.designEffect.toFixed(3),
|
|
132
|
+
effectiveN: scenario.effectiveN.toLocaleString(),
|
|
133
|
+
adequate: scenario.adequate ? "✓ Yes" : "✗ No",
|
|
134
|
+
}));
|
|
135
|
+
|
|
136
|
+
return generateNIHTable({
|
|
137
|
+
columns,
|
|
138
|
+
rows,
|
|
139
|
+
caption: "Table 2. Power Analysis with Intraclass Correlation (ICC) Adjustment for Cluster-Randomized Design",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Generates a timeline diagram.
|
|
145
|
+
*/
|
|
146
|
+
export function generateTimelineDiagram(phases: Array<{
|
|
147
|
+
phase: string;
|
|
148
|
+
startMonth: number;
|
|
149
|
+
duration: number;
|
|
150
|
+
color?: string;
|
|
151
|
+
}>): React.ReactElement {
|
|
152
|
+
const colors = [
|
|
153
|
+
"bg-indigo-500",
|
|
154
|
+
"bg-emerald-500",
|
|
155
|
+
"bg-amber-500",
|
|
156
|
+
"bg-rose-500",
|
|
157
|
+
"bg-violet-500",
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<div className="my-4 overflow-x-auto">
|
|
162
|
+
<div className="relative">
|
|
163
|
+
{/* Timeline axis */}
|
|
164
|
+
<div className="flex items-center mb-2">
|
|
165
|
+
<div className="w-24 text-xs text-zinc-500">Timeline:</div>
|
|
166
|
+
<div className="flex-1 h-px bg-zinc-300 relative">
|
|
167
|
+
{Array.from({ length: 13 }).map((_, i) => (
|
|
168
|
+
<div
|
|
169
|
+
key={i}
|
|
170
|
+
className="absolute top-0 h-2 w-px bg-zinc-400"
|
|
171
|
+
style={{ left: `${(i / 12) * 100}%` }}
|
|
172
|
+
/>
|
|
173
|
+
))}
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
{/* Phase bars */}
|
|
178
|
+
{phases.map((phase, i) => (
|
|
179
|
+
<div key={i} className="flex items-center mb-2">
|
|
180
|
+
<div className="w-24 text-xs text-zinc-700 truncate">{phase.phase}</div>
|
|
181
|
+
<div className="flex-1 relative h-6">
|
|
182
|
+
<div
|
|
183
|
+
className={`absolute h-4 rounded ${phase.color || colors[i % colors.length]}`}
|
|
184
|
+
style={{
|
|
185
|
+
left: `${(phase.startMonth / 12) * 100}%`,
|
|
186
|
+
width: `${(phase.duration / 12) * 100}%`,
|
|
187
|
+
}}
|
|
188
|
+
/>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
))}
|
|
192
|
+
|
|
193
|
+
{/* Month labels */}
|
|
194
|
+
<div className="flex items-center mt-1">
|
|
195
|
+
<div className="w-24" />
|
|
196
|
+
<div className="flex-1 flex justify-between text-[10px] text-zinc-500">
|
|
197
|
+
<span>M0</span>
|
|
198
|
+
<span>M3</span>
|
|
199
|
+
<span>M6</span>
|
|
200
|
+
<span>M9</span>
|
|
201
|
+
<span>M12</span>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
);
|
|
207
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-based WebAssembly Runtime.
|
|
3
|
+
* Provides Wasmtime-like functionality using WebAssembly in browser.
|
|
4
|
+
* Enables isolated, pre emptible Wasm module execution.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface WasmModule {
|
|
8
|
+
id: string;
|
|
9
|
+
instance: WebAssembly.Instance;
|
|
10
|
+
memory?: WebAssembly.Memory;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface WasmRuntime {
|
|
14
|
+
loadModule(wasmBytes: ArrayBuffer): Promise<WasmModule>;
|
|
15
|
+
unloadModule(id: string): void;
|
|
16
|
+
callFunction(moduleId: string, fnName: string, ...args: any[]): Promise<any>;
|
|
17
|
+
getStats(): { loadedModules: number; totalMemory: number };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class BrowserWasmRuntime implements WasmRuntime {
|
|
21
|
+
private modules: Map<string, WasmModule> = new Map();
|
|
22
|
+
|
|
23
|
+
async loadModule(wasmBytes: ArrayBuffer): Promise<WasmModule> {
|
|
24
|
+
const id = crypto.randomUUID();
|
|
25
|
+
const memory = new WebAssembly.Memory({ initial: 1 });
|
|
26
|
+
const { instance } = await WebAssembly.instantiate(wasmBytes, {
|
|
27
|
+
env: {
|
|
28
|
+
memory,
|
|
29
|
+
log: (ptr: number, len: number) => {
|
|
30
|
+
const bytes = new Uint8Array(memory.buffer, ptr, len);
|
|
31
|
+
const text = new TextDecoder().decode(bytes);
|
|
32
|
+
console.log(`[Wasm ${id}] ${text}`);
|
|
33
|
+
},
|
|
34
|
+
abort: (msg: string) => {
|
|
35
|
+
console.error(`[Wasm ${id}] ABORT: ${msg}`);
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const module = {
|
|
41
|
+
id,
|
|
42
|
+
instance,
|
|
43
|
+
memory,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
this.modules.set(id, module);
|
|
47
|
+
return module;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
unloadModule(id: string): void {
|
|
51
|
+
this.modules.delete(id);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async callFunction(moduleId: string, fnName: string, ...args: any[]): Promise<any> {
|
|
55
|
+
const module = this.modules.get(moduleId);
|
|
56
|
+
if (!module) throw new Error(`Module ${moduleId} not found`);
|
|
57
|
+
|
|
58
|
+
const fn = (module.instance.exports as any)[fnName];
|
|
59
|
+
if (!fn) throw new Error(`Function ${fnName} not found in module ${moduleId}`);
|
|
60
|
+
|
|
61
|
+
// Execute with timeout protection using Web Worker
|
|
62
|
+
return await this.executeInWorker(fn, ...args);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private async executeInWorker(fn: Function, ...args: any[]): Promise<any> {
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
const workerBlob = new Blob(
|
|
68
|
+
[
|
|
69
|
+
`
|
|
70
|
+
onmessage = async (e) => {
|
|
71
|
+
try {
|
|
72
|
+
const { fn, args } = e.data;
|
|
73
|
+
// Note: This is a simplified worker execution
|
|
74
|
+
// In production, you'd serialize the Wasm module properly
|
|
75
|
+
const result = fn(...args);
|
|
76
|
+
postMessage({ success: true, result });
|
|
77
|
+
} catch (error) {
|
|
78
|
+
postMessage({ success: false, error: error.message });
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
`,
|
|
82
|
+
],
|
|
83
|
+
{ type: "application/javascript" }
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const worker = new Worker(URL.createObjectURL(workerBlob));
|
|
87
|
+
worker.onmessage = (e) => {
|
|
88
|
+
worker.terminate();
|
|
89
|
+
if (e.data.success) {
|
|
90
|
+
resolve(e.data.result);
|
|
91
|
+
} else {
|
|
92
|
+
reject(new Error(e.data.error));
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
worker.onerror = (e) => {
|
|
96
|
+
worker.terminate();
|
|
97
|
+
reject(new Error(e.message));
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// Send function and args (simplified - in production use proper serialization)
|
|
101
|
+
worker.postMessage({ fn: fn.toString(), args });
|
|
102
|
+
|
|
103
|
+
// Timeout after 5 seconds
|
|
104
|
+
setTimeout(() => {
|
|
105
|
+
worker.terminate();
|
|
106
|
+
reject(new Error("Wasm execution timeout"));
|
|
107
|
+
}, 5000);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
getStats(): { loadedModules: number; totalMemory: number } {
|
|
112
|
+
let totalMemory = 0;
|
|
113
|
+
for (const module of this.modules.values()) {
|
|
114
|
+
if (module.memory) {
|
|
115
|
+
totalMemory += module.memory.buffer.byteLength;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
loadedModules: this.modules.size,
|
|
120
|
+
totalMemory,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Singleton instance
|
|
126
|
+
let wasmRuntimeInstance: WasmRuntime | null = null;
|
|
127
|
+
|
|
128
|
+
export function getWasmRuntime(): WasmRuntime {
|
|
129
|
+
if (!wasmRuntimeInstance) {
|
|
130
|
+
wasmRuntimeInstance = new BrowserWasmRuntime();
|
|
131
|
+
}
|
|
132
|
+
return wasmRuntimeInstance;
|
|
133
|
+
}
|