flexdesk 0.17.18 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/README.md +1 -0
- package/css/flexdesk.css +7544 -5916
- package/css/reset.css +1 -1
- package/css/tokens.css +23 -1
- package/dist/charts.js +10 -6
- package/dist/charts.js.map +1 -1
- package/dist/chunk-5W4EEKSK.js +778 -0
- package/dist/chunk-5W4EEKSK.js.map +7 -0
- package/dist/chunk-DNJ3N4T4.js +82 -0
- package/dist/chunk-DNJ3N4T4.js.map +7 -0
- package/dist/{chunk-REJ5HLIM.js → chunk-HYJYYEPK.js} +2 -2
- package/dist/{chunk-7U4IB65H.js → chunk-LLBJ2SJH.js} +5 -3
- package/dist/{chunk-7U4IB65H.js.map → chunk-LLBJ2SJH.js.map} +1 -1
- package/dist/{chunk-7OL6F2AM.js → chunk-P74F6I6P.js} +6 -4
- package/dist/{chunk-7OL6F2AM.js.map → chunk-P74F6I6P.js.map} +1 -1
- package/dist/chunk-PAI2ZUWV.js +260 -0
- package/dist/chunk-PAI2ZUWV.js.map +7 -0
- package/dist/chunk-Q7BALEPX.js +527 -0
- package/dist/chunk-Q7BALEPX.js.map +7 -0
- package/dist/chunk-QXAOTGCC.js +40 -0
- package/dist/chunk-QXAOTGCC.js.map +7 -0
- package/dist/{chunk-XJNADRGR.js → chunk-RKVYIXDC.js} +664 -91
- package/dist/chunk-RKVYIXDC.js.map +7 -0
- package/dist/{chunk-2Z2ENHR3.js → chunk-U5GKJUOC.js} +3 -3
- package/dist/{chunk-2Z2ENHR3.js.map → chunk-U5GKJUOC.js.map} +1 -1
- package/dist/chunk-UKP22RUG.js +219 -0
- package/dist/chunk-UKP22RUG.js.map +7 -0
- package/dist/chunk-VLOAI3HS.js +43 -0
- package/dist/chunk-VLOAI3HS.js.map +7 -0
- package/dist/{chunk-WUFLGETN.js → chunk-WVFGV5FT.js} +2 -39
- package/dist/{chunk-WUFLGETN.js.map → chunk-WVFGV5FT.js.map} +3 -3
- package/dist/{chunk-PGZ4EHSE.js → chunk-ZL3VKINP.js} +41 -390
- package/dist/chunk-ZL3VKINP.js.map +7 -0
- package/dist/editor.js +3 -2
- package/dist/editor.js.map +1 -1
- package/dist/flexdesk.css +7544 -5916
- package/dist/flow.js +29 -97
- package/dist/flow.js.map +3 -3
- package/dist/git.js +1356 -0
- package/dist/git.js.map +7 -0
- package/dist/reset.css +1 -1
- package/dist/tiles.js +20 -15
- package/dist/tiles.js.map +2 -2
- package/dist/tokens.css +23 -1
- package/dist/widgets.js +3967 -1188
- package/dist/widgets.js.map +4 -4
- package/dist/wm.js +120 -32
- package/dist/wm.js.map +2 -2
- package/docs/README.md +9 -4
- package/docs/best-practices.md +2 -2
- package/docs/components/chat-shell.md +198 -0
- package/docs/components/conversation.md +10 -0
- package/docs/components/filter-builder.md +246 -0
- package/docs/components/forms-and-dialogs.md +22 -0
- package/docs/components/git.md +355 -0
- package/docs/components/input-fields.md +167 -2
- package/docs/components/keymap.md +8 -0
- package/docs/components/menus.md +82 -2
- package/docs/components/panels-and-desktops.md +16 -5
- package/docs/components/shell.md +104 -1
- package/docs/components/workspace-picker.md +149 -0
- package/docs/concepts/building-and-packaging.md +2 -2
- package/docs/concepts/packages-and-entry-points.md +14 -13
- package/docs/concepts/state-guard.md +3 -3
- package/docs/quickstart.md +1 -1
- package/git.js +13 -0
- package/package.json +6 -1
- package/src/flow/kit/dom.js +28 -119
- package/src/flow/kit/step_picker.js +1 -1
- package/src/flow/kit/value_picker.js +1 -1
- package/src/flow/outline/menu.js +1 -1
- package/src/git/diff_viewer.js +212 -0
- package/src/git/diff_window.js +51 -0
- package/src/git/git_graph.js +401 -0
- package/src/git/git_ops.js +61 -0
- package/src/git/git_panel.js +755 -0
- package/src/git/index.js +9 -0
- package/src/git/line_diff.js +202 -0
- package/src/tiles/tile_base.js +5 -4
- package/src/tiling/desktops.js +10 -8
- package/src/tiling/keymap.js +6 -5
- package/src/tiling/kind_taxonomy.js +15 -2
- package/src/tiling/shell.js +124 -17
- package/src/tiling/tile_renderer.js +2 -3
- package/src/ui/components/action_dropdown.js +4 -78
- package/src/ui/components/anchored_layer.js +255 -0
- package/src/ui/components/chat_shell.js +920 -0
- package/src/ui/components/chat_state_machine.js +223 -0
- package/src/ui/components/choice_controls.js +45 -2
- package/src/ui/components/color_field.js +3 -2
- package/src/ui/components/color_list_field.js +3 -2
- package/src/ui/components/combobox.js +422 -0
- package/src/ui/components/conversation_view.js +17 -2
- package/src/ui/components/data_table.js +2 -2
- package/src/ui/components/filter_builder.js +766 -0
- package/src/ui/components/filter_model.js +614 -0
- package/src/ui/components/managed_window.js +24 -47
- package/src/ui/components/modal.js +79 -109
- package/src/ui/components/option_list.js +160 -0
- package/src/ui/components/popover.js +94 -0
- package/src/ui/components/recent_items.js +169 -0
- package/src/ui/components/select.js +322 -0
- package/src/ui/components/tag_input.js +77 -8
- package/src/ui/components/workspace_picker.js +1155 -0
- package/src/ui/utils/fire_event.js +17 -0
- package/src/ui/utils/focusable.js +25 -0
- package/src/ui/utils/modal_host.js +27 -0
- package/widgets.js +12 -2
- package/css/base.css +0 -10547
- package/css/overrides.css +0 -2596
- package/dist/chunk-7JI7HHSY.js +0 -107
- package/dist/chunk-7JI7HHSY.js.map +0 -7
- package/dist/chunk-MIW7D6WC.js +0 -526
- package/dist/chunk-MIW7D6WC.js.map +0 -7
- package/dist/chunk-PGZ4EHSE.js.map +0 -7
- package/dist/chunk-XJNADRGR.js.map +0 -7
- /package/dist/{chunk-REJ5HLIM.js.map → chunk-HYJYYEPK.js.map} +0 -0
package/dist/git.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/git/line_diff.js", "../src/git/diff_viewer.js", "../src/git/diff_window.js", "../src/git/git_ops.js", "../src/git/git_graph.js", "../src/git/git_panel.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * line_diff.js \u2014 what changed between two texts, as lines to draw.\n *\n * Two ways in, one shape out:\n *\n * computeLineDiff(before, after) the two texts themselves, compared here\n * parseUnifiedDiff(text) what `git diff` printed, read here\n *\n * Both answer an array of DiffLine:\n *\n * { kind: 'context' | 'add' | 'del', oldLine, newLine, text }\n * { kind: 'gap', oldLine: null, newLine: null, text: '', hidden } unchanged lines left out\n * { kind: 'hunk' | 'meta' | 'file', oldLine: null, newLine: null, text }\n *\n * `oldLine` and `newLine` are 1-based, and null on the side a line is not on.\n * There is no DOM here and nothing about what the text is: a consumer that\n * compares only part of a file says where that part starts (`beforeStart`,\n * `afterStart`) and the numbers are the file's.\n */\n\n/** Past this many differing lines a side, computeLineDiff answers null rather than compare. */\nexport const LINE_DIFF_LIMIT = 1500;\n\n/**\n * A text as its lines. CRLF and LF are the same line end, and a final line end\n * does not make a last empty line.\n * @param {string|null|undefined} text\n * @returns {string[]}\n */\nexport function splitLines(text) {\n const s = String(text ?? '');\n if (s === '') return [];\n const lines = s.split(/\\r?\\n/);\n if (lines[lines.length - 1] === '') lines.pop();\n return lines;\n}\n\n/** The edit script of two line arrays, by longest common subsequence: deletions before additions. */\nfunction editScript(a, b) {\n const n = a.length;\n const m = b.length;\n const lcs = Array.from({ length: n + 1 }, () => new Uint32Array(m + 1));\n for (let i = n - 1; i >= 0; i--) {\n for (let j = m - 1; j >= 0; j--) {\n lcs[i][j] = a[i] === b[j] ? lcs[i + 1][j + 1] + 1 : Math.max(lcs[i + 1][j], lcs[i][j + 1]);\n }\n }\n const ops = [];\n let i = 0;\n let j = 0;\n while (i < n || j < m) {\n if (i < n && j < m && a[i] === b[j]) { ops.push(['context', i, j]); i++; j++; }\n else if (i < n && (j >= m || lcs[i + 1][j] >= lcs[i][j + 1])) { ops.push(['del', i, -1]); i++; }\n else { ops.push(['add', -1, j]); j++; }\n }\n return ops;\n}\n\n/**\n * Compare two texts line by line.\n *\n * Unchanged lines at the start and the end are set aside first, so `maxLines`\n * limits the part that actually differs: a long file with a small edit is\n * compared, however long it is.\n *\n * @param {string|null|undefined} before\n * @param {string|null|undefined} after\n * @param {Object} [options]\n * @param {number} [options.context=3] - Unchanged lines kept around each change; `Infinity` keeps them all.\n * @param {number} [options.maxLines=LINE_DIFF_LIMIT]\n * @param {number} [options.beforeStart=1] - The line number of `before`'s first line.\n * @param {number} [options.afterStart=1] - The line number of `after`'s first line.\n * @returns {Array<Object>|null} DiffLines; `[]` when the texts have the same lines, `null` when too long to compare.\n */\nexport function computeLineDiff(before, after, {\n context = 3,\n maxLines = LINE_DIFF_LIMIT,\n beforeStart = 1,\n afterStart = 1,\n} = {}) {\n const a = splitLines(before);\n const b = splitLines(after);\n\n let head = 0;\n while (head < a.length && head < b.length && a[head] === b[head]) head++;\n let tail = 0;\n while (tail < a.length - head && tail < b.length - head\n && a[a.length - 1 - tail] === b[b.length - 1 - tail]) tail++;\n\n const midA = a.slice(head, a.length - tail);\n const midB = b.slice(head, b.length - tail);\n if (midA.length === 0 && midB.length === 0) return [];\n if (midA.length > maxLines || midB.length > maxLines) return null;\n\n const ops = [];\n for (let k = 0; k < head; k++) ops.push(['context', k, k]);\n for (const [kind, i, j] of editScript(midA, midB)) {\n ops.push([kind, i < 0 ? -1 : i + head, j < 0 ? -1 : j + head]);\n }\n for (let k = tail; k > 0; k--) ops.push(['context', a.length - k, b.length - k]);\n\n // A line is kept when a change is within `context` lines of it, either way.\n const keep = new Uint8Array(ops.length);\n let reach = -1;\n for (let k = 0; k < ops.length; k++) {\n if (ops[k][0] !== 'context') reach = k + context;\n if (k <= reach) keep[k] = 1;\n }\n reach = ops.length;\n for (let k = ops.length - 1; k >= 0; k--) {\n if (ops[k][0] !== 'context') reach = k - context;\n if (k >= reach) keep[k] = 1;\n }\n\n const out = [];\n let skipped = 0;\n ops.forEach(([kind, i, j], k) => {\n if (!keep[k]) { skipped++; return; }\n if (skipped > 0 && out.length > 0) {\n out.push({ kind: 'gap', oldLine: null, newLine: null, text: '', hidden: skipped });\n }\n skipped = 0;\n out.push({\n kind,\n oldLine: i < 0 ? null : beforeStart + i,\n newLine: j < 0 ? null : afterStart + j,\n text: j < 0 ? a[i] : b[j],\n });\n });\n return out;\n}\n\nconst HUNK_RE = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/;\n\n/**\n * Read a unified diff into DiffLines: `diff --git`, `index`, `---` and `+++`\n * headers are left out, a `@@` line is a `hunk`, and `\\ No newline at end of\n * file`, `Binary files \u2026 differ` and `rename from \u2026`/`rename to \u2026` are `meta`,\n * so that a rename with no change in it is still something to read. A diff of several files has a\n * `file` line before each file's hunks; a diff of one file has none.\n * @param {string|null|undefined} text\n * @returns {Array<Object>}\n */\nexport function parseUnifiedDiff(text) {\n const lines = String(text ?? '').split(/\\r?\\n/);\n const fileHeaders = lines.filter((l) => l.startsWith('diff --git ')).length;\n const out = [];\n const header = (kind, line) => out.push({ kind, oldLine: null, newLine: null, text: line });\n let oldNo = 0;\n let newNo = 0;\n let oldLeft = 0;\n let newLeft = 0;\n for (const line of lines) {\n if (oldLeft > 0 || newLeft > 0) {\n const sign = line[0];\n const body = line.slice(1);\n if (sign === '-') {\n out.push({ kind: 'del', oldLine: oldNo++, newLine: null, text: body });\n oldLeft--;\n } else if (sign === '+') {\n out.push({ kind: 'add', oldLine: null, newLine: newNo++, text: body });\n newLeft--;\n } else if (sign === '\\\\') {\n header('meta', line);\n } else {\n // A context line; a tool that strips trailing blanks leaves it empty.\n out.push({ kind: 'context', oldLine: oldNo++, newLine: newNo++, text: body });\n oldLeft--;\n newLeft--;\n }\n continue;\n }\n const hunk = HUNK_RE.exec(line);\n if (hunk) {\n oldNo = Number(hunk[1]);\n newNo = Number(hunk[3]);\n oldLeft = hunk[2] === undefined ? 1 : Number(hunk[2]);\n newLeft = hunk[4] === undefined ? 1 : Number(hunk[4]);\n header('hunk', line);\n } else if (line.startsWith('\\\\') || /^Binary files .* differ$/.test(line) || /^rename (from|to) /.test(line)) {\n header('meta', line);\n } else if (line.startsWith('diff --git ') && fileHeaders > 1) {\n header('file', / b\\/(.*)$/.exec(line)?.[1] ?? line.slice('diff --git '.length));\n }\n }\n return out;\n}\n\n/**\n * How many lines a diff adds and removes, for a one-glance summary.\n * @param {Array<Object>} lines - DiffLines.\n * @returns {{ added: number, removed: number }}\n */\nexport function diffStats(lines) {\n let added = 0;\n let removed = 0;\n for (const l of lines) {\n if (l.kind === 'add') added++;\n else if (l.kind === 'del') removed++;\n }\n return { added, removed };\n}\n", "/**\n * diff_viewer.js \u2014 what changed, drawn three ways. Usable alone: it needs no\n * adapter and knows nothing of git beyond reading a unified diff.\n *\n * FIELDS named values, `Priority low \u2192 high`. The consumer parses them;\n * they arrive as `{ name, from, to }`\n * TEXT line by line, with old and new line numbers and no diff headers,\n * from `before`/`after` (compared here) or else from `diff` (read)\n * RAW the `diff` text as it came\n *\n * const viewer = createDiffViewer(el, { before, after, diff, fields });\n * viewer.update({ before, after });\n * viewer.setView('raw');\n * viewer.destroy();\n *\n * A view is offered only when its data is there, and the buttons that switch\n * between views only when there are two or more. Which view shows: the one set\n * by `view`, `setView` or a click while it stays on offer, else Fields when a\n * field changed, else Text, else Raw. `setView(null)` hands the choice back.\n */\n\nimport { computeLineDiff, parseUnifiedDiff } from './line_diff.js';\n\nconst DEFAULT_LABELS = Object.freeze({\n fields: 'Fields',\n text: 'Text',\n raw: 'Raw',\n noChanges: 'No differences.',\n noFields: 'No field changes.',\n tooLong: 'Too long to compare here.',\n gap: (hidden) => `${hidden} unchanged line${hidden === 1 ? '' : 's'}`,\n});\n\nfunction el(tag, className, text) {\n const n = document.createElement(tag);\n if (className) n.className = className;\n if (text !== undefined) n.textContent = text;\n return n;\n}\n\n/** A field's value as drawn: an absent or empty one reads as a dash. */\nconst shownField = (v) => {\n const s = v === null || v === undefined ? '' : String(v);\n return s === '' ? '\u2014' : s;\n};\n\nfunction lineRow(line, labels) {\n const row = el('div', `twm-diff__line twm-diff__line--${line.kind}`);\n if (line.kind === 'gap' || line.kind === 'hunk' || line.kind === 'meta' || line.kind === 'file') {\n row.textContent = line.kind === 'gap' ? labels.gap(line.hidden) : line.text;\n return row;\n }\n row.append(\n el('span', 'twm-diff__n', line.oldLine === null ? '' : String(line.oldLine)),\n el('span', 'twm-diff__n', line.newLine === null ? '' : String(line.newLine)),\n el('span', 'twm-diff__sign', line.kind === 'add' ? '+' : line.kind === 'del' ? '-' : ''),\n el('span', 'twm-diff__text', line.text),\n );\n return row;\n}\n\n/**\n * @param {HTMLElement} host\n * @param {Object} [options]\n * @param {string} [options.before] - The old text. With `after`, drawn by comparing the two.\n * @param {string} [options.after] - The new text.\n * @param {string} [options.diff] - A unified diff: the Raw view, and the Text view when there is no `before`/`after`.\n * @param {Array<{name: string, from?: *, to?: *}>} [options.fields] - The Fields view's rows.\n * @param {number} [options.beforeStart=1] - The line number of `before`'s first line.\n * @param {number} [options.afterStart=1] - The line number of `after`'s first line.\n * @param {number} [options.context=3] - Unchanged lines kept around each change.\n * @param {number} [options.maxLines] - Past this many differing lines a side, the texts are not compared.\n * @param {'fields'|'text'|'raw'} [options.view] - The view to show while it is on offer.\n * @param {Object} [options.labels] - Words to replace: `fields`, `text`, `raw`, `noChanges`, `noFields`, `tooLong`, `gap(hidden)`.\n * @param {(view: string) => void} [options.onViewChange] - Told when a click changes the view.\n * @returns {{ el: HTMLElement, update(data: Object): void, setView(view: string|null): void,\n * view(): string|null, showMessage(text: string): void, destroy(): void }}\n */\nexport function createDiffViewer(host, options = {}) {\n const { context = 3, maxLines, onViewChange = null } = options;\n const labels = { ...DEFAULT_LABELS, ...options.labels };\n\n const root = el('div', 'twm-diff');\n const switcher = el('div', 'twm-diff__views');\n switcher.setAttribute('role', 'group');\n switcher.setAttribute('aria-label', 'Diff view');\n const body = el('div', 'twm-diff__body');\n root.append(switcher, body);\n host.appendChild(root);\n\n let data = {};\n let chosen = options.view ?? null;\n let textLines; // this data's Text view; undefined until first drawn\n let current = null;\n\n const hasPair = () => typeof data.before === 'string' || typeof data.after === 'string';\n\n const linesOfText = () => {\n if (textLines !== undefined) return textLines;\n textLines = hasPair()\n ? computeLineDiff(data.before, data.after, {\n context,\n ...(maxLines === undefined ? {} : { maxLines }),\n beforeStart: data.beforeStart ?? 1,\n afterStart: data.afterStart ?? 1,\n })\n : parseUnifiedDiff(data.diff);\n return textLines;\n };\n\n const offered = () => {\n const out = [];\n if (Array.isArray(data.fields)) out.push('fields');\n if (hasPair() || (typeof data.diff === 'string' && linesOfText().length > 0)) out.push('text');\n if (typeof data.diff === 'string') out.push('raw');\n return out;\n };\n\n const pick = (views) => {\n if (chosen && views.includes(chosen)) return chosen;\n if (views.includes('fields') && data.fields.length > 0) return 'fields';\n if (views.includes('text')) return 'text';\n return views[0] ?? null;\n };\n\n const message = (text) => {\n body.replaceChildren(el('div', 'twm-diff__message', text));\n };\n\n const drawFields = () => {\n if (data.fields.length === 0) { message(labels.noFields); return; }\n const grid = el('div', 'twm-diff__fields');\n for (const field of data.fields) {\n const values = el('span', 'twm-diff__field-values');\n const arrow = el('span', 'material-symbols-outlined twm-diff__field-arrow', 'arrow_forward');\n arrow.setAttribute('aria-hidden', 'true');\n values.append(\n el('span', 'twm-diff__field-from', shownField(field.from)),\n arrow,\n el('span', 'twm-diff__field-to', shownField(field.to)),\n );\n grid.append(el('span', 'twm-diff__field-name', String(field.name)), values);\n }\n body.replaceChildren(grid);\n };\n\n const drawText = () => {\n const lines = linesOfText();\n if (lines === null) {\n message(typeof data.diff === 'string' ? `${labels.tooLong} See ${labels.raw}.` : labels.tooLong);\n return;\n }\n if (lines.length === 0) { message(labels.noChanges); return; }\n const list = el('div', 'twm-diff__lines');\n list.append(...lines.map((line) => lineRow(line, labels)));\n body.replaceChildren(list);\n };\n\n const drawRaw = () => {\n if (data.diff === '') { message(labels.noChanges); return; }\n body.replaceChildren(el('pre', 'twm-diff__raw', data.diff));\n };\n\n const draw = () => {\n const views = offered();\n current = pick(views);\n switcher.replaceChildren(...(views.length > 1 ? views.map((v) => {\n const b = el('button', 'twm-diff__view', labels[v]);\n b.type = 'button';\n b.setAttribute('aria-pressed', String(v === current));\n b.addEventListener('click', () => {\n chosen = v;\n draw();\n onViewChange?.(v);\n });\n return b;\n }) : []));\n switcher.hidden = views.length <= 1;\n if (current === 'fields') drawFields();\n else if (current === 'text') drawText();\n else if (current === 'raw') drawRaw();\n else message(labels.noChanges);\n };\n\n const update = (next) => {\n data = next ?? {};\n textLines = undefined;\n draw();\n };\n\n update(options);\n\n return {\n el: root,\n update,\n setView(view) {\n chosen = view;\n draw();\n },\n view: () => current,\n /** Words in place of the diff, while it loads or when it could not be read. The next update replaces them. */\n showMessage(text) {\n switcher.replaceChildren();\n switcher.hidden = true;\n current = null;\n message(text);\n },\n destroy() {\n root.remove();\n },\n };\n}\n", "/**\n * diff_window.js \u2014 a diff in a window of its own: FlexDesk's modal around a\n * createDiffViewer, showing \"Loading\u2026\" until the data arrives.\n */\n\nimport { openModal } from '../ui/components/modal.js';\nimport { createDiffViewer } from './diff_viewer.js';\n\n/**\n * @param {Object} options\n * @param {string} options.title\n * @param {() => Promise<Object>|Object} options.load - Answers what `createDiffViewer`'s `update` takes, or\n * `{ ok: false, error }`; a throw is shown the same way.\n * @param {string} [options.icon='difference']\n * @param {number} [options.width=880]\n * @param {number} [options.height=600]\n * @param {Object} [options.labels] - As for createDiffViewer.\n * @returns {Promise<null>} Settles when the window closes.\n */\nexport function openDiffWindow({ title, load, icon = 'difference', width = 880, height = 600, labels } = {}) {\n const content = document.createElement('div');\n content.className = 'twm-diff-window';\n const viewer = createDiffViewer(content, { labels });\n viewer.showMessage('Loading\u2026');\n const closed = openModal({ title, icon, content, width, height, maximizable: true });\n Promise.resolve()\n .then(load)\n .then((data) => {\n if (data?.ok === false) viewer.showMessage(data.error || 'The diff could not be read.');\n else viewer.update(data);\n })\n .catch((e) => viewer.showMessage(e?.message || String(e)));\n return closed;\n}\n\n/**\n * The diff of one file, from an adapter's `diffFile`, in a window.\n * @param {Object} options\n * @param {Object} options.adapter - A git adapter with `diffFile` (docs/components/git.md).\n * @param {string} options.path\n * @param {string} [options.status]\n * @param {string} [options.renamedFrom] - The path it had before, for a rename.\n * @param {string} [options.ref] - A commit: the file's change in that commit, not the uncommitted one.\n * @returns {Promise<null>}\n */\nexport function openGitDiffWindow({ adapter, path, status, renamedFrom, ref }) {\n return openDiffWindow({\n title: renamedFrom ? `${renamedFrom} \u2192 ${path}` : path,\n load: () => adapter.diffFile({ path, status, ...(renamedFrom ? { renamedFrom } : {}), ...(ref ? { ref } : {}) }),\n });\n}\n", "/**\n * git_ops.js \u2014 what the panel and the graph share about calling an adapter.\n * Internal to @flexdesk/git: not exported from its barrel.\n */\n\nimport { openForm } from '../ui/components/modal.js';\nimport { reportBridgeError } from '../ui/components/toast.js';\nimport { openGitDiffWindow } from './diff_window.js';\n\n/**\n * Call an adapter method. A failure, an `{ ok: false, error }` answer or a\n * throw alike, is an error toast carrying the backend's words; a stop on\n * conflicts is said to be that.\n * @param {string} opName - As the toast names it: 'Git push'.\n * @param {() => Promise<Object>} fn\n * @returns {Promise<Object|null>} The answer, or null when it failed.\n */\nexport async function callGit(opName, fn) {\n let result;\n try {\n result = await fn();\n } catch (e) {\n reportBridgeError(`${opName} failed`, e instanceof Error ? e : new Error(String(e)));\n return null;\n }\n const title = result?.conflicts ? `${opName} stopped on conflicts` : `${opName} failed`;\n return reportBridgeError(title, result) ? (result ?? { ok: true }) : null;\n}\n\n/**\n * Ask for text values in a FlexDesk form.\n * @param {string} title\n * @param {string} submitLabel\n * @param {Array<[string, string]>} fields - `[name, label]` pairs, all required.\n * @returns {Promise<Object|null>} The trimmed values, or null when cancelled or left blank.\n */\nexport async function askFor(title, submitLabel, fields) {\n const values = await openForm({\n title,\n submitLabel,\n fields: fields.map(([name, label]) => ({ name, label, type: 'text', required: true })),\n });\n if (!values) return null;\n const trimmed = Object.fromEntries(fields.map(([name]) => [name, String(values[name] ?? '').trim()]));\n return Object.values(trimmed).every(Boolean) ? trimmed : null;\n}\n\n/**\n * What opening a file's diff does: the consumer's callback, else a diff window\n * when the adapter has `diffFile`.\n * @param {() => Object|null} getAdapter\n * @param {Function|null|undefined} onOpenDiff\n * @returns {(file: {path: string, status: string, renamedFrom?: string, ref?: string}) => void}\n */\nexport function openDiffHandler(getAdapter, onOpenDiff) {\n if (onOpenDiff) return onOpenDiff;\n return ({ path, status, renamedFrom, ref }) => {\n const adapter = getAdapter();\n if (adapter?.diffFile) openGitDiffWindow({ adapter, path, status, renamedFrom, ref });\n };\n}\n", "/**\n * git_graph.js \u2014 a commit history drawn as a vertical SVG swimlane graph, one\n * row a commit, loaded a page at a time from the adapter's `log`.\n *\n * const graph = createGitGraph(el, { adapter, onOpenDiff, onChanged });\n * graph.refresh();\n * graph.destroy();\n *\n * Give `el` a height: the graph scrolls inside it and asks for the next page\n * when the last row comes into view. `refresh()` re-reads what is loaded and\n * redraws only if something differs, so it is safe to call on every status\n * change without losing the scroll position.\n *\n * A row's context menu offers what the adapter can do (docs/components/git.md);\n * each call goes through the adapter and a failure is an error toast with the\n * backend's words. Nothing is stored on the DOM.\n */\n\nimport { showContextMenu } from '../ui/components/context_menu.js';\nimport { reportBridgeError, toastInfo } from '../ui/components/toast.js';\nimport { askFor, callGit, openDiffHandler } from './git_ops.js';\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n/** The tokens `--twm-git-lane-0` \u2026 `-7`; a lane past the last takes them round again. */\nconst LANE_COLOURS = 8;\nconst LANE_WIDTH = 11;\nconst ROW_HEIGHT = 22; // .twm-git-graph__row's height in flexdesk.css\nconst NODE_RADIUS = 4;\nconst DEFAULT_PAGE_SIZE = 50;\n\n/**\n * Assign each commit to a lane. Commits come newest first, children before\n * their parents (`git log --topo-order`). The answer is the same for a list\n * and for any longer list that starts with it, so pages only ever add rows.\n *\n * Each row says what to draw in its own 22 pixels:\n * lane the commit's own lane\n * hasChild a line comes down into the commit (a branch tip has none)\n * outputLanes `{ lane, parentHash }`: a line leaving the commit for each parent\n * passLanes lanes that run straight through this row to a later commit\n *\n * @param {Array<{hash: string, parentHashes: string[]}>} commits\n * @returns {{ rows: Array<Object>, laneCount: number }}\n */\nexport function computeGraphLanes(commits) {\n const active = []; // active[i]: the hash lane i is waiting for; null when free\n const allocate = () => {\n const free = active.indexOf(null);\n if (free !== -1) return free;\n active.push(null);\n return active.length - 1;\n };\n const rows = commits.map((commit) => {\n // A lane waits for one hash and no hash waits in two lanes: a parent\n // already waited for is joined at its lane, not given another.\n const waiting = active.indexOf(commit.hash);\n const hasChild = waiting !== -1;\n const lane = hasChild ? waiting : allocate();\n active[lane] = null;\n const passLanes = [];\n active.forEach((hash, l) => { if (hash !== null) passLanes.push(l); });\n\n const outputLanes = (commit.parentHashes ?? []).map((parentHash, i) => {\n let parentLane = active.indexOf(parentHash);\n if (parentLane === -1) parentLane = i === 0 ? lane : allocate();\n active[parentLane] = parentHash;\n return { lane: parentLane, parentHash };\n });\n return { lane, hasChild, outputLanes, passLanes };\n });\n return { rows, laneCount: Math.max(active.length, 1) };\n}\n\n/** What each full ref name in a decoration list is, by how it starts. */\nconst REF_KINDS = [\n ['HEAD -> refs/heads/', 'head'],\n ['tag: refs/tags/', 'tag'],\n ['refs/heads/', 'branch'],\n ['refs/remotes/', 'remote'],\n];\n\n/**\n * Read `git log --decorate=full`'s `%D` list into pills. Full names are what\n * tell a remote's `refs/remotes/origin/main` from a local branch that happens\n * to be called `origin/main`. Other refs, such as `refs/stash`, are left out.\n * @param {string} refs - `HEAD -> refs/heads/main, tag: refs/tags/v1, refs/remotes/origin/main`\n * @returns {Array<{name: string, type: 'head'|'tag'|'branch'|'remote'}>}\n */\nexport function parseGitRefs(refs) {\n if (!refs) return [];\n return String(refs).split(',').map((s) => s.trim()).flatMap((part) => {\n if (part === 'HEAD') return [{ name: 'HEAD', type: 'head' }];\n const kind = REF_KINDS.find(([prefix]) => part.startsWith(prefix));\n return kind ? [{ name: part.slice(kind[0].length), type: kind[1] }] : [];\n });\n}\n\nconst laneX = (lane) => lane * LANE_WIDTH + LANE_WIDTH / 2;\n\nfunction edge(d, lane) {\n const path = document.createElementNS(SVG_NS, 'path');\n path.setAttribute('class', `twm-git-graph__edge twm-git-lane--${lane % LANE_COLOURS}`);\n path.setAttribute('d', d);\n return path;\n}\n\nfunction sizeGutter(svg, laneCount) {\n const width = Math.max(laneCount * LANE_WIDTH, LANE_WIDTH * 2);\n svg.setAttribute('width', String(width));\n svg.setAttribute('viewBox', `0 0 ${width} ${ROW_HEIGHT}`);\n}\n\nfunction createGutter(row, laneCount) {\n const svg = document.createElementNS(SVG_NS, 'svg');\n svg.setAttribute('class', 'twm-git-graph__svg');\n svg.setAttribute('height', String(ROW_HEIGHT));\n svg.setAttribute('aria-hidden', 'true');\n sizeGutter(svg, laneCount);\n\n const h = ROW_HEIGHT;\n const cx = laneX(row.lane);\n const cy = h / 2;\n for (const lane of row.passLanes) {\n const x = laneX(lane);\n svg.appendChild(edge(`M${x},0 L${x},${h}`, lane));\n }\n if (row.hasChild) svg.appendChild(edge(`M${cx},0 L${cx},${cy}`, row.lane));\n for (const { lane } of row.outputLanes) {\n const x = laneX(lane);\n svg.appendChild(edge(x === cx\n ? `M${cx},${cy} L${cx},${h}`\n : `M${cx},${cy} C${cx},${h * 0.8} ${x},${h * 0.6} ${x},${h}`, lane));\n }\n const node = document.createElementNS(SVG_NS, 'circle');\n node.setAttribute('class', `twm-git-graph__node twm-git-lane--${row.lane % LANE_COLOURS}`);\n node.setAttribute('cx', String(cx));\n node.setAttribute('cy', String(cy));\n node.setAttribute('r', String(NODE_RADIUS));\n svg.appendChild(node);\n return svg;\n}\n\nfunction commitTitle(commit) {\n const date = new Date(commit.timestamp * 1000).toLocaleDateString();\n return `${commit.shortHash} \u2014 ${commit.author}\\n${date}\\n\\n${commit.subject}`;\n}\n\n/**\n * @param {HTMLElement} host\n * @param {Object} [options]\n * @param {Object|null} [options.adapter] - A git adapter with `log`; the rest is used when present.\n * @param {(file: {path: string, status: string, ref: string}) => void} [options.onOpenDiff] - Opens a file of a\n * commit. Without it, a diff window when the adapter has `diffFile`.\n * @param {() => void} [options.onChanged] - Told after a menu operation changed the repository.\n * @param {number} [options.pageSize=50]\n * @param {boolean} [options.showRemoteRefs=false] - Draw remote branches' pills as well; a narrow panel leaves them out.\n * @returns {{ el: HTMLElement, refresh(): Promise<void>, setAdapter(adapter: Object|null): void, destroy(): void }}\n */\nexport function createGitGraph(host, options = {}) {\n const { onChanged = null, pageSize = DEFAULT_PAGE_SIZE, showRemoteRefs = false } = options;\n let adapter = options.adapter ?? null;\n const openDiff = openDiffHandler(() => adapter, options.onOpenDiff);\n\n const root = document.createElement('div');\n root.className = 'twm-git-graph';\n host.appendChild(root);\n\n let commits = [];\n let drawnJson = '';\n let allLoaded = false;\n let generation = 0; // a newer read makes an older answer stale\n let observer = null;\n let sentinel = null;\n let destroyed = false;\n\n const say = (text) => {\n const m = document.createElement('div');\n m.className = 'twm-git-graph__message';\n m.textContent = text;\n root.replaceChildren(m);\n };\n\n const stopObserving = () => {\n observer?.disconnect();\n observer = null;\n sentinel?.remove();\n sentinel = null;\n };\n\n /** `git` is the adapter the menu was opened on; a file opens only while that repository still shows. */\n const openFiles = async (git, commit, x, y) => {\n const result = await callGit('Git changes', () => git.commitFiles({ hash: commit.hash }));\n if (!result || git !== adapter) return;\n const files = result.files ?? [];\n if (files.length === 0) {\n toastInfo('No files changed', commit.shortHash);\n } else if (files.length === 1) {\n openDiff({ ...files[0], ref: commit.hash });\n } else {\n const items = files.map((f, i) => ({ label: f.path, icon: 'difference', action: String(i) }));\n showContextMenu(x, y, items, (action) => {\n if (git === adapter) openDiff({ ...files[Number(action)], ref: commit.hash });\n });\n }\n };\n\n const menuItems = (git) => {\n const groups = [\n [\n git.checkout && { label: 'Checkout (detached)', icon: 'logout', action: 'checkout' },\n git.createBranch && { label: 'Create Branch\u2026', icon: 'commit', action: 'create-branch' },\n { label: 'Copy Commit Hash', icon: 'content_copy', action: 'copy-hash' },\n ],\n [\n git.cherryPick && { label: 'Cherry-pick', icon: 'content_copy', action: 'cherry-pick' },\n git.createTag && { label: 'Create Tag\u2026', icon: 'sell', action: 'create-tag' },\n git.commitFiles && { label: 'View Changes', icon: 'difference', action: 'view-changes' },\n ],\n ].map((group) => group.filter(Boolean)).filter((group) => group.length > 0);\n return groups.flatMap((group, i) => (i === 0 ? group : [{ separator: true }, ...group]));\n };\n\n const onMenuAction = async (git, action, commit, x, y) => {\n const { hash } = commit;\n /** Run an operation; whatever came of it, the graph and its owner read the repository again. */\n const change = async (opName, fn) => {\n await callGit(opName, fn);\n await refresh();\n onChanged?.();\n };\n switch (action) {\n case 'checkout':\n await change('Git checkout', () => git.checkout({ ref: hash }));\n break;\n case 'create-branch': {\n const values = await askFor('Create Branch', 'Create', [['name', 'Branch name']]);\n if (values) await change('Git create branch', () => git.createBranch({ name: values.name, from: hash }));\n break;\n }\n case 'copy-hash':\n try {\n await navigator.clipboard.writeText(hash);\n toastInfo('Commit hash copied', commit.shortHash);\n } catch (e) {\n reportBridgeError('Copy commit hash failed', e);\n }\n break;\n case 'cherry-pick':\n await change('Git cherry-pick', () => git.cherryPick({ hash }));\n break;\n case 'create-tag': {\n const values = await askFor('Create Tag', 'Create', [['name', 'Tag name']]);\n if (values) await change('Git create tag', () => git.createTag({ name: values.name, hash }));\n break;\n }\n case 'view-changes':\n await openFiles(git, commit, x, y);\n break;\n }\n };\n\n const createRow = (commit, laneRow, laneCount) => {\n const row = document.createElement('div');\n row.className = 'twm-git-graph__row';\n row.title = commitTitle(commit);\n row.tabIndex = 0;\n row.appendChild(createGutter(laneRow, laneCount));\n\n const info = document.createElement('div');\n info.className = 'twm-git-graph__info';\n for (const pill of parseGitRefs(commit.refs)) {\n if (pill.type === 'remote' && !showRemoteRefs) continue;\n const span = document.createElement('span');\n span.className = `twm-git-ref twm-git-ref--${pill.type}`;\n span.textContent = pill.name;\n span.title = pill.name;\n info.appendChild(span);\n }\n const subject = document.createElement('span');\n subject.className = 'twm-git-graph__subject';\n subject.textContent = commit.subject;\n info.appendChild(subject);\n row.appendChild(info);\n\n const openMenu = (x, y) => {\n const git = adapter;\n showContextMenu(x, y, menuItems(git), (action) => onMenuAction(git, action, commit, x, y));\n };\n row.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n openMenu(e.clientX, e.clientY);\n });\n row.addEventListener('keydown', (e) => {\n if (e.key !== 'ContextMenu' && !(e.key === 'F10' && e.shiftKey)) return;\n e.preventDefault();\n const r = row.getBoundingClientRect();\n openMenu(r.left, r.bottom);\n });\n return row;\n };\n\n const observeSentinel = () => {\n stopObserving();\n if (allLoaded || commits.length === 0) return;\n sentinel = document.createElement('div');\n sentinel.className = 'twm-git-graph__sentinel';\n root.appendChild(sentinel);\n observer = new IntersectionObserver((entries) => {\n if (entries[0]?.isIntersecting) loadMore();\n }, { root });\n observer.observe(sentinel);\n };\n\n /** Draw the rows from `from` on, and widen the gutters above them when the lanes outgrew them. */\n const drawRows = (from) => {\n stopObserving();\n const { rows, laneCount } = computeGraphLanes(commits);\n for (const svg of root.querySelectorAll('.twm-git-graph__svg')) sizeGutter(svg, laneCount);\n const fragment = document.createDocumentFragment();\n for (let i = from; i < commits.length; i++) fragment.appendChild(createRow(commits[i], rows[i], laneCount));\n root.appendChild(fragment);\n observeSentinel();\n };\n\n const clear = () => {\n stopObserving();\n commits = [];\n drawnJson = '';\n allLoaded = false;\n root.replaceChildren();\n };\n\n /** Read from the top as many commits as are loaded, replacing what is drawn only if they differ. */\n const refresh = async () => {\n const gen = ++generation;\n if (!adapter?.log) {\n clear();\n return;\n }\n const count = Math.max(commits.length, pageSize);\n let result;\n try {\n result = await adapter.log({ count, skip: 0 });\n } catch (e) {\n result = { ok: false, error: e?.message || String(e) };\n }\n if (destroyed || gen !== generation) return;\n if (!result?.ok) {\n clear();\n say(result?.error || 'The history could not be read.');\n return;\n }\n const next = result.commits ?? [];\n const json = JSON.stringify(next);\n if (json === drawnJson) {\n if (!observer) observeSentinel(); // a read that overtook loadMore must not end the paging\n return;\n }\n const top = root.scrollTop;\n clear();\n drawnJson = json;\n commits = next;\n allLoaded = next.length < count;\n if (commits.length === 0) {\n say('No commits yet');\n return;\n }\n drawRows(0);\n root.scrollTop = top;\n };\n\n const loadMore = async () => {\n const gen = ++generation;\n stopObserving();\n const skip = commits.length;\n const result = await callGit('Git log', () => adapter.log({ count: pageSize, skip }));\n if (destroyed || gen !== generation || !result) return;\n const page = result.commits ?? [];\n allLoaded = page.length < pageSize;\n commits = commits.concat(page);\n drawnJson = JSON.stringify(commits);\n drawRows(skip);\n };\n\n refresh();\n\n return {\n el: root,\n refresh,\n setAdapter(next) {\n adapter = next ?? null;\n clear();\n refresh();\n },\n destroy() {\n destroyed = true;\n stopObserving();\n root.remove();\n },\n };\n}\n", "/**\n * git_panel.js \u2014 a source-control panel: the branch and what can be done with\n * it, a commit box, the changed files, and the commit graph.\n *\n * const panel = createGitPanel(el, { adapter, onCountChange: (n) => setBadge(n) });\n * panel.setAdapter(otherRepository); // or null: nothing to show\n * panel.stopPolling(); // while its tab is hidden\n * panel.startPolling();\n * panel.destroy();\n *\n * Every repository operation is a method of `adapter`, whose methods and\n * payloads are the written contract in docs/components/git.md: `isRepo` and\n * `status` are required, and an action whose method the adapter lacks is not\n * offered. The panel knows nothing of where the repository is or how the\n * adapter reaches it.\n *\n * The panel's own elements are built once and updated in place, so a status\n * change never touches what somebody is typing into the commit box. A failed\n * operation is an error toast carrying the backend's words, and the panel reads\n * the repository again either way. Nothing is stored on the DOM.\n *\n * An operation belongs to the repository it started on: whatever waits on a\n * dialog or on an earlier step holds that adapter, not the panel's current one,\n * so `setAdapter` can never send the rest of an operation to another repository.\n */\n\nimport { ActionDropdown } from '../ui/components/action_dropdown.js';\nimport { showConfirmDialog, showSelectDialog } from '../ui/components/confirm_dialog.js';\nimport { showContextMenu } from '../ui/components/context_menu.js';\nimport { toastInfo } from '../ui/components/toast.js';\nimport { createGitGraph } from './git_graph.js';\nimport { askFor, callGit, openDiffHandler } from './git_ops.js';\n\nconst DEFAULT_POLL_MS = 3000;\nconst COMMIT_BOX_MAX_PX = 80;\n\nfunction el(tag, className, text) {\n const n = document.createElement(tag);\n if (className) n.className = className;\n if (text !== undefined) n.textContent = text;\n return n;\n}\n\nfunction icon(name) {\n const span = el('span', 'material-symbols-outlined', name);\n span.setAttribute('aria-hidden', 'true');\n return span;\n}\n\nfunction iconButton(className, iconName, label, onClick) {\n const b = el('button', className);\n b.type = 'button';\n b.title = label;\n b.setAttribute('aria-label', label);\n b.appendChild(icon(iconName));\n b.addEventListener('click', onClick);\n return b;\n}\n\n/** ActionDropdown draws a label as markup; a branch name is text. */\nconst escapeLabel = (s) => String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\n/** A path's last segment, and the folder before it. */\nfunction splitPath(path) {\n const parts = String(path).replace(/\\\\/g, '/').split('/').filter(Boolean);\n return { name: parts[parts.length - 1] ?? String(path), dir: parts.slice(0, -1).join('/') };\n}\n\nfunction requireMethods(adapter) {\n const missing = ['isRepo', 'status'].filter((m) => typeof adapter[m] !== 'function');\n if (missing.length > 0) throw new TypeError(`createGitPanel: the adapter has no ${missing.join(' or ')} method`);\n}\n\n/**\n * @param {HTMLElement} host\n * @param {Object} [options]\n * @param {Object|null} [options.adapter] - The git adapter; null shows `emptyLabel`.\n * @param {(file: {path: string, status: string, staged?: boolean, renamedFrom?: string, ref?: string}) => void} [options.onOpenDiff]\n * Opens a file's diff. Without it, a diff window when the adapter has `diffFile`.\n * @param {(count: number) => void} [options.onCountChange] - Told how many files have changes, whenever that is read.\n * @param {number} [options.pollInterval=3000] - Milliseconds between status reads; 0 reads only on `refresh()`.\n * @param {string} [options.emptyLabel='No repository'] - Shown while there is no adapter.\n * @param {boolean} [options.changesExpanded=true]\n * @param {boolean} [options.graphExpanded=false]\n * @param {boolean} [options.showRemoteRefs=false] - As for createGitGraph.\n * @returns {{ el: HTMLElement, refresh(): Promise<void>, setAdapter(adapter: Object|null): void,\n * startPolling(): void, stopPolling(): void, destroy(): void }}\n */\nexport function createGitPanel(host, options = {}) {\n const {\n onCountChange = null,\n pollInterval = DEFAULT_POLL_MS,\n emptyLabel = 'No repository',\n showRemoteRefs = false,\n } = options;\n\n let adapter = options.adapter ?? null;\n if (adapter) requireMethods(adapter);\n const openDiff = openDiffHandler(() => adapter, options.onOpenDiff);\n\n let isRepo = false;\n let status = null;\n let statusJson = '';\n let branches = [];\n let busy = false;\n let pollTimer = null;\n let generation = 0; // a newer read, or another adapter, makes an older answer stale\n let reading = false;\n let destroyed = false;\n let changesExpanded = options.changesExpanded ?? true;\n let graphExpanded = options.graphExpanded ?? false;\n let graph = null;\n\n // \u2500\u2500 the elements \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const root = el('div', 'twm-git-panel');\n const messageView = el('div', 'twm-git-panel__empty');\n const mainView = el('div', 'twm-git-panel__main');\n const busyBar = el('div', 'twm-git-panel__busy-bar');\n root.append(messageView, mainView);\n\n const branchButton = el('button', 'twm-git-panel__branch');\n branchButton.type = 'button';\n const branchLabel = el('span', 'twm-git-panel__branch-label');\n branchButton.append(icon('commit'), branchLabel);\n const badges = el('div', 'twm-git-panel__badges');\n const barActions = el('div', 'twm-git-panel__bar-actions');\n const bar = el('div', 'twm-git-panel__bar');\n bar.append(branchButton, badges, barActions);\n\n const fetchButton = iconButton('twm-git-panel__bar-btn', 'sync', 'Fetch',\n () => runOp('fetch', () => adapter.fetch()));\n const pullButton = iconButton('twm-git-panel__bar-btn', 'arrow_downward', 'Pull',\n () => runOp('pull', () => adapter.pull()));\n const pushButton = iconButton('twm-git-panel__bar-btn', 'arrow_upward', 'Push',\n () => runOp('push', () => adapter.push({ setUpstream: !status?.hasUpstream })));\n const overflowButton = iconButton('twm-git-panel__bar-btn', 'more_horiz', 'More actions', () => {});\n barActions.append(fetchButton, pullButton, pushButton, overflowButton);\n\n const commitArea = el('div', 'twm-git-panel__commit');\n const commitBox = el('textarea', 'twm-git-panel__commit-box');\n commitBox.rows = 1;\n commitBox.placeholder = 'Commit message (Ctrl+Enter to commit)';\n commitBox.setAttribute('aria-label', 'Commit message');\n const commitButton = el('button', 'twm-git-panel__commit-btn', 'Commit');\n commitButton.type = 'button';\n const commitMenuButton = iconButton('twm-git-panel__commit-menu', 'expand_more', 'Commit options', () => {});\n const commitActions = el('div', 'twm-git-panel__commit-actions');\n commitActions.append(commitButton, commitMenuButton);\n commitArea.append(commitBox, commitActions);\n\n const section = (title, expanded, onToggle) => {\n const arrow = el('span', 'material-symbols-outlined twm-collapsible-arrow twm-git-panel__arrow', 'expand_more');\n arrow.setAttribute('aria-hidden', 'true');\n const count = el('span', 'twm-git-panel__count');\n const head = el('button', 'twm-collapsible-header twm-git-panel__section-head');\n head.type = 'button';\n head.append(arrow, title, count);\n const body = el('div', 'twm-git-panel__section-body');\n const setExpanded = (on) => {\n arrow.classList.toggle('twm-git-panel__arrow--collapsed', !on);\n head.setAttribute('aria-expanded', String(on));\n body.hidden = !on;\n };\n setExpanded(expanded);\n head.addEventListener('click', () => onToggle(setExpanded));\n const wrap = el('div', 'twm-git-panel__section');\n wrap.append(head, body);\n return { wrap, body, count };\n };\n\n const changes = section('Changes', changesExpanded, (setExpanded) => {\n changesExpanded = !changesExpanded;\n setExpanded(changesExpanded);\n });\n const history = section('Graph', graphExpanded, (setExpanded) => {\n graphExpanded = !graphExpanded;\n setExpanded(graphExpanded);\n if (graphExpanded) ensureGraph();\n });\n mainView.append(busyBar, bar, commitArea, changes.wrap, history.wrap);\n host.appendChild(root);\n\n // \u2500\u2500 the views \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const showMessage = (iconName, text, action = null) => {\n const parts = [icon(iconName), el('span', null, text)];\n if (action) parts.push(action);\n messageView.replaceChildren(...parts);\n messageView.hidden = false;\n mainView.hidden = true;\n };\n\n const showNotRepo = () => {\n let action = null;\n if (adapter.init) {\n action = el('button', 'twm-btn twm-btn--primary twm-git-panel__init', 'Initialize Repository');\n action.type = 'button';\n action.addEventListener('click', initRepo);\n }\n showMessage('source', 'Not a git repository', action);\n };\n\n const fileRow = (file) => {\n const { name, dir } = splitPath(file.path);\n const row = el('div', 'twm-git-panel__file');\n row.tabIndex = 0;\n row.setAttribute('role', 'button');\n row.title = file.renamedFrom ? `${file.renamedFrom} \u2192 ${file.path}` : file.path;\n row.append(\n el('span', `twm-git-panel__status twm-git-panel__status--${file.status}`, file.status),\n el('span', 'twm-git-panel__file-name', name),\n );\n if (dir) row.appendChild(el('span', 'twm-git-panel__file-dir', dir));\n const open = () => openDiff({ path: file.path, status: file.status, staged: file.staged,\n ...(file.renamedFrom ? { renamedFrom: file.renamedFrom } : {}) });\n row.addEventListener('click', open);\n row.addEventListener('keydown', (e) => {\n if (e.target === row && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n open();\n }\n });\n\n const actions = el('div', 'twm-git-panel__file-actions');\n const action = (iconName, label, fn) => {\n actions.appendChild(iconButton('twm-git-panel__file-btn', iconName, label, (e) => {\n e.stopPropagation();\n fn();\n }));\n };\n if (!file.staged && adapter.stage) {\n action('add', 'Stage', () => runOp('stage', () => adapter.stage({ paths: [file.path] })));\n }\n if (file.staged && adapter.unstage) {\n // A rename is two paths to the index: the new one alone would leave the old one staged as deleted.\n const paths = file.renamedFrom ? [file.renamedFrom, file.path] : [file.path];\n action('remove', 'Unstage', () => runOp('unstage', () => adapter.unstage({ paths })));\n }\n // A conflict is resolved or the merge aborted; there is no one state to put it back to.\n if (adapter.discard && file.status !== 'C') action('undo', 'Discard changes', () => discard(file));\n row.appendChild(actions);\n return row;\n };\n\n const drawStatus = () => {\n branchLabel.textContent = status.branch ?? '';\n const marks = [];\n if (status.hasUpstream && status.ahead > 0) marks.push(el('span', 'twm-git-panel__badge', `\u2191${status.ahead}`));\n if (status.hasUpstream && status.behind > 0) marks.push(el('span', 'twm-git-panel__badge', `\u2193${status.behind}`));\n badges.replaceChildren(...marks);\n\n const files = status.files ?? [];\n changes.count.textContent = String(files.length);\n changes.body.replaceChildren(...(files.length > 0\n ? files.map(fileRow)\n : [el('div', 'twm-git-panel__no-changes', 'No changes')]));\n overflowDropdown.setOptions(overflowOptions());\n };\n\n const drawBusy = () => {\n busyBar.hidden = !busy;\n for (const b of [branchButton, fetchButton, pullButton, pushButton, overflowButton, commitButton, commitMenuButton]) {\n b.disabled = busy;\n }\n };\n\n /** What is on offer is what the adapter can do. */\n const drawCapabilities = () => {\n if (!adapter) return;\n fetchButton.hidden = !adapter.fetch;\n pullButton.hidden = !adapter.pull;\n pushButton.hidden = !adapter.push;\n commitArea.hidden = !adapter.commit;\n const overflow = overflowOptions();\n overflowButton.hidden = overflow.every((o) => o.separator);\n overflowDropdown.setOptions(overflow);\n commitDropdown.setOptions(commitOptions());\n branchDropdown.setOptions(branchOptions());\n };\n\n // \u2500\u2500 the menus \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const commitOptions = () => [\n { type: 'commit', label: 'Commit', icon: 'check' },\n { type: 'amend', label: 'Commit (Amend)', icon: 'edit' },\n { separator: true },\n ...(adapter?.push ? [{ type: 'commitPush', label: 'Commit & Push', icon: 'arrow_upward' }] : []),\n ...(adapter?.pull && adapter?.push ? [{ type: 'commitSync', label: 'Commit & Sync', icon: 'sync' }] : []),\n ];\n\n const overflowOptions = () => {\n if (!adapter) return [];\n return [\n ...(adapter.stash ? [{ type: 'stash', label: 'Stash', icon: 'archive' }] : []),\n ...(adapter.stashPop ? [{ type: 'stashPop', label: 'Pop Stash', icon: 'unarchive' }] : []),\n { separator: true },\n ...(adapter.merge ? [{ type: 'merge', label: 'Merge\u2026', icon: 'merge' }] : []),\n ...(adapter.rebase ? [{ type: 'rebase', label: 'Rebase\u2026', icon: 'rebase_edit' }] : []),\n ...(adapter.rebase && status?.rebasing ? [\n { type: 'rebaseContinue', label: 'Continue Rebase', icon: 'play_arrow' },\n { type: 'rebaseAbort', label: 'Abort Rebase', icon: 'cancel' },\n ] : []),\n { separator: true },\n ...(adapter.remotes ? [{ type: 'remotes', label: 'Remotes\u2026', icon: 'cloud' }] : []),\n ...(adapter.tags ? [{ type: 'tags', label: 'Tags\u2026', icon: 'sell' }]\n : adapter.createTag ? [{ type: 'createTag', label: 'Create Tag\u2026', icon: 'sell' }] : []),\n ];\n };\n\n /** Local then remote branches to check out, then making and removing branches. */\n const branchOptions = () => {\n if (!adapter) return [];\n const ref = (b, iconName) => ({ type: 'checkout', ref: b.name, label: escapeLabel(b.name), icon: iconName });\n return [\n ...(adapter.checkout ? [\n ...branches.filter((b) => !b.isRemote).map((b) => ref(b, b.isCurrent ? 'check' : 'commit')),\n { separator: true },\n ...branches.filter((b) => b.isRemote).map((b) => ref(b, 'cloud')),\n ] : []),\n { separator: true },\n ...(adapter.createBranch ? [{ type: 'createBranch', label: 'Create Branch\u2026', icon: 'add' }] : []),\n ...(adapter.deleteBranch ? [{ type: 'deleteBranch', label: 'Delete Branch\u2026', icon: 'delete' }] : []),\n ];\n };\n\n const branchDropdown = new ActionDropdown({\n trigger: branchButton,\n options: [],\n onSelect: (option) => onBranchOption(option),\n });\n const commitDropdown = new ActionDropdown({\n trigger: commitMenuButton,\n options: [],\n onSelect: (option) => commit(option.type),\n });\n const overflowDropdown = new ActionDropdown({\n trigger: overflowButton,\n options: [],\n onSelect: (option) => onOverflowOption(option),\n });\n\n // \u2500\u2500 reading the repository \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const readBranches = async (gen) => {\n if (!adapter?.branches) return;\n let result;\n try {\n result = await adapter.branches();\n } catch {\n return; // the branch menu keeps what it has; the next read tries again\n }\n if (gen !== generation || destroyed || !result?.ok) return;\n branches = result.branches ?? [];\n branchDropdown.setOptions(branchOptions());\n };\n\n const refresh = async () => {\n const gen = ++generation;\n if (!adapter) {\n showMessage('folder_off', emptyLabel);\n onCountChange?.(0);\n return;\n }\n reading = true;\n try {\n // Asked until it is yes, so a repository made outside the panel is\n // noticed; a repository that goes away fails `status` and is asked again.\n if (!isRepo) {\n const check = await adapter.isRepo();\n if (gen !== generation || destroyed) return;\n if (!check?.ok) {\n showMessage('error', check?.error || 'The repository could not be read.');\n onCountChange?.(0);\n return;\n }\n if (!check.isRepo) {\n showNotRepo();\n onCountChange?.(0);\n return;\n }\n isRepo = true;\n }\n const result = await adapter.status();\n if (gen !== generation || destroyed) return;\n if (!result?.ok) {\n isRepo = false;\n statusJson = '';\n showMessage('error', result?.error || 'The repository could not be read.');\n onCountChange?.(0);\n return;\n }\n messageView.hidden = true;\n mainView.hidden = false;\n const json = JSON.stringify(result);\n if (json === statusJson) return;\n statusJson = json;\n status = result;\n drawStatus();\n onCountChange?.((result.files ?? []).length);\n readBranches(gen);\n graph?.refresh();\n } catch (e) {\n if (gen !== generation || destroyed) return;\n isRepo = false;\n statusJson = '';\n showMessage('error', e?.message || String(e));\n onCountChange?.(0);\n } finally {\n if (gen === generation) reading = false;\n }\n };\n\n /** A poll that finds the last read still out waits for the next tick; it never queues. */\n const poll = () => {\n if (!reading && !busy) refresh();\n };\n\n const startPolling = () => {\n if (pollTimer !== null || destroyed) return;\n refresh();\n if (pollInterval > 0) pollTimer = setInterval(poll, pollInterval);\n };\n\n const stopPolling = () => {\n if (pollTimer !== null) clearInterval(pollTimer);\n pollTimer = null;\n };\n\n // \u2500\u2500 operations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Run an operation with the panel busy, one at a time; one asked for while\n * another runs does not run, and says so. The panel reads the repository\n * again however it went.\n */\n async function runOp(opName, fn) {\n if (busy) {\n toastInfo('Git is busy', `The ${opName} did not run: another operation is still going.`);\n return;\n }\n busy = true;\n drawBusy();\n await callGit(`Git ${opName}`, fn);\n busy = false;\n drawBusy();\n statusJson = '';\n await refresh();\n }\n\n async function initRepo() {\n const result = await callGit('Git init', () => adapter.init());\n if (result) await refresh();\n }\n\n /** The answer of the first step that failed, else of the last. */\n async function inSteps(steps) {\n let result;\n for (const step of steps) {\n result = await step();\n if (result && result.ok === false) return result;\n }\n return result;\n }\n\n async function commit(mode) {\n const message = commitBox.value.trim();\n const amend = mode === 'amend';\n if (!message && !amend) {\n commitBox.focus();\n return;\n }\n const files = status?.files ?? [];\n if (!amend && files.length === 0) {\n toastInfo('Nothing to commit', 'There are no changes.');\n return;\n }\n const git = adapter;\n // A branch with no upstream yet gets one on its first push.\n const setUpstream = !status?.hasUpstream;\n // With nothing staged, a commit takes every change.\n const stageAll = !amend && git.stage && !files.some((f) => f.staged);\n await runOp('commit', () => inSteps([\n ...(stageAll ? [() => git.stage({ paths: 'all' })] : []),\n async () => {\n const result = await git.commit({ message: message || null, amend });\n if (git === adapter && (!result || result.ok !== false)) {\n commitBox.value = '';\n commitBox.style.height = '';\n }\n return result;\n },\n ...(mode === 'commitSync' ? [() => git.pull()] : []),\n ...(mode === 'commitPush' || mode === 'commitSync' ? [() => git.push({ setUpstream })] : []),\n ]));\n }\n\n /** What the dialog says, by what discarding does to this kind of change. */\n const discardWords = ({ path, status: letter, renamedFrom }) => {\n const { name } = splitPath(path);\n if (letter === 'U') {\n return { title: 'Delete File', okLabel: 'Delete', message: `Delete the untracked file \"${name}\"? This cannot be undone.` };\n }\n if (letter === 'A') {\n return { title: 'Delete File', okLabel: 'Delete', message: `Delete the new file \"${name}\"? It was never committed, so this cannot be undone.` };\n }\n if (renamedFrom) {\n return { title: 'Discard Changes', okLabel: 'Discard', message: `Put \"${splitPath(renamedFrom).name}\" back and discard all changes to \"${name}\"?` };\n }\n return { title: 'Discard Changes', okLabel: 'Discard', message: `Discard all changes to \"${name}\"?` };\n };\n\n async function discard(file) {\n const git = adapter;\n const confirmed = await showConfirmDialog({ ...discardWords(file), icon: 'warning', okVariant: 'danger' });\n if (!confirmed) return;\n await runOp('discard', () => git.discard({ path: file.path, status: file.status,\n ...(file.renamedFrom ? { renamedFrom: file.renamedFrom } : {}) }));\n }\n\n async function onBranchOption(option) {\n if (option.type === 'checkout') {\n await runOp('checkout', () => adapter.checkout({ ref: option.ref }));\n } else if (option.type === 'createBranch') {\n const git = adapter;\n const values = await askFor('Create Branch', 'Create', [['name', 'Branch name']]);\n if (values) await runOp('create branch', () => git.createBranch({ name: values.name }));\n } else if (option.type === 'deleteBranch') {\n await deleteBranch();\n }\n }\n\n const otherLocalBranches = () => branches.filter((b) => !b.isCurrent && !b.isRemote);\n\n /** A branch the adapter refuses as not merged is offered once more, forced; any other refusal is only that. */\n async function deleteBranch() {\n const git = adapter;\n const others = otherLocalBranches();\n if (others.length === 0) {\n toastInfo('Nothing to delete', 'There is no other local branch.');\n return;\n }\n const name = await showSelectDialog({\n title: 'Delete Branch',\n okLabel: 'Delete',\n items: others.map((b) => ({ value: b.name, label: b.name })),\n });\n if (!name) return;\n let notMerged = false;\n await runOp('delete branch', async () => {\n const result = await git.deleteBranch({ name, force: false });\n notMerged = result?.notMerged === true;\n return notMerged ? { ok: true } : result; // the dialog below says it, not a toast as well\n });\n if (!notMerged) return;\n const force = await showConfirmDialog({\n title: 'Force Delete Branch',\n message: `\"${name}\" is not fully merged. Delete it anyway? Commits only on it may be lost.`,\n icon: 'warning',\n okLabel: 'Force Delete',\n okVariant: 'danger',\n });\n if (force) await runOp('delete branch', () => git.deleteBranch({ name, force: true }));\n }\n\n async function onOverflowOption(option) {\n switch (option.type) {\n case 'stash':\n await runOp('stash', () => adapter.stash({}));\n break;\n case 'stashPop':\n await runOp('stash pop', () => adapter.stashPop());\n break;\n case 'merge':\n case 'rebase':\n await mergeOrRebase(option.type);\n break;\n case 'rebaseContinue':\n await runOp('rebase', () => adapter.rebase({ continue: true }));\n break;\n case 'rebaseAbort':\n await runOp('rebase', () => adapter.rebase({ abort: true }));\n break;\n case 'remotes':\n await showRemotesMenu();\n break;\n case 'tags':\n await showTagsMenu();\n break;\n case 'createTag':\n await createTag(adapter);\n break;\n }\n }\n\n /** Merge another local branch into the current one, or rebase onto it. */\n async function mergeOrRebase(op) {\n const git = adapter;\n const others = otherLocalBranches();\n if (others.length === 0) {\n toastInfo(`Nothing to ${op}`, 'There is no other local branch.');\n return;\n }\n const branch = await showSelectDialog({\n title: op === 'merge' ? 'Merge Branch' : 'Rebase onto Branch',\n okLabel: op === 'merge' ? 'Merge' : 'Rebase',\n items: others.map((b) => ({ value: b.name, label: b.name })),\n });\n if (!branch) return;\n await runOp(op, () => (op === 'merge' ? git.merge({ branch }) : git.rebase({ onto: branch })));\n }\n\n /** A menu under the bar's actions: one item per thing listed, then a way to add one. */\n const barMenu = (items, emptyTitle, onAction) => {\n if (items.length === 0) {\n toastInfo(emptyTitle, 'There are none in this repository.');\n return;\n }\n const anchor = barActions.getBoundingClientRect();\n showContextMenu(anchor.left, anchor.bottom + 4, items, onAction);\n };\n\n async function showRemotesMenu() {\n const git = adapter;\n const result = await callGit('Git remotes', () => git.remotes());\n if (!result || git !== adapter) return;\n const remotes = result.remotes ?? [];\n const items = git.removeRemote ? remotes.map((r, i) => ({\n label: `Remove ${r.name}`, title: r.url, icon: 'cloud_off', action: String(i), danger: true,\n })) : remotes.map((r) => ({ label: r.name, title: r.url, icon: 'cloud', disabled: true }));\n if (git.addRemote) {\n if (items.length > 0) items.push({ separator: true });\n items.push({ label: 'Add Remote\u2026', icon: 'add', action: 'add' });\n }\n barMenu(items, 'No remotes', async (action) => {\n if (action === 'add') {\n const values = await askFor('Add Remote', 'Add', [['name', 'Name'], ['url', 'URL']]);\n if (values) await runOp('add remote', () => git.addRemote(values));\n return;\n }\n const { name } = remotes[Number(action)];\n const confirmed = await showConfirmDialog({\n title: 'Remove Remote',\n message: `Remove remote \"${name}\"?`,\n icon: 'warning',\n okLabel: 'Remove',\n okVariant: 'danger',\n });\n if (confirmed) await runOp('remove remote', () => git.removeRemote({ name }));\n });\n }\n\n async function createTag(git) {\n const values = await askFor('Create Tag', 'Create', [['name', 'Tag name']]);\n if (values) await runOp('create tag', () => git.createTag({ name: values.name }));\n }\n\n async function showTagsMenu() {\n const git = adapter;\n const result = await callGit('Git tags', () => git.tags());\n if (!result || git !== adapter) return;\n const tags = result.tags ?? [];\n const items = git.deleteTag ? tags.map((t, i) => ({\n label: `Delete ${t.name}`, title: t.hash, icon: 'delete', action: String(i), danger: true,\n })) : tags.map((t) => ({ label: t.name, title: t.hash, icon: 'sell', disabled: true }));\n if (git.createTag) {\n if (items.length > 0) items.push({ separator: true });\n items.push({ label: 'Create Tag\u2026', icon: 'add', action: 'add' });\n }\n barMenu(items, 'No tags', async (action) => {\n if (action === 'add') {\n await createTag(git);\n return;\n }\n const { name } = tags[Number(action)];\n const confirmed = await showConfirmDialog({\n title: 'Delete Tag',\n message: `Delete tag \"${name}\"?`,\n icon: 'warning',\n okLabel: 'Delete',\n okVariant: 'danger',\n });\n if (confirmed) await runOp('delete tag', () => git.deleteTag({ name }));\n });\n }\n\n function ensureGraph() {\n if (graph || !adapter?.log) return;\n graph = createGitGraph(history.body, {\n adapter,\n onOpenDiff: openDiff,\n showRemoteRefs,\n onChanged: () => {\n statusJson = '';\n refresh();\n },\n });\n }\n\n // \u2500\u2500 wiring \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n commitButton.addEventListener('click', () => commit('commit'));\n commitBox.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {\n e.preventDefault();\n commit('commit');\n }\n });\n commitBox.addEventListener('input', () => {\n commitBox.style.height = 'auto';\n commitBox.style.height = `${Math.min(commitBox.scrollHeight, COMMIT_BOX_MAX_PX)}px`;\n });\n // The menu opens on what is known; a branch made elsewhere arrives while it is open.\n branchButton.addEventListener('click', () => readBranches(generation));\n\n drawBusy();\n drawCapabilities();\n if (graphExpanded) ensureGraph();\n showMessage('hourglass_empty', 'Checking repository\u2026');\n startPolling();\n\n return {\n el: root,\n refresh,\n startPolling,\n stopPolling,\n setAdapter(next) {\n if (next) requireMethods(next);\n adapter = next ?? null;\n isRepo = false;\n status = null;\n statusJson = '';\n branches = [];\n reading = false;\n commitBox.value = '';\n commitBox.style.height = '';\n changes.body.replaceChildren();\n drawCapabilities();\n graph?.setAdapter(adapter);\n if (graphExpanded) ensureGraph();\n if (adapter) showMessage('hourglass_empty', 'Checking repository\u2026');\n refresh();\n },\n destroy() {\n destroyed = true;\n generation++;\n stopPolling();\n branchDropdown.destroy();\n commitDropdown.destroy();\n overflowDropdown.destroy();\n graph?.destroy();\n root.remove();\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["i", "j", "icon", "el"]
|
|
7
|
+
}
|
package/dist/reset.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ════════════════════════════════════════════════════════════════════
|
|
2
|
-
|
|
2
|
+
reset.css — reset, body, scrollbars, headings.
|
|
3
3
|
|
|
4
4
|
Extracted from the inline block at the top of main_new.css so the
|
|
5
5
|
reset lives separately from the rest of the main stylesheet. Loaded
|
package/dist/tiles.js
CHANGED
|
@@ -12,16 +12,15 @@ import {
|
|
|
12
12
|
tile_registry_exports
|
|
13
13
|
} from "./chunk-FOOS3T5L.js";
|
|
14
14
|
import {
|
|
15
|
-
ActionDropdown,
|
|
16
15
|
SlideOutPanel
|
|
17
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-UKP22RUG.js";
|
|
18
17
|
import {
|
|
19
|
-
|
|
20
|
-
} from "./chunk-
|
|
18
|
+
ActionDropdown
|
|
19
|
+
} from "./chunk-PAI2ZUWV.js";
|
|
21
20
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} from "./chunk-
|
|
21
|
+
openModal,
|
|
22
|
+
showContextMenu
|
|
23
|
+
} from "./chunk-RKVYIXDC.js";
|
|
25
24
|
import {
|
|
26
25
|
buildHistogramTrace,
|
|
27
26
|
buildLegendLayout,
|
|
@@ -36,13 +35,19 @@ import {
|
|
|
36
35
|
purge,
|
|
37
36
|
resize,
|
|
38
37
|
strideDownsampleShared
|
|
39
|
-
} from "./chunk-
|
|
40
|
-
import "./chunk-
|
|
38
|
+
} from "./chunk-P74F6I6P.js";
|
|
39
|
+
import "./chunk-U5GKJUOC.js";
|
|
40
|
+
import "./chunk-VLOAI3HS.js";
|
|
41
41
|
import {
|
|
42
|
+
fireEvent,
|
|
42
43
|
isHexColor
|
|
43
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-ZL3VKINP.js";
|
|
45
|
+
import {
|
|
46
|
+
modalHost
|
|
47
|
+
} from "./chunk-Q7BALEPX.js";
|
|
44
48
|
import "./chunk-HNU6MM2B.js";
|
|
45
|
-
import "./chunk-
|
|
49
|
+
import "./chunk-WVFGV5FT.js";
|
|
50
|
+
import "./chunk-QXAOTGCC.js";
|
|
46
51
|
import {
|
|
47
52
|
__toCommonJS
|
|
48
53
|
} from "./chunk-JYWURG5T.js";
|
|
@@ -811,7 +816,7 @@ var TileBase = class {
|
|
|
811
816
|
config: this.config,
|
|
812
817
|
schema: this.getConfigSchema()
|
|
813
818
|
});
|
|
814
|
-
this.element
|
|
819
|
+
if (this.element) fireEvent(this.element, "tile:config-request", {
|
|
815
820
|
bubbles: true,
|
|
816
821
|
detail: {
|
|
817
822
|
tileId: this.id,
|
|
@@ -819,7 +824,7 @@ var TileBase = class {
|
|
|
819
824
|
config: this.config,
|
|
820
825
|
schema: this.getConfigSchema()
|
|
821
826
|
}
|
|
822
|
-
})
|
|
827
|
+
});
|
|
823
828
|
}
|
|
824
829
|
/**
|
|
825
830
|
* Handle remove button click.
|
|
@@ -828,13 +833,13 @@ var TileBase = class {
|
|
|
828
833
|
*/
|
|
829
834
|
_onRemoveClick(event) {
|
|
830
835
|
const removeBtn = this.element?.querySelector(".tile-remove-btn");
|
|
831
|
-
this.element
|
|
836
|
+
if (this.element) fireEvent(this.element, "tile:remove-request", {
|
|
832
837
|
bubbles: true,
|
|
833
838
|
detail: {
|
|
834
839
|
tileId: this.id,
|
|
835
840
|
anchorElement: removeBtn
|
|
836
841
|
}
|
|
837
|
-
})
|
|
842
|
+
});
|
|
838
843
|
}
|
|
839
844
|
/**
|
|
840
845
|
* Set the title displayed in the header.
|