@inkandswitch/patchwork-pkg-base 0.0.111 → 0.0.112

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 (84) hide show
  1. package/module-settings-url +1 -1
  2. package/package.json +1 -1
  3. package/packages/account/dist/{AccountPicker-DCX77HQI.js → AccountPicker-L3IHAMPQ.js} +25 -18
  4. package/packages/account/dist/AccountPicker-L3IHAMPQ.js.map +7 -0
  5. package/packages/account/dist/index.js +1 -1
  6. package/packages/account/package.json +1 -1
  7. package/packages/account-history/dist/assets/{HistoryRecorder-TRWDhOKO.js → HistoryRecorder-mRdg9-Sa.js} +2 -2
  8. package/packages/account-history/dist/assets/{HistoryRecorder-TRWDhOKO.js.map → HistoryRecorder-mRdg9-Sa.js.map} +1 -1
  9. package/packages/account-history/dist/assets/{HistoryViewer-BmG0rAfK.js → HistoryViewer-yhYv3jqn.js} +2 -2
  10. package/packages/account-history/dist/assets/{HistoryViewer-BmG0rAfK.js.map → HistoryViewer-yhYv3jqn.js.map} +1 -1
  11. package/packages/account-history/dist/assets/{NotebookViewer-DZ_ZQU5x.js → NotebookViewer-CLhIU0hN.js} +2 -2
  12. package/packages/account-history/dist/assets/{NotebookViewer-DZ_ZQU5x.js.map → NotebookViewer-CLhIU0hN.js.map} +1 -1
  13. package/packages/account-history/dist/assets/{context-wyGzlZK-.js → context-CgDNOWHV.js} +1 -4
  14. package/packages/account-history/dist/assets/{context-wyGzlZK-.js.map → context-CgDNOWHV.js.map} +1 -1
  15. package/packages/account-history/dist/assets/{index-DBnlnSMc.js → index-Bx2CKRPA.js} +5 -5
  16. package/packages/account-history/dist/assets/{index-DBnlnSMc.js.map → index-Bx2CKRPA.js.map} +1 -1
  17. package/packages/account-history/dist/index.js +1 -1
  18. package/packages/account-history/package.json +1 -1
  19. package/packages/chat/dist/{ChatRoot-1d-658Rr.js → ChatRoot-Ly8PORLd.js} +704 -696
  20. package/packages/chat/dist/{context-tool-iP64Oz6H.js → context-tool-DHIbdY80.js} +2 -2
  21. package/packages/chat/dist/{index-Dm_2jZcu.js → index-fGaJgJ-s.js} +3 -3
  22. package/packages/chat/dist/index.js +1 -1
  23. package/packages/chat/dist/{tool-BmNd5mrj.js → tool-CpslbjKC.js} +1 -1
  24. package/packages/chat/package.json +1 -1
  25. package/packages/codemirror-base/dist/tool.js +1 -1
  26. package/packages/codemirror-base/dist/tool.js.map +1 -1
  27. package/packages/codemirror-base/package.json +1 -1
  28. package/packages/comments-view/dist/assets/{main-wSSvAVfi.js → main-IR1Yfgas.js} +14 -7
  29. package/packages/comments-view/dist/assets/main-IR1Yfgas.js.map +1 -0
  30. package/packages/comments-view/dist/index.js +3 -3
  31. package/packages/comments-view/package.json +1 -1
  32. package/packages/drafts/dist/assets/main-CG9HOCai.js.map +1 -1
  33. package/packages/drafts/package.json +1 -1
  34. package/packages/file/dist/index.js +1 -1
  35. package/packages/file/dist/{tool-Bt8I8T2-.js → tool-DMegb4Cw.js} +814 -806
  36. package/packages/file/dist/tool-DMegb4Cw.js.map +1 -0
  37. package/packages/file/dist/{typescript-language-server-Db4173Y5.js → typescript-language-server-Cx5RlH3z.js} +2 -2
  38. package/packages/file/dist/{typescript-language-server-Db4173Y5.js.map → typescript-language-server-Cx5RlH3z.js.map} +1 -1
  39. package/packages/file/package.json +1 -1
  40. package/packages/history-view/dist/assets/{HistoryTimeline-Bo-BTf2A.js → HistoryTimeline-DOndzpUR.js} +15 -8
  41. package/packages/history-view/dist/assets/HistoryTimeline-DOndzpUR.js.map +1 -0
  42. package/packages/history-view/dist/assets/{index-B5Afrk9Y.js → index-D7nqWI0b.js} +2 -2
  43. package/packages/history-view/dist/assets/{index-B5Afrk9Y.js.map → index-D7nqWI0b.js.map} +1 -1
  44. package/packages/history-view/dist/index.js +1 -1
  45. package/packages/history-view/package.json +1 -1
  46. package/packages/settings/dist/assets/{FrameConfigurator-DVRBzIR-.js → FrameConfigurator-C0ZRifTs.js} +2 -2
  47. package/packages/settings/dist/assets/FrameConfigurator-C0ZRifTs.js.map +1 -0
  48. package/packages/settings/dist/index.js +1 -1
  49. package/packages/settings/package.json +1 -1
  50. package/packages/sideboard/dist/account-bar-67PDNT3H.js +2 -0
  51. package/packages/sideboard/dist/{chunk-25X3B3RC.js → chunk-6KORX3GC.js} +2 -2
  52. package/packages/sideboard/dist/chunk-FFQGRRLJ.js +2 -0
  53. package/packages/sideboard/dist/chunk-FFQGRRLJ.js.map +7 -0
  54. package/packages/sideboard/dist/{chunk-H6GFMJFM.js → chunk-XIUFUJKM.js} +2 -2
  55. package/packages/sideboard/dist/{chunk-H6GFMJFM.js.map → chunk-XIUFUJKM.js.map} +1 -1
  56. package/packages/sideboard/dist/document-list-panel-SPPMZDMX.js +2 -0
  57. package/packages/sideboard/dist/index.js +1 -1
  58. package/packages/sideboard/dist/sideboard/sideboard.js +1 -1
  59. package/packages/sideboard/package.json +1 -1
  60. package/packages/sync-indicator/dist/assets/SyncIndicator-oVMcVRXg.js.map +1 -1
  61. package/packages/sync-indicator/package.json +1 -1
  62. package/packages/threepane/dist/IsolatedDocumentArea-E3VEPUEG.js +2 -0
  63. package/packages/threepane/dist/{PatchworkFrame-22UEOQ6E.js → PatchworkFrame-HCSYM5W5.js} +2 -2
  64. package/packages/threepane/dist/{chunk-U4IJVHXK.js → chunk-HXEHZ5WC.js} +7 -7
  65. package/packages/threepane/dist/chunk-HXEHZ5WC.js.map +7 -0
  66. package/packages/threepane/dist/index.js +1 -1
  67. package/packages/threepane/package.json +1 -1
  68. package/plugin-registry-url +1 -1
  69. package/packages/account/dist/AccountPicker-DCX77HQI.js.map +0 -7
  70. package/packages/comments-view/dist/assets/main-wSSvAVfi.js.map +0 -1
  71. package/packages/file/dist/tool-Bt8I8T2-.js.map +0 -1
  72. package/packages/history-view/dist/assets/HistoryTimeline-Bo-BTf2A.js.map +0 -1
  73. package/packages/settings/dist/assets/FrameConfigurator-DVRBzIR-.js.map +0 -1
  74. package/packages/sideboard/dist/account-bar-JHI3FZZT.js +0 -2
  75. package/packages/sideboard/dist/chunk-FEMULUBJ.js +0 -2
  76. package/packages/sideboard/dist/chunk-FEMULUBJ.js.map +0 -7
  77. package/packages/sideboard/dist/document-list-panel-SEKNECHI.js +0 -2
  78. package/packages/threepane/dist/IsolatedDocumentArea-5WRK3TWL.js +0 -2
  79. package/packages/threepane/dist/chunk-U4IJVHXK.js.map +0 -7
  80. /package/packages/sideboard/dist/{account-bar-JHI3FZZT.js.map → account-bar-67PDNT3H.js.map} +0 -0
  81. /package/packages/sideboard/dist/{chunk-25X3B3RC.js.map → chunk-6KORX3GC.js.map} +0 -0
  82. /package/packages/sideboard/dist/{document-list-panel-SEKNECHI.js.map → document-list-panel-SPPMZDMX.js.map} +0 -0
  83. /package/packages/threepane/dist/{IsolatedDocumentArea-5WRK3TWL.js.map → IsolatedDocumentArea-E3VEPUEG.js.map} +0 -0
  84. /package/packages/threepane/dist/{PatchworkFrame-22UEOQ6E.js.map → PatchworkFrame-HCSYM5W5.js.map} +0 -0
@@ -55,7 +55,7 @@
55
55
  "@inkandswitch/patchwork-providers-solid": "^0.2.8",
56
56
  "@lezer/highlight": "^1.2.3",
57
57
  "codemirror": "^6.0.0",
58
- "solid-automerge": "^2.0.2",
58
+ "solid-automerge": "^2.1.0",
59
59
  "solid-js": "^1.9.11",
60
60
  "tsgo-wasm": "7.0.2"
61
61
  },
@@ -14,7 +14,7 @@ import { insert, createComponent, effect, setAttribute, style, template, delegat
14
14
  import { createSignal, onMount, onCleanup, createMemo, createContext, useContext, createResource, createEffect, Show, For } from "solid-js";
15
15
  import { createStore, reconcile, produce } from "solid-js/store";
16
16
  import * as Providers from "@inkandswitch/patchwork-providers";
17
- import { _ as __vitePreload } from "./index-B5Afrk9Y.js";
17
+ import { _ as __vitePreload } from "./index-D7nqWI0b.js";
18
18
  import * as Automerge from "@automerge/automerge/slim";
19
19
  import { getType } from "@inkandswitch/patchwork-filesystem";
20
20
  import { getRegistry } from "@inkandswitch/patchwork-plugins";
@@ -732,9 +732,6 @@ function makeDocumentProjection(handle) {
732
732
  }
733
733
  handle.on("change", patch);
734
734
  handle.on("delete", ondelete);
735
- handle.whenReady().then(() => {
736
- set(structuredClone(handle.doc()));
737
- });
738
735
  return doc;
739
736
  }
740
737
  const access = (v) => typeof v === "function" && !v.length ? v() : v;
@@ -757,12 +754,11 @@ function useDocHandle(url, options) {
757
754
  if (options?.["~skipInitialValue"]) return void 0;
758
755
  const unwrappedURL = access(url);
759
756
  if (!unwrappedURL) return void 0;
760
- const state = repo2.findWithProgress(unwrappedURL).peek();
761
- return state.state === "ready" ? state.handle : void 0;
757
+ return peekReadyHandle(repo2, unwrappedURL);
762
758
  }
763
759
  const [handle, { mutate }] = createResource(
764
760
  url,
765
- (url2) => repo2.findWithProgress(url2).whenReady(),
761
+ (url2) => repo2.find(url2),
766
762
  {
767
763
  initialValue: getExistingHandle()
768
764
  }
@@ -774,6 +770,17 @@ function useDocHandle(url, options) {
774
770
  });
775
771
  return handle;
776
772
  }
773
+ function isQueryable(repo2) {
774
+ return typeof repo2.query == "function";
775
+ }
776
+ function peekReadyHandle(repo2, url) {
777
+ if (isQueryable(repo2)) {
778
+ const state2 = repo2.query(url).state();
779
+ return state2.status == "ready" ? state2.handle : void 0;
780
+ }
781
+ const state = repo2.findWithProgress(url).peek();
782
+ return state.state == "ready" ? state.handle : void 0;
783
+ }
777
784
  function useDocument(url, options) {
778
785
  const handle = useDocHandle(url, options);
779
786
  return [createDocumentProjection(handle), handle];
@@ -1740,4 +1747,4 @@ export {
1740
1747
  HistoryTimeline,
1741
1748
  renderHistoryTimeline
1742
1749
  };
1743
- //# sourceMappingURL=HistoryTimeline-Bo-BTf2A.js.map
1750
+ //# sourceMappingURL=HistoryTimeline-DOndzpUR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"mappings":"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","names":["ms","debug","template","exports","repo","tasklib.queue","strategyConfig","DocHistoryHeader","props","_el$2","firstChild","_el$5","_$insert","when","undefined","_el$4","_el$6","$$click","e","stopPropagation","onRecompute","_$effect","_p$","animation","_v$","disabled","_v$2","t","_el$","_$delegateEvents","TimelineCard","isSelected","background","color","_$setAttribute","a","authorColor","authorId","hash","h","Math","length","parts","toUpperCase","split","slice","barWidth","value","large","min","HistoryItem","timeDisplay","formatTimeOnly","item","endTime","deletions","label","customLabel","getChangeLabel","visibleAuthors","subItems","isEditing","setIsEditing","editValue","setEditValue","createSignal","isMultiAuthorWithSubItems","isExpanded","createMemo","isOpen","anySubItemSelected","createEffect","startEdit","commitEdit","trim","trimmed","handleKeyDown","preventDefault","_tmpl$7","_$createComponent","handleParentClick","_tmpl$5","_el$3","each","children","author","_el$16","_tmpl$8","_$setStyleProperty","_v$3","extraAuthors","_el$17","_tmpl$0","$$dblclick","_el$18","Show","fallback","_tmpl$9","_el$20","_tmpl$1","_tmpl$2","_$use","el","setTimeout","focus","select","addEventListener","$$input","_el$7","additions","_el$8","_tmpl$3","_el$9","_el$0","_$p","_el$10","_tmpl$4","_el$11","_el$12","nextSibling","thresholds","_el$14","_el$15","_tmpl$6","subDel","subItem","onClick","onSubItemClick","_el$22","_tmpl$10","_el$23","getInitials","subAuthor","_el$24","subAdd","_el$28","_el$26","_el$25","_el$30","_el$31","_el$32","_el$34","_v$4","_v$5","DateHeader","dayOfWeek","weekday","formattedDate","month","isToday","today","date","getDate","getFullYear","yesterday","setDate","displayDay","getItemDate","timestamp","setHours","HistoryList","groupedItems","groups","forEach","dateKey","items","push","Array","values","_tmpl$","group","index","isItemSelected","onSelectItem","shiftKey","onRename","onRenameItem","latestHash","isSubItemSelected","HistoryComputingIndicator","STRATEGY_CONFIG","name","timeWindow","DEFAULT_TIME_WINDOW","DocHistoryView","doc","handle","title","useDocumentMetadata","isInitializing","isRecalculating","forceRecompute","setLabel","useCachedHistory","selectedItems","selectItem","extendSelection","clearSelection","useHistorySelection","handleSelectItem","shiftHeld","_$addEventListener","showTitle","HistoryTimeline","selectedDocUrls","type","primaryUrl","keyed","url","renderHistoryTimeline","element"],"ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,13,16],"sources":["../../node_modules/.pnpm/@inkandswitch+patchwork-providers-solid@0.2.8_@automerge+automerge-repo@2.6.0-subductio_035b4a5671963f498e43552449bcf0ce/node_modules/@inkandswitch/patchwork-providers-solid/dist/index.js","../../node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js","../../node_modules/.pnpm/debug@4.4.3_supports-color@7.2.0/node_modules/debug/src/common.js","../../node_modules/.pnpm/debug@4.4.3_supports-color@7.2.0/node_modules/debug/src/browser.js","../../node_modules/.pnpm/cabbages@0.2.10_supports-color@7.2.0/node_modules/cabbages/output/cabbages.js","../../node_modules/.pnpm/solid-automerge@2.1.0_@automerge+automerge-repo@2.6.0-subduction.26_supports-color@7.2._432eb361aba1bbafbe02618a6bdc0954/node_modules/solid-automerge/out/autoproduce.js","../../node_modules/.pnpm/solid-automerge@2.1.0_@automerge+automerge-repo@2.6.0-subduction.26_supports-color@7.2._432eb361aba1bbafbe02618a6bdc0954/node_modules/solid-automerge/out/makeDocumentProjection.js","../../node_modules/.pnpm/@solid-primitives+utils@6.4.1_solid-js@1.9.11/node_modules/@solid-primitives/utils/dist/index.js","../../node_modules/.pnpm/solid-automerge@2.1.0_@automerge+automerge-repo@2.6.0-subduction.26_supports-color@7.2._432eb361aba1bbafbe02618a6bdc0954/node_modules/solid-automerge/out/createDocumentProjection.js","../../node_modules/.pnpm/solid-automerge@2.1.0_@automerge+automerge-repo@2.6.0-subduction.26_supports-color@7.2._432eb361aba1bbafbe02618a6bdc0954/node_modules/solid-automerge/out/context.js","../../node_modules/.pnpm/solid-automerge@2.1.0_@automerge+automerge-repo@2.6.0-subduction.26_supports-color@7.2._432eb361aba1bbafbe02618a6bdc0954/node_modules/solid-automerge/out/useDocHandle.js","../../node_modules/.pnpm/solid-automerge@2.1.0_@automerge+automerge-repo@2.6.0-subduction.26_supports-color@7.2._432eb361aba1bbafbe02618a6bdc0954/node_modules/solid-automerge/out/useDocument.js","../../src/history/utils.ts","../../node_modules/.pnpm/@awarth+tasklib@0.0.10_supports-color@7.2.0/node_modules/@awarth/tasklib/dist/index.js","../../src/history/hooks/useCachedHistory.ts","../../src/history/lib/solid-plugins.ts","../../node_modules/.pnpm/@inkandswitch+patchwork-plugins@1.2.5_@automerge+automerge-repo@2.6.0-subduction.26_sup_be4c17a4070a7abd8c184f9e9ecca2f5/node_modules/@inkandswitch/patchwork-plugins/dist/registry/guards.js","../../src/history/hooks/useDocumentMetadata.ts","../../src/history/hooks/useHistorySelection.ts","../../src/history/components/DocHistoryHeader.tsx","../../src/types.ts","../../src/history/components/TimelineCard.tsx","../../src/history/components/HistoryItem.tsx","../../src/history/components/DateHeader.tsx","../../src/history/components/HistoryList.tsx","../../src/history/components/HistoryComputingIndicator.tsx","../../src/history/components/DocHistoryView.tsx","../../src/history/HistoryTimeline.tsx"],"sourcesContent":["import { createEffect, createSignal, onCleanup, onMount, } from \"solid-js\";\nimport { createStore, reconcile } from \"solid-js/store\";\nimport * as Providers from \"@inkandswitch/patchwork-providers\";\nfunction resolveElement(source) {\n return typeof source === \"function\" ? source() : source;\n}\n/**\n * Generic reactive request. Resolves the first value a provider emits for\n * `selector` (via the one-shot `request` helper) and returns an accessor that\n * reads `undefined` until then. `T` is the response type.\n */\nexport function request(element, selector) {\n const [value, setValue] = createSignal(undefined);\n onMount(() => {\n const target = resolveElement(element);\n if (!target)\n return;\n Providers.request(target, selector).then((v) => {\n if (v == null)\n return;\n setValue(() => v);\n });\n });\n return value;\n}\nexport function subscribe(element, selector, initialValue) {\n const [value, setValue] = createSignal(initialValue);\n onMount(() => {\n const target = resolveElement(element);\n if (!target)\n return;\n const unsubscribe = Providers.subscribe(target, selector, setValue);\n onCleanup(unsubscribe);\n });\n return value;\n}\n/**\n * Store-backed subscription. Use this when a consumer wants Solid's\n * fine-grained nested reactivity for incoming JSON object or array snapshots.\n * Requires an initial object/array so the store has a stable root.\n *\n * `reconcile` preserves stable object/array identity where possible, so this\n * helper is not a good fit when the top-level value is used as an identity key\n * for resources or memos.\n */\nexport function subscribeReconciled(element, selector, initialValue) {\n const [store, setStore] = createStore(initialValue);\n onMount(() => {\n const target = resolveElement(element);\n if (!target)\n return;\n const unsubscribe = Providers.subscribe(target, selector, (v) => {\n setStore(reconcile(v));\n });\n onCleanup(unsubscribe);\n });\n return store;\n}\n/**\n * Handle-specialized subscription. Use when the answering provider emits an\n * `AutomergeUrl`. The handle is recovered locally from the global repo\n * (`window.repo`), so it stays fully live — reads project reactively and writes go\n * straight back to the same repo. Returns `[doc, handle]` matching the shape\n * of `solid-automerge`'s `useDocument`; both read `undefined` until the first\n * url arrives. `T` is the doc shape inside the handle.\n */\nexport function subscribeDoc(element, selector) {\n const [handle, setHandle] = createSignal(undefined);\n onMount(() => {\n const target = resolveElement(element);\n if (!target)\n return;\n let canceled = false;\n const unsubscribe = Providers.subscribe(target, selector, (url) => {\n if (!url)\n return;\n const repo = \"repo\" in window ? window.repo : undefined;\n if (!repo)\n return;\n void Promise.resolve(repo.find(url)).then((h) => {\n if (canceled)\n return;\n setHandle(() => h);\n });\n });\n onCleanup(() => {\n canceled = true;\n unsubscribe();\n });\n });\n // Mirror the doc into a store by `reconcile`-ing against the *materialized*\n // snapshot (`handle.doc()`) on every change, rather than replaying the\n // change's incremental patches (as `solid-automerge`'s `createDocumentProjection`\n // / `autoproduce` does).\n //\n // A whole-value write such as `doc.list = [...]` is lowered by Automerge to\n // `putObjectFromHydrate`, whose patch stream is a `put` that materializes the\n // new container *plus* per-element `insert` patches. Replaying that delta with\n // `applyPatches` double-applies the contents — the `put` seeds `[a, b]`, then\n // the inserts splice `a, b` in again, yielding `[a, b, a, b]` — even though the\n // document itself is correct. The materialized snapshot is always\n // authoritative, so reconciling against it is robust to any valid change,\n // whole-array reassignment included.\n const [store, setStore] = createStore({});\n const [ready, setReady] = createSignal(false);\n createEffect(() => {\n const h = handle();\n if (!h) {\n setReady(false);\n return;\n }\n const sync = () => {\n setStore(reconcile((h.doc() ?? {})));\n setReady(true);\n };\n sync();\n h.on(\"change\", sync);\n onCleanup(() => h.off(\"change\", sync));\n });\n const doc = () => (ready() ? store : undefined);\n return [doc, handle];\n}\n","/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar w = d * 7;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function (val, options) {\n options = options || {};\n var type = typeof val;\n if (type === 'string' && val.length > 0) {\n return parse(val);\n } else if (type === 'number' && isFinite(val)) {\n return options.long ? fmtLong(val) : fmtShort(val);\n }\n throw new Error(\n 'val is not a non-empty string or a valid number. val=' +\n JSON.stringify(val)\n );\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n str = String(str);\n if (str.length > 100) {\n return;\n }\n var match = /^(-?(?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(\n str\n );\n if (!match) {\n return;\n }\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n case 'weeks':\n case 'week':\n case 'w':\n return n * w;\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n default:\n return undefined;\n }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return Math.round(ms / d) + 'd';\n }\n if (msAbs >= h) {\n return Math.round(ms / h) + 'h';\n }\n if (msAbs >= m) {\n return Math.round(ms / m) + 'm';\n }\n if (msAbs >= s) {\n return Math.round(ms / s) + 's';\n }\n return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return plural(ms, msAbs, d, 'day');\n }\n if (msAbs >= h) {\n return plural(ms, msAbs, h, 'hour');\n }\n if (msAbs >= m) {\n return plural(ms, msAbs, m, 'minute');\n }\n if (msAbs >= s) {\n return plural(ms, msAbs, s, 'second');\n }\n return ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, msAbs, n, name) {\n var isPlural = msAbs >= n * 1.5;\n return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n}\n","\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n\nfunction setup(env) {\n\tcreateDebug.debug = createDebug;\n\tcreateDebug.default = createDebug;\n\tcreateDebug.coerce = coerce;\n\tcreateDebug.disable = disable;\n\tcreateDebug.enable = enable;\n\tcreateDebug.enabled = enabled;\n\tcreateDebug.humanize = require('ms');\n\tcreateDebug.destroy = destroy;\n\n\tObject.keys(env).forEach(key => {\n\t\tcreateDebug[key] = env[key];\n\t});\n\n\t/**\n\t* The currently active debug mode names, and names to skip.\n\t*/\n\n\tcreateDebug.names = [];\n\tcreateDebug.skips = [];\n\n\t/**\n\t* Map of special \"%n\" handling functions, for the debug \"format\" argument.\n\t*\n\t* Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n\t*/\n\tcreateDebug.formatters = {};\n\n\t/**\n\t* Selects a color for a debug namespace\n\t* @param {String} namespace The namespace string for the debug instance to be colored\n\t* @return {Number|String} An ANSI color code for the given namespace\n\t* @api private\n\t*/\n\tfunction selectColor(namespace) {\n\t\tlet hash = 0;\n\n\t\tfor (let i = 0; i < namespace.length; i++) {\n\t\t\thash = ((hash << 5) - hash) + namespace.charCodeAt(i);\n\t\t\thash |= 0; // Convert to 32bit integer\n\t\t}\n\n\t\treturn createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n\t}\n\tcreateDebug.selectColor = selectColor;\n\n\t/**\n\t* Create a debugger with the given `namespace`.\n\t*\n\t* @param {String} namespace\n\t* @return {Function}\n\t* @api public\n\t*/\n\tfunction createDebug(namespace) {\n\t\tlet prevTime;\n\t\tlet enableOverride = null;\n\t\tlet namespacesCache;\n\t\tlet enabledCache;\n\n\t\tfunction debug(...args) {\n\t\t\t// Disabled?\n\t\t\tif (!debug.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst self = debug;\n\n\t\t\t// Set `diff` timestamp\n\t\t\tconst curr = Number(new Date());\n\t\t\tconst ms = curr - (prevTime || curr);\n\t\t\tself.diff = ms;\n\t\t\tself.prev = prevTime;\n\t\t\tself.curr = curr;\n\t\t\tprevTime = curr;\n\n\t\t\targs[0] = createDebug.coerce(args[0]);\n\n\t\t\tif (typeof args[0] !== 'string') {\n\t\t\t\t// Anything else let's inspect with %O\n\t\t\t\targs.unshift('%O');\n\t\t\t}\n\n\t\t\t// Apply any `formatters` transformations\n\t\t\tlet index = 0;\n\t\t\targs[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {\n\t\t\t\t// If we encounter an escaped % then don't increase the array index\n\t\t\t\tif (match === '%%') {\n\t\t\t\t\treturn '%';\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t\tconst formatter = createDebug.formatters[format];\n\t\t\t\tif (typeof formatter === 'function') {\n\t\t\t\t\tconst val = args[index];\n\t\t\t\t\tmatch = formatter.call(self, val);\n\n\t\t\t\t\t// Now we need to remove `args[index]` since it's inlined in the `format`\n\t\t\t\t\targs.splice(index, 1);\n\t\t\t\t\tindex--;\n\t\t\t\t}\n\t\t\t\treturn match;\n\t\t\t});\n\n\t\t\t// Apply env-specific formatting (colors, etc.)\n\t\t\tcreateDebug.formatArgs.call(self, args);\n\n\t\t\tconst logFn = self.log || createDebug.log;\n\t\t\tlogFn.apply(self, args);\n\t\t}\n\n\t\tdebug.namespace = namespace;\n\t\tdebug.useColors = createDebug.useColors();\n\t\tdebug.color = createDebug.selectColor(namespace);\n\t\tdebug.extend = extend;\n\t\tdebug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.\n\n\t\tObject.defineProperty(debug, 'enabled', {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t\tget: () => {\n\t\t\t\tif (enableOverride !== null) {\n\t\t\t\t\treturn enableOverride;\n\t\t\t\t}\n\t\t\t\tif (namespacesCache !== createDebug.namespaces) {\n\t\t\t\t\tnamespacesCache = createDebug.namespaces;\n\t\t\t\t\tenabledCache = createDebug.enabled(namespace);\n\t\t\t\t}\n\n\t\t\t\treturn enabledCache;\n\t\t\t},\n\t\t\tset: v => {\n\t\t\t\tenableOverride = v;\n\t\t\t}\n\t\t});\n\n\t\t// Env-specific initialization logic for debug instances\n\t\tif (typeof createDebug.init === 'function') {\n\t\t\tcreateDebug.init(debug);\n\t\t}\n\n\t\treturn debug;\n\t}\n\n\tfunction extend(namespace, delimiter) {\n\t\tconst newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n\t\tnewDebug.log = this.log;\n\t\treturn newDebug;\n\t}\n\n\t/**\n\t* Enables a debug mode by namespaces. This can include modes\n\t* separated by a colon and wildcards.\n\t*\n\t* @param {String} namespaces\n\t* @api public\n\t*/\n\tfunction enable(namespaces) {\n\t\tcreateDebug.save(namespaces);\n\t\tcreateDebug.namespaces = namespaces;\n\n\t\tcreateDebug.names = [];\n\t\tcreateDebug.skips = [];\n\n\t\tconst split = (typeof namespaces === 'string' ? namespaces : '')\n\t\t\t.trim()\n\t\t\t.replace(/\\s+/g, ',')\n\t\t\t.split(',')\n\t\t\t.filter(Boolean);\n\n\t\tfor (const ns of split) {\n\t\t\tif (ns[0] === '-') {\n\t\t\t\tcreateDebug.skips.push(ns.slice(1));\n\t\t\t} else {\n\t\t\t\tcreateDebug.names.push(ns);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given string matches a namespace template, honoring\n\t * asterisks as wildcards.\n\t *\n\t * @param {String} search\n\t * @param {String} template\n\t * @return {Boolean}\n\t */\n\tfunction matchesTemplate(search, template) {\n\t\tlet searchIndex = 0;\n\t\tlet templateIndex = 0;\n\t\tlet starIndex = -1;\n\t\tlet matchIndex = 0;\n\n\t\twhile (searchIndex < search.length) {\n\t\t\tif (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {\n\t\t\t\t// Match character or proceed with wildcard\n\t\t\t\tif (template[templateIndex] === '*') {\n\t\t\t\t\tstarIndex = templateIndex;\n\t\t\t\t\tmatchIndex = searchIndex;\n\t\t\t\t\ttemplateIndex++; // Skip the '*'\n\t\t\t\t} else {\n\t\t\t\t\tsearchIndex++;\n\t\t\t\t\ttemplateIndex++;\n\t\t\t\t}\n\t\t\t} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition\n\t\t\t\t// Backtrack to the last '*' and try to match more characters\n\t\t\t\ttemplateIndex = starIndex + 1;\n\t\t\t\tmatchIndex++;\n\t\t\t\tsearchIndex = matchIndex;\n\t\t\t} else {\n\t\t\t\treturn false; // No match\n\t\t\t}\n\t\t}\n\n\t\t// Handle trailing '*' in template\n\t\twhile (templateIndex < template.length && template[templateIndex] === '*') {\n\t\t\ttemplateIndex++;\n\t\t}\n\n\t\treturn templateIndex === template.length;\n\t}\n\n\t/**\n\t* Disable debug output.\n\t*\n\t* @return {String} namespaces\n\t* @api public\n\t*/\n\tfunction disable() {\n\t\tconst namespaces = [\n\t\t\t...createDebug.names,\n\t\t\t...createDebug.skips.map(namespace => '-' + namespace)\n\t\t].join(',');\n\t\tcreateDebug.enable('');\n\t\treturn namespaces;\n\t}\n\n\t/**\n\t* Returns true if the given mode name is enabled, false otherwise.\n\t*\n\t* @param {String} name\n\t* @return {Boolean}\n\t* @api public\n\t*/\n\tfunction enabled(name) {\n\t\tfor (const skip of createDebug.skips) {\n\t\t\tif (matchesTemplate(name, skip)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfor (const ns of createDebug.names) {\n\t\t\tif (matchesTemplate(name, ns)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t* Coerce `val`.\n\t*\n\t* @param {Mixed} val\n\t* @return {Mixed}\n\t* @api private\n\t*/\n\tfunction coerce(val) {\n\t\tif (val instanceof Error) {\n\t\t\treturn val.stack || val.message;\n\t\t}\n\t\treturn val;\n\t}\n\n\t/**\n\t* XXX DO NOT USE. This is a temporary stub function.\n\t* XXX It WILL be removed in the next major release.\n\t*/\n\tfunction destroy() {\n\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t}\n\n\tcreateDebug.enable(createDebug.load());\n\n\treturn createDebug;\n}\n\nmodule.exports = setup;\n","/* eslint-env browser */\n\n/**\n * This is the web browser implementation of `debug()`.\n */\n\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = localstorage();\nexports.destroy = (() => {\n\tlet warned = false;\n\n\treturn () => {\n\t\tif (!warned) {\n\t\t\twarned = true;\n\t\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t\t}\n\t};\n})();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n\t'#0000CC',\n\t'#0000FF',\n\t'#0033CC',\n\t'#0033FF',\n\t'#0066CC',\n\t'#0066FF',\n\t'#0099CC',\n\t'#0099FF',\n\t'#00CC00',\n\t'#00CC33',\n\t'#00CC66',\n\t'#00CC99',\n\t'#00CCCC',\n\t'#00CCFF',\n\t'#3300CC',\n\t'#3300FF',\n\t'#3333CC',\n\t'#3333FF',\n\t'#3366CC',\n\t'#3366FF',\n\t'#3399CC',\n\t'#3399FF',\n\t'#33CC00',\n\t'#33CC33',\n\t'#33CC66',\n\t'#33CC99',\n\t'#33CCCC',\n\t'#33CCFF',\n\t'#6600CC',\n\t'#6600FF',\n\t'#6633CC',\n\t'#6633FF',\n\t'#66CC00',\n\t'#66CC33',\n\t'#9900CC',\n\t'#9900FF',\n\t'#9933CC',\n\t'#9933FF',\n\t'#99CC00',\n\t'#99CC33',\n\t'#CC0000',\n\t'#CC0033',\n\t'#CC0066',\n\t'#CC0099',\n\t'#CC00CC',\n\t'#CC00FF',\n\t'#CC3300',\n\t'#CC3333',\n\t'#CC3366',\n\t'#CC3399',\n\t'#CC33CC',\n\t'#CC33FF',\n\t'#CC6600',\n\t'#CC6633',\n\t'#CC9900',\n\t'#CC9933',\n\t'#CCCC00',\n\t'#CCCC33',\n\t'#FF0000',\n\t'#FF0033',\n\t'#FF0066',\n\t'#FF0099',\n\t'#FF00CC',\n\t'#FF00FF',\n\t'#FF3300',\n\t'#FF3333',\n\t'#FF3366',\n\t'#FF3399',\n\t'#FF33CC',\n\t'#FF33FF',\n\t'#FF6600',\n\t'#FF6633',\n\t'#FF9900',\n\t'#FF9933',\n\t'#FFCC00',\n\t'#FFCC33'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\n// eslint-disable-next-line complexity\nfunction useColors() {\n\t// NB: In an Electron preload script, document will be defined but not fully\n\t// initialized. Since we know we're in Chrome, we'll just detect this case\n\t// explicitly\n\tif (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n\t\treturn true;\n\t}\n\n\t// Internet Explorer and Edge do not support colors.\n\tif (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n\t\treturn false;\n\t}\n\n\tlet m;\n\n\t// Is webkit? http://stackoverflow.com/a/16459606/376773\n\t// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\t// eslint-disable-next-line no-return-assign\n\treturn (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||\n\t\t// Is firebug? http://stackoverflow.com/a/398120/376773\n\t\t(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||\n\t\t// Is firefox >= v31?\n\t\t// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/)) && parseInt(m[1], 10) >= 31) ||\n\t\t// Double check webkit in userAgent just in case we are in a worker\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/));\n}\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\targs[0] = (this.useColors ? '%c' : '') +\n\t\tthis.namespace +\n\t\t(this.useColors ? ' %c' : ' ') +\n\t\targs[0] +\n\t\t(this.useColors ? '%c ' : ' ') +\n\t\t'+' + module.exports.humanize(this.diff);\n\n\tif (!this.useColors) {\n\t\treturn;\n\t}\n\n\tconst c = 'color: ' + this.color;\n\targs.splice(1, 0, c, 'color: inherit');\n\n\t// The final \"%c\" is somewhat tricky, because there could be other\n\t// arguments passed either before or after the %c, so we need to\n\t// figure out the correct index to insert the CSS into\n\tlet index = 0;\n\tlet lastC = 0;\n\targs[0].replace(/%[a-zA-Z%]/g, match => {\n\t\tif (match === '%%') {\n\t\t\treturn;\n\t\t}\n\t\tindex++;\n\t\tif (match === '%c') {\n\t\t\t// We only are interested in the *last* %c\n\t\t\t// (the user may have provided their own)\n\t\t\tlastC = index;\n\t\t}\n\t});\n\n\targs.splice(lastC, 0, c);\n}\n\n/**\n * Invokes `console.debug()` when available.\n * No-op when `console.debug` is not a \"function\".\n * If `console.debug` is not available, falls back\n * to `console.log`.\n *\n * @api public\n */\nexports.log = console.debug || console.log || (() => {});\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\ttry {\n\t\tif (namespaces) {\n\t\t\texports.storage.setItem('debug', namespaces);\n\t\t} else {\n\t\t\texports.storage.removeItem('debug');\n\t\t}\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\nfunction load() {\n\tlet r;\n\ttry {\n\t\tr = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n\n\t// If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\tif (!r && typeof process !== 'undefined' && 'env' in process) {\n\t\tr = process.env.DEBUG;\n\t}\n\n\treturn r;\n}\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage() {\n\ttry {\n\t\t// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n\t\t// The Browser also has localStorage in the global context.\n\t\treturn localStorage;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\nmodule.exports = require('./common')(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nformatters.j = function (v) {\n\ttry {\n\t\treturn JSON.stringify(v);\n\t} catch (error) {\n\t\treturn '[UnexpectedJSONParseError]: ' + error.message;\n\t}\n};\n","// cabbages.ts\nimport debug from \"debug\";\nvar log = debug(\"cabbages\");\nfunction pojo(target) {\n return typeof target == \"object\" && typeof target != null && Object.getPrototypeOf(target) == Object.prototype;\n}\nvar BLOCK_MARKER = \"\\uFFFC\";\nfunction apply(target, ...rest) {\n if (rest.length == 0) {\n log(\"empty patch\");\n return;\n }\n const [path, range, val] = rest;\n let p = [...path];\n while (true) {\n let key = p.shift();\n if (!p.length) {\n const RANGE_ARRAY = Array.isArray(range);\n if (pojo(target) && RANGE_ARRAY && typeof key == \"undefined\" && typeof range[0] == \"string\") {\n delete target[range[0]];\n return;\n }\n if (RANGE_ARRAY || typeof range == \"number\") {\n if (typeof key == \"undefined\") {\n throw new Error(\"cant treat top level as a seq\");\n }\n key = key;\n let [start, end] = Array.isArray(range) ? range : [range, range + 1];\n const ZERO_LENGTH = Array.isArray(range) && range.length == 0;\n if (!ZERO_LENGTH && (start == null || end == null)) {\n throw new RangeError(\"it's all or nothing, no half measures\");\n }\n const DELETE = typeof val == \"undefined\";\n const INSERT = start === end && !DELETE;\n const APPEND = ZERO_LENGTH && !DELETE;\n const REPLACE = !INSERT && !DELETE && !APPEND;\n if (typeof target[key] == \"undefined\") {\n if (typeof target == \"string\") {\n return;\n } else if (typeof val == \"string\") {\n target[key] = \"\";\n } else {\n target[key] = [];\n }\n }\n let seq = target[key];\n if (Array.isArray(seq)) {\n if (APPEND) {\n Array.isArray(val) ? seq.push(...val) : seq.push(val);\n return;\n }\n if (INSERT || REPLACE) {\n Array.isArray(val) ? seq.splice(start, end - start, ...val) : seq.splice(start, end - start, val);\n return;\n }\n if (DELETE) {\n seq.splice(start, end - start);\n return;\n }\n throw new Error(\"i don't know what happened\");\n }\n if (typeof seq == \"string\") {\n if (APPEND) {\n target[key] = seq + val;\n return;\n }\n if (REPLACE || INSERT) {\n target[key] = seq.slice(0, start) + (typeof val == \"string\" ? val : val.map(\n (n) => typeof n == \"string\" ? n : BLOCK_MARKER\n ).join(\"\")) + seq.slice(end);\n return;\n }\n if (DELETE) {\n target[key] = seq.slice(0, start) + seq.slice(end);\n return;\n }\n throw new Error(\"i don't know what happened\");\n }\n if (pojo(seq) && RANGE_ARRAY && typeof range[0] == \"string\") {\n delete seq[range[0]];\n return;\n }\n throw new Error(\"not implemented\");\n }\n if (typeof key == \"undefined\") {\n if (typeof range != \"string\") {\n throw new Error(`can't index top-level map with ${range}`);\n }\n if (typeof val == \"undefined\") {\n delete target[range];\n } else {\n target[range] = val;\n }\n return;\n }\n if (typeof target[key] == \"undefined\") {\n target[key] = {};\n }\n if (RANGE_ARRAY) {\n let [a, b] = range;\n if (a != null && b != null) {\n if (typeof val == \"undefined\" && a != null && b != null) {\n delete target[key][a || b];\n } else {\n target[key][a || b] = val;\n }\n }\n } else {\n if (typeof val == \"undefined\") {\n delete target[key][range];\n } else if (typeof target[key] == \"string\") {\n return;\n } else {\n target[key][range] = val;\n }\n }\n return;\n }\n if (typeof key == \"undefined\") {\n throw new Error(\"cant treat top level as a seq\");\n }\n key = key;\n let nextkey = p[0];\n if (typeof target[key] == \"undefined\") {\n if (typeof nextkey == \"string\") {\n target[key] = {};\n } else if (typeof nextkey == \"number\") {\n target[key] = [];\n } else {\n throw new Error(`can't go down this road ${target}.${key}.${nextkey}`);\n }\n }\n target = target[key];\n }\n}\nvar patch = apply;\nfunction get(obj, key) {\n for (let p = 0; p < key.length; p++) {\n obj = obj ? obj[key[p]] : void 0;\n }\n return obj;\n}\nfunction fromAutomerge(autopatch, payload) {\n const path = autopatch.path.slice(0, -1);\n const key = autopatch.path[autopatch.path.length - 1];\n switch (autopatch.action) {\n case \"mark\":\n case \"unmark\":\n log(\n `skipping ${autopatch.action} because it doesn't affect material reality`\n );\n return [];\n case \"inc\":\n if (payload) {\n return [path, key, get(payload.patchInfo.after, autopatch.path)];\n } else {\n throw new Error(\n `can't apply ${autopatch.action} without payload argument`\n );\n }\n case \"conflict\":\n if (payload) {\n return [path, key, get(payload.patchInfo.after, autopatch.path)];\n } else {\n throw new Error(\n `can't apply ${autopatch.action} without payload argument`\n );\n }\n case \"del\": {\n return typeof key == \"string\" ? [path, key] : [path, [key, key + (autopatch.length || 1)]];\n }\n case \"insert\": {\n return [\n path,\n [key, key],\n structuredClone(autopatch.values)\n ];\n }\n case \"splice\": {\n return [path, [key, key], [autopatch.value]];\n }\n case \"put\": {\n return [path, key, structuredClone(autopatch.value)];\n }\n }\n}\nexport {\n apply,\n fromAutomerge,\n patch,\n pojo\n};\n","\"use strict\";\nimport { apply, fromAutomerge } from \"cabbages\";\nexport default function autoproduce(payload) {\n return (doc) => {\n for (let patch of payload.patches) {\n apply(doc, ...fromAutomerge(patch, payload));\n }\n };\n}\n//# sourceMappingURL=autoproduce.js.map\n","\"use strict\";\nimport { onCleanup } from \"solid-js\";\nimport autoproduce from \"./autoproduce.js\";\nimport { createStore, produce, reconcile } from \"solid-js/store\";\nconst cache = /* @__PURE__ */ new WeakMap();\nexport default function makeDocumentProjection(handle) {\n onCleanup(() => {\n const item = cache.get(handle);\n if (!item) return;\n if (!item.refs--) {\n item.cleanup();\n }\n });\n if (cache.has(handle)) {\n const item = cache.get(handle);\n item.refs++;\n return item.store;\n }\n const [doc, set] = createStore(structuredClone(handle.doc()));\n cache.set(handle, {\n refs: 0,\n store: doc,\n cleanup() {\n handle.off(\"change\", patch);\n handle.off(\"delete\", ondelete);\n cache.delete(handle);\n }\n });\n function patch(payload) {\n if (payload.scopeReplaced) {\n set(reconcile(payload.doc ?? {}));\n return;\n }\n set(produce(autoproduce(payload)));\n }\n function ondelete() {\n set(reconcile({}));\n }\n handle.on(\"change\", patch);\n handle.on(\"delete\", ondelete);\n return doc;\n}\n//# sourceMappingURL=makeDocumentProjection.js.map\n","import { getOwner, onCleanup, createSignal, untrack, sharedConfig, onMount, DEV, equalFn, } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nexport * from \"./types.js\";\n//\n// GENERAL HELPERS:\n//\nexport { isServer };\nexport const isClient = !isServer;\nexport const isDev = isClient && !!DEV;\nexport const isProd = !isDev;\n/** no operation */\nexport const noop = (() => void 0);\nexport const trueFn = () => true;\nexport const falseFn = () => false;\n/** @deprecated use {@link equalFn} from \"solid-js\" */\nexport const defaultEquals = equalFn;\nexport const EQUALS_FALSE_OPTIONS = { equals: false };\nexport const INTERNAL_OPTIONS = { internal: true };\n/**\n * Check if the value is an instance of ___\n */\nexport const ofClass = (v, c) => v instanceof c || (v && v.constructor === c);\n/** Check if value is typeof \"object\" or \"function\" */\nexport function isObject(value) {\n return value !== null && (typeof value === \"object\" || typeof value === \"function\");\n}\nexport const isNonNullable = (i) => i != null;\nexport const filterNonNullable = (arr) => arr.filter(isNonNullable);\nexport const compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0);\n/**\n * Check shallow array equality\n */\nexport const arrayEquals = (a, b) => a === b || (a.length === b.length && a.every((e, i) => e === b[i]));\n/**\n * Returns a function that will call all functions in the order they were chained with the same arguments.\n */\nexport function chain(callbacks) {\n return (...args) => {\n for (const callback of callbacks)\n callback && callback(...args);\n };\n}\n/**\n * Returns a function that will call all functions in the reversed order with the same arguments.\n */\nexport function reverseChain(callbacks) {\n return (...args) => {\n for (let i = callbacks.length - 1; i >= 0; i--) {\n const callback = callbacks[i];\n callback && callback(...args);\n }\n };\n}\nexport const clamp = (n, min, max) => Math.min(Math.max(n, min), max);\n/**\n * Accesses the value of a MaybeAccessor\n * @example\n * ```ts\n * access(\"foo\") // => \"foo\"\n * access(() => \"foo\") // => \"foo\"\n * ```\n */\nexport const access = (v) => typeof v === \"function\" && !v.length ? v() : v;\nexport const asArray = (value) => Array.isArray(value) ? value : value ? [value] : [];\n/**\n * Access an array of MaybeAccessors\n * @example\n * const list = [1, 2, () => 3)] // T: MaybeAccessor<number>[]\n * const newList = accessArray(list) // T: number[]\n */\nexport const accessArray = (list) => list.map(v => access(v));\n/**\n * Run the function if the accessed value is not `undefined` nor `null`\n * @param value\n * @param fn\n */\nexport const withAccess = (value, fn) => {\n const _value = access(value);\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n typeof _value != null && fn(_value);\n};\nexport const asAccessor = (v) => (typeof v === \"function\" ? v : () => v);\n/** If value is a function – call it with a given arguments – otherwise get the value as is */\nexport function accessWith(valueOrFn, ...args) {\n return typeof valueOrFn === \"function\" ? valueOrFn(...args) : valueOrFn;\n}\nexport function defer(deps, fn, initialValue) {\n const isArray = Array.isArray(deps);\n let prevInput;\n let shouldDefer = true;\n return prevValue => {\n let input;\n if (isArray) {\n input = Array(deps.length);\n for (let i = 0; i < deps.length; i++)\n input[i] = deps[i]();\n }\n else\n input = deps();\n if (shouldDefer) {\n shouldDefer = false;\n prevInput = input;\n return initialValue;\n }\n const result = untrack(() => fn(input, prevInput, prevValue));\n prevInput = input;\n return result;\n };\n}\n/**\n * Get entries of an object\n */\nexport const entries = Object.entries;\n/**\n * Get keys of an object\n */\nexport const keys = Object.keys;\n/**\n * Solid's `onCleanup` that doesn't warn in development if used outside of a component.\n */\nexport const tryOnCleanup = isDev\n ? fn => (getOwner() ? onCleanup(fn) : fn)\n : onCleanup;\nexport const createCallbackStack = () => {\n let stack = [];\n const clear = () => (stack = []);\n return {\n push: (...callbacks) => stack.push(...callbacks),\n execute(arg0, arg1, arg2, arg3) {\n stack.forEach(cb => cb(arg0, arg1, arg2, arg3));\n clear();\n },\n clear,\n };\n};\n/**\n * Group synchronous function calls.\n * @param fn\n * @returns `fn`\n */\nexport function createMicrotask(fn) {\n let calls = 0;\n let args;\n onCleanup(() => (calls = 0));\n return (...a) => {\n (args = a), calls++;\n queueMicrotask(() => --calls === 0 && fn(...args));\n };\n}\n/**\n * A hydratable version of the {@link createSignal}. It will use the serverValue on the server and the update function on the client. If initialized during hydration it will use serverValue as the initial value and update it once hydration is complete.\n *\n * @param serverValue initial value of the state on the server\n * @param update called once on the client or on hydration to initialize the value\n * @param options {@link SignalOptions}\n * @returns\n * ```ts\n * [state: Accessor<T>, setState: Setter<T>]\n * ```\n * @see {@link createSignal}\n */\nexport function createHydratableSignal(serverValue, update, options) {\n if (isServer) {\n return createSignal(serverValue, options);\n }\n if (sharedConfig.context) {\n const [state, setState] = createSignal(serverValue, options);\n onMount(() => setState(() => update()));\n return [state, setState];\n }\n return createSignal(update(), options);\n}\n/** @deprecated use {@link createHydratableSignal} instead */\nexport const createHydrateSignal = createHydratableSignal;\n/**\n * Handle items removed and added to the array by diffing it by refference.\n *\n * @param current new array instance\n * @param prev previous array copy\n * @param handleAdded called once for every added item to array\n * @param handleRemoved called once for every removed from array\n */\nexport function handleDiffArray(current, prev, handleAdded, handleRemoved) {\n const currLength = current.length;\n const prevLength = prev.length;\n let i = 0;\n if (!prevLength) {\n for (; i < currLength; i++)\n handleAdded(current[i]);\n return;\n }\n if (!currLength) {\n for (; i < prevLength; i++)\n handleRemoved(prev[i]);\n return;\n }\n for (; i < prevLength; i++) {\n if (prev[i] !== current[i])\n break;\n }\n let prevEl;\n let currEl;\n prev = prev.slice(i);\n current = current.slice(i);\n for (prevEl of prev) {\n if (!current.includes(prevEl))\n handleRemoved(prevEl);\n }\n for (currEl of current) {\n if (!prev.includes(currEl))\n handleAdded(currEl);\n }\n}\n// ─── String transforms ────────────────────────────────────────────────────────\n/**\n * Parse a string as a single JSON value.\n *\n * ```ts\n * const { data } = createSSE<{ status: string }>(url, { transform: json });\n * ```\n */\nexport const json = (raw) => JSON.parse(raw);\n/**\n * Parse a string as newline-delimited JSON (NDJSON / JSON Lines).\n *\n * Each non-empty line is parsed as a separate JSON value and returned as an array.\n *\n * ```ts\n * const { data } = createSSE<TickEvent[]>(url, { transform: ndjson });\n * // data() === [{ id: 1, type: \"tick\" }, { id: 2, type: \"tick\" }]\n * ```\n */\nexport const ndjson = (raw) => raw\n .split(\"\\n\")\n .filter(line => line !== \"\")\n .map(line => JSON.parse(line));\n/**\n * Split a string into individual lines, returning a `string[]`. Empty lines are filtered out.\n *\n * ```ts\n * const { data } = createSSE<string[]>(url, { transform: lines });\n * // data() === [\"line one\", \"line two\"]\n * ```\n */\nexport const lines = (raw) => raw.split(\"\\n\").filter(line => line !== \"\");\n/**\n * Parse a string as a number using `Number()` semantics.\n *\n * Note: `\"\"` → `0`, non-numeric strings → `NaN`.\n *\n * ```ts\n * const { data } = createSSE<number>(url, { transform: number });\n * // data() === 42\n * ```\n */\nexport const number = (raw) => Number(raw);\nexport function safe(transform, fallback) {\n return (raw) => {\n try {\n return transform(raw);\n }\n catch {\n return fallback;\n }\n };\n}\n/**\n * Compose two transforms into one: the output of `a` is passed as the input of `b`.\n *\n * ```ts\n * const { data } = createSSE<RawEvent[]>(url, {\n * transform: pipe(ndjson<RawEvent>, rows => rows.filter(r => r.type === \"tick\")),\n * });\n * ```\n */\nexport function pipe(a, b) {\n return (raw) => b(a(raw));\n}\n","\"use strict\";\nimport { createMemo } from \"solid-js\";\nimport makeDocumentProjection from \"./makeDocumentProjection.js\";\nimport { access } from \"@solid-primitives/utils\";\nexport default function createDocumentProjection(handle) {\n const projection = createMemo(\n () => access(handle) && makeDocumentProjection(access(handle))\n );\n return projection;\n}\n//# sourceMappingURL=createDocumentProjection.js.map\n","\"use strict\";\nimport { createContext } from \"solid-js\";\nexport const RepoContext = createContext(\n null\n);\n//# sourceMappingURL=context.js.map\n","\"use strict\";\nimport { createEffect, createResource, useContext } from \"solid-js\";\nimport { access } from \"@solid-primitives/utils\";\nimport { RepoContext } from \"./context.js\";\nexport default function useDocHandle(url, options) {\n const contextRepo = useContext(RepoContext);\n if (!options?.repo && !contextRepo) {\n throw new Error(\"use outside <RepoContext> requires options.repo\");\n }\n const repo = options?.repo || contextRepo;\n function getExistingHandle() {\n if (options?.[\"~skipInitialValue\"]) return void 0;\n const unwrappedURL = access(url);\n if (!unwrappedURL) return void 0;\n return peekReadyHandle(repo, unwrappedURL);\n }\n const [handle, { mutate }] = createResource(\n url,\n (url2) => repo.find(url2),\n {\n initialValue: getExistingHandle()\n }\n );\n createEffect(() => {\n if (!access(url)) {\n mutate();\n }\n });\n return handle;\n}\nfunction isQueryable(repo) {\n return typeof repo.query == \"function\";\n}\nfunction peekReadyHandle(repo, url) {\n if (isQueryable(repo)) {\n const state2 = repo.query(url).state();\n return state2.status == \"ready\" ? state2.handle : void 0;\n }\n const state = repo.findWithProgress(url).peek();\n return state.state == \"ready\" ? state.handle : void 0;\n}\n//# sourceMappingURL=useDocHandle.js.map\n","\"use strict\";\nimport createDocumentProjection from \"./createDocumentProjection.js\";\nimport useDocHandle from \"./useDocHandle.js\";\nexport default function useDocument(url, options) {\n const handle = useDocHandle(url, options);\n return [createDocumentProjection(handle), handle];\n}\n//# sourceMappingURL=useDocument.js.map\n","import type { GroupingStrategyConfig, HistoryItem } from \"../types\";\n\nconst relativeTime = (timestamp: number): string => {\n const now = Date.now();\n const diff = now - timestamp;\n\n const seconds = Math.floor(diff / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n const weeks = Math.floor(days / 7);\n const months = Math.floor(days / 30);\n const years = Math.floor(days / 365);\n\n if (seconds < 60) {\n return \"just now\";\n } else if (minutes < 60) {\n return `${minutes} minute${minutes === 1 ? \"\" : \"s\"} ago`;\n } else if (hours < 24) {\n return `${hours} hour${hours === 1 ? \"\" : \"s\"} ago`;\n } else if (days < 7) {\n return `${days} day${days === 1 ? \"\" : \"s\"} ago`;\n } else if (weeks < 4) {\n return `${weeks} week${weeks === 1 ? \"\" : \"s\"} ago`;\n } else if (months < 12) {\n return `${months} month${months === 1 ? \"\" : \"s\"} ago`;\n } else {\n return `${years} year${years === 1 ? \"\" : \"s\"} ago`;\n }\n};\n\n/**\n * Format a Unix timestamp (in seconds) to a display string.\n * Returns e.g. \"Jan 5, 2:30 PM (3 hours ago)\" or \"\" if no timestamp.\n */\nexport function formatTime(timestampSeconds: number | undefined): string {\n if (!timestampSeconds) return \"\";\n\n const date = new Date(timestampSeconds * 1000);\n const datePart = date.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n });\n const timePart = date.toLocaleTimeString(undefined, {\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n });\n const relative = relativeTime(timestampSeconds * 1000);\n\n return `${relative} (${datePart}, ${timePart})`;\n}\n\nexport function formatTimeOnly(timestampSeconds: number | undefined): string {\n if (!timestampSeconds) return \"\";\n const date = new Date(timestampSeconds * 1000);\n return date\n .toLocaleTimeString(undefined, {\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n })\n .toLowerCase();\n}\n\n// ============================================================================\n// Change labels\n// ============================================================================\n\nexport type ChangeSizeThresholds = { large: number; medium: number };\n\nexport function computeChangeSizeThresholds(items: HistoryItem[]): ChangeSizeThresholds {\n const magnitudes = items\n .map((i) => (i.additions ?? 0) + (i.deletions ?? 0))\n .filter((m) => m > 0)\n .sort((a, b) => a - b);\n\n if (magnitudes.length === 0) return { large: 0, medium: 0 };\n\n const at = (p: number) => magnitudes[Math.floor((magnitudes.length - 1) * p)];\n return { large: at(0.66), medium: at(0.33) };\n}\n\nexport function getChangeLabel(item: HistoryItem, thresholds: ChangeSizeThresholds): string {\n const add = item.additions ?? 0;\n const del = item.deletions ?? 0;\n const magnitude = add + del;\n\n if (magnitude === 0) return \"No change\";\n\n const size =\n magnitude >= thresholds.large ? \"Large\"\n : magnitude >= thresholds.medium ? \"Medium\"\n : \"Minor\";\n\n const direction =\n del < add * 0.2 ? \"addition\"\n : add < del * 0.2 ? \"deletion\"\n : \"edits\";\n\n return `${size} ${direction}`;\n}\n\n// ============================================================================\n// Strategies\n// ============================================================================\n\nexport const DEFAULT_TIME_WINDOW = 15 * 60 * 1000; // 15 minutes\n\n/**\n * Generate a unique cache key for a grouping strategy configuration.\n *\n * NOTE: Keep in sync with the duplicate implementation in `./task.ts` — the\n * task module can't currently import from siblings when run under the shared\n * worker.\n */\nexport function getStrategyKey(config: GroupingStrategyConfig): string {\n switch (config.name) {\n case \"author\":\n return \"author\";\n case \"timeWindow\": {\n const windowMs = config.params?.timeWindow ?? DEFAULT_TIME_WINDOW;\n if (config.params?.perActor) return `timeWindowPerActor:${windowMs}`;\n return `timeWindow:${windowMs}`;\n }\n default:\n throw new Error(`Unknown strategy: ${(config as { name: string }).name}`);\n }\n}\n","export * from './types';\nexport function queueSet(accountHandle) {\n return new TaskQueueSet(accountHandle);\n}\nexport function queue(taskQueueUrl) {\n return new TaskQueue(taskQueueUrl);\n}\nexport function createQueue(name) {\n const taskQueueHandle = repo.create({\n title: name,\n activeRouter: null,\n pending: [],\n done: [],\n doneSet: {},\n });\n return new TaskQueue(taskQueueHandle);\n}\nexport class TaskQueueSet {\n constructor(accountHandle) {\n this.accountHandle = accountHandle;\n }\n /** Adds a task queue to this set. */\n add(taskQueue) {\n const url = typeof taskQueue === 'string' ? taskQueue : taskQueue.url;\n this.accountHandle.change((doc) => {\n if (!doc.__taskQueues__) {\n doc.__taskQueues__ = {};\n }\n doc.__taskQueues__[url] = true;\n });\n }\n /** Removes a task queue from this set. */\n remove(taskQueue) {\n const url = typeof taskQueue === 'string' ? taskQueue : taskQueue.url;\n this.accountHandle.change((doc) => {\n if (doc.__taskQueues__) {\n delete doc.__taskQueues__[url];\n }\n });\n }\n}\nexport class TaskQueue {\n constructor(handleOrUrl) {\n this._handle = null;\n if (typeof handleOrUrl === 'string') {\n this.url = handleOrUrl;\n }\n else {\n this.url = handleOrUrl.url;\n this._handle = handleOrUrl;\n }\n }\n async getHandle() {\n if (!this._handle) {\n this._handle = await repo.find(this.url);\n }\n return this._handle;\n }\n async addTask(task) {\n const importUrl = task.code\n ? `data:application/javascript;base64,${btoa(task.code)}`\n : '' + task.importUrl;\n const taskDocHandle = repo.create({\n input: task.input,\n importUrl,\n runs: [],\n });\n const handle = await this.getHandle();\n handle.change((doc) => doc.pending.push(taskDocHandle.url));\n return new Task(handle, taskDocHandle);\n }\n}\nclass Task {\n constructor(queueHandle, handle) {\n this.queueHandle = queueHandle;\n this.handle = handle;\n }\n get url() {\n return this.handle.url;\n }\n /** Returns this task's input. */\n getInput() {\n return this.handle.doc().input;\n }\n /** Returns this task's result, or `undefined` if it has not yet completed. */\n getResultSync() {\n return this.getSuccessfulRun(this.handle.doc())?.result;\n }\n /** Returns this task's result, once it's available. */\n getResult() {\n return new Promise((resolve) => {\n const changeHandler = (payload) => {\n const successfulRun = this.getSuccessfulRun(payload.doc);\n if (successfulRun) {\n this.handle.off('change', changeHandler);\n resolve(successfulRun.result);\n }\n };\n this.handle.on('change', changeHandler);\n });\n }\n getSuccessfulRun(doc) {\n const runs = doc.runs;\n for (let idx = runs.length - 1; idx >= 0; idx--) {\n const run = runs[idx];\n if (run.status === 'succeeded') {\n return run;\n }\n }\n return null;\n }\n /** Returns `true` if this task was pending and has now been cancelled. */\n cancel() {\n let found = false;\n this.queueHandle.change((doc) => {\n const idx = doc.pending.indexOf(this.url);\n if (idx >= 0) {\n doc.pending.splice(idx, 1);\n found = true;\n }\n });\n return found;\n }\n /** Returns the execution history of this task. */\n getRunInfos() {\n return this.handle.doc().runs;\n }\n}\n//# sourceMappingURL=index.js.map","import * as Automerge from \"@automerge/automerge/slim\";\nimport type { ChangeMetadata } from \"@automerge/automerge/slim\";\nimport type { DocHandle, Repo } from \"@automerge/automerge-repo/slim\";\nimport type { AutomergeUrl } from \"@automerge/automerge-repo/slim\";\nimport {\n makeDocumentProjection,\n useDocument,\n} from \"solid-automerge\";\nimport {\n createMemo,\n createEffect,\n createSignal,\n Accessor,\n onCleanup,\n} from \"solid-js\";\nimport type {\n HistoryItem,\n GroupingStrategyConfig,\n HistoryGroupingsDoc,\n} from \"../../types\";\nimport type { HasPatchworkMetadata } from \"@inkandswitch/patchwork-filesystem\";\nimport { DEFAULT_TIME_WINDOW, getStrategyKey } from \"../utils\";\nimport * as tasklib from \"@awarth/tasklib\";\n\n// Short cooldown between consecutive dispatches to suppress duplicate enqueues\n// while a task is still in-flight / has yet to update `cachedHeads`. The\n// primary dispatch gate is the precise group-boundary condition below; this is\n// just a safety net.\nconst DISPATCH_COOLDOWN_MS = 5 * 1000;\n\nexport interface CachedHistory {\n items: Accessor<HistoryItem[]>;\n /**\n * True while no history document exists yet for this source doc — the\n * bootstrap task has been dispatched but hasn't finished creating and\n * linking the history doc. Consumers can use this to show a dedicated\n * \"computing history…\" UI instead of the (empty) item list.\n */\n isInitializing: Accessor<boolean>;\n /** True while a forced recompute is in progress */\n isRecalculating: Accessor<boolean>;\n /** Unix ms timestamp from historyDoc.updatedAt — when the task last ran */\n updatedAt: Accessor<number | undefined>;\n /** Reset the cache and re-dispatch the grouping task from scratch */\n forceRecompute: () => void;\n /** Persist a user-defined label for an item (keyed by latestHash) */\n setLabel: (hash: string, label: string) => void;\n}\n\n/**\n * Hook that manages history grouping with the history document as the source\n * of truth for stored groupings, plus a synthesized \"virtual\" trailing item\n * for any changes that have landed since the last task run.\n *\n * A single change-listener on the source handle:\n * - publishes the current source heads into a reactive signal so the virtual\n * tail can re-render, and\n * - (re)dispatches the background grouping task precisely when doing so would\n * actually change what the UI shows — namely, when the delta since\n * `cachedHeads` would no longer fit inside one grouping window. Until that\n * point the virtual trailing item is an exact stand-in for the single group\n * the task would produce, so dispatching would be pure churn.\n *\n * @param sourceHandle - Handle to the source document\n * @param strategyConfig - Grouping strategy configuration (reactive)\n * @param repo - Automerge repository\n * @returns Reactive items accessor + an `isInitializing` flag for the\n * pre-history-doc state.\n */\nexport function useCachedHistory(\n sourceHandle: Accessor<DocHandle<unknown> | undefined>,\n strategyConfig: Accessor<GroupingStrategyConfig>,\n repo: Repo\n): CachedHistory {\n const sourceDoc = createMemo(() => {\n const handle = sourceHandle();\n if (!handle) return undefined;\n return makeDocumentProjection(handle as DocHandle<HasPatchworkMetadata>);\n });\n\n // PART 1: Get history document URL from source document\n const historyUrl = createMemo<AutomergeUrl | undefined>(() => {\n const handle = sourceHandle();\n const doc = sourceDoc();\n if (!handle || !doc) return undefined;\n\n const metadata = (doc as HasPatchworkMetadata)?.[\"@patchwork\"];\n return metadata?.history as AutomergeUrl | undefined;\n });\n\n // PART 2: Subscribe to history document reactively (for UI updates)\n const [historyDoc, historyDocHandle] = useDocument<HistoryGroupingsDoc>(\n historyUrl,\n { repo }\n );\n\n let lastDispatchTime = 0;\n\n const dispatchTask = (sourceUrl: AutomergeUrl) => {\n if (localStorage.useTasks) {\n tasklib\n .queue(\"automerge:2xrHArq3QwSGHaeUdquP7ECTpnEL\" as AutomergeUrl)\n .addTask<AutomergeUrl, void>({\n input: sourceUrl,\n importUrl: new URL(/* @vite-ignore */ \"../task.js\", import.meta.url),\n });\n lastDispatchTime = Date.now();\n } else {\n import(\"../task\").then((m) => {\n m.default(sourceUrl);\n lastDispatchTime = Date.now();\n });\n }\n };\n\n // PART 3: Watch the source document. On every change we update\n // `sourceHeads` (so the items memo re-renders the virtual tail) and decide\n // whether to dispatch the grouping task.\n //\n // Dispatch condition:\n // - Bootstrap: no history doc exists yet → dispatch.\n // - Heads match the history doc's cached heads → nothing to do.\n // - Otherwise, dispatch iff the delta's time span exceeds the grouping\n // window. This is the *exact* point at which the task would produce a\n // materially different result than the virtual trailing item the UI is\n // already showing. A small `DISPATCH_COOLDOWN_MS` suppresses duplicate\n // enqueues while a task is still in-flight.\n const [sourceHeads, setSourceHeads] = createSignal<string[] | undefined>(\n undefined\n );\n\n const [isRecalculating, setIsRecalculating] = createSignal(false);\n\n createEffect(() => {\n const source = sourceHandle();\n if (!source) {\n setSourceHeads(undefined);\n return;\n }\n\n const onChange = () => {\n const sourceRawDoc = source.doc();\n if (!sourceRawDoc) return;\n\n const currentHeads = Automerge.getHeads(sourceRawDoc);\n setSourceHeads(currentHeads);\n\n const hHandle = historyDocHandle();\n const histDoc = hHandle?.doc();\n\n // Bootstrap: no history doc yet — dispatch to create one.\n if (!histDoc) {\n if (Date.now() - lastDispatchTime < DISPATCH_COOLDOWN_MS) return;\n dispatchTask(source.url);\n return;\n }\n\n const cachedHeads = histDoc.heads ?? [];\n if (headsEqual(currentHeads, cachedHeads)) return;\n\n if (Date.now() - lastDispatchTime < DISPATCH_COOLDOWN_MS) return;\n\n const deltaMeta = Automerge.getChangesMetaSince(\n sourceRawDoc,\n cachedHeads\n );\n if (deltaMeta.length === 0) return;\n\n const windowMs = strategyWindowMs(strategyConfig());\n if (windowMs !== undefined && deltaTimeSpan(deltaMeta) <= windowMs) {\n return;\n }\n\n dispatchTask(source.url);\n };\n\n source.on(\"change\", onChange);\n onChange();\n\n onCleanup(() => {\n source.off(\"change\", onChange);\n });\n });\n\n // Clear isRecalculating once the task writes non-empty heads back.\n createEffect(() => {\n const heads = historyDoc()?.heads;\n if (heads && heads.length > 0 && isRecalculating()) {\n setIsRecalculating(false);\n }\n });\n\n // PART 4: Return reactive items. If the source doc has advanced past the\n // cached heads, synthesize a single \"virtual\" item at the top of the list\n // covering the ungrouped tail. The virtual item is never stored; it\n // disappears once the background task runs and folds the tail into the\n // cached groupings.\n const items = createMemo<HistoryItem[]>(() => {\n const doc = historyDoc();\n const strategyKey = getStrategyKey(strategyConfig());\n const labels = doc?.labels ?? {};\n // Deduplicate by latestHash — concurrent task runs (e.g. two browser tabs)\n // can each splice the same group into the array before syncing, leaving\n // duplicate entries in the stored doc.\n const storedItems: HistoryItem[] = deduplicateItems(\n doc?.groupings?.[strategyKey]?.items ?? []\n ).map((item) =>\n labels[item.latestHash]\n ? { ...item, customLabel: labels[item.latestHash] }\n : item\n );\n\n // While recalculating, keep existing items visible to avoid collapsing the\n // list into a single virtual item covering all history.\n if (isRecalculating()) return storedItems;\n\n const cachedHeads = doc?.heads ?? [];\n const currentSourceHeads = sourceHeads();\n if (!currentSourceHeads || headsEqual(currentSourceHeads, cachedHeads)) {\n return storedItems;\n }\n\n const handle = sourceHandle();\n const sourceRawDoc = handle?.doc();\n if (!sourceRawDoc) return storedItems;\n\n const deltaMeta = Automerge.getChangesMetaSince(sourceRawDoc, cachedHeads);\n if (deltaMeta.length === 0) return storedItems;\n\n // Newest-first to match the cached items ordering.\n deltaMeta.reverse();\n\n const virtualItem = buildVirtualItem(deltaMeta, storedItems[0]?.latestHash);\n\n const virtualWithLabel = labels[virtualItem.latestHash]\n ? { ...virtualItem, customLabel: labels[virtualItem.latestHash] }\n : virtualItem;\n return [virtualWithLabel, ...storedItems];\n });\n\n // True until the source doc carries a link to a history doc AND that doc\n // has actually loaded. Covers both the bootstrap window (task hasn't yet\n // created and linked the history doc) and the brief load window for a doc\n // that already had one.\n const isInitializing = createMemo(() => {\n if (!historyUrl()) return true;\n return historyDoc() === undefined;\n });\n\n const updatedAt = createMemo<number | undefined>(\n () => historyDoc()?.updatedAt\n );\n\n const forceRecompute = () => {\n const hHandle = historyDocHandle();\n if (hHandle) {\n hHandle.change((doc: HistoryGroupingsDoc) => {\n doc.heads = [];\n doc.updatedAt = 0; // bypass throttle so the task runs immediately\n });\n setIsRecalculating(true);\n }\n const source = sourceHandle();\n if (source) dispatchTask(source.url);\n };\n\n const setLabel = (hash: string, label: string) => {\n const hHandle = historyDocHandle();\n if (!hHandle) return;\n hHandle.change((doc: HistoryGroupingsDoc) => {\n if (!doc.labels) doc.labels = {};\n if (label.trim() === \"\") {\n delete doc.labels[hash];\n } else {\n doc.labels[hash] = label.trim();\n }\n });\n };\n\n return {\n items,\n isInitializing,\n isRecalculating,\n updatedAt,\n forceRecompute,\n setLabel,\n };\n}\n\n/**\n * Build a single `HistoryItem` covering every change between the history\n * doc's cached heads and the source doc's current heads. This item exists\n * only at runtime — it is never written to the cache.\n */\nfunction buildVirtualItem(\n deltaMeta: ChangeMetadata[],\n firstStoredLatestHash: string | undefined\n): HistoryItem {\n const authors: string[] = [];\n let minTime = Infinity;\n let maxTime = -Infinity;\n for (const m of deltaMeta) {\n if (m.actor && !authors.includes(m.actor)) authors.push(m.actor);\n const t = m.time;\n if (t !== undefined) {\n if (t < minTime) minTime = t;\n if (t > maxTime) maxTime = t;\n }\n }\n\n const item: HistoryItem = {\n id: `virtual-${deltaMeta[0].hash}-${deltaMeta.length}`,\n count: deltaMeta.length,\n latestHash: deltaMeta[0].hash,\n authors,\n isVirtual: true,\n };\n\n if (minTime !== Infinity) {\n item.startTime = minTime;\n item.endTime = maxTime;\n }\n\n // The change immediately before the virtual tail is the newest stored item's\n // representative hash. Leave `beforeHead` unset on a fresh doc (no stored\n // items yet) so the selection yields a from-genesis diff.\n if (firstStoredLatestHash) {\n item.beforeHead = firstStoredLatestHash;\n }\n\n return item;\n}\n\n/**\n * Remove items with duplicate latestHash values, keeping the first occurrence.\n * Guards against concurrent task runs each splicing the same group into the\n * stored array before their changes sync and merge.\n */\nfunction deduplicateItems(items: HistoryItem[]): HistoryItem[] {\n const seen = new Set<string>();\n return items.filter((item) => {\n if (seen.has(item.latestHash)) return false;\n seen.add(item.latestHash);\n return true;\n });\n}\n\n/**\n * Check if two heads arrays are equal (order-independent)\n */\nfunction headsEqual(heads1: string[], heads2: string[]): boolean {\n if (heads1.length !== heads2.length) return false;\n const set = new Set(heads2);\n return heads1.every((h) => set.has(h));\n}\n\n/**\n * Wall-clock span covered by a set of change metadata entries, in\n * milliseconds. Returns 0 if no entries carry a timestamp. Change `time` is\n * stored by Automerge in seconds.\n */\nfunction deltaTimeSpan(deltaMeta: ChangeMetadata[]): number {\n let min = Infinity;\n let max = -Infinity;\n for (const m of deltaMeta) {\n const t = m.time;\n if (t === undefined) continue;\n if (t < min) min = t;\n if (t > max) max = t;\n }\n if (min === Infinity || max === -Infinity) return 0;\n return (max - min) * 1000;\n}\n\n/**\n * Width (in ms) of a grouping strategy's natural boundary, or `undefined` if\n * the strategy doesn't have a time-based boundary. For such strategies we\n * don't yet have a precise group-boundary dispatch condition, so callers\n * should dispatch on any delta rather than waiting.\n */\nfunction strategyWindowMs(config: GroupingStrategyConfig): number | undefined {\n if (config.name === \"timeWindow\") {\n return config.params?.timeWindow ?? DEFAULT_TIME_WINDOW;\n }\n return undefined;\n}\n","import type {\n DatatypeDescription,\n Plugin,\n PluginDescription,\n} from \"@inkandswitch/patchwork-plugins\";\nimport { getRegistry } from \"@inkandswitch/patchwork-plugins\";\nimport { onCleanup } from \"solid-js\";\nimport { createStore, reconcile } from \"solid-js/store\";\n\nfunction usePlugins<T extends PluginDescription>(type: string): Plugin<T>[] {\n const registry = getRegistry<T>(type);\n const [plugins, setPlugins] = createStore(registry.all());\n const dispose = registry.on(\"changed\", () =>\n setPlugins(reconcile(registry.all()))\n );\n onCleanup(dispose);\n return plugins;\n}\n\nexport function useDatatypes(): Plugin<DatatypeDescription>[] {\n return usePlugins<DatatypeDescription>(\"patchwork:datatype\");\n}\n","/**\n * Type predicate to ensure a value is of type D\n */\nexport function isPluginDescription(value) {\n return (value !== null &&\n typeof value === \"object\" &&\n \"id\" in value &&\n \"type\" in value &&\n \"name\" in value);\n}\n/**\n * Check if a value is a loadable plugin\n */\nexport function isLoadablePlugin(value) {\n return (isPluginDescription(value) &&\n ((\"load\" in value && typeof value.load === \"function\") ||\n (\"import\" in value && typeof value.import === \"string\")));\n}\n/**\n * Check if a value is a loaded plugin\n */\nexport function isLoadedPlugin(value) {\n return isPluginDescription(value) && \"module\" in value;\n}\n/**\n * Check if a value is a plugin, optionally of a specific type\n * If a type is provided, it will be used to infer the correct plugin type\n */\nexport function isPlugin(value) {\n return isPluginDescription(value);\n}\n","import { createMemo, Accessor } from \"solid-js\";\nimport {\n getType,\n HasPatchworkMetadata,\n} from \"@inkandswitch/patchwork-filesystem\";\nimport { useDatatypes } from \"../lib/solid-plugins\";\nimport { isLoadedPlugin } from \"@inkandswitch/patchwork-plugins/dist/registry/guards\";\n\n/**\n * Hook to compute document metadata (title)\n */\nexport function useDocumentMetadata(\n doc: Accessor<HasPatchworkMetadata | undefined>\n) {\n const datatypes = useDatatypes();\n\n const title = createMemo(() => {\n const currentDoc = doc();\n if (!currentDoc) return \"\";\n const type = getType(currentDoc);\n const datatype = datatypes.find((dt) => dt.id === type);\n if (!datatype) return \"\";\n if (datatype && isLoadedPlugin(datatype) && datatype.module) {\n return datatype.module.getTitle(currentDoc);\n }\n return \"\";\n });\n\n return {\n title,\n };\n}\n","import { createMemo, createSignal } from \"solid-js\";\nimport type { ViewHeadsType, HistoryItem } from \"../../types\";\n\nexport function useHistorySelection() {\n const [selectedItems, setSelectedItems] = createSignal<HistoryItem[]>([]);\n const [anchorItem, setAnchorItem] = createSignal<HistoryItem | null>(null);\n\n const selectItem = (item: HistoryItem) => {\n if (item.count === 0) {\n console.warn(\"Empty history item encountered\");\n return;\n }\n setSelectedItems([item]);\n setAnchorItem(item);\n };\n\n /**\n * Extend the selection from the current anchor to `item`, using `allItems`\n * (ordered newest-first) to determine the contiguous range.\n */\n const extendSelection = (item: HistoryItem, allItems: HistoryItem[]) => {\n const anchor = anchorItem();\n if (!anchor) {\n selectItem(item);\n return;\n }\n\n const anchorIdx = allItems.findIndex((i) => i.id === anchor.id);\n const targetIdx = allItems.findIndex((i) => i.id === item.id);\n\n if (anchorIdx === -1 || targetIdx === -1) {\n selectItem(item);\n return;\n }\n\n const start = Math.min(anchorIdx, targetIdx);\n const end = Math.max(anchorIdx, targetIdx);\n setSelectedItems(allItems.slice(start, end + 1));\n };\n\n const clearSelection = () => {\n setSelectedItems([]);\n setAnchorItem(null);\n };\n\n const viewHeads = createMemo<ViewHeadsType | null>(() => {\n const items = selectedItems();\n if (items.length === 0) return null;\n\n // Find oldest (smallest startTime) and newest (largest endTime) in the selection.\n // The oldest item's beforeHead is the \"before\" boundary; the newest item's\n // latestHash is the \"after\" boundary.\n let oldest = items[0];\n let newest = items[0];\n for (const item of items) {\n if (item.startTime !== undefined && (oldest.startTime === undefined || item.startTime < oldest.startTime)) {\n oldest = item;\n }\n if (item.endTime !== undefined && (newest.endTime === undefined || item.endTime > newest.endTime)) {\n newest = item;\n }\n }\n\n return {\n beforeHeads: oldest.beforeHead ? [oldest.beforeHead] : [],\n afterHeads: [newest.latestHash],\n };\n });\n\n return {\n viewHeads,\n selectedItems,\n selectItem,\n extendSelection,\n clearSelection,\n };\n}\n","import { Show } from \"solid-js\";\n\nexport interface DocHistoryHeaderProps {\n title?: string;\n onRecompute: () => void;\n isRecalculating?: boolean;\n}\n\nexport function DocHistoryHeader(props: DocHistoryHeaderProps) {\n return (\n <div class=\"history-header\">\n <div style={{ display: \"flex\", \"flex-direction\": \"column\", \"min-width\": \"0\" }}>\n <div class=\"history-header-title\">Version History</div>\n <Show when={props.title !== undefined}>\n <div style={{ \"font-size\": \"10px\", color: \"var(--history-muted-fg)\", overflow: \"hidden\", \"text-overflow\": \"ellipsis\", \"white-space\": \"nowrap\", \"margin-top\": \"2px\" }}>{props.title}</div>\n </Show>\n </div>\n\n <div class=\"history-header-actions\">\n <button\n style={{ background: \"none\", border: \"none\", cursor: \"var(--studio-cursor-pointer, pointer)\", padding: \"4px\", \"border-radius\": \"4px\", display: \"flex\", \"align-items\": \"center\", \"justify-content\": \"center\" }}\n disabled={props.isRecalculating}\n title={props.isRecalculating ? \"Recalculating history...\" : \"Recompute\"}\n onClick={(e) => { e.stopPropagation(); props.onRecompute(); }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n style={props.isRecalculating ? { animation: \"spin 1s linear infinite reverse\" } : {}}\n >\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </svg>\n </button>\n </div>\n </div>\n );\n}\n","import type { AutomergeUrl } from \"@automerge/automerge-repo/slim\";\n\n/**\n * Represents a run of one-or-more changes in the document history.\n *\n * A \"singleton\" change is simply a `HistoryItem` with `count === 1`; the\n * storage and render paths do not distinguish it from a multi-change group.\n *\n * Intermediate per-change metadata is not kept here — only the aggregate\n * information the UI reads. Per-change `actor` / `time` fields live on the\n * source document itself and are not duplicated into this cache.\n */\nexport interface HistoryItem {\n id: string;\n /** Number of changes covered by this item (1 for a lone change) */\n count: number;\n /** Hash of the newest change in the item (used for selection and copy) */\n latestHash: string;\n /** Deduplicated list of authors across all changes in the item */\n authors: string[];\n /** Start time in Unix seconds (from Automerge ChangeMetadata.time) */\n startTime?: number;\n /** End time in Unix seconds (from Automerge ChangeMetadata.time) */\n endTime?: number;\n /** Hash of the change immediately preceding this item in linear history */\n beforeHead?: string;\n /** Number of characters/elements added across all changes in the item */\n additions?: number;\n /** Number of characters/elements removed across all changes in the item */\n deletions?: number;\n /** User-defined label overriding the auto-generated one */\n customLabel?: string;\n /** True for the runtime-only virtual item representing in-progress changes */\n isVirtual?: boolean;\n /** Per-author breakdown, present when multiple authors contributed to this item */\n subItems?: HistoryItem[];\n}\n\n/**\n * ViewHeads structure for annotations\n */\nexport interface ViewHeadsType {\n beforeHeads: string[];\n afterHeads: string[];\n}\n\n/**\n * Configuration for a grouping strategy including parameters.\n *\n * Only `timeWindow` is implemented today; the discriminated shape is kept so\n * future strategies can be added without reshuffling consumers.\n */\nexport type StrategyName = \"timeWindow\" | \"author\";\nexport interface GroupingStrategyConfig {\n name: StrategyName;\n params?: {\n timeWindow?: number; // ms, for timeWindow strategy\n perActor?: boolean; // when true, split groups on actor change within the window\n };\n}\n\n/**\n * Cached grouping for a single strategy\n */\nexport interface CachedGrouping {\n items: HistoryItem[];\n}\n\n/**\n * Schema version for the cached history document.\n * Bump when the shape of `HistoryItem` changes so the task can discard a\n * stale cache instead of reading a now-incompatible structure.\n */\nexport const HISTORY_DOC_VERSION = 8;\n\n/**\n * Document structure for storing persistent history groupings.\n * `heads` is stored at the top level because the background task\n * computes all strategies in a single pass.\n */\nexport interface HistoryGroupingsDoc {\n [\"@patchwork\"]: { type: \"patchwork:history-change-groups\" };\n version: number;\n sourceDocumentUrl: AutomergeUrl;\n /** Unix ms timestamp of when the task last ran (set at task start) */\n updatedAt: number;\n /** Throttle interval in ms — minimum wait before dispatching another task */\n throttleMs: number;\n heads: string[];\n groupings: {\n [strategyKey: string]: CachedGrouping;\n };\n /** User-defined labels keyed by item latestHash — survives task recomputation */\n labels?: { [hash: string]: string };\n}\n\n/**\n * Find an item matching a specific hash.\n *\n * Only the item's latest/representative hash is matched, since the selection\n * UI only ever produces that hash — intermediate change hashes inside a\n * multi-change item are never looked up here.\n */\nexport function findItemByHash(\n items: HistoryItem[],\n hash: string\n): HistoryItem | null {\n for (const item of items) {\n if (item.latestHash === hash) return item;\n }\n return null;\n}\n\n/**\n * Check if an item is currently selected\n */\nexport function isItemSelected(\n item: HistoryItem,\n selectedItems: HistoryItem[]\n): boolean {\n return selectedItems.some((s) => s.id === item.id);\n}\n","import type { JSXElement } from \"solid-js\";\n\nexport interface TimelineCardProps {\n isSelected: boolean;\n onClick: (e: MouseEvent) => void;\n children: JSXElement;\n}\n\n/**\n * Card wrapper providing timeline dot, connecting line,\n * selected/unselected styling, and accessibility attributes.\n */\nexport function TimelineCard(props: TimelineCardProps) {\n return (\n <div\n role=\"button\"\n tabIndex={0}\n aria-selected={props.isSelected}\n data-selected={props.isSelected ? \"\" : undefined}\n onClick={(e) => { e.stopPropagation(); props.onClick(e); }}\n class=\"timeline-card\"\n style={{\n \"font-size\": \"0.75rem\",\n cursor: \"var(--studio-cursor-pointer, pointer)\",\n ...(props.isSelected\n ? { background: \"var(--history-accent)\", \"border-color\": \"var(--history-accent)\", color: \"var(--history-accent-fg)\" }\n : {})\n }}\n >\n {props.children}\n </div>\n );\n}\n","import { For, Show, createSignal, createMemo, createEffect } from \"solid-js\";\nimport type { HistoryItem as HistoryItemType } from \"../../types\";\nimport { formatTimeOnly, getChangeLabel, type ChangeSizeThresholds } from \"../utils\";\nimport { TimelineCard } from \"./TimelineCard\";\n\nexport interface HistoryItemProps {\n item: HistoryItemType;\n isSelected: boolean;\n thresholds: ChangeSizeThresholds;\n onClick: (e: MouseEvent) => void;\n onRename: (label: string) => void;\n onSubItemClick?: (item: HistoryItemType, e: MouseEvent) => void;\n isSubItemSelected?: (item: HistoryItemType) => boolean;\n}\n\nfunction authorColor(authorId: string): string {\n let hash = 0;\n for (let i = 0; i < authorId.length; i++) {\n hash = authorId.charCodeAt(i) + ((hash << 5) - hash);\n }\n const h = Math.abs(hash) % 360;\n return `hsl(${h}, 45%, 63%)`;\n}\n\nfunction getInitials(authorId: string): string {\n const parts = authorId.trim().split(/\\s+/);\n if (parts.length >= 2) {\n return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n }\n if (authorId.includes(\"@\")) {\n return authorId.split(\"@\")[0].slice(0, 2).toUpperCase();\n }\n return authorId.slice(0, 2).toUpperCase();\n}\n\nfunction barWidth(value: number, large: number): number {\n if (value === 0) return 0;\n return Math.max(2, Math.min(60, (value / Math.max(large, value)) * 60));\n}\n\nexport function HistoryItem(props: HistoryItemProps) {\n const timeDisplay = () => formatTimeOnly(props.item.endTime);\n const additions = () => props.item.additions ?? 0;\n const deletions = () => props.item.deletions ?? 0;\n const label = () => props.item.customLabel ?? getChangeLabel(props.item, props.thresholds);\n const authors = () => props.item.authors ?? [];\n const visibleAuthors = () => authors().slice(0, 3);\n const extraAuthors = () => Math.max(0, authors().length - 3);\n const subItems = () => props.item.subItems ?? [];\n\n const [isEditing, setIsEditing] = createSignal(false);\n const [editValue, setEditValue] = createSignal(\"\");\n\n const [isOpen, setIsOpen] = createSignal(false);\n const isMultiAuthorWithSubItems = () => authors().length > 1 && subItems().length > 0;\n const isExpanded = createMemo(() => isOpen() && isMultiAuthorWithSubItems());\n\n const anySubItemSelected = createMemo(() =>\n subItems().some((si) => props.isSubItemSelected?.(si) ?? false)\n );\n\n // Auto-collapse when neither the parent nor any sub-item is selected\n createEffect(() => {\n if (!props.isSelected && !anySubItemSelected()) setIsOpen(false);\n });\n\n const startEdit = (e: MouseEvent) => {\n e.stopPropagation();\n setEditValue(label());\n setIsEditing(true);\n };\n\n const commitEdit = () => {\n const trimmed = editValue().trim();\n if (trimmed !== label()) {\n props.onRename(trimmed);\n }\n setIsEditing(false);\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Enter\") { e.preventDefault(); commitEdit(); }\n if (e.key === \"Escape\") { setIsEditing(false); }\n };\n\n const handleParentClick = (e: MouseEvent) => {\n if (isMultiAuthorWithSubItems()) setIsOpen((v) => !v);\n props.onClick(e);\n };\n\n return (\n <div>\n <TimelineCard isSelected={props.isSelected} onClick={handleParentClick}>\n <div style={{ display: \"flex\", \"align-items\": \"center\", gap: \"0.5rem\" }}>\n <div style={{ display: \"flex\", \"align-items\": \"center\", \"flex-shrink\": \"0\" }}>\n <For each={visibleAuthors()}>\n {(author, i) => (\n <div\n title={author}\n style={{\n background: authorColor(author),\n \"margin-left\": i() === 0 ? \"0\" : \"-4px\",\n \"z-index\": visibleAuthors().length - i(),\n \"font-size\": \"9px\",\n position: \"relative\",\n width: \"18px\",\n height: \"18px\",\n \"border-radius\": \"50%\",\n display: \"flex\",\n \"align-items\": \"center\",\n \"justify-content\": \"center\",\n color: \"white\",\n \"font-weight\": \"300\",\n \"user-select\": \"none\",\n \"flex-shrink\": \"0\",\n }}\n >\n {getInitials(author)}\n </div>\n )}\n </For>\n <Show when={extraAuthors() > 0}>\n <div\n style={{\n \"margin-left\": \"-4px\",\n \"font-size\": \"7px\",\n width: \"18px\",\n height: \"18px\",\n \"border-radius\": \"50%\",\n background: \"var(--history-muted-fg)\",\n display: \"flex\",\n \"align-items\": \"center\",\n \"justify-content\": \"center\",\n color: \"white\",\n position: \"relative\",\n \"flex-shrink\": \"0\",\n }}\n >\n +{extraAuthors()}\n </div>\n </Show>\n </div>\n\n <Show\n when={isEditing()}\n fallback={\n <>\n <div\n style={{ display: \"flex\", \"align-items\": \"center\", gap: \"0.25rem\", cursor: \"var(--studio-cursor-text, text)\", \"min-width\": \"0\", overflow: \"hidden\", \"flex-shrink\": \"1\" }}\n onDblClick={startEdit}\n title=\"Double-click to rename\"\n >\n <span style={{ overflow: \"hidden\", \"text-overflow\": \"ellipsis\", \"white-space\": \"nowrap\", color: \"var(--history-secondary-fg)\" }}>\n <Show\n when={props.item.isVirtual && !props.item.customLabel}\n fallback={label()}\n >\n <em>Making changes...</em>\n </Show>\n </span>\n <svg\n style={{ \"flex-shrink\": \"0\", width: \"12px\", height: \"12px\", opacity: \"0\", cursor: \"var(--studio-cursor-pointer, pointer)\", color: \"inherit\", transition: \"opacity max(1ms, calc(0.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))\" }}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n aria-label=\"Edit label\"\n onClick={startEdit}\n >\n <path d=\"M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Z\" />\n </svg>\n </div>\n <div style={{ flex: \"1\" }} />\n </>\n }\n >\n <input\n style={{ flex: \"1\", \"min-width\": \"0\", background: \"transparent\", border: \"none\", \"border-bottom\": \"var(--studio-border-width, 1px) var(--studio-border-style, solid) currentColor\", outline: \"none\", padding: \"0\", \"line-height\": \"1\", font: \"inherit\", color: \"inherit\" }}\n value={editValue()}\n onInput={(e) => setEditValue(e.currentTarget.value)}\n onBlur={commitEdit}\n onKeyDown={handleKeyDown}\n onClick={(e) => e.stopPropagation()}\n ref={(el) => setTimeout(() => { el.focus(); el.select(); }, 0)}\n />\n </Show>\n\n <div style={{ display: \"flex\", \"align-items\": \"center\", gap: \"0.375rem\", \"flex-shrink\": \"0\" }}>\n <Show when={additions() > 0}>\n <div style={{ display: \"flex\", \"align-items\": \"center\", gap: \"0.125rem\" }}>\n <div style={{ height: \"6px\", \"border-radius\": \"2px\", background: \"var(--history-addition)\", width: `${barWidth(additions(), props.thresholds.large)}px` }} />\n <span style={{ color: \"var(--history-addition-fg)\", \"font-size\": \"11px\", \"font-weight\": \"300\" }}>+{additions()}</span>\n </div>\n </Show>\n <Show when={deletions() > 0}>\n <div style={{ display: \"flex\", \"align-items\": \"center\", gap: \"0.125rem\" }}>\n <div style={{ height: \"6px\", \"border-radius\": \"2px\", background: \"var(--history-deletion)\", width: `${barWidth(deletions(), props.thresholds.large)}px` }} />\n <span style={{ color: \"var(--history-deletion-fg)\", \"font-size\": \"11px\", \"font-weight\": \"300\" }}>-{deletions()}</span>\n </div>\n </Show>\n </div>\n\n <span style={{ color: \"var(--history-muted-fg)\", \"font-size\": \"11px\", \"font-weight\": \"300\", \"flex-shrink\": \"0\", width: \"3.5rem\", \"text-align\": \"right\" }}>\n {timeDisplay()}\n </span>\n </div>\n </TimelineCard>\n\n <Show when={isExpanded()}>\n <div class=\"history-subitems\" style={{ \"margin-left\": \"1rem\", \"margin-top\": \"0.25rem\", display: \"flex\", \"flex-direction\": \"column\", gap: \"0.25rem\" }}>\n <For each={subItems()}>\n {(subItem) => {\n const subAdd = () => subItem.additions ?? 0;\n const subDel = () => subItem.deletions ?? 0;\n const subAuthor = () => subItem.authors[0] ?? \"\";\n\n return (\n <TimelineCard\n isSelected={props.isSubItemSelected?.(subItem) ?? false}\n onClick={(e) => {\n e.stopPropagation();\n props.onSubItemClick?.(subItem, e);\n }}\n >\n <div style={{ display: \"flex\", \"align-items\": \"center\", gap: \"0.5rem\" }}>\n <div\n title={subAuthor()}\n style={{\n background: authorColor(subAuthor()),\n \"font-size\": \"9px\",\n width: \"18px\",\n height: \"18px\",\n \"border-radius\": \"50%\",\n display: \"flex\",\n \"align-items\": \"center\",\n \"justify-content\": \"center\",\n color: \"white\",\n \"font-weight\": \"300\",\n \"user-select\": \"none\",\n \"flex-shrink\": \"0\",\n }}\n >\n {getInitials(subAuthor())}\n </div>\n\n <span style={{ flex: \"1\", overflow: \"hidden\", \"text-overflow\": \"ellipsis\", \"white-space\": \"nowrap\", color: \"var(--history-secondary-fg)\" }}>\n {getChangeLabel(subItem, props.thresholds)}\n </span>\n\n <div style={{ display: \"flex\", \"align-items\": \"center\", gap: \"0.375rem\", \"flex-shrink\": \"0\" }}>\n <Show when={subAdd() > 0}>\n <div style={{ display: \"flex\", \"align-items\": \"center\", gap: \"0.125rem\" }}>\n <div style={{ height: \"6px\", \"border-radius\": \"2px\", background: \"var(--history-addition)\", width: `${barWidth(subAdd(), props.thresholds.large)}px` }} />\n <span style={{ color: \"var(--history-addition-fg)\", \"font-size\": \"11px\", \"font-weight\": \"300\" }}>+{subAdd()}</span>\n </div>\n </Show>\n <Show when={subDel() > 0}>\n <div style={{ display: \"flex\", \"align-items\": \"center\", gap: \"0.125rem\" }}>\n <div style={{ height: \"6px\", \"border-radius\": \"2px\", background: \"var(--history-deletion)\", width: `${barWidth(subDel(), props.thresholds.large)}px` }} />\n <span style={{ color: \"var(--history-deletion-fg)\", \"font-size\": \"11px\", \"font-weight\": \"300\" }}>-{subDel()}</span>\n </div>\n </Show>\n </div>\n\n <span style={{ color: \"var(--history-muted-fg)\", \"font-size\": \"11px\", \"font-weight\": \"300\", \"flex-shrink\": \"0\", width: \"3.5rem\", \"text-align\": \"right\" }}>\n {formatTimeOnly(subItem.endTime)}\n </span>\n </div>\n </TimelineCard>\n );\n }}\n </For>\n </div>\n </Show>\n </div>\n );\n}\n","export interface DateHeaderProps {\n date: Date;\n}\n\n/**\n * Component to display a date header in the timeline\n * Groups history items by day\n */\nexport function DateHeader(props: DateHeaderProps) {\n const dayOfWeek = () => {\n return props.date.toLocaleDateString(undefined, { weekday: \"long\" });\n };\n\n const formattedDate = () => {\n return props.date.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n });\n };\n\n // Check if this date is today\n const isToday = () => {\n const today = new Date();\n return (\n props.date.getDate() === today.getDate() &&\n props.date.getMonth() === today.getMonth() &&\n props.date.getFullYear() === today.getFullYear()\n );\n };\n\n // Check if this date is yesterday\n const isYesterday = () => {\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n return (\n props.date.getDate() === yesterday.getDate() &&\n props.date.getMonth() === yesterday.getMonth() &&\n props.date.getFullYear() === yesterday.getFullYear()\n );\n };\n\n const displayDay = () => {\n if (isToday()) return \"Today\";\n if (isYesterday()) return \"Yesterday\";\n return dayOfWeek();\n };\n\n return (\n <div class=\"history-date-header\">\n {displayDay()}, {formattedDate()}\n </div>\n );\n}\n","import { For, createMemo } from \"solid-js\";\nimport type { HistoryItem as HistoryItemType } from \"../../types\";\nimport { isItemSelected } from \"../../types\";\nimport { computeChangeSizeThresholds, type ChangeSizeThresholds } from \"../utils\";\nimport { HistoryItem } from \"./HistoryItem\";\nimport { DateHeader } from \"./DateHeader\";\n\nexport interface HistoryListProps {\n items: HistoryItemType[];\n selectedItems: HistoryItemType[];\n onSelectItem: (item: HistoryItemType, shiftHeld: boolean) => void;\n onRenameItem: (hash: string, label: string) => void;\n}\n\ninterface GroupedByDate {\n date: Date;\n items: HistoryItemType[];\n}\n\n/**\n * Get the date (without time) from a history item\n */\nfunction getItemDate(item: HistoryItemType): Date | null {\n const timestamp = item.endTime;\n if (!timestamp) return null;\n\n const date = new Date(timestamp * 1000);\n // Reset time to midnight for grouping\n date.setHours(0, 0, 0, 0);\n return date;\n}\n\n/**\n * Scrollable list container for history items.\n * Groups items by date and shows date headers.\n */\nexport function HistoryList(props: HistoryListProps) {\n const thresholds = createMemo<ChangeSizeThresholds>(() => {\n const allItems = props.items.flatMap(item => [item, ...(item.subItems ?? [])]);\n return computeChangeSizeThresholds(allItems);\n });\n\n // Group items by date\n const groupedItems = createMemo<GroupedByDate[]>(() => {\n const groups: Map<string, GroupedByDate> = new Map();\n\n props.items.forEach((item) => {\n const date = getItemDate(item);\n if (!date) return;\n\n const dateKey = date.toISOString();\n if (!groups.has(dateKey)) {\n groups.set(dateKey, { date, items: [] });\n }\n groups.get(dateKey)!.items.push(item);\n });\n\n // Convert to array and sort by date (newest first)\n return Array.from(groups.values()).sort(\n (a, b) => b.date.getTime() - a.date.getTime()\n );\n });\n\n return (\n <div class=\"history-list\" style={{ \"min-height\": \"0\" }}>\n <For each={groupedItems()}>\n {(group) => (\n <>\n <DateHeader date={group.date} />\n <div style={{ display: \"flex\", \"flex-direction\": \"column\", gap: \"0.5rem\", padding: \"0 0.5rem 1rem\" }}>\n <For each={group.items}>\n {(item, index) => {\n const isLast = () => index() === group.items.length - 1;\n const isSelected = () =>\n isItemSelected(item, props.selectedItems);\n\n return (\n <div class={isLast() ? \"last-timeline-item\" : \"\"}>\n <HistoryItem\n item={item}\n isSelected={isSelected()}\n thresholds={thresholds()}\n onClick={(e) => props.onSelectItem(item, e.shiftKey)}\n onRename={(label) => props.onRenameItem(item.latestHash, label)}\n onSubItemClick={(subItem, e) => props.onSelectItem(subItem, e.shiftKey)}\n isSubItemSelected={(subItem) => isItemSelected(subItem, props.selectedItems)}\n />\n </div>\n );\n }}\n </For>\n </div>\n </>\n )}\n </For>\n </div>\n );\n}\n","/**\n * Placeholder shown while the history document is being created for the first\n * time (or is still loading). Lives in the same flex slot as the item list so\n * the surrounding layout doesn't jump when it swaps out.\n */\nexport function HistoryComputingIndicator() {\n return (\n <div\n class=\"history-computing\"\n style={{ flex: \"1\", \"min-height\": \"0\", \"flex-direction\": \"column\", \"align-items\": \"center\", \"justify-content\": \"center\", padding: \"2.5rem 1.5rem\", \"text-align\": \"center\" }}\n role=\"status\"\n aria-live=\"polite\"\n >\n <div style={{ \"font-size\": \"0.875rem\" }}>Computing history...</div>\n </div>\n );\n}\n","import type { AutomergeUrl, Repo } from \"@automerge/automerge-repo/slim\";\nimport { type Accessor, Show } from \"solid-js\";\nimport { useDocument } from \"solid-automerge\";\nimport type { HasPatchworkMetadata } from \"@inkandswitch/patchwork-filesystem\";\nimport {\n useDocumentMetadata,\n useHistorySelection,\n useCachedHistory,\n} from \"../hooks\";\nimport { type GroupingStrategyConfig, type HistoryItem } from \"../../types\";\nimport { DEFAULT_TIME_WINDOW } from \"../utils\";\nimport { DocHistoryHeader } from \"./DocHistoryHeader\";\nimport { HistoryList } from \"./HistoryList\";\nimport { HistoryComputingIndicator } from \"./HistoryComputingIndicator\";\n\nexport interface DocHistoryViewProps {\n url: AutomergeUrl;\n repo: Repo;\n /**\n * Whether to render the document's title in the header. Defaults to true;\n * pass an accessor returning `false` (e.g. when the sidebar is showing a\n * single doc whose title is already visible elsewhere) to suppress it\n * while keeping the reset button.\n */\n showTitle?: Accessor<boolean>;\n}\n\nconst STRATEGY_CONFIG: GroupingStrategyConfig = {\n name: \"timeWindow\",\n params: { timeWindow: DEFAULT_TIME_WINDOW },\n};\nconst strategyConfig = () => STRATEGY_CONFIG;\n\nexport function DocHistoryView(props: DocHistoryViewProps) {\n const [doc, handle] = useDocument<HasPatchworkMetadata>(props.url, {\n repo: props.repo,\n });\n\n const { title } = useDocumentMetadata(doc);\n\n const { items: groupedItems, isInitializing, isRecalculating, forceRecompute, setLabel } = useCachedHistory(\n handle,\n strategyConfig,\n props.repo\n );\n\n const { selectedItems, selectItem, extendSelection, clearSelection } = useHistorySelection();\n\n const handleSelectItem = (item: HistoryItem, shiftHeld: boolean) => {\n if (shiftHeld) {\n extendSelection(item, groupedItems());\n } else {\n selectItem(item);\n }\n };\n\n return (\n <div class=\"history-panel\" style={{ flex: \"1\", \"min-height\": \"0\" }} onClick={clearSelection}>\n <DocHistoryHeader\n title={(props.showTitle?.() ?? true) ? title() : undefined}\n onRecompute={forceRecompute}\n isRecalculating={isRecalculating()}\n />\n <Show\n when={!isInitializing()}\n fallback={<HistoryComputingIndicator />}\n >\n <HistoryList\n items={groupedItems()}\n selectedItems={selectedItems()}\n onSelectItem={handleSelectItem}\n onRenameItem={setLabel}\n />\n </Show>\n </div>\n );\n}\n","import type { AutomergeUrl, Repo } from \"@automerge/automerge-repo/slim\";\nimport { Show } from \"solid-js\";\nimport { render } from \"solid-js/web\";\nimport { subscribe } from \"@inkandswitch/patchwork-providers-solid\";\nimport type { ToolElement } from \"@inkandswitch/patchwork-plugins\";\nimport { DocHistoryView } from \"./components/DocHistoryView\";\nimport \"../styles.css\";\n\nexport interface PatchworkToolProps {\n repo: Repo;\n element: HTMLElement;\n}\n\n/**\n * Main timeline component that renders history for the primary selected\n * document (the first URL in the selection). Ignores additional selected URLs\n * that may appear when interacting with the document, so that clicking in the\n * editor never spawns a second history panel below the original.\n */\nexport function HistoryTimeline(props: PatchworkToolProps) {\n const selectedDocUrls = subscribe<AutomergeUrl[]>(\n props.element,\n { type: \"patchwork:selected-doc\" },\n []\n );\n const primaryUrl = () => selectedDocUrls()[0] as AutomergeUrl | undefined;\n\n return (\n <div class=\"history-panel\">\n <Show when={primaryUrl()} keyed>\n {(url) => (\n <DocHistoryView\n url={url}\n repo={props.repo}\n />\n )}\n </Show>\n </div>\n );\n}\n\nexport const renderHistoryTimeline = (element: ToolElement) =>\n render(\n () => <HistoryTimeline repo={element.repo} element={element} />,\n element\n );\n"],"file":"HistoryTimeline-DOndzpUR.js"}
@@ -99,7 +99,7 @@ const plugins = [
99
99
  } = await __vitePreload(async () => {
100
100
  const {
101
101
  renderHistoryTimeline: renderHistoryTimeline2
102
- } = await import("./HistoryTimeline-Bo-BTf2A.js");
102
+ } = await import("./HistoryTimeline-DOndzpUR.js");
103
103
  return {
104
104
  renderHistoryTimeline: renderHistoryTimeline2
105
105
  };
@@ -112,4 +112,4 @@ export {
112
112
  __vitePreload as _,
113
113
  plugins as p
114
114
  };
115
- //# sourceMappingURL=index-B5Afrk9Y.js.map
115
+ //# sourceMappingURL=index-D7nqWI0b.js.map
@@ -1 +1 @@
1
- {"version":3,"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGO,MAAMA,UAAyB;AAAA,EACpC;AAAA,IACEC,MAAM;AAAA,IACNC,IAAI;AAAA,IACJC,MAAM;AAAA,IACNC,MAAM;AAAA,IACNC,UAAU;AAAA,IACV,MAAMC,OAAO;AACX,aAAO;AAAA,QACLC,MAAMA,CAACC,QAA6B;AAClC,cAAI,CAACA,IAAIC,kBAAmB;AAC5BC,iBAAOC,OAAOH,KAAK;AAAA,YACjB,CAAC,YAAY,GAAG;AAAA,cAAEP,MAAM;AAAA;AAAA,YACxBW,SAASJ,IAAII,WAAW;AAAA,YACxBH,mBAAmBD,IAAIC;AAAAA,YACvBI,WAAWL,IAAIK,aAAa;AAAA,YAC5BC,YAAYN,IAAIM,cAAc,KAAK,KAAK;AAAA,YACxCC,OAAOP,IAAIO,SAAS;AAAA,YACpBC,WAAWR,IAAIQ,aAAa;AAAA,UAAC,CACP;AAAA,QAC1B;AAAA,QACAC,UAAUA,CAACT,QAA6B;AACtC,iBAAO,6BAA6BA,IAAIC,iBAAiB;AAAA,QAC3D;AAAA;AAAA,IAEJ;AAAA;AAAA;AAAA;AAAA,EAIF;AAAA,IACER,MAAM;AAAA,IACNC,IAAI;AAAA,IACJgB,MAAM,CAAC,cAAc;AAAA,IACrBf,MAAM;AAAA,IACNC,MAAM;AAAA,IACN,MAAME,OAAO;AACX,YAAM;AAAA,QAAEa;AAAAA,UAA0B;AAAA;AAAA;QAAM,iBAAO,+BAA2B;AAAA;AAAA;QAAA;AAAA;AAC1E,aAAOA;AAAAA,IACT;AAAA;AACD","names":["plugins","type","id","name","icon","unlisted","load","init","doc","sourceDocumentUrl","Object","assign","version","updatedAt","throttleMs","heads","groupings","getTitle","tags","renderHistoryTimeline"],"ignoreList":[],"sources":["../../src/index.tsx"],"sourcesContent":["import { Plugin } from \"@inkandswitch/patchwork-plugins\";\nimport { HistoryGroupingsDoc } from \"./types\";\n\nexport const plugins: Plugin<any>[] = [\n {\n type: \"patchwork:datatype\",\n id: \"patchwork:history-change-groups\",\n name: \"Document History Change Groups\",\n icon: \"History\",\n unlisted: true,\n async load() {\n return {\n init: (doc: HistoryGroupingsDoc) => {\n if (!doc.sourceDocumentUrl) return;\n Object.assign(doc, {\n [\"@patchwork\"]: { type: \"patchwork:history-change-groups\" },\n version: doc.version || 1,\n sourceDocumentUrl: doc.sourceDocumentUrl,\n updatedAt: doc.updatedAt || 0,\n throttleMs: doc.throttleMs || 30 * 60 * 1000,\n heads: doc.heads || [],\n groupings: doc.groupings || {},\n } as HistoryGroupingsDoc);\n },\n getTitle: (doc: HistoryGroupingsDoc) => {\n return `History Change Groups for ${doc.sourceDocumentUrl}`;\n },\n };\n },\n },\n // A `patchwork:component` that takes no document: the view reads everything\n // off `element`, so it can be slotted in without an account doc.\n {\n type: \"patchwork:component\",\n id: \"history-view\",\n tags: [\"context-tool\"],\n name: \"History\",\n icon: \"History\",\n async load() {\n const { renderHistoryTimeline } = await import(\"./history/HistoryTimeline\");\n return renderHistoryTimeline;\n },\n },\n];\n"],"file":"index-B5Afrk9Y.js"}
1
+ {"version":3,"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGO,MAAMA,UAAyB;AAAA,EACpC;AAAA,IACEC,MAAM;AAAA,IACNC,IAAI;AAAA,IACJC,MAAM;AAAA,IACNC,MAAM;AAAA,IACNC,UAAU;AAAA,IACV,MAAMC,OAAO;AACX,aAAO;AAAA,QACLC,MAAMA,CAACC,QAA6B;AAClC,cAAI,CAACA,IAAIC,kBAAmB;AAC5BC,iBAAOC,OAAOH,KAAK;AAAA,YACjB,CAAC,YAAY,GAAG;AAAA,cAAEP,MAAM;AAAA;AAAA,YACxBW,SAASJ,IAAII,WAAW;AAAA,YACxBH,mBAAmBD,IAAIC;AAAAA,YACvBI,WAAWL,IAAIK,aAAa;AAAA,YAC5BC,YAAYN,IAAIM,cAAc,KAAK,KAAK;AAAA,YACxCC,OAAOP,IAAIO,SAAS;AAAA,YACpBC,WAAWR,IAAIQ,aAAa;AAAA,UAAC,CACP;AAAA,QAC1B;AAAA,QACAC,UAAUA,CAACT,QAA6B;AACtC,iBAAO,6BAA6BA,IAAIC,iBAAiB;AAAA,QAC3D;AAAA;AAAA,IAEJ;AAAA;AAAA;AAAA;AAAA,EAIF;AAAA,IACER,MAAM;AAAA,IACNC,IAAI;AAAA,IACJgB,MAAM,CAAC,cAAc;AAAA,IACrBf,MAAM;AAAA,IACNC,MAAM;AAAA,IACN,MAAME,OAAO;AACX,YAAM;AAAA,QAAEa;AAAAA,UAA0B;AAAA;AAAA;QAAM,iBAAO,+BAA2B;AAAA;AAAA;QAAA;AAAA;AAC1E,aAAOA;AAAAA,IACT;AAAA;AACD","names":["plugins","type","id","name","icon","unlisted","load","init","doc","sourceDocumentUrl","Object","assign","version","updatedAt","throttleMs","heads","groupings","getTitle","tags","renderHistoryTimeline"],"ignoreList":[],"sources":["../../src/index.tsx"],"sourcesContent":["import { Plugin } from \"@inkandswitch/patchwork-plugins\";\nimport { HistoryGroupingsDoc } from \"./types\";\n\nexport const plugins: Plugin<any>[] = [\n {\n type: \"patchwork:datatype\",\n id: \"patchwork:history-change-groups\",\n name: \"Document History Change Groups\",\n icon: \"History\",\n unlisted: true,\n async load() {\n return {\n init: (doc: HistoryGroupingsDoc) => {\n if (!doc.sourceDocumentUrl) return;\n Object.assign(doc, {\n [\"@patchwork\"]: { type: \"patchwork:history-change-groups\" },\n version: doc.version || 1,\n sourceDocumentUrl: doc.sourceDocumentUrl,\n updatedAt: doc.updatedAt || 0,\n throttleMs: doc.throttleMs || 30 * 60 * 1000,\n heads: doc.heads || [],\n groupings: doc.groupings || {},\n } as HistoryGroupingsDoc);\n },\n getTitle: (doc: HistoryGroupingsDoc) => {\n return `History Change Groups for ${doc.sourceDocumentUrl}`;\n },\n };\n },\n },\n // A `patchwork:component` that takes no document: the view reads everything\n // off `element`, so it can be slotted in without an account doc.\n {\n type: \"patchwork:component\",\n id: \"history-view\",\n tags: [\"context-tool\"],\n name: \"History\",\n icon: \"History\",\n async load() {\n const { renderHistoryTimeline } = await import(\"./history/HistoryTimeline\");\n return renderHistoryTimeline;\n },\n },\n];\n"],"file":"index-D7nqWI0b.js"}
@@ -1,4 +1,4 @@
1
- import { p } from "./assets/index-B5Afrk9Y.js";
1
+ import { p } from "./assets/index-D7nqWI0b.js";
2
2
  export {
3
3
  p as plugins
4
4
  };
@@ -20,7 +20,7 @@
20
20
  "@inkandswitch/patchwork-filesystem": "^0.2.9",
21
21
  "@inkandswitch/patchwork-plugins": "^1.2.5",
22
22
  "@inkandswitch/patchwork-providers-solid": "^0.2.8",
23
- "solid-automerge": "^2.0.2",
23
+ "solid-automerge": "^2.1.0",
24
24
  "solid-js": "^1.9.10"
25
25
  },
26
26
  "devDependencies": {
@@ -1,3 +1,3 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var r=document.createElement("style");r.appendChild(document.createTextNode("@layer package{:root,:host,[theme]{--configurator-fg: var(--editor-line, black);--configurator-fill: var(--editor-fill, white);--configurator-family: var(--editor-family-sans, system-ui, sans-serif);--configurator-family-code: var(--editor-family-code, ui-monospace, monospace);--configurator-accent: var(--studio-accent, oklch(.6 .15 250))}}.configurator{container-type:inline-size;padding:1.25rem 1.25rem 4rem;display:flex;flex-direction:column;gap:1.5rem;height:100%;overflow-y:auto;font-family:var(--configurator-family);color:var(--configurator-fg)}.configurator.loading{opacity:.5;font-size:.875rem}.configurator-title{font-size:.9375rem;font-weight:600;letter-spacing:-.01em;color:inherit}.config-section{display:flex;flex-direction:column;gap:.625rem;padding-top:1rem;border-top:var(--studio-border-width, 1px) var(--studio-border-style, solid) color-mix(in oklch,currentColor 10%,transparent)}.config-section:first-of-type{border-top:none;padding-top:0}.section-label{font-size:.625rem;font-weight:600;text-transform:uppercase;letter-spacing:var(--studio-chrome-letter-spacing, .06em);opacity:.5}.preview-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:.5rem}@container (max-width: 279px){.preview-grid{grid-template-columns:1fr}}@container (min-width: 400px){.preview-grid{grid-template-columns:repeat(3,1fr)}}.preview-card{display:flex;flex-direction:column;border:1.5px solid color-mix(in oklch,currentColor 12%,transparent);border-radius:.5rem;overflow:hidden;cursor:var(--studio-cursor-pointer, pointer);transition:border-color max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),box-shadow max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));background:none;color:inherit;padding:0;text-align:left}.preview-card:hover{border-color:color-mix(in oklch,currentColor 25%,transparent)}.preview-card[aria-checked=true]{border-color:var(--configurator-accent);box-shadow:0 0 0 1px var(--configurator-accent)}.preview-card-label{display:flex;align-items:center;gap:.375rem;padding:.5rem .625rem;font-size:.75rem;font-weight:500}.preview-card-check{margin-left:auto;color:var(--configurator-accent);flex-shrink:0;display:none}.preview-card[aria-checked=true] .preview-card-check{display:flex}.empty-message{font-size:.8125rem;opacity:.7;font-style:italic;margin:0;padding:.375rem 0}.toolbar-strip{display:flex;flex-wrap:wrap;gap:.375rem;align-items:flex-end}.toolbar-box{display:flex;flex-direction:row;align-items:center;border:var(--studio-border-width, 1px) var(--studio-border-style, solid) color-mix(in oklch,currentColor 12%,transparent);border-radius:.375rem;overflow:hidden;cursor:var(--studio-cursor-grab, grab);-webkit-user-select:none;user-select:none;position:relative;transition:border-color max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),opacity max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),transform max(1ms,calc(.2s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))) ease}.toolbar-box:active{cursor:var(--studio-cursor-grabbing, grabbing)}.toolbar-box.dragging{opacity:0}.toolbar-box.shift-left{transform:translate(calc(-100% - .375rem))}.toolbar-box.shift-right{transform:translate(calc(100% + .375rem))}.toolbar-box-label{font-size:.6875rem;padding:.3125rem .625rem;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.toolbar-box-remove{margin-right:.25rem;flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1rem;height:1rem;border:none;border-radius:50%;background:color-mix(in oklch,currentColor 10%,transparent);color:inherit;opacity:0;cursor:var(--studio-cursor-pointer, pointer);padding:0;transition:opacity max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),background max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),color max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.toolbar-box:hover .toolbar-box-remove{opacity:.5}.toolbar-box-remove:hover{opacity:1!important;color:#f04c5a;background:#f04c5a26}.toolbar-add-btn{display:flex;align-items:center;justify-content:center;width:2.25rem;height:100%;min-height:3.5rem;border:1.5px dashed color-mix(in oklch,currentColor 18%,transparent);border-radius:.375rem;background:none;color:inherit;opacity:.45;cursor:var(--studio-cursor-pointer, pointer);padding:0;transition:opacity max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),border-color max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),background max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.toolbar-add-btn:hover{opacity:.8;border-color:color-mix(in oklch,currentColor 30%,transparent);background:color-mix(in oklch,currentColor 4%,transparent)}.context-tabs{display:flex;flex-wrap:wrap;gap:0;border-bottom:1.5px solid color-mix(in oklch,currentColor 12%,transparent)}.context-tab{display:flex;align-items:center;gap:.25rem;padding:.375rem .625rem;border:var(--studio-border-width, 1px) var(--studio-border-style, solid) color-mix(in oklch,currentColor 12%,transparent);border-bottom:none;border-radius:.375rem .375rem 0 0;background:none;color:inherit;font-size:.75rem;font-weight:500;cursor:var(--studio-cursor-grab, grab);-webkit-user-select:none;user-select:none;margin-bottom:-1.5px;transition:background max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),opacity max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),transform max(1ms,calc(.2s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))) ease}.context-tab:active{cursor:var(--studio-cursor-grabbing, grabbing)}.context-tab.dragging{opacity:0}.context-tab.shift-left{transform:translate(-100%)}.context-tab.shift-right{transform:translate(100%)}.context-tab:hover{background:color-mix(in oklch,currentColor 6%,transparent)}.context-tab-remove{display:flex;align-items:center;justify-content:center;width:.875rem;height:.875rem;border:none;border-radius:50%;background:none;color:inherit;opacity:.25;cursor:var(--studio-cursor-pointer, pointer);padding:0;flex-shrink:0;transition:opacity max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),color max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),background max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.context-tab-remove:hover{opacity:1;color:#f04c5a;background:#f04c5a1f}.context-tab-add{display:flex;align-items:center;gap:.25rem;padding:.375rem .625rem;border:var(--studio-border-width, 1px) dashed color-mix(in oklch,currentColor 15%,transparent);border-bottom:none;border-radius:.375rem .375rem 0 0;background:none;color:inherit;font-size:.75rem;opacity:.45;cursor:var(--studio-cursor-pointer, pointer);margin-bottom:-1.5px;transition:opacity max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),background max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.context-tab-add:hover{opacity:.8;background:color-mix(in oklch,currentColor 4%,transparent)}.add-popover-anchor{position:relative}.add-popover{position:absolute;bottom:calc(100% + .375rem);left:0;z-index:var(--studio-layer-dropdown, 10);min-width:12rem;padding:.375rem;background:var(--configurator-fill);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) color-mix(in oklch,currentColor 15%,transparent);border-radius:.5rem;box-shadow:0 4px 16px #0000001a,0 1px 4px #0000000f;display:flex;flex-direction:column;gap:2px}.add-popover-option{display:flex;align-items:center;gap:.375rem;padding:.375rem .5rem;border:none;border-radius:.375rem;background:none;color:inherit;font-size:.8125rem;cursor:var(--studio-cursor-pointer, pointer);text-align:left;width:100%;transition:background max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.add-popover-option:hover{background:color-mix(in oklch,currentColor 8%,transparent)}.add-popover-option svg{opacity:.4;flex-shrink:0}.add-popover-custom{display:flex;align-items:center;gap:4px;padding:.375rem .375rem .25rem;border-top:var(--studio-border-width, 1px) var(--studio-border-style, solid) color-mix(in oklch,currentColor 8%,transparent);margin-top:2px}.add-popover-custom-input{flex:1;min-width:0;padding:.25rem .375rem;border:var(--studio-border-width, 1px) var(--studio-border-style, solid) color-mix(in oklch,currentColor 15%,transparent);border-radius:.25rem;background:none;color:inherit;font-size:.8125rem;font-family:var(--configurator-family-code);outline:none;transition:border-color max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.add-popover-custom-input::placeholder{opacity:.4;font-family:inherit;font-style:italic}.add-popover-custom-input:focus{border-color:color-mix(in oklch,currentColor 35%,transparent)}.add-popover-custom-btn{display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;border-radius:.25rem;background:none;color:inherit;opacity:.5;cursor:var(--studio-cursor-pointer, pointer);flex-shrink:0;padding:0;transition:opacity max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),background max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.add-popover-custom-btn:hover:not(:disabled){opacity:.8;background:color-mix(in oklch,currentColor 8%,transparent)}.add-popover-custom-btn:disabled{opacity:.2;cursor:var(--studio-cursor-default, default)}.add-popover-done{display:flex;align-items:center;justify-content:center;padding:.3125rem;border:none;border-radius:.25rem;background:none;color:inherit;opacity:.5;font-size:.75rem;cursor:var(--studio-cursor-pointer, pointer);transition:background max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))),opacity max(1ms,calc(.12s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.add-popover-done:hover{opacity:.8;background:color-mix(in oklch,currentColor 8%,transparent)}.theme-embed{border:var(--studio-border-width, 1px) var(--studio-border-style, solid) color-mix(in oklch,currentColor 10%,transparent);border-radius:.5rem;overflow:hidden}.theme-embed patchwork-view{display:block;width:100%}")),document.head.appendChild(r)}}catch(o){console.error("vite-plugin-css-injected-by-js",o)}})();
2
- import{render as le,createComponent as y,insert as v,getOwner as ae,effect as E,template as w,use as ne,setAttribute as I,className as W,delegateEvents as ce}from"solid-js/web";import{getRegistry as ue}from"@inkandswitch/patchwork-plugins";import{accept as J}from"@inkandswitch/patchwork-providers";import{onCleanup as re,createMemo as x,createContext as de,useContext as fe,createResource as pe,createEffect as he,Show as P,For as V,createSignal as M}from"solid-js";import{createStore as oe,reconcile as U,produce as Ce}from"solid-js/store";function me(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var j={exports:{}},N,Z;function ge(){if(Z)return N;Z=1;var e=1e3,n=e*60,o=n*60,t=o*24,c=t*7,d=t*365.25;N=function(i,r){r=r||{};var l=typeof i;if(l==="string"&&i.length>0)return a(i);if(l==="number"&&isFinite(i))return r.long?h(i):p(i);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(i))};function a(i){if(i=String(i),!(i.length>100)){var r=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(r){var l=parseFloat(r[1]),f=(r[2]||"ms").toLowerCase();switch(f){case"years":case"year":case"yrs":case"yr":case"y":return l*d;case"weeks":case"week":case"w":return l*c;case"days":case"day":case"d":return l*t;case"hours":case"hour":case"hrs":case"hr":case"h":return l*o;case"minutes":case"minute":case"mins":case"min":case"m":return l*n;case"seconds":case"second":case"secs":case"sec":case"s":return l*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return l;default:return}}}}function p(i){var r=Math.abs(i);return r>=t?Math.round(i/t)+"d":r>=o?Math.round(i/o)+"h":r>=n?Math.round(i/n)+"m":r>=e?Math.round(i/e)+"s":i+"ms"}function h(i){var r=Math.abs(i);return r>=t?s(i,r,t,"day"):r>=o?s(i,r,o,"hour"):r>=n?s(i,r,n,"minute"):r>=e?s(i,r,e,"second"):i+" ms"}function s(i,r,l,f){var C=r>=l*1.5;return Math.round(i/l)+" "+f+(C?"s":"")}return N}var z,K;function ve(){if(K)return z;K=1;function e(n){t.debug=t,t.default=t,t.coerce=s,t.disable=p,t.enable=d,t.enabled=h,t.humanize=ge(),t.destroy=i,Object.keys(n).forEach(r=>{t[r]=n[r]}),t.names=[],t.skips=[],t.formatters={};function o(r){let l=0;for(let f=0;f<r.length;f++)l=(l<<5)-l+r.charCodeAt(f),l|=0;return t.colors[Math.abs(l)%t.colors.length]}t.selectColor=o;function t(r){let l,f=null,C,b;function u(...m){if(!u.enabled)return;const g=u,k=Number(new Date),L=k-(l||k);g.diff=L,g.prev=l,g.curr=k,l=k,m[0]=t.coerce(m[0]),typeof m[0]!="string"&&m.unshift("%O");let A=0;m[0]=m[0].replace(/%([a-zA-Z%])/g,(_,$)=>{if(_==="%%")return"%";A++;const D=t.formatters[$];if(typeof D=="function"){const R=m[A];_=D.call(g,R),m.splice(A,1),A--}return _}),t.formatArgs.call(g,m),(g.log||t.log).apply(g,m)}return u.namespace=r,u.useColors=t.useColors(),u.color=t.selectColor(r),u.extend=c,u.destroy=t.destroy,Object.defineProperty(u,"enabled",{enumerable:!0,configurable:!1,get:()=>f!==null?f:(C!==t.namespaces&&(C=t.namespaces,b=t.enabled(r)),b),set:m=>{f=m}}),typeof t.init=="function"&&t.init(u),u}function c(r,l){const f=t(this.namespace+(typeof l>"u"?":":l)+r);return f.log=this.log,f}function d(r){t.save(r),t.namespaces=r,t.names=[],t.skips=[];const l=(typeof r=="string"?r:"").trim().replace(/\s+/g,",").split(",").filter(Boolean);for(const f of l)f[0]==="-"?t.skips.push(f.slice(1)):t.names.push(f)}function a(r,l){let f=0,C=0,b=-1,u=0;for(;f<r.length;)if(C<l.length&&(l[C]===r[f]||l[C]==="*"))l[C]==="*"?(b=C,u=f,C++):(f++,C++);else if(b!==-1)C=b+1,u++,f=u;else return!1;for(;C<l.length&&l[C]==="*";)C++;return C===l.length}function p(){const r=[...t.names,...t.skips.map(l=>"-"+l)].join(",");return t.enable(""),r}function h(r){for(const l of t.skips)if(a(r,l))return!1;for(const l of t.names)if(a(r,l))return!0;return!1}function s(r){return r instanceof Error?r.stack||r.message:r}function i(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return t.enable(t.load()),t}return z=e,z}var Y;function ye(){return Y||(Y=1,(function(e,n){var o={};n.formatArgs=c,n.save=d,n.load=a,n.useColors=t,n.storage=p(),n.destroy=(()=>{let s=!1;return()=>{s||(s=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),n.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function t(){if(typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs))return!0;if(typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;let s;return typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&(s=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(s[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function c(s){if(s[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+s[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const i="color: "+this.color;s.splice(1,0,i,"color: inherit");let r=0,l=0;s[0].replace(/%[a-zA-Z%]/g,f=>{f!=="%%"&&(r++,f==="%c"&&(l=r))}),s.splice(l,0,i)}n.log=console.debug||console.log||(()=>{});function d(s){try{s?n.storage.setItem("debug",s):n.storage.removeItem("debug")}catch{}}function a(){let s;try{s=n.storage.getItem("debug")||n.storage.getItem("DEBUG")}catch{}return!s&&typeof process<"u"&&"env"in process&&(s=o.DEBUG),s}function p(){try{return localStorage}catch{}}e.exports=ve()(n);const{formatters:h}=e.exports;h.j=function(s){try{return JSON.stringify(s)}catch(i){return"[UnexpectedJSONParseError]: "+i.message}}})(j,j.exports)),j.exports}var we=ye();const be=me(we);var se=be("cabbages");function Q(e){return typeof e=="object"&&typeof e!=null&&Object.getPrototypeOf(e)==Object.prototype}var Fe="";function ke(e,...n){if(n.length==0){se("empty patch");return}const[o,t,c]=n;let d=[...o];for(;;){let a=d.shift();if(!d.length){const h=Array.isArray(t);if(Q(e)&&h&&typeof a>"u"&&typeof t[0]=="string"){delete e[t[0]];return}if(h||typeof t=="number"){if(typeof a>"u")throw new Error("cant treat top level as a seq");a=a;let[s,i]=Array.isArray(t)?t:[t,t+1];const r=Array.isArray(t)&&t.length==0;if(!r&&(s==null||i==null))throw new RangeError("it's all or nothing, no half measures");const l=typeof c>"u",f=s===i&&!l,C=r&&!l,b=!f&&!l&&!C;if(typeof e[a]>"u"){if(typeof e=="string")return;typeof c=="string"?e[a]="":e[a]=[]}let u=e[a];if(Array.isArray(u)){if(C){Array.isArray(c)?u.push(...c):u.push(c);return}if(f||b){Array.isArray(c)?u.splice(s,i-s,...c):u.splice(s,i-s,c);return}if(l){u.splice(s,i-s);return}throw new Error("i don't know what happened")}if(typeof u=="string"){if(C){e[a]=u+c;return}if(b||f){e[a]=u.slice(0,s)+(typeof c=="string"?c:c.map(m=>typeof m=="string"?m:Fe).join(""))+u.slice(i);return}if(l){e[a]=u.slice(0,s)+u.slice(i);return}throw new Error("i don't know what happened")}if(Q(u)&&h&&typeof t[0]=="string"){delete u[t[0]];return}throw new Error("not implemented")}if(typeof a>"u"){if(typeof t!="string")throw new Error(`can't index top-level map with ${t}`);typeof c>"u"?delete e[t]:e[t]=c;return}if(typeof e[a]>"u"&&(e[a]={}),h){let[s,i]=t;s!=null&&i!=null&&(typeof c>"u"&&s!=null&&i!=null?delete e[a][s||i]:e[a][s||i]=c)}else if(typeof c>"u")delete e[a][t];else{if(typeof e[a]=="string")return;e[a][t]=c}return}if(typeof a>"u")throw new Error("cant treat top level as a seq");a=a;let p=d[0];if(typeof e[a]>"u")if(typeof p=="string")e[a]={};else if(typeof p=="number")e[a]=[];else throw new Error(`can't go down this road ${e}.${a}.${p}`);e=e[a]}}function X(e,n){for(let o=0;o<n.length;o++)e=e?e[n[o]]:void 0;return e}function $e(e,n){const o=e.path.slice(0,-1),t=e.path[e.path.length-1];switch(e.action){case"mark":case"unmark":return se(`skipping ${e.action} because it doesn't affect material reality`),[];case"inc":if(n)return[o,t,X(n.patchInfo.after,e.path)];throw new Error(`can't apply ${e.action} without payload argument`);case"conflict":if(n)return[o,t,X(n.patchInfo.after,e.path)];throw new Error(`can't apply ${e.action} without payload argument`);case"del":return typeof t=="string"?[o,t]:[o,[t,t+(e.length||1)]];case"insert":return[o,[t,t],structuredClone(e.values)];case"splice":return[o,[t,t],[e.value]];case"put":return[o,t,structuredClone(e.value)]}}function _e(e){return n=>{for(let o of e.patches)ke(n,...$e(o,e))}}const S=new WeakMap;function Ae(e){if(re(()=>{const d=S.get(e);d&&(d.refs--||d.cleanup())}),S.has(e)){const d=S.get(e);return d.refs++,d.store}const[n,o]=oe(structuredClone(e.doc()));S.set(e,{refs:0,store:n,cleanup(){e.off("change",t),e.off("delete",c),S.delete(e)}});function t(d){if(d.scopeReplaced){o(U(d.doc??{}));return}o(Ce(_e(d)))}function c(){o(U({}))}return e.on("change",t),e.on("delete",c),e.whenReady().then(()=>{o(structuredClone(e.doc()))}),n}const T=e=>typeof e=="function"&&!e.length?e():e;function Ee(e){return x(()=>T(e)&&Ae(T(e)))}const ie=de(null);function xe(e,n){const o=fe(ie);if(!o)throw new Error("use outside <RepoContext> requires options.repo");const t=o;function c(){const p=T(e);if(!p)return;const h=t.findWithProgress(p).peek();return h.state==="ready"?h.handle:void 0}const[d,{mutate:a}]=pe(e,p=>t.findWithProgress(p).whenReady(),{initialValue:c()});return he(()=>{T(e)||a()}),d}function ee(e,n){const o=xe(e);return[Ee(o),o]}var Ie=w('<svg width=14 height=14 viewBox="0 0 14 14"fill=none stroke=var(--studio-chrome-line) stroke-width=1.5 stroke-linecap=round><line x1=7 y1=3 x2=7 y2=11></line><line x1=3 y1=7 x2=11 y2=7>'),De=w('<svg viewBox="0 0 10 10"fill=none stroke=var(--studio-chrome-line) stroke-width=1.5 stroke-linecap=round><line x1=2 y1=2 x2=8 y2=8></line><line x1=8 y1=2 x2=2 y2=8>'),Re=w('<svg width=12 height=12 viewBox="0 0 12 12"fill=none stroke=var(--studio-chrome-line) stroke-width=2 stroke-linecap=round stroke-linejoin=round><polyline points="2.5 6 5 8.5 9.5 3.5">'),Oe=w("<div class=add-popover><div class=add-popover-custom><input type=text class=add-popover-custom-input><button class=add-popover-custom-btn></button></div><button class=add-popover-done>Done"),Se=w("<button class=add-popover-option>"),Pe=w("<div class=preview-grid>"),Le=w("<div class=config-section><div class=section-label>"),je=w("<p class=empty-message>No tools available"),Me=w("<button class=preview-card><div class=preview-card-label><span></span><span class=preview-card-check>"),Te=w('<div class=config-section><div class=section-label></div><div><div class=add-popover-anchor><button class=toolbar-add-btn aria-label="Add doc titlebar tool">'),qe=w("<div><div class=toolbar-box-label></div><button class=toolbar-box-remove>"),Be=w("<div class=configurator>"),Ne=w('<div class="configurator loading">Loading configuration...'),ze=w("<p class=empty-message>Preparing layout configuration…"),Ue=w("<div class=config-section><div class=section-label>Theme</div><div class=theme-embed><patchwork-view tool-id=theme-picker>",!0,!1,!1);const Ge=250;function Ve(e){const n=ue(e),[o,t]=oe((n.all?.()??[]).map(a=>a)),c=()=>{const a=(n.all?.()??[]).map(p=>p);t(U(a))};c();const d=n.on("changed",c);return re(d),o}function te(e,n){return e.filter(o=>!o.unlisted&&(o.tags??[]).includes(n)).map(o=>({id:o.id,name:o.name||o.id})).sort((o,t)=>o.name.localeCompare(t.name))}const G=()=>Ie(),He=e=>{const n=()=>e.size??10;return(()=>{var o=De();return E(t=>{var c=n(),d=n();return c!==t.e&&I(o,"width",t.e=c),d!==t.t&&I(o,"height",t.t=d),t},{e:void 0,t:void 0}),o})()},We=()=>Re();function Je(e){const[n,o]=M(""),t=()=>{const c=n().trim();c&&(e.onAdd(c),o(""))};return(()=>{var c=Oe(),d=c.firstChild,a=d.firstChild,p=a.nextSibling,h=d.nextSibling;return v(c,y(V,{get each(){return e.available},children:s=>(()=>{var i=Se();return i.$$click=()=>e.onAdd(s.id),v(i,y(G,{}),null),v(i,()=>s.name,null),i})()}),d),a.$$keydown=s=>s.key==="Enter"&&t(),a.$$input=s=>o(s.currentTarget.value),p.$$click=t,v(p,y(G,{})),h.$$click=()=>e.onClose(),E(s=>{var i=e.customPlaceholder??"tool-id",r=!n().trim();return i!==s.e&&I(a,"placeholder",s.e=i),r!==s.t&&(p.disabled=s.t=r),s},{e:void 0,t:void 0}),E(()=>a.value=n()),c})()}function q(e){e.addEventListener("patchwork:subscribe",(n=>{n.detail.selector.type==="patchwork:selected-doc"?J(n,o=>{o([])}):n.detail.selector.type==="patchwork:selected-view"&&J(n,o=>{o(null)})}),!0)}function Ze(e){return(()=>{var n=Le(),o=n.firstChild;return v(o,()=>e.label),v(n,y(P,{get when(){return e.options.length>0},get fallback(){return je()},get children(){var t=Pe(),c=q;return typeof c=="function"?ne(c,t):q=t,v(t,y(V,{get each(){return e.options},children:d=>(()=>{var a=Me(),p=a.firstChild,h=p.firstChild,s=h.nextSibling;return a.$$click=()=>e.onChange(d.id),v(h,()=>d.name),v(s,y(We,{})),E(()=>I(a,"aria-checked",e.value===d.id)),a})()})),t}}),null),n})()}function Ke(e,n,o){return n===null||o===null?"":e===n?" dragging":o===n?"":n<o&&e>n&&e<=o?" shift-left":n>o&&e<n&&e>=o?" shift-right":""}function Ye(e){const[n,o]=M(!1),[t,c]=M(null),[d,a]=M(null);let p=null;const h=x(()=>e.values??[]),s=x(()=>new Set(h())),i=x(()=>e.allOptions.filter(u=>!s().has(u.id))),r=u=>e.allOptions.find(m=>m.id===u)?.name??u,l=u=>{e.setValues(h().filter((m,g)=>g!==u))},f=u=>{e.setValues([...h(),u])},C=u=>{p=u,a(u)},b=()=>{const u=t(),m=p;if(c(null),a(null),p=null,u==null||m==null||u===m)return;const g=[...h()],[k]=g.splice(u,1);g.splice(m,0,k),e.setValues(g)};return(()=>{var u=Te(),m=u.firstChild,g=m.nextSibling,k=g.firstChild,L=k.firstChild;v(m,()=>e.label);var A=q;return typeof A=="function"?ne(A,g):q=g,v(g,y(V,{get each(){return h()},children:(B,_)=>(()=>{var $=qe(),D=$.firstChild,R=D.nextSibling;return $.addEventListener("dragend",()=>b()),$.addEventListener("dragover",F=>{F.preventDefault(),F.dataTransfer.dropEffect="move",C(_())}),$.addEventListener("dragstart",F=>{F.dataTransfer.effectAllowed="move";const O=_();requestAnimationFrame(()=>{c(O),C(O)})}),I($,"draggable",!0),v(D,()=>r(B)),R.$$click=F=>{F.stopPropagation(),l(_())},v(R,y(He,{size:8})),E(F=>{var O=`toolbar-box${Ke(_(),t(),d())}`,H=`Remove ${r(B)}`;return O!==F.e&&W($,F.e=O),H!==F.t&&I(R,"aria-label",F.t=H),F},{e:void 0,t:void 0}),$})()}),k),L.$$click=()=>o(!n()),v(L,y(G,{})),v(k,y(P,{get when(){return n()},get children(){return y(Je,{get available(){return i()},onAdd:f,onClose:()=>o(!1)})}}),null),E(()=>W(g,`toolbar-strip${t()!==null?" is-dragging":""}`)),u})()}function Qe(e){const[n]=ee(()=>e.handle.url),[o,t]=ee(()=>n()?.tools?.threepane),c=Ve("patchwork:tool"),d=x(()=>te([...c],"frame-tool")),a=x(()=>te([...c],"titlebar-tool")),p=r=>typeof r=="string"?r:r[0],h=()=>o()?.doctitle?.tools?.map(p),s=r=>t()?.change(l=>{l.doctitle.tools=r.slice()}),i=(r,l)=>{e.handle.change(f=>{f[r]=l})};return y(P,{get when(){return n()},get fallback(){return Ne()},get children(){var r=Be();return v(r,y(Ze,{label:"Frame Tool",get value(){return n().frameToolId},onChange:l=>{i("frameToolId",l),setTimeout(async()=>{await e.element.repo.flush().catch(()=>null),window.location.reload()},Ge)},get options(){return d()}}),null),v(r,y(P,{get when(){return o()},get fallback(){return ze()},get children(){return y(Ye,{label:"Doc Titlebar",get values(){return h()},setValues:s,get allOptions(){return a()}})}}),null),v(r,y(P,{get when(){return n()?.toolStorage?.["theme-preferences"]},children:l=>(()=>{var f=Ue(),C=f.firstChild,b=C.nextSibling,u=b.firstChild;return u._$owner=ae(),E(()=>u.docUrl=l()),f})()}),null),r}})}function ot(e,n){const o=le(()=>y(ie.Provider,{get value(){return n.repo},get children(){return y(Qe,{handle:e,element:n})}}),n);return()=>o()}ce(["input","keydown","click"]);export{Qe as FrameConfigurator,ot as renderFrameConfigurator};
3
- //# sourceMappingURL=FrameConfigurator-DVRBzIR-.js.map
2
+ import{render as le,createComponent as y,insert as v,getOwner as ae,effect as E,template as w,use as ne,setAttribute as I,className as J,delegateEvents as ce}from"solid-js/web";import{getRegistry as ue}from"@inkandswitch/patchwork-plugins";import{accept as W}from"@inkandswitch/patchwork-providers";import{onCleanup as re,createMemo as x,createContext as de,useContext as fe,createResource as pe,createEffect as he,Show as P,For as H,createSignal as M}from"solid-js";import{createStore as oe,reconcile as U,produce as Ce}from"solid-js/store";function me(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var j={exports:{}},N,Z;function ge(){if(Z)return N;Z=1;var e=1e3,n=e*60,r=n*60,t=r*24,c=t*7,d=t*365.25;N=function(i,o){o=o||{};var l=typeof i;if(l==="string"&&i.length>0)return a(i);if(l==="number"&&isFinite(i))return o.long?m(i):p(i);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(i))};function a(i){if(i=String(i),!(i.length>100)){var o=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(o){var l=parseFloat(o[1]),f=(o[2]||"ms").toLowerCase();switch(f){case"years":case"year":case"yrs":case"yr":case"y":return l*d;case"weeks":case"week":case"w":return l*c;case"days":case"day":case"d":return l*t;case"hours":case"hour":case"hrs":case"hr":case"h":return l*r;case"minutes":case"minute":case"mins":case"min":case"m":return l*n;case"seconds":case"second":case"secs":case"sec":case"s":return l*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return l;default:return}}}}function p(i){var o=Math.abs(i);return o>=t?Math.round(i/t)+"d":o>=r?Math.round(i/r)+"h":o>=n?Math.round(i/n)+"m":o>=e?Math.round(i/e)+"s":i+"ms"}function m(i){var o=Math.abs(i);return o>=t?s(i,o,t,"day"):o>=r?s(i,o,r,"hour"):o>=n?s(i,o,n,"minute"):o>=e?s(i,o,e,"second"):i+" ms"}function s(i,o,l,f){var h=o>=l*1.5;return Math.round(i/l)+" "+f+(h?"s":"")}return N}var z,K;function ve(){if(K)return z;K=1;function e(n){t.debug=t,t.default=t,t.coerce=s,t.disable=p,t.enable=d,t.enabled=m,t.humanize=ge(),t.destroy=i,Object.keys(n).forEach(o=>{t[o]=n[o]}),t.names=[],t.skips=[],t.formatters={};function r(o){let l=0;for(let f=0;f<o.length;f++)l=(l<<5)-l+o.charCodeAt(f),l|=0;return t.colors[Math.abs(l)%t.colors.length]}t.selectColor=r;function t(o){let l,f=null,h,b;function u(...C){if(!u.enabled)return;const g=u,k=Number(new Date),L=k-(l||k);g.diff=L,g.prev=l,g.curr=k,l=k,C[0]=t.coerce(C[0]),typeof C[0]!="string"&&C.unshift("%O");let A=0;C[0]=C[0].replace(/%([a-zA-Z%])/g,(_,$)=>{if(_==="%%")return"%";A++;const D=t.formatters[$];if(typeof D=="function"){const R=C[A];_=D.call(g,R),C.splice(A,1),A--}return _}),t.formatArgs.call(g,C),(g.log||t.log).apply(g,C)}return u.namespace=o,u.useColors=t.useColors(),u.color=t.selectColor(o),u.extend=c,u.destroy=t.destroy,Object.defineProperty(u,"enabled",{enumerable:!0,configurable:!1,get:()=>f!==null?f:(h!==t.namespaces&&(h=t.namespaces,b=t.enabled(o)),b),set:C=>{f=C}}),typeof t.init=="function"&&t.init(u),u}function c(o,l){const f=t(this.namespace+(typeof l>"u"?":":l)+o);return f.log=this.log,f}function d(o){t.save(o),t.namespaces=o,t.names=[],t.skips=[];const l=(typeof o=="string"?o:"").trim().replace(/\s+/g,",").split(",").filter(Boolean);for(const f of l)f[0]==="-"?t.skips.push(f.slice(1)):t.names.push(f)}function a(o,l){let f=0,h=0,b=-1,u=0;for(;f<o.length;)if(h<l.length&&(l[h]===o[f]||l[h]==="*"))l[h]==="*"?(b=h,u=f,h++):(f++,h++);else if(b!==-1)h=b+1,u++,f=u;else return!1;for(;h<l.length&&l[h]==="*";)h++;return h===l.length}function p(){const o=[...t.names,...t.skips.map(l=>"-"+l)].join(",");return t.enable(""),o}function m(o){for(const l of t.skips)if(a(o,l))return!1;for(const l of t.names)if(a(o,l))return!0;return!1}function s(o){return o instanceof Error?o.stack||o.message:o}function i(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return t.enable(t.load()),t}return z=e,z}var Y;function ye(){return Y||(Y=1,(function(e,n){var r={};n.formatArgs=c,n.save=d,n.load=a,n.useColors=t,n.storage=p(),n.destroy=(()=>{let s=!1;return()=>{s||(s=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),n.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function t(){if(typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs))return!0;if(typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;let s;return typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&(s=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(s[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function c(s){if(s[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+s[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const i="color: "+this.color;s.splice(1,0,i,"color: inherit");let o=0,l=0;s[0].replace(/%[a-zA-Z%]/g,f=>{f!=="%%"&&(o++,f==="%c"&&(l=o))}),s.splice(l,0,i)}n.log=console.debug||console.log||(()=>{});function d(s){try{s?n.storage.setItem("debug",s):n.storage.removeItem("debug")}catch{}}function a(){let s;try{s=n.storage.getItem("debug")||n.storage.getItem("DEBUG")}catch{}return!s&&typeof process<"u"&&"env"in process&&(s=r.DEBUG),s}function p(){try{return localStorage}catch{}}e.exports=ve()(n);const{formatters:m}=e.exports;m.j=function(s){try{return JSON.stringify(s)}catch(i){return"[UnexpectedJSONParseError]: "+i.message}}})(j,j.exports)),j.exports}var we=ye();const be=me(we);var se=be("cabbages");function Q(e){return typeof e=="object"&&typeof e!=null&&Object.getPrototypeOf(e)==Object.prototype}var Fe="";function ke(e,...n){if(n.length==0){se("empty patch");return}const[r,t,c]=n;let d=[...r];for(;;){let a=d.shift();if(!d.length){const m=Array.isArray(t);if(Q(e)&&m&&typeof a>"u"&&typeof t[0]=="string"){delete e[t[0]];return}if(m||typeof t=="number"){if(typeof a>"u")throw new Error("cant treat top level as a seq");a=a;let[s,i]=Array.isArray(t)?t:[t,t+1];const o=Array.isArray(t)&&t.length==0;if(!o&&(s==null||i==null))throw new RangeError("it's all or nothing, no half measures");const l=typeof c>"u",f=s===i&&!l,h=o&&!l,b=!f&&!l&&!h;if(typeof e[a]>"u"){if(typeof e=="string")return;typeof c=="string"?e[a]="":e[a]=[]}let u=e[a];if(Array.isArray(u)){if(h){Array.isArray(c)?u.push(...c):u.push(c);return}if(f||b){Array.isArray(c)?u.splice(s,i-s,...c):u.splice(s,i-s,c);return}if(l){u.splice(s,i-s);return}throw new Error("i don't know what happened")}if(typeof u=="string"){if(h){e[a]=u+c;return}if(b||f){e[a]=u.slice(0,s)+(typeof c=="string"?c:c.map(C=>typeof C=="string"?C:Fe).join(""))+u.slice(i);return}if(l){e[a]=u.slice(0,s)+u.slice(i);return}throw new Error("i don't know what happened")}if(Q(u)&&m&&typeof t[0]=="string"){delete u[t[0]];return}throw new Error("not implemented")}if(typeof a>"u"){if(typeof t!="string")throw new Error(`can't index top-level map with ${t}`);typeof c>"u"?delete e[t]:e[t]=c;return}if(typeof e[a]>"u"&&(e[a]={}),m){let[s,i]=t;s!=null&&i!=null&&(typeof c>"u"&&s!=null&&i!=null?delete e[a][s||i]:e[a][s||i]=c)}else if(typeof c>"u")delete e[a][t];else{if(typeof e[a]=="string")return;e[a][t]=c}return}if(typeof a>"u")throw new Error("cant treat top level as a seq");a=a;let p=d[0];if(typeof e[a]>"u")if(typeof p=="string")e[a]={};else if(typeof p=="number")e[a]=[];else throw new Error(`can't go down this road ${e}.${a}.${p}`);e=e[a]}}function X(e,n){for(let r=0;r<n.length;r++)e=e?e[n[r]]:void 0;return e}function $e(e,n){const r=e.path.slice(0,-1),t=e.path[e.path.length-1];switch(e.action){case"mark":case"unmark":return se(`skipping ${e.action} because it doesn't affect material reality`),[];case"inc":if(n)return[r,t,X(n.patchInfo.after,e.path)];throw new Error(`can't apply ${e.action} without payload argument`);case"conflict":if(n)return[r,t,X(n.patchInfo.after,e.path)];throw new Error(`can't apply ${e.action} without payload argument`);case"del":return typeof t=="string"?[r,t]:[r,[t,t+(e.length||1)]];case"insert":return[r,[t,t],structuredClone(e.values)];case"splice":return[r,[t,t],[e.value]];case"put":return[r,t,structuredClone(e.value)]}}function _e(e){return n=>{for(let r of e.patches)ke(n,...$e(r,e))}}const S=new WeakMap;function Ae(e){if(re(()=>{const d=S.get(e);d&&(d.refs--||d.cleanup())}),S.has(e)){const d=S.get(e);return d.refs++,d.store}const[n,r]=oe(structuredClone(e.doc()));S.set(e,{refs:0,store:n,cleanup(){e.off("change",t),e.off("delete",c),S.delete(e)}});function t(d){if(d.scopeReplaced){r(U(d.doc??{}));return}r(Ce(_e(d)))}function c(){r(U({}))}return e.on("change",t),e.on("delete",c),n}const T=e=>typeof e=="function"&&!e.length?e():e;function Ee(e){return x(()=>T(e)&&Ae(T(e)))}const ie=de(null);function xe(e,n){const r=fe(ie);if(!r)throw new Error("use outside <RepoContext> requires options.repo");const t=r;function c(){const p=T(e);if(p)return De(t,p)}const[d,{mutate:a}]=pe(e,p=>t.find(p),{initialValue:c()});return he(()=>{T(e)||a()}),d}function Ie(e){return typeof e.query=="function"}function De(e,n){if(Ie(e)){const t=e.query(n).state();return t.status=="ready"?t.handle:void 0}const r=e.findWithProgress(n).peek();return r.state=="ready"?r.handle:void 0}function ee(e,n){const r=xe(e);return[Ee(r),r]}var Re=w('<svg width=14 height=14 viewBox="0 0 14 14"fill=none stroke=var(--studio-chrome-line) stroke-width=1.5 stroke-linecap=round><line x1=7 y1=3 x2=7 y2=11></line><line x1=3 y1=7 x2=11 y2=7>'),Oe=w('<svg viewBox="0 0 10 10"fill=none stroke=var(--studio-chrome-line) stroke-width=1.5 stroke-linecap=round><line x1=2 y1=2 x2=8 y2=8></line><line x1=8 y1=2 x2=2 y2=8>'),Se=w('<svg width=12 height=12 viewBox="0 0 12 12"fill=none stroke=var(--studio-chrome-line) stroke-width=2 stroke-linecap=round stroke-linejoin=round><polyline points="2.5 6 5 8.5 9.5 3.5">'),Pe=w("<div class=add-popover><div class=add-popover-custom><input type=text class=add-popover-custom-input><button class=add-popover-custom-btn></button></div><button class=add-popover-done>Done"),Le=w("<button class=add-popover-option>"),je=w("<div class=preview-grid>"),Me=w("<div class=config-section><div class=section-label>"),Te=w("<p class=empty-message>No tools available"),qe=w("<button class=preview-card><div class=preview-card-label><span></span><span class=preview-card-check>"),Be=w('<div class=config-section><div class=section-label></div><div><div class=add-popover-anchor><button class=toolbar-add-btn aria-label="Add doc titlebar tool">'),Ne=w("<div><div class=toolbar-box-label></div><button class=toolbar-box-remove>"),ze=w("<div class=configurator>"),Ue=w('<div class="configurator loading">Loading configuration...'),Ge=w("<p class=empty-message>Preparing layout configuration…"),He=w("<div class=config-section><div class=section-label>Theme</div><div class=theme-embed><patchwork-view tool-id=theme-picker>",!0,!1,!1);const Ve=250;function Je(e){const n=ue(e),[r,t]=oe((n.all?.()??[]).map(a=>a)),c=()=>{const a=(n.all?.()??[]).map(p=>p);t(U(a))};c();const d=n.on("changed",c);return re(d),r}function te(e,n){return e.filter(r=>!r.unlisted&&(r.tags??[]).includes(n)).map(r=>({id:r.id,name:r.name||r.id})).sort((r,t)=>r.name.localeCompare(t.name))}const G=()=>Re(),We=e=>{const n=()=>e.size??10;return(()=>{var r=Oe();return E(t=>{var c=n(),d=n();return c!==t.e&&I(r,"width",t.e=c),d!==t.t&&I(r,"height",t.t=d),t},{e:void 0,t:void 0}),r})()},Ze=()=>Se();function Ke(e){const[n,r]=M(""),t=()=>{const c=n().trim();c&&(e.onAdd(c),r(""))};return(()=>{var c=Pe(),d=c.firstChild,a=d.firstChild,p=a.nextSibling,m=d.nextSibling;return v(c,y(H,{get each(){return e.available},children:s=>(()=>{var i=Le();return i.$$click=()=>e.onAdd(s.id),v(i,y(G,{}),null),v(i,()=>s.name,null),i})()}),d),a.$$keydown=s=>s.key==="Enter"&&t(),a.$$input=s=>r(s.currentTarget.value),p.$$click=t,v(p,y(G,{})),m.$$click=()=>e.onClose(),E(s=>{var i=e.customPlaceholder??"tool-id",o=!n().trim();return i!==s.e&&I(a,"placeholder",s.e=i),o!==s.t&&(p.disabled=s.t=o),s},{e:void 0,t:void 0}),E(()=>a.value=n()),c})()}function q(e){e.addEventListener("patchwork:subscribe",(n=>{n.detail.selector.type==="patchwork:selected-doc"?W(n,r=>{r([])}):n.detail.selector.type==="patchwork:selected-view"&&W(n,r=>{r(null)})}),!0)}function Ye(e){return(()=>{var n=Me(),r=n.firstChild;return v(r,()=>e.label),v(n,y(P,{get when(){return e.options.length>0},get fallback(){return Te()},get children(){var t=je(),c=q;return typeof c=="function"?ne(c,t):q=t,v(t,y(H,{get each(){return e.options},children:d=>(()=>{var a=qe(),p=a.firstChild,m=p.firstChild,s=m.nextSibling;return a.$$click=()=>e.onChange(d.id),v(m,()=>d.name),v(s,y(Ze,{})),E(()=>I(a,"aria-checked",e.value===d.id)),a})()})),t}}),null),n})()}function Qe(e,n,r){return n===null||r===null?"":e===n?" dragging":r===n?"":n<r&&e>n&&e<=r?" shift-left":n>r&&e<n&&e>=r?" shift-right":""}function Xe(e){const[n,r]=M(!1),[t,c]=M(null),[d,a]=M(null);let p=null;const m=x(()=>e.values??[]),s=x(()=>new Set(m())),i=x(()=>e.allOptions.filter(u=>!s().has(u.id))),o=u=>e.allOptions.find(C=>C.id===u)?.name??u,l=u=>{e.setValues(m().filter((C,g)=>g!==u))},f=u=>{e.setValues([...m(),u])},h=u=>{p=u,a(u)},b=()=>{const u=t(),C=p;if(c(null),a(null),p=null,u==null||C==null||u===C)return;const g=[...m()],[k]=g.splice(u,1);g.splice(C,0,k),e.setValues(g)};return(()=>{var u=Be(),C=u.firstChild,g=C.nextSibling,k=g.firstChild,L=k.firstChild;v(C,()=>e.label);var A=q;return typeof A=="function"?ne(A,g):q=g,v(g,y(H,{get each(){return m()},children:(B,_)=>(()=>{var $=Ne(),D=$.firstChild,R=D.nextSibling;return $.addEventListener("dragend",()=>b()),$.addEventListener("dragover",F=>{F.preventDefault(),F.dataTransfer.dropEffect="move",h(_())}),$.addEventListener("dragstart",F=>{F.dataTransfer.effectAllowed="move";const O=_();requestAnimationFrame(()=>{c(O),h(O)})}),I($,"draggable",!0),v(D,()=>o(B)),R.$$click=F=>{F.stopPropagation(),l(_())},v(R,y(We,{size:8})),E(F=>{var O=`toolbar-box${Qe(_(),t(),d())}`,V=`Remove ${o(B)}`;return O!==F.e&&J($,F.e=O),V!==F.t&&I(R,"aria-label",F.t=V),F},{e:void 0,t:void 0}),$})()}),k),L.$$click=()=>r(!n()),v(L,y(G,{})),v(k,y(P,{get when(){return n()},get children(){return y(Ke,{get available(){return i()},onAdd:f,onClose:()=>r(!1)})}}),null),E(()=>J(g,`toolbar-strip${t()!==null?" is-dragging":""}`)),u})()}function et(e){const[n]=ee(()=>e.handle.url),[r,t]=ee(()=>n()?.tools?.threepane),c=Je("patchwork:tool"),d=x(()=>te([...c],"frame-tool")),a=x(()=>te([...c],"titlebar-tool")),p=o=>typeof o=="string"?o:o[0],m=()=>r()?.doctitle?.tools?.map(p),s=o=>t()?.change(l=>{l.doctitle.tools=o.slice()}),i=(o,l)=>{e.handle.change(f=>{f[o]=l})};return y(P,{get when(){return n()},get fallback(){return Ue()},get children(){var o=ze();return v(o,y(Ye,{label:"Frame Tool",get value(){return n().frameToolId},onChange:l=>{i("frameToolId",l),setTimeout(async()=>{await e.element.repo.flush().catch(()=>null),window.location.reload()},Ve)},get options(){return d()}}),null),v(o,y(P,{get when(){return r()},get fallback(){return Ge()},get children(){return y(Xe,{label:"Doc Titlebar",get values(){return m()},setValues:s,get allOptions(){return a()}})}}),null),v(o,y(P,{get when(){return n()?.toolStorage?.["theme-preferences"]},children:l=>(()=>{var f=He(),h=f.firstChild,b=h.nextSibling,u=b.firstChild;return u._$owner=ae(),E(()=>u.docUrl=l()),f})()}),null),o}})}function it(e,n){const r=le(()=>y(ie.Provider,{get value(){return n.repo},get children(){return y(et,{handle:e,element:n})}}),n);return()=>r()}ce(["input","keydown","click"]);export{et as FrameConfigurator,it as renderFrameConfigurator};
3
+ //# sourceMappingURL=FrameConfigurator-C0ZRifTs.js.map