@arbidocs/blocks 0.4.127 → 0.4.129

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 (115) hide show
  1. package/README.md +21 -7
  2. package/dist/{StreamedArtifactEditor-EEYAXJ4H.cjs → StreamedArtifactEditor-TQAND4H5.cjs} +6 -5
  3. package/dist/StreamedArtifactEditor-TQAND4H5.cjs.map +1 -0
  4. package/dist/{StreamedArtifactEditor-TDATDYD2.js → StreamedArtifactEditor-XQNANTWM.js} +4 -3
  5. package/dist/StreamedArtifactEditor-XQNANTWM.js.map +1 -0
  6. package/dist/agents/index.cjs +213 -213
  7. package/dist/agents/index.js +2 -2
  8. package/dist/artifacts/ArtifactCodeView.d.ts +6 -0
  9. package/dist/artifacts/ArtifactPreview.d.ts +22 -0
  10. package/dist/artifacts/index.cjs +50 -21
  11. package/dist/artifacts/index.d.ts +3 -0
  12. package/dist/artifacts/index.js +2 -1
  13. package/dist/artifacts/sandbox-policy.d.ts +34 -0
  14. package/dist/artifacts/sandboxDocument.d.ts +7 -0
  15. package/dist/calendar/index.cjs +156 -243
  16. package/dist/calendar/index.cjs.map +1 -1
  17. package/dist/calendar/index.js +8 -151
  18. package/dist/calendar/index.js.map +1 -1
  19. package/dist/chat/index.cjs +90 -73
  20. package/dist/chat/index.d.ts +1 -0
  21. package/dist/chat/index.js +3 -2
  22. package/dist/chat/open-document.d.ts +66 -0
  23. package/dist/{chunk-INW76PEL.cjs → chunk-2YV7FBLO.cjs} +175 -2
  24. package/dist/chunk-2YV7FBLO.cjs.map +1 -0
  25. package/dist/{chunk-DZI7WOUD.cjs → chunk-3BJLNKOB.cjs} +6 -2
  26. package/dist/chunk-3BJLNKOB.cjs.map +1 -0
  27. package/dist/{chunk-KELGOCJA.js → chunk-65S53MZK.js} +174 -5
  28. package/dist/chunk-65S53MZK.js.map +1 -0
  29. package/dist/{chunk-T6I6ZCBE.js → chunk-6BTCDKCK.js} +6 -3
  30. package/dist/chunk-6BTCDKCK.js.map +1 -0
  31. package/dist/{chunk-ZLRQ5K77.cjs → chunk-7423V6RM.cjs} +6 -3
  32. package/dist/chunk-7423V6RM.cjs.map +1 -0
  33. package/dist/{chunk-6Z72CXZR.js → chunk-CJBN5HIS.js} +6 -2
  34. package/dist/chunk-CJBN5HIS.js.map +1 -0
  35. package/dist/{chunk-XFKF3WRN.cjs → chunk-DZYAAL4H.cjs} +2 -2
  36. package/dist/{chunk-XFKF3WRN.cjs.map → chunk-DZYAAL4H.cjs.map} +1 -1
  37. package/dist/chunk-GYCQ3FNL.js +60 -0
  38. package/dist/chunk-GYCQ3FNL.js.map +1 -0
  39. package/dist/{chunk-UUXKB3WQ.js → chunk-H2KQ6OSU.js} +2 -2
  40. package/dist/{chunk-UUXKB3WQ.js.map → chunk-H2KQ6OSU.js.map} +1 -1
  41. package/dist/{chunk-T2CVFK2I.js → chunk-HSFLEVZY.js} +3 -3
  42. package/dist/{chunk-T2CVFK2I.js.map → chunk-HSFLEVZY.js.map} +1 -1
  43. package/dist/{chunk-MCPRNDOJ.cjs → chunk-JLTXVW25.cjs} +3 -3
  44. package/dist/{chunk-MCPRNDOJ.cjs.map → chunk-JLTXVW25.cjs.map} +1 -1
  45. package/dist/chunk-NS4JD2VR.js +22 -0
  46. package/dist/chunk-NS4JD2VR.js.map +1 -0
  47. package/dist/chunk-SWQX6CTT.cjs +65 -0
  48. package/dist/chunk-SWQX6CTT.cjs.map +1 -0
  49. package/dist/chunk-TGJNPKST.js +153 -0
  50. package/dist/chunk-TGJNPKST.js.map +1 -0
  51. package/dist/chunk-TGWTLNXW.cjs +177 -0
  52. package/dist/chunk-TGWTLNXW.cjs.map +1 -0
  53. package/dist/chunk-VG24E4JJ.cjs +26 -0
  54. package/dist/chunk-VG24E4JJ.cjs.map +1 -0
  55. package/dist/components/DroppableContainer.d.ts +6 -0
  56. package/dist/components/GridRowNavigator.d.ts +29 -0
  57. package/dist/components/LoadingIndicator.d.ts +21 -0
  58. package/dist/components/RowNavigatorControls.d.ts +29 -0
  59. package/dist/components/SharedCell.d.ts +27 -0
  60. package/dist/connect/docx.cjs +4 -3
  61. package/dist/connect/docx.cjs.map +1 -1
  62. package/dist/connect/docx.js +3 -2
  63. package/dist/connect/docx.js.map +1 -1
  64. package/dist/connect/index.cjs +22 -20
  65. package/dist/connect/index.cjs.map +1 -1
  66. package/dist/connect/index.js +12 -10
  67. package/dist/connect/index.js.map +1 -1
  68. package/dist/connection/mail/types.d.ts +2 -6
  69. package/dist/facts/index.cjs +5 -23
  70. package/dist/facts/index.cjs.map +1 -1
  71. package/dist/facts/index.d.ts +0 -1
  72. package/dist/facts/index.js +6 -22
  73. package/dist/facts/index.js.map +1 -1
  74. package/dist/index.cjs +616 -417
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.d.ts +5 -0
  77. package/dist/index.js +189 -11
  78. package/dist/index.js.map +1 -1
  79. package/dist/sandboxDocument-JLEETIWW.js +71 -0
  80. package/dist/sandboxDocument-JLEETIWW.js.map +1 -0
  81. package/dist/sandboxDocument-WQUNODSC.cjs +76 -0
  82. package/dist/sandboxDocument-WQUNODSC.cjs.map +1 -0
  83. package/dist/settings/DraggableHeader.d.ts +10 -0
  84. package/dist/settings/FilterChip.d.ts +15 -0
  85. package/dist/settings/MessageJsonTree.d.ts +7 -0
  86. package/dist/settings/index.cjs +248 -5
  87. package/dist/settings/index.cjs.map +1 -1
  88. package/dist/settings/index.d.ts +3 -0
  89. package/dist/settings/index.js +247 -7
  90. package/dist/settings/index.js.map +1 -1
  91. package/dist/settings/message-schema-hints.d.ts +19 -0
  92. package/dist/studio/index.cjs +3 -2
  93. package/dist/studio/index.cjs.map +1 -1
  94. package/dist/studio/index.js +2 -1
  95. package/dist/studio/index.js.map +1 -1
  96. package/dist/workflow-canvas/index.cjs +9 -9
  97. package/dist/workflow-canvas/index.js +2 -2
  98. package/dist/workspaces/index.cjs +39 -0
  99. package/dist/workspaces/index.cjs.map +1 -1
  100. package/dist/workspaces/index.d.ts +1 -0
  101. package/dist/workspaces/index.js +36 -1
  102. package/dist/workspaces/index.js.map +1 -1
  103. package/dist/workspaces/workspace-type.d.ts +29 -0
  104. package/node_modules/@arbidocs/coedit/package.json +1 -1
  105. package/package.json +6 -5
  106. package/src/docx/README.md +7 -3
  107. package/dist/StreamedArtifactEditor-EEYAXJ4H.cjs.map +0 -1
  108. package/dist/StreamedArtifactEditor-TDATDYD2.js.map +0 -1
  109. package/dist/chunk-6Z72CXZR.js.map +0 -1
  110. package/dist/chunk-DZI7WOUD.cjs.map +0 -1
  111. package/dist/chunk-INW76PEL.cjs.map +0 -1
  112. package/dist/chunk-KELGOCJA.js.map +0 -1
  113. package/dist/chunk-T6I6ZCBE.js.map +0 -1
  114. package/dist/chunk-ZLRQ5K77.cjs.map +0 -1
  115. package/dist/facts/timezone.d.ts +0 -4
@@ -0,0 +1,22 @@
1
+ "use client";
2
+ // src/artifacts/sandbox-policy.ts
3
+ var ARTIFACT_SANDBOX = "allow-scripts";
4
+ var ARTIFACT_CSP = [
5
+ "default-src 'none'",
6
+ "script-src 'unsafe-inline'",
7
+ "style-src 'unsafe-inline'",
8
+ "img-src data: blob:",
9
+ "font-src data:",
10
+ "media-src data: blob:",
11
+ "connect-src 'none'",
12
+ "frame-src 'none'",
13
+ "object-src 'none'",
14
+ "worker-src 'none'",
15
+ "form-action 'none'",
16
+ "base-uri 'none'"
17
+ ].join("; ");
18
+ var ARTIFACT_MESSAGE_TAG = "__arbiArtifact";
19
+
20
+ export { ARTIFACT_CSP, ARTIFACT_MESSAGE_TAG, ARTIFACT_SANDBOX };
21
+ //# sourceMappingURL=chunk-NS4JD2VR.js.map
22
+ //# sourceMappingURL=chunk-NS4JD2VR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/artifacts/sandbox-policy.ts"],"names":[],"mappings":";AAOO,IAAM,gBAAA,GAAmB;AAEzB,IAAM,YAAA,GAAe;AAAA,EAC1B,oBAAA;AAAA,EACA,4BAAA;AAAA,EACA,2BAAA;AAAA,EACA,qBAAA;AAAA,EACA,gBAAA;AAAA,EACA,uBAAA;AAAA,EACA,oBAAA;AAAA,EACA,kBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAA,CAAE,KAAK,IAAI;AAGJ,IAAM,oBAAA,GAAuB","file":"chunk-NS4JD2VR.js","sourcesContent":["/**\n * The artifact sandbox's fixed policy: iframe sandbox flags, CSP, the message marker and the runtime\n * shape. Kept apart from `sandboxDocument` (which pulls in the JSX compiler) so the preview can render\n * its frame attributes without loading the compiler until an artifact is actually shown.\n */\n\n/** Exactly this and nothing else. Do not add allow-same-origin (it voids the sandbox). */\nexport const ARTIFACT_SANDBOX = 'allow-scripts'\n\nexport const ARTIFACT_CSP = [\n \"default-src 'none'\",\n \"script-src 'unsafe-inline'\",\n \"style-src 'unsafe-inline'\",\n 'img-src data: blob:',\n 'font-src data:',\n 'media-src data: blob:',\n \"connect-src 'none'\",\n \"frame-src 'none'\",\n \"object-src 'none'\",\n \"worker-src 'none'\",\n \"form-action 'none'\",\n \"base-uri 'none'\",\n].join('; ')\n\n/** Marker on every message the sandbox posts to the app. */\nexport const ARTIFACT_MESSAGE_TAG = '__arbiArtifact'\n\n/**\n * Source text of the generated runtime (scripts/build-artifact-runtime.mjs). It is inlined into the\n * document: a frame with an opaque origin cannot load blob: URLs from the app, and inlining needs no\n * network or CSP exception.\n */\nexport interface ArtifactRuntime {\n /** React + ReactDOM as one IIFE. */\n react: string\n /** Tailwind v4 browser build. */\n tailwind: string\n}\n\nexport type ArtifactSandboxMessage =\n | { [ARTIFACT_MESSAGE_TAG]: true; type: 'ready' }\n | { [ARTIFACT_MESSAGE_TAG]: true; type: 'console'; level: string; text: string }\n | { [ARTIFACT_MESSAGE_TAG]: true; type: 'error'; text: string }\n"]}
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('react');
5
+ var artifacts = require('@arbidocs/react/artifacts');
6
+
7
+ // src/chat/open-document.ts
8
+ function savedDocumentIdFor(input) {
9
+ const { documentId, isDraft, isStreaming, isBlobArtifact, documentData } = input;
10
+ if (!documentId || isDraft || isStreaming || isBlobArtifact) return null;
11
+ if (documentData?.wp_type !== "artifact" && !documentData?.file_name?.toLowerCase().endsWith(".docx"))
12
+ return null;
13
+ if (documentData.external_id !== documentId) return null;
14
+ return documentId;
15
+ }
16
+ var entries = [];
17
+ var listeners = /* @__PURE__ */ new Set();
18
+ function subscribe(listener) {
19
+ listeners.add(listener);
20
+ return () => listeners.delete(listener);
21
+ }
22
+ function emit() {
23
+ listeners.forEach((l) => l());
24
+ }
25
+ var top = () => entries[entries.length - 1];
26
+ function useRegisterOpenDocument(registration) {
27
+ const latest = react.useRef(registration);
28
+ react.useEffect(() => {
29
+ latest.current = registration;
30
+ });
31
+ const { documentId } = registration;
32
+ react.useEffect(() => {
33
+ if (!documentId) return;
34
+ const entry = { documentId, current: () => latest.current };
35
+ entries = [...entries, entry];
36
+ emit();
37
+ return () => {
38
+ entries = entries.filter((e) => e !== entry);
39
+ emit();
40
+ };
41
+ }, [documentId]);
42
+ }
43
+ function useOpenDocumentId() {
44
+ return react.useSyncExternalStore(
45
+ subscribe,
46
+ () => top()?.documentId ?? null,
47
+ () => null
48
+ );
49
+ }
50
+ function takeOpenDocumentForTurn(options) {
51
+ const entry = top();
52
+ if (!entry) return null;
53
+ const { shownId, showLive, workspaceId } = entry.current();
54
+ if (options?.workspaceId && workspaceId && options.workspaceId !== workspaceId) return null;
55
+ if (shownId && shownId !== entry.documentId && artifacts.parseVersionRef(shownId).docId === entry.documentId)
56
+ showLive?.();
57
+ return entry.documentId;
58
+ }
59
+
60
+ exports.savedDocumentIdFor = savedDocumentIdFor;
61
+ exports.takeOpenDocumentForTurn = takeOpenDocumentForTurn;
62
+ exports.useOpenDocumentId = useOpenDocumentId;
63
+ exports.useRegisterOpenDocument = useRegisterOpenDocument;
64
+ //# sourceMappingURL=chunk-SWQX6CTT.cjs.map
65
+ //# sourceMappingURL=chunk-SWQX6CTT.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chat/open-document.ts"],"names":["useRef","useEffect","useSyncExternalStore","parseVersionRef"],"mappings":";;;;;;AA2CO,SAAS,mBAAmB,KAAA,EAA0C;AAC3E,EAAA,MAAM,EAAE,UAAA,EAAY,OAAA,EAAS,WAAA,EAAa,cAAA,EAAgB,cAAa,GAAI,KAAA;AAC3E,EAAA,IAAI,CAAC,UAAA,IAAc,OAAA,IAAW,WAAA,IAAe,gBAAgB,OAAO,IAAA;AACpE,EAAA,IACE,YAAA,EAAc,YAAY,UAAA,IAC1B,CAAC,cAAc,SAAA,EAAW,WAAA,EAAY,CAAE,QAAA,CAAS,OAAO,CAAA;AAExD,IAAA,OAAO,IAAA;AAET,EAAA,IAAI,YAAA,CAAa,WAAA,KAAgB,UAAA,EAAY,OAAO,IAAA;AACpD,EAAA,OAAO,UAAA;AACT;AAkBA,IAAI,UAAmB,EAAC;AACxB,IAAM,SAAA,uBAAgB,GAAA,EAAgB;AAEtC,SAAS,UAAU,QAAA,EAAkC;AACnD,EAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,EAAA,OAAO,MAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AACxC;AAEA,SAAS,IAAA,GAAO;AACd,EAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA;AAC9B;AAEA,IAAM,GAAA,GAAM,MAAyB,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAC,CAAA;AAMxD,SAAS,wBAAwB,YAAA,EAA8C;AACpF,EAAA,MAAM,MAAA,GAASA,aAAO,YAAY,CAAA;AAClC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,OAAA,GAAU,YAAA;AAAA,EACnB,CAAC,CAAA;AACD,EAAA,MAAM,EAAE,YAAW,GAAI,YAAA;AACvB,EAAAA,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,UAAA,EAAY;AACjB,IAAA,MAAM,QAAe,EAAE,UAAA,EAAY,OAAA,EAAS,MAAM,OAAO,OAAA,EAAQ;AACjE,IAAA,OAAA,GAAU,CAAC,GAAG,OAAA,EAAS,KAAK,CAAA;AAC5B,IAAA,IAAA,EAAK;AACL,IAAA,OAAO,MAAM;AACX,MAAA,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,MAAM,KAAK,CAAA;AAC3C,MAAA,IAAA,EAAK;AAAA,IACP,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AACjB;AAGO,SAAS,iBAAA,GAAmC;AACjD,EAAA,OAAOC,0BAAA;AAAA,IACL,SAAA;AAAA,IACA,MAAM,GAAA,EAAI,EAAG,UAAA,IAAc,IAAA;AAAA,IAC3B,MAAM;AAAA,GACR;AACF;AAQO,SAAS,wBAAwB,OAAA,EAA0D;AAChG,EAAA,MAAM,QAAQ,GAAA,EAAI;AAClB,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAU,WAAA,EAAY,GAAI,MAAM,OAAA,EAAQ;AACzD,EAAA,IAAI,SAAS,WAAA,IAAe,WAAA,IAAe,OAAA,CAAQ,WAAA,KAAgB,aAAa,OAAO,IAAA;AACvF,EAAA,IACE,OAAA,IACA,YAAY,KAAA,CAAM,UAAA,IAClBC,0BAAgB,OAAO,CAAA,CAAE,UAAU,KAAA,CAAM,UAAA;AAEzC,IAAA,QAAA,IAAW;AACb,EAAA,OAAO,KAAA,CAAM,UAAA;AACf","file":"chunk-SWQX6CTT.cjs","sourcesContent":["import { useEffect, useRef, useSyncExternalStore } from 'react'\nimport { parseVersionRef } from '@arbidocs/react/artifacts'\n\n/**\n * Drafting mode: the saved document open beside the chat is what a chat turn is about.\n *\n * A viewer registers the document it shows (`useRegisterOpenDocument`); every assistant turn names\n * it (`active_artifact_ext_id`, read with `takeOpenDocumentForTurn` as the question is sent), so the\n * server binds the live document to the turn: a Word document is read on demand and edited as\n * tracked changes in the open editor, and what the assistant saves becomes a child version of it.\n * The request carries a reference, never the content.\n *\n * The open document is always the subject, also while one of its earlier versions is on screen\n * read-only: a version still names its document. Sending a turn then returns the viewer to the live\n * document (`showLive`), where the assistant's edits appear as they are made. (Pinning a specific\n * version as a source is a separate feature: it does not go through here.)\n *\n * A module-level registry (not React context), like `useChatSurface`, so a viewer and a chat agree\n * wherever they sit in the tree; the most recently opened document wins and closing it hands back\n * to the one before.\n */\n\n/** What a viewer knows about the document it shows. */\nexport interface SavedDocumentInput {\n /** The document (`doc-…`), never a version reference. */\n documentId: string | null | undefined\n /** An unsaved draft (client-minted id, no backend record). */\n isDraft: boolean\n /** Still streaming: nothing is persisted yet. */\n isStreaming: boolean\n /** An image, audio or video artifact: there is no text to draft in. */\n isBlobArtifact: boolean\n /** The loaded document record. */\n documentData:\n | { external_id?: string | null; wp_type?: string | null; file_name?: string | null }\n | null\n | undefined\n}\n\n/**\n * The saved, content-backed document a chat can draft in, or null. Only a saved artifact or Word\n * document counts: drafts, an artifact still streaming and blob artifacts do not.\n */\nexport function savedDocumentIdFor(input: SavedDocumentInput): string | null {\n const { documentId, isDraft, isStreaming, isBlobArtifact, documentData } = input\n if (!documentId || isDraft || isStreaming || isBlobArtifact) return null\n if (\n documentData?.wp_type !== 'artifact' &&\n !documentData?.file_name?.toLowerCase().endsWith('.docx')\n )\n return null\n // A stale record of the previously viewed document is not this one.\n if (documentData.external_id !== documentId) return null\n return documentId\n}\n\nexport interface OpenDocumentRegistration {\n /** The saved document the viewer shows (`doc-…`); null or empty registers nothing. */\n documentId: string | null | undefined\n /** What is on screen: the document itself, or one of its earlier versions (`doc-…@v2`). */\n shownId?: string | null\n /** Show the live document again. Called when a turn starts while an earlier version is shown. */\n showLive?: () => void\n /** The workspace the document belongs to; a chat in another workspace does not draft in it. */\n workspaceId?: string | null\n}\n\ninterface Entry {\n documentId: string\n current: () => OpenDocumentRegistration\n}\n\nlet entries: Entry[] = []\nconst listeners = new Set<() => void>()\n\nfunction subscribe(listener: () => void): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n\nfunction emit() {\n listeners.forEach((l) => l())\n}\n\nconst top = (): Entry | undefined => entries[entries.length - 1]\n\n/**\n * Registers the document a viewer shows as the open document while the caller is mounted and\n * `documentId` is set. Pass `savedDocumentIdFor(...)`, or the id of a document known to be saved.\n */\nexport function useRegisterOpenDocument(registration: OpenDocumentRegistration): void {\n const latest = useRef(registration)\n useEffect(() => {\n latest.current = registration\n })\n const { documentId } = registration\n useEffect(() => {\n if (!documentId) return\n const entry: Entry = { documentId, current: () => latest.current }\n entries = [...entries, entry]\n emit()\n return () => {\n entries = entries.filter((e) => e !== entry)\n emit()\n }\n }, [documentId])\n}\n\n/** The open document's id, or null. Re-renders when another document opens or it closes. */\nexport function useOpenDocumentId(): string | null {\n return useSyncExternalStore(\n subscribe,\n () => top()?.documentId ?? null,\n () => null\n )\n}\n\n/**\n * The document an assistant turn about to be sent drafts in, or null. Call it once per turn as the\n * question is sent: when an earlier version of the document is on screen, the viewer returns to the\n * live document, where the assistant's edits appear. With `workspaceId`, a document registered in\n * another workspace is not named (and its viewer is left alone).\n */\nexport function takeOpenDocumentForTurn(options?: { workspaceId?: string | null }): string | null {\n const entry = top()\n if (!entry) return null\n const { shownId, showLive, workspaceId } = entry.current()\n if (options?.workspaceId && workspaceId && options.workspaceId !== workspaceId) return null\n if (\n shownId &&\n shownId !== entry.documentId &&\n parseVersionRef(shownId).docId === entry.documentId\n )\n showLive?.()\n return entry.documentId\n}\n"]}
@@ -0,0 +1,153 @@
1
+ "use client";
2
+ import { Temporal } from 'temporal-polyfill';
3
+
4
+ // src/calendar/zone.ts
5
+ var pad2 = (n) => String(n).padStart(2, "0");
6
+ var pad4 = (n) => String(n).padStart(4, "0");
7
+ function isValidTimeZone(zone) {
8
+ if (!zone) return false;
9
+ try {
10
+ Temporal.Now.instant().toZonedDateTimeISO(zone);
11
+ return true;
12
+ } catch {
13
+ return false;
14
+ }
15
+ }
16
+ function safeZone(zone, fallback = "UTC") {
17
+ if (isValidTimeZone(zone)) return zone;
18
+ return isValidTimeZone(fallback) ? fallback : "UTC";
19
+ }
20
+ function toPlainDateTime(wall) {
21
+ return /^\d{4}-\d{2}-\d{2}$/.test(wall) ? Temporal.PlainDate.from(wall).toPlainDateTime() : Temporal.PlainDateTime.from(wall);
22
+ }
23
+ function wallToUtc(wall, zone) {
24
+ const zdt = toPlainDateTime(wall).toZonedDateTime(safeZone(zone), {
25
+ disambiguation: "compatible"
26
+ });
27
+ return zdt.toInstant().toString();
28
+ }
29
+ function wallToEpochMs(wall, zone) {
30
+ return toPlainDateTime(wall).toZonedDateTime(safeZone(zone), { disambiguation: "compatible" }).epochMilliseconds;
31
+ }
32
+ function instantOf(utc) {
33
+ if (typeof utc === "number") return Temporal.Instant.fromEpochMilliseconds(utc);
34
+ if (utc instanceof Date) return Temporal.Instant.fromEpochMilliseconds(utc.getTime());
35
+ return Temporal.Instant.from(utc);
36
+ }
37
+ function zoned(utc, zone) {
38
+ return instantOf(utc).toZonedDateTimeISO(safeZone(zone));
39
+ }
40
+ function utcToWall(utc, zone) {
41
+ const z = zoned(utc, zone);
42
+ return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}T${pad2(z.hour)}:${pad2(z.minute)}`;
43
+ }
44
+ function utcToDate(utc, zone) {
45
+ const z = zoned(utc, zone);
46
+ return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}`;
47
+ }
48
+ function utcToTime(utc, zone) {
49
+ const z = zoned(utc, zone);
50
+ return `${pad2(z.hour)}:${pad2(z.minute)}`;
51
+ }
52
+ function convertWall(wall, fromZone, toZone) {
53
+ return utcToWall(wallToUtc(wall, fromZone), toZone);
54
+ }
55
+ function todayInZone(zone, now = Date.now()) {
56
+ return utcToDate(now, zone);
57
+ }
58
+ function addDays(date, days) {
59
+ return Temporal.PlainDate.from(date).add({ days }).toString();
60
+ }
61
+ function addMonths(date, months) {
62
+ return Temporal.PlainDate.from(date).add({ months }).toString();
63
+ }
64
+ function diffDays(a, b) {
65
+ return Temporal.PlainDate.from(a).until(Temporal.PlainDate.from(b), { largestUnit: "days" }).days;
66
+ }
67
+ function dayOfWeekSun0(date) {
68
+ return Temporal.PlainDate.from(date).dayOfWeek % 7;
69
+ }
70
+ function startOfWeek(date, weekStart) {
71
+ const back = (dayOfWeekSun0(date) - weekStart + 7) % 7;
72
+ return addDays(date, -back);
73
+ }
74
+ function isoWeekNumber(date) {
75
+ return Temporal.PlainDate.from(date).weekOfYear ?? 1;
76
+ }
77
+ function zoneOffsetMinutes(zone, at = Date.now()) {
78
+ return Math.round(zoned(at, zone).offsetNanoseconds / 6e10);
79
+ }
80
+ function zoneOffsetLabel(zone, at = Date.now()) {
81
+ const total = zoneOffsetMinutes(zone, at);
82
+ if (total === 0) return "GMT";
83
+ const sign = total > 0 ? "+" : "-";
84
+ const abs = Math.abs(total);
85
+ const h = Math.floor(abs / 60);
86
+ const m = abs % 60;
87
+ return `GMT${sign}${h}${m ? `:${pad2(m)}` : ""}`;
88
+ }
89
+ function zoneCity(zone) {
90
+ const last = zone.split("/").pop() ?? zone;
91
+ return last.replace(/_/g, " ");
92
+ }
93
+ function listTimeZones() {
94
+ try {
95
+ const fn = Intl.supportedValuesOf;
96
+ const zones = fn ? fn("timeZone") : [];
97
+ if (zones.length) return zones.includes("UTC") ? zones : ["UTC", ...zones];
98
+ } catch {
99
+ }
100
+ return [
101
+ "UTC",
102
+ "Europe/London",
103
+ "Europe/Paris",
104
+ "Europe/Berlin",
105
+ "America/New_York",
106
+ "America/Chicago",
107
+ "America/Denver",
108
+ "America/Los_Angeles",
109
+ "Asia/Tokyo",
110
+ "Asia/Singapore",
111
+ "Australia/Sydney"
112
+ ];
113
+ }
114
+ function detectTimeZone() {
115
+ try {
116
+ return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
117
+ } catch {
118
+ return "UTC";
119
+ }
120
+ }
121
+ function formatInZone(utc, zone, options, locale) {
122
+ const ms = instantOf(utc).epochMilliseconds;
123
+ return new Intl.DateTimeFormat(locale, { ...options, timeZone: safeZone(zone) }).format(ms);
124
+ }
125
+ function formatPlainDate(date, options, locale) {
126
+ return new Intl.DateTimeFormat(locale, { ...options, timeZone: "UTC" }).format(
127
+ Date.parse(`${date}T12:00:00Z`)
128
+ );
129
+ }
130
+ function epochToWallArray(ms, zone) {
131
+ const z = Temporal.Instant.fromEpochMilliseconds(ms).toZonedDateTimeISO(zone);
132
+ return [z.year, z.month - 1, z.day, z.hour, z.minute, z.second, z.millisecond];
133
+ }
134
+ function wallArrayOffset(a, zone) {
135
+ const norm = new Date(
136
+ Date.UTC(a[0], a[1] ?? 0, a[2] ?? 1, a[3] ?? 0, a[4] ?? 0, a[5] ?? 0, a[6] ?? 0)
137
+ );
138
+ const pdt = new Temporal.PlainDateTime(
139
+ norm.getUTCFullYear(),
140
+ norm.getUTCMonth() + 1,
141
+ norm.getUTCDate(),
142
+ norm.getUTCHours(),
143
+ norm.getUTCMinutes(),
144
+ norm.getUTCSeconds(),
145
+ norm.getUTCMilliseconds()
146
+ );
147
+ const zdt = pdt.toZonedDateTime(zone, { disambiguation: "compatible" });
148
+ return Math.round(zdt.offsetNanoseconds / 6e10);
149
+ }
150
+
151
+ export { addDays, addMonths, convertWall, detectTimeZone, diffDays, epochToWallArray, formatInZone, formatPlainDate, isValidTimeZone, isoWeekNumber, listTimeZones, safeZone, startOfWeek, todayInZone, utcToDate, utcToTime, utcToWall, wallArrayOffset, wallToEpochMs, wallToUtc, zoneCity, zoneOffsetLabel, zoneOffsetMinutes };
152
+ //# sourceMappingURL=chunk-TGJNPKST.js.map
153
+ //# sourceMappingURL=chunk-TGJNPKST.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/calendar/zone.ts"],"names":[],"mappings":"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","file":"chunk-TGJNPKST.js","sourcesContent":["/**\n * Zone math for the calendar. Every conversion between a wall time in a named IANA zone and a UTC\n * instant goes through Temporal (the polyfill, imported as a module: nothing global is patched),\n * so DST gaps/overlaps resolve the way RFC 5545 says (`compatible`: a skipped time moves forward,\n * a repeated time takes the earlier instant). Nothing here reads the browser's local zone.\n */\nimport { Temporal } from 'temporal-polyfill'\n\nconst pad2 = (n: number) => String(n).padStart(2, '0')\nconst pad4 = (n: number) => String(n).padStart(4, '0')\n\n/** True when `zone` is a time zone the runtime can resolve. */\nexport function isValidTimeZone(zone: string | null | undefined): zone is string {\n if (!zone) return false\n try {\n Temporal.Now.instant().toZonedDateTimeISO(zone)\n return true\n } catch {\n return false\n }\n}\n\n/** `zone` when valid, else `fallback` (else UTC). */\nexport function safeZone(zone: string | null | undefined, fallback = 'UTC'): string {\n if (isValidTimeZone(zone)) return zone\n return isValidTimeZone(fallback) ? fallback : 'UTC'\n}\n\nfunction toPlainDateTime(wall: string): Temporal.PlainDateTime {\n // Accept `YYYY-MM-DDTHH:MM`, `…:SS` and a bare date (midnight).\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(wall)\n ? Temporal.PlainDate.from(wall).toPlainDateTime()\n : Temporal.PlainDateTime.from(wall)\n}\n\n/** The instant a wall time in `zone` names, as an ISO string ending in `Z` (no milliseconds unless set). */\nexport function wallToUtc(wall: string, zone: string): string {\n const zdt = toPlainDateTime(wall).toZonedDateTime(safeZone(zone), {\n disambiguation: 'compatible',\n })\n return zdt.toInstant().toString()\n}\n\n/** Epoch milliseconds of a wall time in `zone`. */\nexport function wallToEpochMs(wall: string, zone: string): number {\n return toPlainDateTime(wall).toZonedDateTime(safeZone(zone), { disambiguation: 'compatible' })\n .epochMilliseconds\n}\n\nfunction instantOf(utc: string | Date | number): Temporal.Instant {\n if (typeof utc === 'number') return Temporal.Instant.fromEpochMilliseconds(utc)\n if (utc instanceof Date) return Temporal.Instant.fromEpochMilliseconds(utc.getTime())\n return Temporal.Instant.from(utc)\n}\n\n/** The zoned date-time of an instant. */\nexport function zoned(utc: string | Date | number, zone: string): Temporal.ZonedDateTime {\n return instantOf(utc).toZonedDateTimeISO(safeZone(zone))\n}\n\n/** `YYYY-MM-DDTHH:MM` wall time of an instant in `zone`. */\nexport function utcToWall(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}T${pad2(z.hour)}:${pad2(z.minute)}`\n}\n\n/** `YYYY-MM-DD` date of an instant in `zone`. */\nexport function utcToDate(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}`\n}\n\n/** `HH:MM` of an instant in `zone`. */\nexport function utcToTime(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad2(z.hour)}:${pad2(z.minute)}`\n}\n\n/** Convert a wall time from one zone to the same instant's wall time in another. */\nexport function convertWall(wall: string, fromZone: string, toZone: string): string {\n return utcToWall(wallToUtc(wall, fromZone), toZone)\n}\n\n/** Today's date in `zone`. */\nexport function todayInZone(zone: string, now: Date | number = Date.now()): string {\n return utcToDate(now, zone)\n}\n\n/** Calendar arithmetic on a `YYYY-MM-DD` date. */\nexport function addDays(date: string, days: number): string {\n return Temporal.PlainDate.from(date).add({ days }).toString()\n}\n\nexport function addMonths(date: string, months: number): string {\n return Temporal.PlainDate.from(date).add({ months }).toString()\n}\n\n/** Whole days from `a` to `b` (both `YYYY-MM-DD`). */\nexport function diffDays(a: string, b: string): number {\n return Temporal.PlainDate.from(a).until(Temporal.PlainDate.from(b), { largestUnit: 'days' }).days\n}\n\n/** 0 = Sunday … 6 = Saturday, for a `YYYY-MM-DD` date. */\nexport function dayOfWeekSun0(date: string): number {\n return Temporal.PlainDate.from(date).dayOfWeek % 7\n}\n\n/** The first day of the week containing `date`, for a week starting on `weekStart` (0 = Sunday). */\nexport function startOfWeek(date: string, weekStart: number): string {\n const back = (dayOfWeekSun0(date) - weekStart + 7) % 7\n return addDays(date, -back)\n}\n\n/** ISO-8601 week number of a `YYYY-MM-DD` date. */\nexport function isoWeekNumber(date: string): number {\n return Temporal.PlainDate.from(date).weekOfYear ?? 1\n}\n\n/** Offset of `zone` at an instant, in minutes east of UTC. */\nexport function zoneOffsetMinutes(zone: string, at: string | Date | number = Date.now()): number {\n return Math.round(zoned(at, zone).offsetNanoseconds / 60_000_000_000)\n}\n\n/** `GMT+5:30` / `GMT-4` / `GMT` label for `zone` at an instant. */\nexport function zoneOffsetLabel(zone: string, at: string | Date | number = Date.now()): string {\n const total = zoneOffsetMinutes(zone, at)\n if (total === 0) return 'GMT'\n const sign = total > 0 ? '+' : '-'\n const abs = Math.abs(total)\n const h = Math.floor(abs / 60)\n const m = abs % 60\n return `GMT${sign}${h}${m ? `:${pad2(m)}` : ''}`\n}\n\n/** Short city-ish label for a zone: `America/New_York` → `New York`. */\nexport function zoneCity(zone: string): string {\n const last = zone.split('/').pop() ?? zone\n return last.replace(/_/g, ' ')\n}\n\n/** Every IANA zone the runtime knows (falls back to a short list on old engines). */\nexport function listTimeZones(): string[] {\n try {\n const fn = (Intl as unknown as { supportedValuesOf?: (k: string) => string[] })\n .supportedValuesOf\n const zones = fn ? fn('timeZone') : []\n if (zones.length) return zones.includes('UTC') ? zones : ['UTC', ...zones]\n } catch {\n // fall through\n }\n return [\n 'UTC',\n 'Europe/London',\n 'Europe/Paris',\n 'Europe/Berlin',\n 'America/New_York',\n 'America/Chicago',\n 'America/Denver',\n 'America/Los_Angeles',\n 'Asia/Tokyo',\n 'Asia/Singapore',\n 'Australia/Sydney',\n ]\n}\n\n/** The viewer's zone (only as a default for a new user; rendering always uses an explicit zone). */\nexport function detectTimeZone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'\n } catch {\n return 'UTC'\n }\n}\n\n/** Format an instant in `zone` with Intl (never the browser zone). */\nexport function formatInZone(\n utc: string | Date | number,\n zone: string,\n options: Intl.DateTimeFormatOptions,\n locale?: string\n): string {\n const ms = instantOf(utc).epochMilliseconds\n return new Intl.DateTimeFormat(locale, { ...options, timeZone: safeZone(zone) }).format(ms)\n}\n\n/** Format a `YYYY-MM-DD` date (zone-free: rendered at UTC noon so no zone can shift the day). */\nexport function formatPlainDate(\n date: string,\n options: Intl.DateTimeFormatOptions,\n locale?: string\n): string {\n return new Intl.DateTimeFormat(locale, { ...options, timeZone: 'UTC' }).format(\n Date.parse(`${date}T12:00:00Z`)\n )\n}\n\n/** Wall-clock array FullCalendar's NamedTimeZoneImpl speaks: [y, m0, d, h, min, s, ms]. */\nexport function epochToWallArray(ms: number, zone: string): number[] {\n const z = Temporal.Instant.fromEpochMilliseconds(ms).toZonedDateTimeISO(zone)\n return [z.year, z.month - 1, z.day, z.hour, z.minute, z.second, z.millisecond]\n}\n\n/** Offset (minutes east of UTC) for a wall-clock array in `zone`, resolving gaps `compatible`. */\nexport function wallArrayOffset(a: number[], zone: string): number {\n // FullCalendar may pass out-of-range parts (e.g. hour 24): normalise via a UTC Date first.\n const norm = new Date(\n Date.UTC(a[0], a[1] ?? 0, a[2] ?? 1, a[3] ?? 0, a[4] ?? 0, a[5] ?? 0, a[6] ?? 0)\n )\n const pdt = new Temporal.PlainDateTime(\n norm.getUTCFullYear(),\n norm.getUTCMonth() + 1,\n norm.getUTCDate(),\n norm.getUTCHours(),\n norm.getUTCMinutes(),\n norm.getUTCSeconds(),\n norm.getUTCMilliseconds()\n )\n const zdt = pdt.toZonedDateTime(zone, { disambiguation: 'compatible' })\n return Math.round(zdt.offsetNanoseconds / 60_000_000_000)\n}\n"]}
@@ -0,0 +1,177 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var temporalPolyfill = require('temporal-polyfill');
5
+
6
+ // src/calendar/zone.ts
7
+ var pad2 = (n) => String(n).padStart(2, "0");
8
+ var pad4 = (n) => String(n).padStart(4, "0");
9
+ function isValidTimeZone(zone) {
10
+ if (!zone) return false;
11
+ try {
12
+ temporalPolyfill.Temporal.Now.instant().toZonedDateTimeISO(zone);
13
+ return true;
14
+ } catch {
15
+ return false;
16
+ }
17
+ }
18
+ function safeZone(zone, fallback = "UTC") {
19
+ if (isValidTimeZone(zone)) return zone;
20
+ return isValidTimeZone(fallback) ? fallback : "UTC";
21
+ }
22
+ function toPlainDateTime(wall) {
23
+ return /^\d{4}-\d{2}-\d{2}$/.test(wall) ? temporalPolyfill.Temporal.PlainDate.from(wall).toPlainDateTime() : temporalPolyfill.Temporal.PlainDateTime.from(wall);
24
+ }
25
+ function wallToUtc(wall, zone) {
26
+ const zdt = toPlainDateTime(wall).toZonedDateTime(safeZone(zone), {
27
+ disambiguation: "compatible"
28
+ });
29
+ return zdt.toInstant().toString();
30
+ }
31
+ function wallToEpochMs(wall, zone) {
32
+ return toPlainDateTime(wall).toZonedDateTime(safeZone(zone), { disambiguation: "compatible" }).epochMilliseconds;
33
+ }
34
+ function instantOf(utc) {
35
+ if (typeof utc === "number") return temporalPolyfill.Temporal.Instant.fromEpochMilliseconds(utc);
36
+ if (utc instanceof Date) return temporalPolyfill.Temporal.Instant.fromEpochMilliseconds(utc.getTime());
37
+ return temporalPolyfill.Temporal.Instant.from(utc);
38
+ }
39
+ function zoned(utc, zone) {
40
+ return instantOf(utc).toZonedDateTimeISO(safeZone(zone));
41
+ }
42
+ function utcToWall(utc, zone) {
43
+ const z = zoned(utc, zone);
44
+ return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}T${pad2(z.hour)}:${pad2(z.minute)}`;
45
+ }
46
+ function utcToDate(utc, zone) {
47
+ const z = zoned(utc, zone);
48
+ return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}`;
49
+ }
50
+ function utcToTime(utc, zone) {
51
+ const z = zoned(utc, zone);
52
+ return `${pad2(z.hour)}:${pad2(z.minute)}`;
53
+ }
54
+ function convertWall(wall, fromZone, toZone) {
55
+ return utcToWall(wallToUtc(wall, fromZone), toZone);
56
+ }
57
+ function todayInZone(zone, now = Date.now()) {
58
+ return utcToDate(now, zone);
59
+ }
60
+ function addDays(date, days) {
61
+ return temporalPolyfill.Temporal.PlainDate.from(date).add({ days }).toString();
62
+ }
63
+ function addMonths(date, months) {
64
+ return temporalPolyfill.Temporal.PlainDate.from(date).add({ months }).toString();
65
+ }
66
+ function diffDays(a, b) {
67
+ return temporalPolyfill.Temporal.PlainDate.from(a).until(temporalPolyfill.Temporal.PlainDate.from(b), { largestUnit: "days" }).days;
68
+ }
69
+ function dayOfWeekSun0(date) {
70
+ return temporalPolyfill.Temporal.PlainDate.from(date).dayOfWeek % 7;
71
+ }
72
+ function startOfWeek(date, weekStart) {
73
+ const back = (dayOfWeekSun0(date) - weekStart + 7) % 7;
74
+ return addDays(date, -back);
75
+ }
76
+ function isoWeekNumber(date) {
77
+ return temporalPolyfill.Temporal.PlainDate.from(date).weekOfYear ?? 1;
78
+ }
79
+ function zoneOffsetMinutes(zone, at = Date.now()) {
80
+ return Math.round(zoned(at, zone).offsetNanoseconds / 6e10);
81
+ }
82
+ function zoneOffsetLabel(zone, at = Date.now()) {
83
+ const total = zoneOffsetMinutes(zone, at);
84
+ if (total === 0) return "GMT";
85
+ const sign = total > 0 ? "+" : "-";
86
+ const abs = Math.abs(total);
87
+ const h = Math.floor(abs / 60);
88
+ const m = abs % 60;
89
+ return `GMT${sign}${h}${m ? `:${pad2(m)}` : ""}`;
90
+ }
91
+ function zoneCity(zone) {
92
+ const last = zone.split("/").pop() ?? zone;
93
+ return last.replace(/_/g, " ");
94
+ }
95
+ function listTimeZones() {
96
+ try {
97
+ const fn = Intl.supportedValuesOf;
98
+ const zones = fn ? fn("timeZone") : [];
99
+ if (zones.length) return zones.includes("UTC") ? zones : ["UTC", ...zones];
100
+ } catch {
101
+ }
102
+ return [
103
+ "UTC",
104
+ "Europe/London",
105
+ "Europe/Paris",
106
+ "Europe/Berlin",
107
+ "America/New_York",
108
+ "America/Chicago",
109
+ "America/Denver",
110
+ "America/Los_Angeles",
111
+ "Asia/Tokyo",
112
+ "Asia/Singapore",
113
+ "Australia/Sydney"
114
+ ];
115
+ }
116
+ function detectTimeZone() {
117
+ try {
118
+ return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
119
+ } catch {
120
+ return "UTC";
121
+ }
122
+ }
123
+ function formatInZone(utc, zone, options, locale) {
124
+ const ms = instantOf(utc).epochMilliseconds;
125
+ return new Intl.DateTimeFormat(locale, { ...options, timeZone: safeZone(zone) }).format(ms);
126
+ }
127
+ function formatPlainDate(date, options, locale) {
128
+ return new Intl.DateTimeFormat(locale, { ...options, timeZone: "UTC" }).format(
129
+ Date.parse(`${date}T12:00:00Z`)
130
+ );
131
+ }
132
+ function epochToWallArray(ms, zone) {
133
+ const z = temporalPolyfill.Temporal.Instant.fromEpochMilliseconds(ms).toZonedDateTimeISO(zone);
134
+ return [z.year, z.month - 1, z.day, z.hour, z.minute, z.second, z.millisecond];
135
+ }
136
+ function wallArrayOffset(a, zone) {
137
+ const norm = new Date(
138
+ Date.UTC(a[0], a[1] ?? 0, a[2] ?? 1, a[3] ?? 0, a[4] ?? 0, a[5] ?? 0, a[6] ?? 0)
139
+ );
140
+ const pdt = new temporalPolyfill.Temporal.PlainDateTime(
141
+ norm.getUTCFullYear(),
142
+ norm.getUTCMonth() + 1,
143
+ norm.getUTCDate(),
144
+ norm.getUTCHours(),
145
+ norm.getUTCMinutes(),
146
+ norm.getUTCSeconds(),
147
+ norm.getUTCMilliseconds()
148
+ );
149
+ const zdt = pdt.toZonedDateTime(zone, { disambiguation: "compatible" });
150
+ return Math.round(zdt.offsetNanoseconds / 6e10);
151
+ }
152
+
153
+ exports.addDays = addDays;
154
+ exports.addMonths = addMonths;
155
+ exports.convertWall = convertWall;
156
+ exports.detectTimeZone = detectTimeZone;
157
+ exports.diffDays = diffDays;
158
+ exports.epochToWallArray = epochToWallArray;
159
+ exports.formatInZone = formatInZone;
160
+ exports.formatPlainDate = formatPlainDate;
161
+ exports.isValidTimeZone = isValidTimeZone;
162
+ exports.isoWeekNumber = isoWeekNumber;
163
+ exports.listTimeZones = listTimeZones;
164
+ exports.safeZone = safeZone;
165
+ exports.startOfWeek = startOfWeek;
166
+ exports.todayInZone = todayInZone;
167
+ exports.utcToDate = utcToDate;
168
+ exports.utcToTime = utcToTime;
169
+ exports.utcToWall = utcToWall;
170
+ exports.wallArrayOffset = wallArrayOffset;
171
+ exports.wallToEpochMs = wallToEpochMs;
172
+ exports.wallToUtc = wallToUtc;
173
+ exports.zoneCity = zoneCity;
174
+ exports.zoneOffsetLabel = zoneOffsetLabel;
175
+ exports.zoneOffsetMinutes = zoneOffsetMinutes;
176
+ //# sourceMappingURL=chunk-TGWTLNXW.cjs.map
177
+ //# sourceMappingURL=chunk-TGWTLNXW.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/calendar/zone.ts"],"names":["Temporal"],"mappings":"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","file":"chunk-TGWTLNXW.cjs","sourcesContent":["/**\n * Zone math for the calendar. Every conversion between a wall time in a named IANA zone and a UTC\n * instant goes through Temporal (the polyfill, imported as a module: nothing global is patched),\n * so DST gaps/overlaps resolve the way RFC 5545 says (`compatible`: a skipped time moves forward,\n * a repeated time takes the earlier instant). Nothing here reads the browser's local zone.\n */\nimport { Temporal } from 'temporal-polyfill'\n\nconst pad2 = (n: number) => String(n).padStart(2, '0')\nconst pad4 = (n: number) => String(n).padStart(4, '0')\n\n/** True when `zone` is a time zone the runtime can resolve. */\nexport function isValidTimeZone(zone: string | null | undefined): zone is string {\n if (!zone) return false\n try {\n Temporal.Now.instant().toZonedDateTimeISO(zone)\n return true\n } catch {\n return false\n }\n}\n\n/** `zone` when valid, else `fallback` (else UTC). */\nexport function safeZone(zone: string | null | undefined, fallback = 'UTC'): string {\n if (isValidTimeZone(zone)) return zone\n return isValidTimeZone(fallback) ? fallback : 'UTC'\n}\n\nfunction toPlainDateTime(wall: string): Temporal.PlainDateTime {\n // Accept `YYYY-MM-DDTHH:MM`, `…:SS` and a bare date (midnight).\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(wall)\n ? Temporal.PlainDate.from(wall).toPlainDateTime()\n : Temporal.PlainDateTime.from(wall)\n}\n\n/** The instant a wall time in `zone` names, as an ISO string ending in `Z` (no milliseconds unless set). */\nexport function wallToUtc(wall: string, zone: string): string {\n const zdt = toPlainDateTime(wall).toZonedDateTime(safeZone(zone), {\n disambiguation: 'compatible',\n })\n return zdt.toInstant().toString()\n}\n\n/** Epoch milliseconds of a wall time in `zone`. */\nexport function wallToEpochMs(wall: string, zone: string): number {\n return toPlainDateTime(wall).toZonedDateTime(safeZone(zone), { disambiguation: 'compatible' })\n .epochMilliseconds\n}\n\nfunction instantOf(utc: string | Date | number): Temporal.Instant {\n if (typeof utc === 'number') return Temporal.Instant.fromEpochMilliseconds(utc)\n if (utc instanceof Date) return Temporal.Instant.fromEpochMilliseconds(utc.getTime())\n return Temporal.Instant.from(utc)\n}\n\n/** The zoned date-time of an instant. */\nexport function zoned(utc: string | Date | number, zone: string): Temporal.ZonedDateTime {\n return instantOf(utc).toZonedDateTimeISO(safeZone(zone))\n}\n\n/** `YYYY-MM-DDTHH:MM` wall time of an instant in `zone`. */\nexport function utcToWall(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}T${pad2(z.hour)}:${pad2(z.minute)}`\n}\n\n/** `YYYY-MM-DD` date of an instant in `zone`. */\nexport function utcToDate(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}`\n}\n\n/** `HH:MM` of an instant in `zone`. */\nexport function utcToTime(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad2(z.hour)}:${pad2(z.minute)}`\n}\n\n/** Convert a wall time from one zone to the same instant's wall time in another. */\nexport function convertWall(wall: string, fromZone: string, toZone: string): string {\n return utcToWall(wallToUtc(wall, fromZone), toZone)\n}\n\n/** Today's date in `zone`. */\nexport function todayInZone(zone: string, now: Date | number = Date.now()): string {\n return utcToDate(now, zone)\n}\n\n/** Calendar arithmetic on a `YYYY-MM-DD` date. */\nexport function addDays(date: string, days: number): string {\n return Temporal.PlainDate.from(date).add({ days }).toString()\n}\n\nexport function addMonths(date: string, months: number): string {\n return Temporal.PlainDate.from(date).add({ months }).toString()\n}\n\n/** Whole days from `a` to `b` (both `YYYY-MM-DD`). */\nexport function diffDays(a: string, b: string): number {\n return Temporal.PlainDate.from(a).until(Temporal.PlainDate.from(b), { largestUnit: 'days' }).days\n}\n\n/** 0 = Sunday … 6 = Saturday, for a `YYYY-MM-DD` date. */\nexport function dayOfWeekSun0(date: string): number {\n return Temporal.PlainDate.from(date).dayOfWeek % 7\n}\n\n/** The first day of the week containing `date`, for a week starting on `weekStart` (0 = Sunday). */\nexport function startOfWeek(date: string, weekStart: number): string {\n const back = (dayOfWeekSun0(date) - weekStart + 7) % 7\n return addDays(date, -back)\n}\n\n/** ISO-8601 week number of a `YYYY-MM-DD` date. */\nexport function isoWeekNumber(date: string): number {\n return Temporal.PlainDate.from(date).weekOfYear ?? 1\n}\n\n/** Offset of `zone` at an instant, in minutes east of UTC. */\nexport function zoneOffsetMinutes(zone: string, at: string | Date | number = Date.now()): number {\n return Math.round(zoned(at, zone).offsetNanoseconds / 60_000_000_000)\n}\n\n/** `GMT+5:30` / `GMT-4` / `GMT` label for `zone` at an instant. */\nexport function zoneOffsetLabel(zone: string, at: string | Date | number = Date.now()): string {\n const total = zoneOffsetMinutes(zone, at)\n if (total === 0) return 'GMT'\n const sign = total > 0 ? '+' : '-'\n const abs = Math.abs(total)\n const h = Math.floor(abs / 60)\n const m = abs % 60\n return `GMT${sign}${h}${m ? `:${pad2(m)}` : ''}`\n}\n\n/** Short city-ish label for a zone: `America/New_York` → `New York`. */\nexport function zoneCity(zone: string): string {\n const last = zone.split('/').pop() ?? zone\n return last.replace(/_/g, ' ')\n}\n\n/** Every IANA zone the runtime knows (falls back to a short list on old engines). */\nexport function listTimeZones(): string[] {\n try {\n const fn = (Intl as unknown as { supportedValuesOf?: (k: string) => string[] })\n .supportedValuesOf\n const zones = fn ? fn('timeZone') : []\n if (zones.length) return zones.includes('UTC') ? zones : ['UTC', ...zones]\n } catch {\n // fall through\n }\n return [\n 'UTC',\n 'Europe/London',\n 'Europe/Paris',\n 'Europe/Berlin',\n 'America/New_York',\n 'America/Chicago',\n 'America/Denver',\n 'America/Los_Angeles',\n 'Asia/Tokyo',\n 'Asia/Singapore',\n 'Australia/Sydney',\n ]\n}\n\n/** The viewer's zone (only as a default for a new user; rendering always uses an explicit zone). */\nexport function detectTimeZone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'\n } catch {\n return 'UTC'\n }\n}\n\n/** Format an instant in `zone` with Intl (never the browser zone). */\nexport function formatInZone(\n utc: string | Date | number,\n zone: string,\n options: Intl.DateTimeFormatOptions,\n locale?: string\n): string {\n const ms = instantOf(utc).epochMilliseconds\n return new Intl.DateTimeFormat(locale, { ...options, timeZone: safeZone(zone) }).format(ms)\n}\n\n/** Format a `YYYY-MM-DD` date (zone-free: rendered at UTC noon so no zone can shift the day). */\nexport function formatPlainDate(\n date: string,\n options: Intl.DateTimeFormatOptions,\n locale?: string\n): string {\n return new Intl.DateTimeFormat(locale, { ...options, timeZone: 'UTC' }).format(\n Date.parse(`${date}T12:00:00Z`)\n )\n}\n\n/** Wall-clock array FullCalendar's NamedTimeZoneImpl speaks: [y, m0, d, h, min, s, ms]. */\nexport function epochToWallArray(ms: number, zone: string): number[] {\n const z = Temporal.Instant.fromEpochMilliseconds(ms).toZonedDateTimeISO(zone)\n return [z.year, z.month - 1, z.day, z.hour, z.minute, z.second, z.millisecond]\n}\n\n/** Offset (minutes east of UTC) for a wall-clock array in `zone`, resolving gaps `compatible`. */\nexport function wallArrayOffset(a: number[], zone: string): number {\n // FullCalendar may pass out-of-range parts (e.g. hour 24): normalise via a UTC Date first.\n const norm = new Date(\n Date.UTC(a[0], a[1] ?? 0, a[2] ?? 1, a[3] ?? 0, a[4] ?? 0, a[5] ?? 0, a[6] ?? 0)\n )\n const pdt = new Temporal.PlainDateTime(\n norm.getUTCFullYear(),\n norm.getUTCMonth() + 1,\n norm.getUTCDate(),\n norm.getUTCHours(),\n norm.getUTCMinutes(),\n norm.getUTCSeconds(),\n norm.getUTCMilliseconds()\n )\n const zdt = pdt.toZonedDateTime(zone, { disambiguation: 'compatible' })\n return Math.round(zdt.offsetNanoseconds / 60_000_000_000)\n}\n"]}
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ // src/artifacts/sandbox-policy.ts
5
+ var ARTIFACT_SANDBOX = "allow-scripts";
6
+ var ARTIFACT_CSP = [
7
+ "default-src 'none'",
8
+ "script-src 'unsafe-inline'",
9
+ "style-src 'unsafe-inline'",
10
+ "img-src data: blob:",
11
+ "font-src data:",
12
+ "media-src data: blob:",
13
+ "connect-src 'none'",
14
+ "frame-src 'none'",
15
+ "object-src 'none'",
16
+ "worker-src 'none'",
17
+ "form-action 'none'",
18
+ "base-uri 'none'"
19
+ ].join("; ");
20
+ var ARTIFACT_MESSAGE_TAG = "__arbiArtifact";
21
+
22
+ exports.ARTIFACT_CSP = ARTIFACT_CSP;
23
+ exports.ARTIFACT_MESSAGE_TAG = ARTIFACT_MESSAGE_TAG;
24
+ exports.ARTIFACT_SANDBOX = ARTIFACT_SANDBOX;
25
+ //# sourceMappingURL=chunk-VG24E4JJ.cjs.map
26
+ //# sourceMappingURL=chunk-VG24E4JJ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/artifacts/sandbox-policy.ts"],"names":[],"mappings":";;;AAOO,IAAM,gBAAA,GAAmB;AAEzB,IAAM,YAAA,GAAe;AAAA,EAC1B,oBAAA;AAAA,EACA,4BAAA;AAAA,EACA,2BAAA;AAAA,EACA,qBAAA;AAAA,EACA,gBAAA;AAAA,EACA,uBAAA;AAAA,EACA,oBAAA;AAAA,EACA,kBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAA,CAAE,KAAK,IAAI;AAGJ,IAAM,oBAAA,GAAuB","file":"chunk-VG24E4JJ.cjs","sourcesContent":["/**\n * The artifact sandbox's fixed policy: iframe sandbox flags, CSP, the message marker and the runtime\n * shape. Kept apart from `sandboxDocument` (which pulls in the JSX compiler) so the preview can render\n * its frame attributes without loading the compiler until an artifact is actually shown.\n */\n\n/** Exactly this and nothing else. Do not add allow-same-origin (it voids the sandbox). */\nexport const ARTIFACT_SANDBOX = 'allow-scripts'\n\nexport const ARTIFACT_CSP = [\n \"default-src 'none'\",\n \"script-src 'unsafe-inline'\",\n \"style-src 'unsafe-inline'\",\n 'img-src data: blob:',\n 'font-src data:',\n 'media-src data: blob:',\n \"connect-src 'none'\",\n \"frame-src 'none'\",\n \"object-src 'none'\",\n \"worker-src 'none'\",\n \"form-action 'none'\",\n \"base-uri 'none'\",\n].join('; ')\n\n/** Marker on every message the sandbox posts to the app. */\nexport const ARTIFACT_MESSAGE_TAG = '__arbiArtifact'\n\n/**\n * Source text of the generated runtime (scripts/build-artifact-runtime.mjs). It is inlined into the\n * document: a frame with an opaque origin cannot load blob: URLs from the app, and inlining needs no\n * network or CSP exception.\n */\nexport interface ArtifactRuntime {\n /** React + ReactDOM as one IIFE. */\n react: string\n /** Tailwind v4 browser build. */\n tailwind: string\n}\n\nexport type ArtifactSandboxMessage =\n | { [ARTIFACT_MESSAGE_TAG]: true; type: 'ready' }\n | { [ARTIFACT_MESSAGE_TAG]: true; type: 'console'; level: string; text: string }\n | { [ARTIFACT_MESSAGE_TAG]: true; type: 'error'; text: string }\n"]}
@@ -0,0 +1,6 @@
1
+ export interface DroppableContainerProps {
2
+ id: string;
3
+ children: React.ReactNode;
4
+ className?: string;
5
+ }
6
+ export declare function DroppableContainer({ id, children, className }: DroppableContainerProps): import("react").JSX.Element;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * GridRowNavigator
3
+ *
4
+ * A ‹ n / N › row navigator for an AG Grid table — the table twin of the one
5
+ * the calendar and timeline blocks portal into the Facts toolbar, and the same
6
+ * control on the Files table. It walks the rows in the ORDER THE TABLE SHOWS
7
+ * THEM (after the grid's own sort and quick filters), scrolls each into view
8
+ * and hands it to `onSelect` (Facts opens it in the composer, Files in the
9
+ * viewer), so the row being stepped to is the one highlighted on screen.
10
+ *
11
+ * The position tracks `selectedId` (the fact open in the composer / the doc in
12
+ * the viewer), falling back to "– / N" when nothing is open. It re-reads the
13
+ * grid whenever its row model changes (sort, filter, data), so the counter
14
+ * stays honest.
15
+ */
16
+ import type { GridApi } from 'ag-grid-community';
17
+ export interface GridRowNavigatorProps<T> {
18
+ /** The mounted grid's API, or null until the grid is ready. */
19
+ gridApi: GridApi<T> | null;
20
+ /** The row currently open — where the counter points. */
21
+ selectedId: string | null;
22
+ /** Open the row the user stepped to. */
23
+ onSelect: (item: T) => void;
24
+ /** Prefix for every `data-testid` this control emits. */
25
+ testId: string;
26
+ /** Noun for the buttons' aria-labels ("Previous fact" / "Next document"). */
27
+ itemLabel?: string;
28
+ }
29
+ export declare function GridRowNavigator<T>({ gridApi, selectedId, onSelect, testId, itemLabel, }: GridRowNavigatorProps<T>): import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * LoadingIndicator Component
3
+ *
4
+ * Centralized loading indicator for consistent loading states across the app
5
+ * Provides different variants and sizes for various use cases
6
+ */
7
+ export interface LoadingIndicatorProps {
8
+ /** Optional message to display below the spinner */
9
+ message?: string;
10
+ /** Size variant of the spinner */
11
+ size?: 'small' | 'medium' | 'large';
12
+ /** Whether to center the loader in its container */
13
+ centered?: boolean;
14
+ /** Whether to use full screen overlay */
15
+ fullScreen?: boolean;
16
+ /** Additional CSS classes */
17
+ className?: string;
18
+ /** Test ID for testing */
19
+ testId?: string;
20
+ }
21
+ export declare function LoadingIndicator({ message, size, centered, fullScreen, className, testId, }: LoadingIndicatorProps): import("react").JSX.Element;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * RowNavigatorControls
3
+ *
4
+ * The bare ‹ n / N › stepper shared by every list navigator — the Files table
5
+ * (GridRowNavigator, over AG Grid's displayed rows) and the Files gallery
6
+ * (ExplorerFileNavigator, over the explorer's displayed tiles). Presentation
7
+ * only: the owner resolves what "current" and "total" mean and what stepping
8
+ * does, so the two surfaces stay pixel-identical while their sources differ.
9
+ */
10
+ export interface RowNavigatorControlsProps {
11
+ /** Rows currently displayed. Renders nothing at 0. */
12
+ total: number;
13
+ /** Zero-based position of the open row, or null for "– / N". */
14
+ currentIndex: number | null;
15
+ /** Step to a zero-based index (already clamped by the caller if it cares). */
16
+ onGo: (index: number) => void;
17
+ /** Prefix for every `data-testid` this control emits. */
18
+ testId: string;
19
+ /** Noun for the buttons' aria-labels ("Previous fact" / "Next document"). */
20
+ itemLabel?: string;
21
+ /**
22
+ * Render a disabled "– / –" stepper instead of nothing when there is nothing
23
+ * to step through. The gallery keeps it so a folder-only view doesn't drop a
24
+ * control out of the toolbar (and shift everything left) on every folder hop;
25
+ * the table, whose empty state replaces the whole grid, hides it.
26
+ */
27
+ keepWhenEmpty?: boolean;
28
+ }
29
+ export declare function RowNavigatorControls({ total, currentIndex, onGo, testId, itemLabel, keepWhenEmpty, }: RowNavigatorControlsProps): import("react").JSX.Element | null;