@mulmoclaude/core 0.13.0 → 0.14.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.
Files changed (56) hide show
  1. package/assets/helps/billing-clients-worklog.md +15 -12
  2. package/assets/helps/collection-skills.md +42 -19
  3. package/assets/helps/gemini.md +5 -3
  4. package/assets/helps/todo-collection.md +13 -7
  5. package/dist/{deriveAll-CMFXDQ_G.js → calendarGrid-C1rfCXJ3.cjs} +468 -3
  6. package/dist/calendarGrid-C1rfCXJ3.cjs.map +1 -0
  7. package/dist/{deriveAll-BQ_p5HSB.cjs → calendarGrid-kO6rGfm0.js} +289 -74
  8. package/dist/calendarGrid-kO6rGfm0.js.map +1 -0
  9. package/dist/collection/core/ids.d.ts +12 -0
  10. package/dist/collection/core/recordZ.d.ts +25 -0
  11. package/dist/collection/core/schema.d.ts +65 -418
  12. package/dist/collection/core/schemaZ.d.ts +846 -0
  13. package/dist/collection/core/templatePath.d.ts +34 -0
  14. package/dist/collection/core/where.d.ts +9 -15
  15. package/dist/collection/index.cjs +34 -295
  16. package/dist/collection/index.cjs.map +1 -1
  17. package/dist/collection/index.d.ts +1 -0
  18. package/dist/collection/index.js +5 -270
  19. package/dist/collection/index.js.map +1 -1
  20. package/dist/collection/paths.cjs +1 -1
  21. package/dist/collection/paths.cjs.map +1 -1
  22. package/dist/collection/paths.js +1 -1
  23. package/dist/collection/paths.js.map +1 -1
  24. package/dist/collection/registry/server/index.cjs +1 -1
  25. package/dist/collection/registry/server/index.js +1 -1
  26. package/dist/collection/server/discovery.d.ts +2 -244
  27. package/dist/collection/server/index.cjs +3 -1
  28. package/dist/collection/server/index.js +2 -2
  29. package/dist/collection/server/templatePath.d.ts +1 -34
  30. package/dist/collection/server/validate.d.ts +11 -7
  31. package/dist/collection-watchers/clock.d.ts +1 -0
  32. package/dist/collection-watchers/index.cjs +13 -4
  33. package/dist/collection-watchers/index.cjs.map +1 -1
  34. package/dist/collection-watchers/index.d.ts +1 -0
  35. package/dist/collection-watchers/index.js +13 -5
  36. package/dist/collection-watchers/index.js.map +1 -1
  37. package/dist/feeds/index.cjs +4 -4
  38. package/dist/feeds/index.js +2 -2
  39. package/dist/feeds/ingestTypes.d.ts +15 -40
  40. package/dist/feeds/server/index.cjs +5 -5
  41. package/dist/feeds/server/index.js +3 -3
  42. package/dist/{ingestTypes-C7EheYZX.cjs → ingestTypes-BIFXlw7M.cjs} +3 -3
  43. package/dist/ingestTypes-BIFXlw7M.cjs.map +1 -0
  44. package/dist/{ingestTypes-CmJeOUJc.js → ingestTypes-KuYPX9Ea.js} +2 -2
  45. package/dist/ingestTypes-KuYPX9Ea.js.map +1 -0
  46. package/dist/{server-DKXXFTbw.js → server-Cc6XcyOA.js} +417 -187
  47. package/dist/server-Cc6XcyOA.js.map +1 -0
  48. package/dist/{server-G6GtOdaW.cjs → server-Cd5WdM8a.cjs} +440 -198
  49. package/dist/server-Cd5WdM8a.cjs.map +1 -0
  50. package/package.json +2 -2
  51. package/dist/deriveAll-BQ_p5HSB.cjs.map +0 -1
  52. package/dist/deriveAll-CMFXDQ_G.js.map +0 -1
  53. package/dist/ingestTypes-C7EheYZX.cjs.map +0 -1
  54. package/dist/ingestTypes-CmJeOUJc.js.map +0 -1
  55. package/dist/server-DKXXFTbw.js.map +0 -1
  56. package/dist/server-G6GtOdaW.cjs.map +0 -1
@@ -0,0 +1,34 @@
1
+ /**
2
+ * A safe skill-relative path: non-empty, no backslash, not absolute,
3
+ * and every `/`-separated segment is a plain `[A-Za-z0-9._-]+` token
4
+ * that isn't `.` / `..` (no traversal). Multi-segment (nested) paths
5
+ * are allowed. The reader's realpath containment is the hard
6
+ * guarantee; this fails a bad path fast.
7
+ */
8
+ export declare function isSafeTemplatePath(value: string): boolean;
9
+ /**
10
+ * An action `template` value: a safe path that lives under the skill's
11
+ * `templates/` subdir. This is the canonical contract — the schema
12
+ * validator rejects anything else up front, and the bridge mirrors
13
+ * exactly these. Nested paths (`templates/mail/welcome.md`) and any
14
+ * extension are allowed as long as the path is otherwise safe.
15
+ */
16
+ export declare function isSafeActionTemplatePath(value: string): boolean;
17
+ /**
18
+ * A custom-view `file` value: a safe path under the skill's `views/`
19
+ * subdir that ends in `.html`. Custom views are LLM-authored HTML the
20
+ * host renders in a sandboxed iframe; constraining them to `views/*.html`
21
+ * keeps the data folder and the schema/template files off-limits to the
22
+ * view-file reader. Same per-segment safety as templates; the reader's
23
+ * realpath containment is the hard guarantee.
24
+ */
25
+ export declare function isSafeCustomViewPath(value: string): boolean;
26
+ /**
27
+ * A custom-view `i18n` value: the JSON dictionary file authors ship next to
28
+ * their `views/<id>.html`. Constrained to `views/<name>.i18n.json` so the
29
+ * field can only point at a translation file co-located with the view it
30
+ * translates — the same `views/` containment the HTML reader uses. The
31
+ * `.i18n.json` suffix (vs plain `.json`) makes the file's purpose grep-able
32
+ * for both authors and tooling.
33
+ */
34
+ export declare function isSafeCustomViewI18nPath(value: string): boolean;
@@ -1,28 +1,22 @@
1
- /** Comparison operators one `WhereCond` may apply to `record[field]`. */
2
- export type WhereOp = "eq" | "ne" | "in" | "gt" | "gte" | "lt" | "lte" | "contains";
1
+ import { z } from 'zod';
2
+ import { ValueRefZ, WhereCondZ, WhereZ } from './schemaZ';
3
3
  /** Reads the comparison value from a field instead of a schema literal:
4
4
  * - `record` set → another record: `recordsById[record][field]` (e.g. a
5
5
  * `_config` singleton's `defaultCity`, following a per-user setting);
6
6
  * - `record` omitted → the SAME record being matched (field-to-field, e.g.
7
7
  * `spent > budget`). */
8
- export interface ValueRef {
9
- record?: string;
10
- field: string;
11
- }
8
+ export type ValueRef = z.infer<typeof ValueRefZ>;
12
9
  /** One typed condition: `record[field] <op> value`. The comparison value is
13
10
  * either a literal `value` (a plain string for every op except `in`, which
14
11
  * takes the allowed set) or a `valueFrom` reference resolved against the
15
12
  * `recordsById` map passed to `matchesWhere`. Exactly one of the two is
16
- * expected — enforced by zod at the schema boundary (`server/discovery.ts`),
17
- * not here. */
18
- export interface WhereCond {
19
- field: string;
20
- op: WhereOp;
21
- value?: string | string[];
22
- valueFrom?: ValueRef;
23
- }
13
+ * expected — enforced by zod at the schema boundary (`./schemaZ`), not
14
+ * here. */
15
+ export type WhereCond = z.infer<typeof WhereCondZ>;
16
+ /** Comparison operators one `WhereCond` may apply to `record[field]`. */
17
+ export type WhereOp = WhereCond["op"];
24
18
  /** A `where` clause is the AND of its conditions — every one must match. */
25
- export type Where = WhereCond[];
19
+ export type Where = z.infer<typeof WhereZ>;
26
20
  /** True when `record` satisfies every condition in `where` (AND). An empty
27
21
  * `where` matches everything. `recordsById` — the source collection's
28
22
  * records keyed by primaryKey — resolves any `valueFrom` reference;
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_deriveAll = require("../deriveAll-BQ_p5HSB.cjs");
2
+ const require_calendarGrid = require("../calendarGrid-C1rfCXJ3.cjs");
3
3
  const require_errorMessage = require("../errorMessage--LvXe_Jx.cjs");
4
4
  //#region src/collection/core/presentCollection.ts
5
5
  var TOOL_NAME = "presentCollection";
@@ -149,7 +149,8 @@ function resolveEnumColor(schema, fieldKey, value) {
149
149
  if (rank < 0) return ENUM_NEUTRAL;
150
150
  return rank === 0 ? ENUM_ALERT : ENUM_NUDGE;
151
151
  }
152
- return enumColorClasses(enumValueIndex(schema.fields[fieldKey]?.values, value));
152
+ const spec = schema.fields[fieldKey];
153
+ return enumColorClasses(enumValueIndex(spec?.type === "enum" ? spec.values : void 0, value));
153
154
  }
154
155
  //#endregion
155
156
  //#region src/collection/core/actionVisible.ts
@@ -294,7 +295,7 @@ function isMissingDraftValue(value) {
294
295
  }
295
296
  /** Label of the first required table sub-field empty in any row, else null. */
296
297
  function firstMissingTableSubField(field, rows) {
297
- if (!field.of || !rows) return null;
298
+ if (field.type !== "table" || !rows) return null;
298
299
  for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {
299
300
  const row = rows[rowIdx];
300
301
  for (const [subKey, subField] of Object.entries(field.of)) {
@@ -444,272 +445,6 @@ function itemLabelOf(item, schema, labelField) {
444
445
  return itemIdOf(item, schema);
445
446
  }
446
447
  //#endregion
447
- //#region src/collection/core/calendarGrid.ts
448
- var MS_PER_DAY = 864e5;
449
- var ISO_DATE_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
450
- var TWO_DIGIT_RE = /^\d{2}$/;
451
- var CLOCK_RE = /(\d{1,2}):(\d{2})/g;
452
- var RANGE_SEP_RE = /[-–—~〜~]/;
453
- /** Minutes in a full day — the timeline's vertical extent. */
454
- var MINUTES_PER_DAY = 1440;
455
- function pad2(value) {
456
- return String(value).padStart(2, "0");
457
- }
458
- /** Canonical `YYYY-MM-DD` string for a civil date. */
459
- function ymdKey(ymd) {
460
- return `${String(ymd.year).padStart(4, "0")}-${pad2(ymd.month)}-${pad2(ymd.day)}`;
461
- }
462
- /** Strictly parse a `YYYY-MM-DD` string into a civil date, rejecting
463
- * anything that isn't a real calendar day (e.g. `2026-02-30`, `2026-13-01`).
464
- * Returns null for non-strings and malformed values so callers can route
465
- * records with no usable date into the "no date" tray rather than crash. */
466
- function parseIsoDate(value) {
467
- if (typeof value !== "string") return null;
468
- const match = ISO_DATE_RE.exec(value.trim());
469
- if (!match) return null;
470
- const year = Number(match[1]);
471
- const month = Number(match[2]);
472
- const day = Number(match[3]);
473
- const probe = new Date(Date.UTC(year, month - 1, day));
474
- if (probe.getUTCFullYear() !== year || probe.getUTCMonth() !== month - 1 || probe.getUTCDate() !== day) return null;
475
- return {
476
- year,
477
- month,
478
- day
479
- };
480
- }
481
- /** Minutes-of-day for an `HH:MM` pair, or null when out of range. */
482
- function clockToMinutes(hours, minutes) {
483
- if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null;
484
- return hours * 60 + minutes;
485
- }
486
- /** Strictly parse a `YYYY-MM-DDTHH:MM` (optional `:SS`) datetime into its
487
- * civil date and minutes-of-day. Returns null for anything that isn't a real
488
- * calendar day or a valid 24h clock. */
489
- function parseIsoDateTime(value) {
490
- if (typeof value !== "string") return null;
491
- const trimmed = value.trim();
492
- const tIndex = trimmed.indexOf("T");
493
- if (tIndex === -1) return null;
494
- const ymd = parseIsoDate(trimmed.slice(0, tIndex));
495
- if (!ymd) return null;
496
- const parts = trimmed.slice(tIndex + 1).split(":");
497
- if (parts.length < 2 || parts.length > 3 || !parts.every((part) => TWO_DIGIT_RE.test(part))) return null;
498
- const minutes = clockToMinutes(Number(parts[0]), Number(parts[1]));
499
- if (minutes === null) return null;
500
- return {
501
- ymd,
502
- minutes
503
- };
504
- }
505
- /** Civil date from either a `YYYY-MM-DD` or a `YYYY-MM-DDTHH:MM` value, so the
506
- * month grid buckets date-only and datetime anchors alike. */
507
- function dateOf(value) {
508
- return parseIsoDate(value) ?? parseIsoDateTime(value)?.ymd ?? null;
509
- }
510
- /** Minutes-of-day from a datetime value, or null for date-only / invalid. */
511
- function timeOf(value) {
512
- return parseIsoDateTime(value)?.minutes ?? null;
513
- }
514
- /** Parse a free-form time-string field into start/end minutes-of-day.
515
- * Handles the common shapes in user data:
516
- * "14:00-17:00" → { start: 840, end: 1020 } (range → block)
517
- * "17:00-" → { start: 1020, end: null } (open end → single line)
518
- * "16:30" → { start: 990, end: null } (point in time → single line)
519
- * "終日" / "" → null (no clock → all-day)
520
- * Returns null when no clock token is parseable. */
521
- function parseTimeRange(value) {
522
- if (typeof value !== "string") return null;
523
- const text = value.trim();
524
- if (!text) return null;
525
- const tokens = [...text.matchAll(CLOCK_RE)];
526
- if (tokens.length === 0) return null;
527
- const minutesOf = (match) => clockToMinutes(Number(match[1]), Number(match[2]));
528
- if (!RANGE_SEP_RE.test(text)) {
529
- const startMin = minutesOf(tokens[0]);
530
- return startMin === null ? null : {
531
- startMin,
532
- endMin: null
533
- };
534
- }
535
- const sepIndex = text.search(RANGE_SEP_RE);
536
- let startMin = null;
537
- let endMin = null;
538
- for (const token of tokens) if ((token.index ?? 0) < sepIndex) startMin = minutesOf(token);
539
- else endMin = minutesOf(token);
540
- if (startMin === null) return null;
541
- return {
542
- startMin,
543
- endMin
544
- };
545
- }
546
- function ymdToUtcMs(ymd) {
547
- return Date.UTC(ymd.year, ymd.month - 1, ymd.day);
548
- }
549
- function utcMsToYmd(epochMs) {
550
- const date = new Date(epochMs);
551
- return {
552
- year: date.getUTCFullYear(),
553
- month: date.getUTCMonth() + 1,
554
- day: date.getUTCDate()
555
- };
556
- }
557
- /** Chronological comparison: negative if `left` precedes `right`, 0 if the
558
- * same day, positive if after. */
559
- function compareYmd(left, right) {
560
- return ymdToUtcMs(left) - ymdToUtcMs(right);
561
- }
562
- /** True iff `day` falls within the inclusive span `[span.start, span.end]`. */
563
- function spanCoversDay(span, day) {
564
- return compareYmd(span.start, day) <= 0 && compareYmd(day, span.end) <= 0;
565
- }
566
- /** Build the 6×7 (42-cell) grid for the given month, including the
567
- * leading/trailing days of the adjacent months so every week is full.
568
- * `month` is 1-12. `weekStartsOn` is 0 (Sunday) … 6 (Saturday). */
569
- function buildMonthGrid(year, month, weekStartsOn = 0) {
570
- const lead = (new Date(Date.UTC(year, month - 1, 1)).getUTCDay() - weekStartsOn + 7) % 7;
571
- const startMs = Date.UTC(year, month - 1, 1) - lead * MS_PER_DAY;
572
- const cells = [];
573
- for (let i = 0; i < 42; i++) {
574
- const ymd = utcMsToYmd(startMs + i * MS_PER_DAY);
575
- cells.push({
576
- ymd,
577
- inMonth: ymd.year === year && ymd.month === month,
578
- key: ymdKey(ymd)
579
- });
580
- }
581
- return cells;
582
- }
583
- /** Resolve a record's calendar span from its date/datetime fields. Returns
584
- * null when the anchor date is missing/invalid (→ the caller's "no date"
585
- * tray). An end date that is missing, invalid, or earlier than the start
586
- * collapses to a single-day span — never an inverted range.
587
- *
588
- * Times for the day (time-allocation) view come from, in priority order:
589
- * 1. the clock on a `datetime` anchor/end value, else
590
- * 2. `timeField` — a separate free-form time-string column (e.g. "14:00-17:00").
591
- * A record with no resolvable clock has `startMin === endMin === null`. */
592
- function recordSpan(item, anchorField, endField, timeField) {
593
- const startRaw = item[anchorField];
594
- const start = dateOf(startRaw);
595
- if (!start) return null;
596
- let end = start;
597
- let startMin = timeOf(startRaw);
598
- let endMin = null;
599
- if (endField) {
600
- const endRaw = item[endField];
601
- const parsedEnd = dateOf(endRaw);
602
- if (parsedEnd && compareYmd(parsedEnd, start) >= 0) {
603
- end = parsedEnd;
604
- endMin = timeOf(endRaw);
605
- }
606
- }
607
- if (timeField && startMin === null && endMin === null) {
608
- const range = parseTimeRange(item[timeField]);
609
- if (range) ({startMin, endMin} = range);
610
- }
611
- return {
612
- item,
613
- start,
614
- end,
615
- startMin,
616
- endMin
617
- };
618
- }
619
- /** Split records into those that land on the calendar (with their spans)
620
- * and those with no usable anchor date (the "no date" tray). Spans are
621
- * sorted by start day so same-day stacking is stable across renders. */
622
- function bucketRecords(items, anchorField, endField, timeField) {
623
- const spans = [];
624
- const noDate = [];
625
- for (const item of items) {
626
- const span = recordSpan(item, anchorField, endField, timeField);
627
- if (span) spans.push(span);
628
- else noDate.push(item);
629
- }
630
- spans.sort((left, right) => compareYmd(left.start, right.start));
631
- return {
632
- spans,
633
- noDate
634
- };
635
- }
636
- /** Project a record's span onto a single day for the time-allocation view, or
637
- * null when the span doesn't cover that day. */
638
- function daySlice(span, day) {
639
- if (!spanCoversDay(span, day)) return null;
640
- const hasStart = span.startMin !== null;
641
- const hasEnd = span.endMin !== null;
642
- if (!hasStart && !hasEnd) return {
643
- kind: "allDay",
644
- startMin: 0,
645
- endMin: MINUTES_PER_DAY,
646
- bleedsBefore: false,
647
- bleedsAfter: false
648
- };
649
- const singleDay = compareYmd(span.start, span.end) === 0;
650
- const isStartDay = compareYmd(day, span.start) === 0;
651
- const isEndDay = compareYmd(day, span.end) === 0;
652
- if (singleDay && hasStart && !hasEnd) return {
653
- kind: "line",
654
- startMin: span.startMin,
655
- endMin: span.startMin,
656
- bleedsBefore: false,
657
- bleedsAfter: false
658
- };
659
- const startMin = isStartDay && hasStart ? span.startMin : 0;
660
- const endMin = isEndDay && hasEnd ? span.endMin : MINUTES_PER_DAY;
661
- if (singleDay && endMin <= startMin) return {
662
- kind: "line",
663
- startMin,
664
- endMin: startMin,
665
- bleedsBefore: false,
666
- bleedsAfter: false
667
- };
668
- return {
669
- kind: "block",
670
- startMin,
671
- endMin,
672
- bleedsBefore: !isStartDay,
673
- bleedsAfter: !isEndDay
674
- };
675
- }
676
- function assignLanes(blocks) {
677
- const order = [...blocks.keys()].sort((left, right) => blocks[left].startMin - blocks[right].startMin || blocks[left].endMin - blocks[right].endMin);
678
- const result = blocks.map(() => ({
679
- lane: 0,
680
- lanes: 1
681
- }));
682
- let cluster = [];
683
- let clusterEnd = Number.NEGATIVE_INFINITY;
684
- const laneEnds = [];
685
- const flush = () => {
686
- for (const index of cluster) result[index].lanes = laneEnds.length;
687
- cluster = [];
688
- laneEnds.length = 0;
689
- clusterEnd = Number.NEGATIVE_INFINITY;
690
- };
691
- for (const index of order) {
692
- const block = blocks[index];
693
- if (cluster.length > 0 && block.startMin >= clusterEnd) flush();
694
- let lane = laneEnds.findIndex((end) => end <= block.startMin);
695
- if (lane === -1) {
696
- lane = laneEnds.length;
697
- laneEnds.push(block.endMin);
698
- } else laneEnds[lane] = block.endMin;
699
- result[index].lane = lane;
700
- cluster.push(index);
701
- clusterEnd = Math.max(clusterEnd, block.endMin);
702
- }
703
- flush();
704
- return result;
705
- }
706
- /** Month label key inputs — returns the 1st of the month as a `Date` so the
707
- * component can feed it to `Intl.DateTimeFormat(locale, …)` for a localized
708
- * "April 2026" header without this module taking a locale dependency. */
709
- function monthAnchorDate(year, month) {
710
- return new Date(Date.UTC(year, month - 1, 1));
711
- }
712
- //#endregion
713
448
  //#region src/collection/core/shortHexId.ts
714
449
  /**
715
450
  * 8-char hex id — short, slug-safe, and editable. Produces the same id *shape*
@@ -729,64 +464,68 @@ function defangForPrompt(value) {
729
464
  return value.replace(/[<>]/g, "").replace(/`/g, "'").replace(/\$\{/g, "$ {").replace(/\s+/g, " ").slice(0, DEFANG_MAX_LEN);
730
465
  }
731
466
  //#endregion
732
- exports.AGENT_INGEST_KIND = require_deriveAll.AGENT_INGEST_KIND;
467
+ exports.AGENT_INGEST_KIND = require_calendarGrid.AGENT_INGEST_KIND;
733
468
  exports.ENUM_ALERT = ENUM_ALERT;
734
469
  exports.ENUM_NEUTRAL = ENUM_NEUTRAL;
735
470
  exports.ENUM_NUDGE = ENUM_NUDGE;
736
- exports.FEED_SCHEDULES = require_deriveAll.FEED_SCHEDULES;
737
- exports.INGEST_KINDS = require_deriveAll.INGEST_KINDS;
738
- exports.MINUTES_PER_DAY = MINUTES_PER_DAY;
471
+ exports.FEED_SCHEDULES = require_calendarGrid.FEED_SCHEDULES;
472
+ exports.INGEST_KINDS = require_calendarGrid.INGEST_KINDS;
473
+ exports.MINUTES_PER_DAY = require_calendarGrid.MINUTES_PER_DAY;
474
+ exports.SAFE_RECORD_ID_PATTERN = require_calendarGrid.SAFE_RECORD_ID_PATTERN;
475
+ exports.SAFE_SLUG_PATTERN = require_calendarGrid.SAFE_SLUG_PATTERN;
739
476
  exports.TOOL_DEFINITION = TOOL_DEFINITION;
740
477
  exports.TOOL_NAME = TOOL_NAME;
741
478
  exports.actionVisible = actionVisible;
742
- exports.assignLanes = assignLanes;
479
+ exports.assignLanes = require_calendarGrid.assignLanes;
743
480
  exports.boolSortValue = boolSortValue;
744
- exports.bucketRecords = bucketRecords;
745
- exports.buildMonthGrid = buildMonthGrid;
481
+ exports.bucketRecords = require_calendarGrid.bucketRecords;
482
+ exports.buildMonthGrid = require_calendarGrid.buildMonthGrid;
746
483
  exports.buildUpdatedRecord = buildUpdatedRecord;
747
484
  exports.coerceInlineValue = coerceInlineValue;
748
485
  exports.compareSortValues = compareSortValues;
749
- exports.compareYmd = compareYmd;
750
- exports.dateOf = dateOf;
486
+ exports.compareYmd = require_calendarGrid.compareYmd;
487
+ exports.dateOf = require_calendarGrid.dateOf;
751
488
  exports.dateSortValue = dateSortValue;
752
- exports.daySlice = daySlice;
489
+ exports.daySlice = require_calendarGrid.daySlice;
753
490
  exports.defangForPrompt = defangForPrompt;
754
- exports.deriveAll = require_deriveAll.deriveAll;
491
+ exports.deriveAll = require_calendarGrid.deriveAll;
755
492
  exports.draftToRecord = draftToRecord;
756
- exports.embedTargetId = require_deriveAll.embedTargetId;
493
+ exports.embedTargetId = require_calendarGrid.embedTargetId;
757
494
  exports.emptyRow = emptyRow;
758
495
  exports.enumColorClasses = enumColorClasses;
759
496
  exports.enumSortValue = enumSortValue;
760
497
  exports.enumValueIndex = enumValueIndex;
761
498
  exports.errorMessage = require_errorMessage.errorMessage;
762
- exports.evaluateDerived = require_deriveAll.evaluateDerived;
499
+ exports.evaluateDerived = require_calendarGrid.evaluateDerived;
763
500
  exports.executePresentCollection = executePresentCollection;
764
501
  exports.fieldVisible = fieldVisible;
765
- exports.firstDateField = require_deriveAll.firstDateField;
502
+ exports.firstDateField = require_calendarGrid.firstDateField;
766
503
  exports.firstMissingRequiredField = firstMissingRequiredField;
767
- exports.isFieldDrivenEvery = require_deriveAll.isFieldDrivenEvery;
504
+ exports.isFieldDrivenEvery = require_calendarGrid.isFieldDrivenEvery;
505
+ exports.isSafeRecordId = require_calendarGrid.isSafeRecordId;
506
+ exports.isSafeSlug = require_calendarGrid.isSafeSlug;
768
507
  exports.isSortableField = isSortableField;
769
508
  exports.itemIdOf = itemIdOf;
770
509
  exports.itemLabelOf = itemLabelOf;
771
510
  exports.labelFieldFor = labelFieldFor;
772
- exports.matchesWhere = require_deriveAll.matchesWhere;
773
- exports.monthAnchorDate = monthAnchorDate;
511
+ exports.matchesWhere = require_calendarGrid.matchesWhere;
512
+ exports.monthAnchorDate = require_calendarGrid.monthAnchorDate;
774
513
  exports.nextSortDirection = nextSortDirection;
775
514
  exports.numericSortValue = numericSortValue;
776
- exports.parseIsoDate = parseIsoDate;
777
- exports.parseIsoDateTime = parseIsoDateTime;
778
- exports.parseTimeRange = parseTimeRange;
779
- exports.recordSpan = recordSpan;
515
+ exports.parseIsoDate = require_calendarGrid.parseIsoDate;
516
+ exports.parseIsoDateTime = require_calendarGrid.parseIsoDateTime;
517
+ exports.parseTimeRange = require_calendarGrid.parseTimeRange;
518
+ exports.recordSpan = require_calendarGrid.recordSpan;
780
519
  exports.resolveEnumColor = resolveEnumColor;
781
- exports.resolveIcon = require_deriveAll.resolveIcon;
782
- exports.resolveRowRefs = require_deriveAll.resolveRowRefs;
520
+ exports.resolveIcon = require_calendarGrid.resolveIcon;
521
+ exports.resolveRowRefs = require_calendarGrid.resolveRowRefs;
783
522
  exports.rowFromItem = rowFromItem;
784
- exports.selectDynamicRecord = require_deriveAll.selectDynamicRecord;
523
+ exports.selectDynamicRecord = require_calendarGrid.selectDynamicRecord;
785
524
  exports.shortHexId = shortHexId;
786
525
  exports.sortItems = sortItems;
787
- exports.spanCoversDay = spanCoversDay;
526
+ exports.spanCoversDay = require_calendarGrid.spanCoversDay;
788
527
  exports.stringSortValue = stringSortValue;
789
528
  exports.whenMatches = whenMatches;
790
- exports.ymdKey = ymdKey;
529
+ exports.ymdKey = require_calendarGrid.ymdKey;
791
530
 
792
531
  //# sourceMappingURL=index.cjs.map