@bitcobblers/wod-wiki-lang 0.42.2148 → 0.43.2149

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -4911,6 +4911,284 @@ var ExecutionContext = class {
4911
4911
  }
4912
4912
  }
4913
4913
  };
4914
+
4915
+ // src/runtime/RuntimeLogFormat.ts
4916
+ var RUNTIME_LOG_SUBJECT_WIDTH = 24;
4917
+ var pad2 = (n) => String(n).padStart(2, "0");
4918
+ var pad3 = (n) => String(n).padStart(3, "0");
4919
+ function formatRuntimeTimestamp(d) {
4920
+ return `${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}.${pad3(d.getMilliseconds())}`;
4921
+ }
4922
+ function padRuntimeLogEvent(event) {
4923
+ return (event + " ").slice(0, 5);
4924
+ }
4925
+ function padRuntimeLogSubject(subject) {
4926
+ return (subject + " ".repeat(RUNTIME_LOG_SUBJECT_WIDTH)).slice(0, RUNTIME_LOG_SUBJECT_WIDTH);
4927
+ }
4928
+ function formatRuntimeLogLine(timestamp, event, subject, payload) {
4929
+ return `${formatRuntimeTimestamp(timestamp)} ${padRuntimeLogEvent(event)} ${padRuntimeLogSubject(subject)}${payload ? " " + payload : ""}`;
4930
+ }
4931
+ function formatRuntimeLogRule(label) {
4932
+ const width = 52;
4933
+ if (!label) return "\u2500".repeat(width);
4934
+ const inner = ` ${label} `;
4935
+ const left = Math.max(0, Math.floor((width - inner.length) / 2));
4936
+ const right = Math.max(0, width - inner.length - left);
4937
+ return `${"\u2500".repeat(left)}${inner}${"\u2500".repeat(right)}`;
4938
+ }
4939
+
4940
+ // src/runtime/RuntimeLogger.ts
4941
+ var RuntimeLoggerImpl = class {
4942
+ // Console is this logger's designated output sink; all writes funnel
4943
+ // through this single reference so the no-console rule is waived once.
4944
+ // eslint-disable-next-line no-console
4945
+ _console = console;
4946
+ _enabled = false;
4947
+ _history = [];
4948
+ _maxHistory = 500;
4949
+ EVENT_STYLES = {
4950
+ BOOT: "color: #3b82f6; font-weight: bold",
4951
+ // primary
4952
+ PUSH: "color: #a855f7; font-weight: bold",
4953
+ // rounds violet
4954
+ POP: "color: #64748b",
4955
+ // muted
4956
+ NEXT: "color: #b45309; font-weight: bold",
4957
+ // action ochre
4958
+ EVNT: "color: #a855f7; font-weight: bold",
4959
+ // violet
4960
+ OUT: "color: #16a34a; font-weight: bold",
4961
+ // effort green
4962
+ MEM: "color: #f59e0b",
4963
+ // amber
4964
+ TIME: "color: #3b82f6; font-weight: bold",
4965
+ // time slate
4966
+ HALT: "color: #ef4444; font-weight: bold",
4967
+ // destructive
4968
+ WARN: "color: #f59e0b; font-weight: bold",
4969
+ ERR: "color: #ef4444; font-weight: bold"
4970
+ };
4971
+ constructor() {
4972
+ if (typeof window !== "undefined") {
4973
+ const debugWindow = window;
4974
+ this._enabled = !!debugWindow.__WOD_DEBUG__;
4975
+ }
4976
+ }
4977
+ get enabled() {
4978
+ return this._enabled;
4979
+ }
4980
+ enable() {
4981
+ this._enabled = true;
4982
+ this.writeLine("BOOT", "runtime:ready", "logging enabled");
4983
+ }
4984
+ disable() {
4985
+ this.writeLine("HALT", "runtime:logger", "logging disabled");
4986
+ this._enabled = false;
4987
+ }
4988
+ getHistory() {
4989
+ return [...this._history];
4990
+ }
4991
+ clearHistory() {
4992
+ this._history = [];
4993
+ }
4994
+ // ============================================================================
4995
+ // Logging Methods
4996
+ // ============================================================================
4997
+ /**
4998
+ * Log runtime construction. Called once by ScriptRuntime's constructor;
4999
+ * dropped when logging is disabled, so cheap to leave wired.
5000
+ */
5001
+ logBoot(detail) {
5002
+ if (!this._enabled) return;
5003
+ this.writeLine("BOOT", "runtime:ready", detail);
5004
+ }
5005
+ /**
5006
+ * Log when a block is pushed onto the stack. `depth` is the 1-based
5007
+ * stack depth the block landed at (prototype's `dN` column).
5008
+ */
5009
+ logPush(block, parentKey, depth) {
5010
+ if (!this._enabled) return;
5011
+ const behaviors = this.getBehaviorNames(block);
5012
+ const payload = [
5013
+ `d${depth ?? "?"} ${block.blockType ?? "block"}`,
5014
+ behaviors.length > 0 ? `behaviors [${behaviors.join(", ")}]` : void 0,
5015
+ parentKey ? `parent ${parentKey.slice(0, 8)}` : void 0
5016
+ ].filter(Boolean).join(" \xB7 ");
5017
+ this.writeLine("PUSH", block.label || block.blockType || "Block", payload);
5018
+ this.addToHistory("info", "push", `PUSH ${block.label}`, {
5019
+ key: block.key.toString(),
5020
+ parentKey,
5021
+ behaviors,
5022
+ sourceIds: block.sourceIds
5023
+ });
5024
+ }
5025
+ /**
5026
+ * Log when a block is popped from the stack. `depth` is the 1-based
5027
+ * depth the block occupied (prototype's `dN` column).
5028
+ */
5029
+ logPop(block, reason, depth) {
5030
+ if (!this._enabled) return;
5031
+ this.writeLine("POP", block.label || block.blockType || "Block", `d${depth ?? "?"}${reason ? " " + reason : ""}`);
5032
+ this.addToHistory("info", "pop", `POP ${block.label}`, {
5033
+ key: block.key.toString(),
5034
+ reason
5035
+ });
5036
+ }
5037
+ /**
5038
+ * Log when next() is called on a block
5039
+ */
5040
+ logNext(block, actions) {
5041
+ if (!this._enabled) return;
5042
+ if (actions.length === 0) return;
5043
+ const actionNames = actions.map((a) => a.type || a.constructor?.name || "Action");
5044
+ this.writeLine("NEXT", block.label || "Block", `${actionNames.length} action(s): [${actionNames.join(", ")}]`);
5045
+ this.addToHistory("info", "next", `NEXT ${block.label}`, {
5046
+ key: block.key.toString(),
5047
+ actions: actionNames
5048
+ });
5049
+ }
5050
+ /**
5051
+ * Log when an event produces actions
5052
+ */
5053
+ logEvent(event, actions) {
5054
+ if (!this._enabled) return;
5055
+ if (actions.length === 0) return;
5056
+ const actionNames = actions.map((a) => a.type || a.constructor?.name || "Action");
5057
+ this.writeLine("EVNT", event.name, `${actionNames.length} action(s): [${actionNames.join(", ")}]`);
5058
+ this.addToHistory("info", "event", `EVENT ${event.name}`, {
5059
+ eventName: event.name,
5060
+ eventData: event.data,
5061
+ actions: actionNames
5062
+ });
5063
+ }
5064
+ /**
5065
+ * Log an output statement (segment / milestone). Called by OutputEmitter
5066
+ * on every published output. 'system' outputs (sound cues etc.) and
5067
+ * label-less structural outputs (the boot 'load' statement) are skipped —
5068
+ * volume stays proportional to what the athlete did.
5069
+ */
5070
+ logOutput(output) {
5071
+ if (!this._enabled) return;
5072
+ if (output.outputType !== "segment" && output.outputType !== "milestone") return;
5073
+ const subject = output.text || this.outputSubject(output.metrics);
5074
+ if (!subject) return;
5075
+ this.writeLine("OUT", subject, output.outputType);
5076
+ this.addToHistory("info", "output", `OUT ${subject}`, {
5077
+ outputType: output.outputType,
5078
+ label: subject
5079
+ });
5080
+ }
5081
+ /** No `label` field exists on outputs — fall back to the explicit Label
5082
+ * metric (image, then value), matching the UI's naming convention. */
5083
+ outputSubject(metrics) {
5084
+ if (!metrics) return void 0;
5085
+ for (const m of metrics) {
5086
+ if (m.type === "label") return m.image || (m.value != null ? String(m.value) : "") || void 0;
5087
+ }
5088
+ return void 0;
5089
+ }
5090
+ /**
5091
+ * Log when memory is updated on a block
5092
+ */
5093
+ logMemoryUpdate(blockKey, memoryType, value) {
5094
+ if (!this._enabled) return;
5095
+ const displayValue = typeof value === "object" && value !== null ? this.summarizeObject(value) : value;
5096
+ this.writeLine("MEM", memoryType, `[${blockKey.slice(0, 8)}] ${safeJson(displayValue)}`);
5097
+ this.addToHistory("debug", "memory", `MEMORY ${memoryType}`, {
5098
+ blockKey,
5099
+ memoryType,
5100
+ value: displayValue
5101
+ });
5102
+ }
5103
+ /**
5104
+ * Log action execution
5105
+ */
5106
+ logAction(action, depth) {
5107
+ if (!this._enabled) return;
5108
+ const actionName = action.type || action.constructor?.name || "Action";
5109
+ this.writeLine("EVNT", actionName, `d${depth}`);
5110
+ }
5111
+ /**
5112
+ * General-purpose message log for runtime consumers.
5113
+ * Gates on _enabled; writes to the console sink and history.
5114
+ */
5115
+ logMessage(level, category, message, data) {
5116
+ if (!this._enabled) return;
5117
+ this.writeLine(level === "error" ? "ERR" : level === "warn" ? "WARN" : "EVNT", category, message);
5118
+ this.addToHistory(level, category, message, data);
5119
+ }
5120
+ /**
5121
+ * Always-on variant of `logMessage`. Use sparingly for errors/warnings that
5122
+ * must be visible even when debug logging is disabled.
5123
+ */
5124
+ logAlways(level, category, message, data) {
5125
+ this.writeLine(level === "error" ? "ERR" : level === "warn" ? "WARN" : "EVNT", category, message);
5126
+ this.addToHistory(level, category, message, data);
5127
+ }
5128
+ /** A round-boundary rule in the paper format (prototype tier 04). */
5129
+ logRule(label) {
5130
+ if (!this._enabled) return;
5131
+ this._console.log(`%c${formatRuntimeLogRule(label)}`, "color: #94a3b8");
5132
+ }
5133
+ // ============================================================================
5134
+ // Helpers
5135
+ // ============================================================================
5136
+ /**
5137
+ * The one console write path: a single paper line with the event code
5138
+ * tinted. `addToHistory` stays separate — entries carry structured data,
5139
+ * lines carry display text.
5140
+ */
5141
+ writeLine(code, subject, payload) {
5142
+ const ts = formatRuntimeTimestamp(/* @__PURE__ */ new Date());
5143
+ this._console.log(
5144
+ `${ts} %c${padRuntimeLogEvent(code)}%c ${padRuntimeLogSubject(subject)}${payload ? " " + payload : ""}`,
5145
+ this.EVENT_STYLES[code],
5146
+ "color: inherit"
5147
+ );
5148
+ }
5149
+ getBehaviorNames(block) {
5150
+ const blockWithBehaviors = block;
5151
+ const behaviors = blockWithBehaviors.behaviors;
5152
+ if (!behaviors || !Array.isArray(behaviors)) return [];
5153
+ return behaviors.map((b) => b.constructor?.name || "Behavior");
5154
+ }
5155
+ summarizeObject(obj) {
5156
+ const summary = {};
5157
+ for (const [key, val] of Object.entries(obj)) {
5158
+ if (Array.isArray(val)) {
5159
+ summary[key] = `[${val.length} items]`;
5160
+ } else if (typeof val === "object" && val !== null) {
5161
+ summary[key] = "{...}";
5162
+ } else {
5163
+ summary[key] = val;
5164
+ }
5165
+ }
5166
+ return summary;
5167
+ }
5168
+ addToHistory(level, category, message, data) {
5169
+ this._history.push({
5170
+ timestamp: /* @__PURE__ */ new Date(),
5171
+ level,
5172
+ category,
5173
+ message,
5174
+ data
5175
+ });
5176
+ if (this._history.length > this._maxHistory) {
5177
+ this._history = this._history.slice(-this._maxHistory);
5178
+ }
5179
+ }
5180
+ };
5181
+ function safeJson(value) {
5182
+ try {
5183
+ return JSON.stringify(value) ?? "";
5184
+ } catch {
5185
+ return String(value);
5186
+ }
5187
+ }
5188
+ var RuntimeLogger = new RuntimeLoggerImpl();
5189
+ if (typeof window !== "undefined") {
5190
+ window.RuntimeLogger = RuntimeLogger;
5191
+ }
4914
5192
  var OutputEmitter = class {
4915
5193
  _outputStatements = [];
4916
5194
  _outputListeners = /* @__PURE__ */ new Set();
@@ -4964,6 +5242,7 @@ var OutputEmitter = class {
4964
5242
  }
4965
5243
  const processed = this._analyticsEngine ? this._analyticsEngine.run(output) : output;
4966
5244
  this._propagateSourceLine(processed);
5245
+ RuntimeLogger.logOutput(processed);
4967
5246
  this._outputStatements.push(processed);
4968
5247
  for (const listener of this._outputListeners) {
4969
5248
  try {
@@ -5309,249 +5588,6 @@ var RuntimeObservers = class {
5309
5588
  }
5310
5589
  };
5311
5590
 
5312
- // src/runtime/RuntimeLogger.ts
5313
- var RuntimeLoggerImpl = class {
5314
- // Console is this logger's designated output sink; all writes funnel
5315
- // through this single reference so the no-console rule is waived once.
5316
- // eslint-disable-next-line no-console
5317
- _console = console;
5318
- _enabled = false;
5319
- _history = [];
5320
- _maxHistory = 500;
5321
- // Style constants for console output
5322
- STYLES = {
5323
- push: "color: #22c55e; font-weight: bold",
5324
- // green
5325
- pop: "color: #ef4444; font-weight: bold",
5326
- // red
5327
- next: "color: #3b82f6; font-weight: bold",
5328
- // blue
5329
- event: "color: #a855f7; font-weight: bold",
5330
- // purple
5331
- memory: "color: #f59e0b; font-weight: bold",
5332
- // amber
5333
- action: "color: #6366f1; font-weight: normal",
5334
- // indigo
5335
- origin: "color: #64748b; font-weight: normal"
5336
- // slate
5337
- };
5338
- constructor() {
5339
- if (typeof window !== "undefined") {
5340
- const debugWindow = window;
5341
- this._enabled = !!debugWindow.__WOD_DEBUG__;
5342
- }
5343
- }
5344
- get enabled() {
5345
- return this._enabled;
5346
- }
5347
- enable() {
5348
- this._enabled = true;
5349
- this._console.log("%c[RT] \u{1F527} Runtime logging ENABLED", "color: #22c55e; font-weight: bold");
5350
- }
5351
- disable() {
5352
- this._enabled = false;
5353
- this._console.log("%c[RT] Runtime logging disabled", "color: #64748b");
5354
- }
5355
- getHistory() {
5356
- return [...this._history];
5357
- }
5358
- clearHistory() {
5359
- this._history = [];
5360
- }
5361
- // ============================================================================
5362
- // Logging Methods
5363
- // ============================================================================
5364
- /**
5365
- * Log when a block is pushed onto the stack
5366
- */
5367
- logPush(block, parentKey) {
5368
- if (!this._enabled) return;
5369
- const behaviors = this.getBehaviorNames(block);
5370
- const memoryTypes = block.getAllMemory?.().map((loc) => loc.tag) ?? [];
5371
- this._console.groupCollapsed(
5372
- `%c[RT] \u25B6 PUSH %c${block.label || block.blockType || "Block"}%c [${block.key.toString().slice(0, 8)}]`,
5373
- this.STYLES.push,
5374
- "color: inherit; font-weight: bold",
5375
- "color: #64748b; font-weight: normal"
5376
- );
5377
- this._console.log("Key:", block.key.toString());
5378
- if (parentKey) this._console.log("Parent:", parentKey);
5379
- this._console.log("Source IDs:", block.sourceIds);
5380
- this._console.log("Behaviors:", behaviors);
5381
- if (memoryTypes.length > 0) this._console.log("Memory Types:", memoryTypes);
5382
- this._console.groupEnd();
5383
- this.addToHistory("info", "push", `PUSH ${block.label}`, {
5384
- key: block.key.toString(),
5385
- parentKey,
5386
- behaviors,
5387
- sourceIds: block.sourceIds
5388
- });
5389
- }
5390
- /**
5391
- * Log when a block is popped from the stack
5392
- */
5393
- logPop(block, reason) {
5394
- if (!this._enabled) return;
5395
- this._console.log(
5396
- `%c[RT] \u25C0 POP %c${block.label || block.blockType || "Block"}%c [${block.key.toString().slice(0, 8)}]${reason ? ` (${reason})` : ""}`,
5397
- this.STYLES.pop,
5398
- "color: inherit; font-weight: bold",
5399
- "color: #64748b; font-weight: normal"
5400
- );
5401
- this.addToHistory("info", "pop", `POP ${block.label}`, {
5402
- key: block.key.toString(),
5403
- reason
5404
- });
5405
- }
5406
- /**
5407
- * Log when next() is called on a block
5408
- */
5409
- logNext(block, actions) {
5410
- if (!this._enabled) return;
5411
- const actionNames = actions.map((a) => a.type || a.constructor?.name || "Action");
5412
- if (actions.length === 0) {
5413
- return;
5414
- }
5415
- this._console.groupCollapsed(
5416
- `%c[RT] \u2192 NEXT %c${block.label || "Block"}%c \u2192 ${actions.length} action(s)`,
5417
- this.STYLES.next,
5418
- "color: inherit; font-weight: bold",
5419
- "color: #64748b; font-weight: normal"
5420
- );
5421
- this._console.log("Block:", block.key.toString());
5422
- this._console.log("Actions:", actionNames);
5423
- this._console.groupEnd();
5424
- this.addToHistory("info", "next", `NEXT ${block.label}`, {
5425
- key: block.key.toString(),
5426
- actions: actionNames
5427
- });
5428
- }
5429
- /**
5430
- * Log when an event produces actions
5431
- */
5432
- logEvent(event, actions) {
5433
- if (!this._enabled) return;
5434
- if (actions.length === 0) return;
5435
- const actionNames = actions.map((a) => a.type || a.constructor?.name || "Action");
5436
- this._console.groupCollapsed(
5437
- `%c[RT] \u26A1 EVENT %c${event.name}%c \u2192 ${actions.length} action(s)`,
5438
- this.STYLES.event,
5439
- "color: inherit; font-weight: bold",
5440
- "color: #64748b; font-weight: normal"
5441
- );
5442
- this._console.log("Event Data:", event.data);
5443
- this._console.log("Actions:", actionNames);
5444
- this._console.groupEnd();
5445
- this.addToHistory("info", "event", `EVENT ${event.name}`, {
5446
- eventName: event.name,
5447
- eventData: event.data,
5448
- actions: actionNames
5449
- });
5450
- }
5451
- /**
5452
- * Log when memory is updated on a block
5453
- */
5454
- logMemoryUpdate(blockKey, memoryType, value) {
5455
- if (!this._enabled) return;
5456
- let displayValue = value;
5457
- if (typeof value === "object" && value !== null) {
5458
- displayValue = this.summarizeObject(value);
5459
- }
5460
- this._console.log(
5461
- `%c[RT] \u{1F4DD} MEMORY %c${memoryType}%c on [${blockKey.slice(0, 8)}]:`,
5462
- this.STYLES.memory,
5463
- "color: inherit; font-weight: bold",
5464
- "color: #64748b; font-weight: normal",
5465
- displayValue
5466
- );
5467
- this.addToHistory("debug", "memory", `MEMORY ${memoryType}`, {
5468
- blockKey,
5469
- memoryType,
5470
- value: displayValue
5471
- });
5472
- }
5473
- /**
5474
- * Log action execution (verbose, under a group)
5475
- */
5476
- logAction(action, depth) {
5477
- if (!this._enabled) return;
5478
- const indent = " ".repeat(depth);
5479
- const actionName = action.type || action.constructor?.name || "Action";
5480
- this._console.log(
5481
- `%c[RT] ${indent}\u2699 %c${actionName}`,
5482
- this.STYLES.action,
5483
- "color: inherit"
5484
- );
5485
- }
5486
- /**
5487
- * General-purpose message log for runtime consumers.
5488
- * Gates on _enabled; writes to the console sink and history.
5489
- */
5490
- logMessage(level, category, message, data) {
5491
- if (!this._enabled) return;
5492
- this._console.log(`%c[RT] ${category} %c${message}`, this.styleFor(level), "color: inherit");
5493
- this.addToHistory(level, category, message, data);
5494
- }
5495
- /**
5496
- * Always-on variant of `logMessage`. Use sparingly for errors/warnings that
5497
- * must be visible even when debug logging is disabled.
5498
- */
5499
- logAlways(level, category, message, data) {
5500
- this._console.log(`%c[RT] ${category} %c${message}`, this.styleFor(level), "color: inherit");
5501
- this.addToHistory(level, category, message, data);
5502
- }
5503
- // ============================================================================
5504
- // Helpers
5505
- // ============================================================================
5506
- getBehaviorNames(block) {
5507
- const blockWithBehaviors = block;
5508
- const behaviors = blockWithBehaviors.behaviors;
5509
- if (!behaviors || !Array.isArray(behaviors)) return [];
5510
- return behaviors.map((b) => b.constructor?.name || "Behavior");
5511
- }
5512
- summarizeObject(obj) {
5513
- const summary = {};
5514
- for (const [key, val] of Object.entries(obj)) {
5515
- if (Array.isArray(val)) {
5516
- summary[key] = `[${val.length} items]`;
5517
- } else if (typeof val === "object" && val !== null) {
5518
- summary[key] = "{...}";
5519
- } else {
5520
- summary[key] = val;
5521
- }
5522
- }
5523
- return summary;
5524
- }
5525
- styleFor(level) {
5526
- switch (level) {
5527
- case "error":
5528
- return "color: #ef4444; font-weight: bold";
5529
- case "warn":
5530
- return "color: #f59e0b; font-weight: bold";
5531
- case "info":
5532
- return "color: #3b82f6; font-weight: bold";
5533
- default:
5534
- return "color: #64748b";
5535
- }
5536
- }
5537
- addToHistory(level, category, message, data) {
5538
- this._history.push({
5539
- timestamp: /* @__PURE__ */ new Date(),
5540
- level,
5541
- category,
5542
- message,
5543
- data
5544
- });
5545
- if (this._history.length > this._maxHistory) {
5546
- this._history = this._history.slice(-this._maxHistory);
5547
- }
5548
- }
5549
- };
5550
- var RuntimeLogger = new RuntimeLoggerImpl();
5551
- if (typeof window !== "undefined") {
5552
- window.RuntimeLogger = RuntimeLogger;
5553
- }
5554
-
5555
5591
  // src/runtime/actions/stack/PushBlockAction.ts
5556
5592
  var PushBlockAction = class {
5557
5593
  constructor(block, options = {}) {
@@ -5585,7 +5621,7 @@ var PushBlockAction = class {
5585
5621
  runtime.stack.push(this.block);
5586
5622
  const mountActions = this.block.mount(runtime, lifecycle);
5587
5623
  const parentKey = runtime.stack.blocks.length > 1 ? runtime.stack.blocks[1]?.key.toString() : void 0;
5588
- RuntimeLogger.logPush(this.block, parentKey);
5624
+ RuntimeLogger.logPush(this.block, parentKey, runtime.stack.blocks.length);
5589
5625
  return mountActions;
5590
5626
  } catch (error) {
5591
5627
  const runtimeWithSetError = runtime;
@@ -5616,7 +5652,7 @@ var PopBlockAction = class {
5616
5652
  }
5617
5653
  if (!current.isComplete && typeof current.markComplete === "function") {
5618
5654
  current.markComplete("forced-pop");
5619
- RuntimeLogger.logPop(current, "forced-pop (incomplete block popped without next)");
5655
+ RuntimeLogger.logPop(current, "forced-pop (incomplete block popped without next)", runtime.stack.blocks.length);
5620
5656
  }
5621
5657
  const unmountActions = current.unmount(runtime, lifecycleOptions) ?? [];
5622
5658
  const popped = runtime.stack.pop();
@@ -5626,7 +5662,7 @@ var PopBlockAction = class {
5626
5662
  popped.dispose(runtime);
5627
5663
  popped.context?.release?.();
5628
5664
  if (popped.completionReason !== "forced-pop") {
5629
- RuntimeLogger.logPop(popped, popped.completionReason);
5665
+ RuntimeLogger.logPop(popped, popped.completionReason, runtime.stack.blocks.length + 1);
5630
5666
  }
5631
5667
  const parent = runtime.stack.current;
5632
5668
  return parent ? [...unmountActions, new NextAction(lifecycleOptions, runtime.nowProvider)] : unmountActions;
@@ -5665,6 +5701,7 @@ var ScriptRuntime = class {
5665
5701
  });
5666
5702
  this.clock.start();
5667
5703
  this._output.emitLoad();
5704
+ RuntimeLogger.logBoot(`statements ${this.script.statements.length}`);
5668
5705
  }
5669
5706
  script;
5670
5707
  eventBus;
@@ -8379,6 +8416,10 @@ var ReportOutputBehavior = class {
8379
8416
  writeResultMemory(ctx, resultFragments) {
8380
8417
  const existing = ctx.block.getMemoryByTag("metric:result");
8381
8418
  if (existing.length > 0) {
8419
+ const preserved = collectUserOriginMetrics(existing);
8420
+ if (preserved.length > 0) {
8421
+ resultFragments = resultFragments.clone().add(...preserved);
8422
+ }
8382
8423
  ctx.updateMemory("metric:result", resultFragments.toArray());
8383
8424
  return;
8384
8425
  }
@@ -8386,11 +8427,22 @@ var ReportOutputBehavior = class {
8386
8427
  }
8387
8428
  writeResultGroups(ctx, resultGroups) {
8388
8429
  const existing = ctx.block.getMemoryByTag("metric:result");
8389
- if (existing.length > 0) {
8430
+ if (existing.length === 0) {
8431
+ for (const group of resultGroups) {
8432
+ ctx.pushMemory("metric:result", group.toArray());
8433
+ }
8390
8434
  return;
8391
8435
  }
8392
- for (const group of resultGroups) {
8393
- ctx.pushMemory("metric:result", group.toArray());
8436
+ const count = Math.max(existing.length, resultGroups.length);
8437
+ for (let i = 0; i < count; i++) {
8438
+ const base = resultGroups[i] ? resultGroups[i].clone() : existing[i].metrics.clone();
8439
+ const userMetrics = resultGroups[i] && i < existing.length ? collectUserOriginMetrics([existing[i]]) : [];
8440
+ const merged = base.add(...userMetrics);
8441
+ if (i < existing.length) {
8442
+ existing[i].update(merged);
8443
+ } else {
8444
+ ctx.pushMemory("metric:result", merged.toArray());
8445
+ }
8394
8446
  }
8395
8447
  }
8396
8448
  formatLabel(ctx) {
@@ -8400,6 +8452,15 @@ var ReportOutputBehavior = class {
8400
8452
  return round.total !== void 0 ? `Round ${round.current} of ${round.total}` : `Round ${round.current}`;
8401
8453
  }
8402
8454
  };
8455
+ function collectUserOriginMetrics(locations) {
8456
+ const userMetrics = [];
8457
+ for (const loc of locations) {
8458
+ for (const m of loc.metrics) {
8459
+ if (m.origin === "user") userMetrics.push(m);
8460
+ }
8461
+ }
8462
+ return userMetrics;
8463
+ }
8403
8464
  var SoundMetric = class {
8404
8465
  constructor(sound, trigger, options = {}) {
8405
8466
  this.sound = sound;
@@ -10729,8 +10790,7 @@ var CalcEngine = class {
10729
10790
  for (const segment of segments) {
10730
10791
  if (segment.outputType !== "segment") continue;
10731
10792
  if (exclusion && matchesExclusion(effortOf(segment).slug, exclusion)) continue;
10732
- for (const metric of segment.metrics.rawMetrics) {
10733
- if (metric.type !== metricType) continue;
10793
+ for (const metric of segment.getDisplayMetrics({ types: [metricType] })) {
10734
10794
  const value = numericMetricValue(metric);
10735
10795
  if (value === void 0) continue;
10736
10796
  values.push(value);
@@ -14706,6 +14766,6 @@ function compareStatement(expectations, actual, mode) {
14706
14766
  return diffs;
14707
14767
  }
14708
14768
 
14709
- export { ABSENT, AGGREGATE_BUILTINS, AUTHORITATIVE_CASTS, AbortSessionAction, AmrapLogicStrategy, AnalyticsEngine, AnalyticsTransformer, BUILTIN_CALCS, BUNDLED_EFFORT_COUNT, BehaviorContext, BlockBuilder, BlockContext, ButtonBehavior, CATALOG_PRECEDENCE_RANK, CONSUMED_HINTS, CONSUMED_HINT_KEYS, CONTEXT_ATOMS, CalcEngine, CalcEvalError, CalcParseError, CalcRegistrationError, CalcUnitError, CalculateBlockProcessor, CalculationRegistry, CardioDialect, ChildSelectionBehavior, ChildrenStrategy, ChoiceGroupMetric, ClearChildrenAction, ClimbDialect, ClimbMetricType, CompileAndPushBlockAction, CompletionTimestampBehavior, CompositeEffortRegistry, CountdownTimerBehavior, CountupTimerBehavior, CrossFitDialect, DAY, DEFAULT_RESOLVER_OPTIONS, DEFAULT_RUNTIME_OPTIONS, DEFAULT_UNRESOLVED_EFFORT_MET, DIM_COUNT, DIM_ENERGY, DIM_LENGTH, DIM_MASS, DIM_TIME, DIM_ZERO, DISCIPLINE_FACTORS, DialectStack, EFFORT_DATA_METRIC_TYPE, EFFORT_DISCIPLINES, EFFORT_REGISTRY_ORIGINS, EffortBlock, EffortFallbackStrategy, EffortResolver, EmitEventAction, EmitSystemOutputAction, ErrorAction, EventBus, ExecutionContext, ExitBehavior, FixtureSyntaxError, GenericGroupStrategy, GenericLoopStrategy, GenericTimerStrategy, HabitsDialect, INTENSITY_TIERS, InMemoryEffortRegistry, IntervalLogicStrategy, JitCompiler, LabelingBehavior, LocalEventProvider, LocalRuntimeSubscription, LookupRegistry, MdTimerRuntime, MemoryLocation, MemoryTypeEnum, MetricPromotionBehavior, NAMED_COMPOUNDS, NextAction, NextEvent, NextEventHandler, OutputEmitter, PREDEFINED_SOUNDS, PRODUCTION_STRATEGIES, PlaySoundAction, PopBlockAction, PushBlockAction, PushRestBlockAction, REST_EXCLUSION, RPE_LABELS, RegisterEventHandlerAction, Registry, ReportOutputBehavior, ReportOutputStrategy, RestBlock, RoundsMetric, RuntimeAdapter, RuntimeBlock, RuntimeBuilder, RuntimeClock, RuntimeFactory, RuntimeLogger, RuntimeMemory, RuntimeObservers, RuntimeStack, STANDARD_UNITS, STORE_CALCS, STREAM_ATOMS, ScriptRuntime, SessionRootBlock, SessionRootStrategy, SnapshotClock, SoundCueBehavior, SoundStrategy, SpanTrackingBehavior, StandardAnalyticsProfile, StartSessionAction, StartWorkoutAction, SubscriptionManager, ThrowError, ThrowErrorAction, TimeSpan, TwoPassEffortResolutionProcess, TypedMemoryReference, UNITS, UnitRegistry, UnitSet, UnitsDialect, UnregisterEventHandlerAction, UpdateNextPreviewAction, VISIBILITY_ICONS, VISIBILITY_LABELS, WaitingToStartBlock, WaitingToStartInjectorBehavior, WhiteboardScript, WodDialect, YogaDialect, addAliasToEffort, addDim, buildStaticLookups, buildTooltip, bundledEfforts, calculateElapsed, canonicalizeType, checkCalcLine, classifyStatements, closeCurrentSpan, collapseUnresolvedChoices, commonFixtureSet, compareStatement, compileLineForm, composeDivUnit, composeMulUnit, compoundName, computeColumnLabel, computeLabel, computeWorkloadRollups, convertScalar, createAnalyticsEngineForBlock, createCalcEngine, createCalcStack, createCompiler, createDialectStack, createDisciplinesTable, createEffortTable, createLineLocator, createPolicy as createMetricPresentationPolicy, createMockClock, createParser, createProfileTable, createReferenceIndex, createRpeLabelsTable, dailySessionLoads, dayBucket, dedupeEntitiesByPrecedence, dialectRegistry, dialectStack, diffStatement, dimEquals, disciplineFactorFor, documentToEffort, documentToEquipment, effortToDocument, equipmentToDocument, evaluate, evaluateCalculateDefinitions, extractEffortData, extractMetrics, extractStatementRefs, extractStatements, extractStatementsRaw, extractSyntaxFacts, filterTagsByVisibility, findBestFuzzyMatch, findUnresolvedChoices, fixtureBackSquat, fixtureBurpee, fixturePlank, fixtureRowing, fixtureRunning, fixtureUserCustom, fixtureUserOverride, formatDim, formatDuration, metricsToLabel as fragmentsToLabel, fullFixtureSet, fuseUnits, fuseUnitsInMetrics, getAnalyticsFromLogs, getAnalyticsFromRuntime, getHints, getMetricVisibility, getUnit, hasHint, hintMetric, hintsToContainer, inferDim, isCastSubscription, isChoiceResolved, isDimensionless, isEffortDiscipline, isFragmentTag, isTimeLikeMetric, isWithinThreshold, levenshteinDistance, metricPresentation, mutateTimerSpans, normalizeForFuzzy, num, openSpan, outputNodeId, outputNodeIds, parseCalcLine, parseCalculateBlock, parseEffortFile, parseEquipmentFile, parseExpression, parseMetricLine, parseScript, printCalculation, readNestedSection, readTimer, realtimeProcessorRegistry, renderMetric, resolveDominantOrigin, resolveEntityRank, resolveEntityTier, resolveSourceRank, resolveSourceTier, slugifyRefLabel, startSpan, str, strategyRegistry, subDim, summaryProcessorRegistry, toStoredOutputStatement, truthy, validateOutputUnit, parser as whiteboardParser, whiteboardScript, whiteboardScriptLanguage, writeChoiceSelection };
14769
+ export { ABSENT, AGGREGATE_BUILTINS, AUTHORITATIVE_CASTS, AbortSessionAction, AmrapLogicStrategy, AnalyticsEngine, AnalyticsTransformer, BUILTIN_CALCS, BUNDLED_EFFORT_COUNT, BehaviorContext, BlockBuilder, BlockContext, ButtonBehavior, CATALOG_PRECEDENCE_RANK, CONSUMED_HINTS, CONSUMED_HINT_KEYS, CONTEXT_ATOMS, CalcEngine, CalcEvalError, CalcParseError, CalcRegistrationError, CalcUnitError, CalculateBlockProcessor, CalculationRegistry, CardioDialect, ChildSelectionBehavior, ChildrenStrategy, ChoiceGroupMetric, ClearChildrenAction, ClimbDialect, ClimbMetricType, CompileAndPushBlockAction, CompletionTimestampBehavior, CompositeEffortRegistry, CountdownTimerBehavior, CountupTimerBehavior, CrossFitDialect, DAY, DEFAULT_RESOLVER_OPTIONS, DEFAULT_RUNTIME_OPTIONS, DEFAULT_UNRESOLVED_EFFORT_MET, DIM_COUNT, DIM_ENERGY, DIM_LENGTH, DIM_MASS, DIM_TIME, DIM_ZERO, DISCIPLINE_FACTORS, DialectStack, EFFORT_DATA_METRIC_TYPE, EFFORT_DISCIPLINES, EFFORT_REGISTRY_ORIGINS, EffortBlock, EffortFallbackStrategy, EffortResolver, EmitEventAction, EmitSystemOutputAction, ErrorAction, EventBus, ExecutionContext, ExitBehavior, FixtureSyntaxError, GenericGroupStrategy, GenericLoopStrategy, GenericTimerStrategy, HabitsDialect, INTENSITY_TIERS, InMemoryEffortRegistry, IntervalLogicStrategy, JitCompiler, LabelingBehavior, LocalEventProvider, LocalRuntimeSubscription, LookupRegistry, MdTimerRuntime, MemoryLocation, MemoryTypeEnum, MetricPromotionBehavior, NAMED_COMPOUNDS, NextAction, NextEvent, NextEventHandler, OutputEmitter, PREDEFINED_SOUNDS, PRODUCTION_STRATEGIES, PlaySoundAction, PopBlockAction, PushBlockAction, PushRestBlockAction, REST_EXCLUSION, RPE_LABELS, RUNTIME_LOG_SUBJECT_WIDTH, RegisterEventHandlerAction, Registry, ReportOutputBehavior, ReportOutputStrategy, RestBlock, RoundsMetric, RuntimeAdapter, RuntimeBlock, RuntimeBuilder, RuntimeClock, RuntimeFactory, RuntimeLogger, RuntimeMemory, RuntimeObservers, RuntimeStack, STANDARD_UNITS, STORE_CALCS, STREAM_ATOMS, ScriptRuntime, SessionRootBlock, SessionRootStrategy, SnapshotClock, SoundCueBehavior, SoundStrategy, SpanTrackingBehavior, StandardAnalyticsProfile, StartSessionAction, StartWorkoutAction, SubscriptionManager, ThrowError, ThrowErrorAction, TimeSpan, TwoPassEffortResolutionProcess, TypedMemoryReference, UNITS, UnitRegistry, UnitSet, UnitsDialect, UnregisterEventHandlerAction, UpdateNextPreviewAction, VISIBILITY_ICONS, VISIBILITY_LABELS, WaitingToStartBlock, WaitingToStartInjectorBehavior, WhiteboardScript, WodDialect, YogaDialect, addAliasToEffort, addDim, buildStaticLookups, buildTooltip, bundledEfforts, calculateElapsed, canonicalizeType, checkCalcLine, classifyStatements, closeCurrentSpan, collapseUnresolvedChoices, commonFixtureSet, compareStatement, compileLineForm, composeDivUnit, composeMulUnit, compoundName, computeColumnLabel, computeLabel, computeWorkloadRollups, convertScalar, createAnalyticsEngineForBlock, createCalcEngine, createCalcStack, createCompiler, createDialectStack, createDisciplinesTable, createEffortTable, createLineLocator, createPolicy as createMetricPresentationPolicy, createMockClock, createParser, createProfileTable, createReferenceIndex, createRpeLabelsTable, dailySessionLoads, dayBucket, dedupeEntitiesByPrecedence, dialectRegistry, dialectStack, diffStatement, dimEquals, disciplineFactorFor, documentToEffort, documentToEquipment, effortToDocument, equipmentToDocument, evaluate, evaluateCalculateDefinitions, extractEffortData, extractMetrics, extractStatementRefs, extractStatements, extractStatementsRaw, extractSyntaxFacts, filterTagsByVisibility, findBestFuzzyMatch, findUnresolvedChoices, fixtureBackSquat, fixtureBurpee, fixturePlank, fixtureRowing, fixtureRunning, fixtureUserCustom, fixtureUserOverride, formatDim, formatDuration, formatRuntimeLogLine, formatRuntimeLogRule, formatRuntimeTimestamp, metricsToLabel as fragmentsToLabel, fullFixtureSet, fuseUnits, fuseUnitsInMetrics, getAnalyticsFromLogs, getAnalyticsFromRuntime, getHints, getMetricVisibility, getUnit, hasHint, hintMetric, hintsToContainer, inferDim, isCastSubscription, isChoiceResolved, isDimensionless, isEffortDiscipline, isFragmentTag, isTimeLikeMetric, isWithinThreshold, levenshteinDistance, metricPresentation, mutateTimerSpans, normalizeForFuzzy, num, openSpan, outputNodeId, outputNodeIds, padRuntimeLogEvent, padRuntimeLogSubject, parseCalcLine, parseCalculateBlock, parseEffortFile, parseEquipmentFile, parseExpression, parseMetricLine, parseScript, printCalculation, readNestedSection, readTimer, realtimeProcessorRegistry, renderMetric, resolveDominantOrigin, resolveEntityRank, resolveEntityTier, resolveSourceRank, resolveSourceTier, slugifyRefLabel, startSpan, str, strategyRegistry, subDim, summaryProcessorRegistry, toStoredOutputStatement, truthy, validateOutputUnit, parser as whiteboardParser, whiteboardScript, whiteboardScriptLanguage, writeChoiceSelection };
14710
14770
  //# sourceMappingURL=index.mjs.map
14711
14771
  //# sourceMappingURL=index.mjs.map