nuvox 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -21,24 +21,45 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
23
  DEFAULT_COLOR_PRESETS: () => DEFAULT_PRESETS,
24
+ DRAG_START_THRESHOLD_PX: () => DRAG_START_THRESHOLD_PX,
25
+ LABELED_SKIP_SECONDS: () => LABELED_SKIP_SECONDS,
26
+ LANGUAGE_LABELS: () => LANGUAGE_LABELS,
27
+ PLAYBACK_RATES: () => PLAYBACK_RATES,
24
28
  REQUIRED_TOKEN_PATHS: () => REQUIRED_TOKEN_PATHS,
29
+ SKIP_SECONDS: () => SKIP_SECONDS,
25
30
  TOKEN_CATEGORIES: () => TOKEN_CATEGORIES,
26
31
  amber: () => amber,
32
+ aspectRatioFromDims: () => aspectRatioFromDims,
27
33
  brutalism: () => brutalism,
34
+ computeColumnDropIndex: () => computeColumnDropIndex,
35
+ computeDropColumn: () => computeDropColumn,
36
+ computeDropIndex: () => computeDropIndex,
37
+ computeJustifiedRows: () => computeJustifiedRows,
28
38
  copper: () => copper,
39
+ createHistory: () => createHistory,
29
40
  cyberpunk: () => cyberpunk,
30
41
  dark: () => dark,
31
42
  darkGlass: () => darkGlass,
32
43
  defineTheme: () => defineTheme,
33
44
  emerald: () => emerald,
45
+ execRichTextCommand: () => execRichTextCommand,
46
+ findCardLocation: () => findCardLocation,
34
47
  findMissingTokenPaths: () => findMissingTokenPaths,
48
+ formatMediaTime: () => formatMediaTime,
49
+ formatZoomPercent: () => formatZoomPercent,
35
50
  getAccent: () => getAccent,
51
+ getActiveCommands: () => getActiveCommands,
52
+ getAdjacentColumnId: () => getAdjacentColumnId,
53
+ getColumnKeyboardMoveTarget: () => getColumnKeyboardMoveTarget,
54
+ getKeyboardMoveTarget: () => getKeyboardMoveTarget,
55
+ getMediaKeyAction: () => getMediaKeyAction,
36
56
  getNextSortDirection: () => getNextSortDirection,
37
57
  getSelectAllState: () => getSelectAllState,
38
58
  getTheme: () => getTheme,
39
59
  glass: () => glass,
40
60
  gradient: () => gradient,
41
61
  graphite: () => graphite,
62
+ hasLabeledSkipIcon: () => hasLabeledSkipIcon,
42
63
  indigo: () => indigo,
43
64
  light: () => light,
44
65
  listAccents: () => listAccents,
@@ -46,12 +67,23 @@ __export(src_exports, {
46
67
  magenta: () => magenta,
47
68
  material: () => material,
48
69
  minimalism: () => minimalism,
70
+ moveCard: () => moveCard,
71
+ moveColumn: () => moveColumn,
49
72
  neobrutalism: () => neobrutalism,
73
+ nuvoxHighlight: () => nuvoxHighlight,
74
+ pushHistory: () => pushHistory,
75
+ redoHistory: () => redoHistory,
50
76
  registerAccent: () => registerAccent,
51
77
  registerTheme: () => registerTheme,
78
+ removeCard: () => removeCard,
79
+ removeColumn: () => removeColumn,
80
+ resolveMediaTransport: () => resolveMediaTransport,
81
+ resolveSkipSeconds: () => resolveSkipSeconds,
52
82
  rose: () => rose,
83
+ sanitizeHtml: () => sanitizeHtml,
53
84
  skeuomorphism: () => skeuomorphism,
54
85
  teal: () => teal,
86
+ undoHistory: () => undoHistory,
55
87
  violet: () => violet
56
88
  });
57
89
  module.exports = __toCommonJS(src_exports);
@@ -213,7 +245,7 @@ var light = defineTheme({
213
245
  "2xl": "0 28px 56px rgba(0,0,0,0.16)",
214
246
  inner: "inset 0 1px 2px rgba(0,0,0,0.05)"
215
247
  },
216
- elevation: { dropdown: 1e3, popover: 1100, modal: 1200, toast: 1300, tooltip: 1400 },
248
+ elevation: { dropdown: 1050, popover: 1060, modal: 1e3, toast: 1200, tooltip: 1100 },
217
249
  motion: {
218
250
  durationFast: "120ms",
219
251
  durationNormal: "200ms",
@@ -286,7 +318,7 @@ var dark = defineTheme({
286
318
  "2xl": "0 28px 56px rgba(0,0,0,0.65)",
287
319
  inner: "inset 0 1px 2px rgba(0,0,0,0.4)"
288
320
  },
289
- elevation: { dropdown: 1e3, popover: 1100, modal: 1200, toast: 1300, tooltip: 1400 },
321
+ elevation: { dropdown: 1050, popover: 1060, modal: 1e3, toast: 1200, tooltip: 1100 },
290
322
  motion: {
291
323
  durationFast: "120ms",
292
324
  durationNormal: "200ms",
@@ -370,7 +402,7 @@ var glass = defineTheme({
370
402
  "2xl": "0 32px 80px rgba(0,0,0,0.18)",
371
403
  inner: "inset 0 1px 0 rgba(255,255,255,0.4)"
372
404
  },
373
- elevation: { dropdown: 1e3, popover: 1100, modal: 1200, toast: 1300, tooltip: 1400 },
405
+ elevation: { dropdown: 1050, popover: 1060, modal: 1e3, toast: 1200, tooltip: 1100 },
374
406
  motion: {
375
407
  // Slightly slower/softer than light/dark — matches "everything floats".
376
408
  durationFast: "160ms",
@@ -890,27 +922,948 @@ function getSelectAllState(totalCount, selectedCount) {
890
922
  if (selectedCount >= totalCount) return "all";
891
923
  return "some";
892
924
  }
925
+
926
+ // src/core/kanban.ts
927
+ var DRAG_START_THRESHOLD_PX = 4;
928
+ function findCardLocation(value, cardId) {
929
+ for (const column of value.columns) {
930
+ const index = column.cardIds.indexOf(cardId);
931
+ if (index !== -1) return { columnId: column.id, index };
932
+ }
933
+ return null;
934
+ }
935
+ function removeCard(value, cardId) {
936
+ const location = findCardLocation(value, cardId);
937
+ if (!location) return value;
938
+ return {
939
+ columns: value.columns.map(
940
+ (column) => column.id === location.columnId ? { ...column, cardIds: column.cardIds.filter((id) => id !== cardId) } : column
941
+ )
942
+ };
943
+ }
944
+ function moveCard(value, target) {
945
+ const location = findCardLocation(value, target.cardId);
946
+ const destExists = value.columns.some((column) => column.id === target.toColumnId);
947
+ if (!location || !destExists) return value;
948
+ const withoutCard = value.columns.map(
949
+ (column) => column.cardIds.includes(target.cardId) ? { ...column, cardIds: column.cardIds.filter((id) => id !== target.cardId) } : column
950
+ );
951
+ return {
952
+ columns: withoutCard.map((column) => {
953
+ if (column.id !== target.toColumnId) return column;
954
+ const clampedIndex = Math.max(0, Math.min(target.toIndex, column.cardIds.length));
955
+ const cardIds = [...column.cardIds];
956
+ cardIds.splice(clampedIndex, 0, target.cardId);
957
+ return { ...column, cardIds };
958
+ })
959
+ };
960
+ }
961
+ function getAdjacentColumnId(value, columnId, direction) {
962
+ const index = value.columns.findIndex((column) => column.id === columnId);
963
+ if (index === -1) return null;
964
+ return value.columns[index + direction]?.id ?? null;
965
+ }
966
+ function getKeyboardMoveTarget(value, cardId, direction) {
967
+ const location = findCardLocation(value, cardId);
968
+ if (!location) return null;
969
+ const column = value.columns.find((c) => c.id === location.columnId);
970
+ if (!column) return null;
971
+ if (direction === "up" || direction === "down") {
972
+ const toIndex2 = direction === "up" ? location.index - 1 : location.index + 1;
973
+ if (toIndex2 < 0 || toIndex2 > column.cardIds.length - 1) return null;
974
+ return { cardId, toColumnId: location.columnId, toIndex: toIndex2 };
975
+ }
976
+ const adjacentColumnId = getAdjacentColumnId(value, location.columnId, direction === "prev" ? -1 : 1);
977
+ if (!adjacentColumnId) return null;
978
+ const destColumn = value.columns.find((c) => c.id === adjacentColumnId);
979
+ if (!destColumn) return null;
980
+ const toIndex = Math.min(location.index, destColumn.cardIds.length);
981
+ return { cardId, toColumnId: adjacentColumnId, toIndex };
982
+ }
983
+ function computeDropIndex(pointerY, cardRects) {
984
+ for (let i = 0; i < cardRects.length; i++) {
985
+ const midpoint = (cardRects[i].top + cardRects[i].bottom) / 2;
986
+ if (pointerY < midpoint) return i;
987
+ }
988
+ return cardRects.length;
989
+ }
990
+ function computeDropColumn(pointerX, pointerY, columns) {
991
+ for (const column of columns) {
992
+ if (pointerX >= column.left && pointerX <= column.right && pointerY >= column.top && pointerY <= column.bottom) {
993
+ return column.id;
994
+ }
995
+ }
996
+ return null;
997
+ }
998
+ function moveColumn(value, target) {
999
+ const fromIndex = value.columns.findIndex((c) => c.id === target.columnId);
1000
+ if (fromIndex === -1) return value;
1001
+ const columns = [...value.columns];
1002
+ const [moved] = columns.splice(fromIndex, 1);
1003
+ const clampedIndex = Math.max(0, Math.min(target.toIndex, columns.length));
1004
+ columns.splice(clampedIndex, 0, moved);
1005
+ return { columns };
1006
+ }
1007
+ function removeColumn(value, columnId) {
1008
+ if (!value.columns.some((c) => c.id === columnId)) return value;
1009
+ return { columns: value.columns.filter((c) => c.id !== columnId) };
1010
+ }
1011
+ function getColumnKeyboardMoveTarget(value, columnId, direction) {
1012
+ const fromIndex = value.columns.findIndex((c) => c.id === columnId);
1013
+ if (fromIndex === -1) return null;
1014
+ const toIndex = direction === "prev" ? fromIndex - 1 : fromIndex + 1;
1015
+ if (toIndex < 0 || toIndex > value.columns.length - 1) return null;
1016
+ return { columnId, toIndex };
1017
+ }
1018
+ function computeColumnDropIndex(pointerX, columnRects) {
1019
+ for (let i = 0; i < columnRects.length; i++) {
1020
+ const midpoint = (columnRects[i].left + columnRects[i].right) / 2;
1021
+ if (pointerX < midpoint) return i;
1022
+ }
1023
+ return columnRects.length;
1024
+ }
1025
+
1026
+ // src/core/code-highlight.ts
1027
+ function tokenizeFlat(source, grammar) {
1028
+ const tokens = [];
1029
+ const n = source.length;
1030
+ let i = 0;
1031
+ outer: while (i < n) {
1032
+ for (const rule of grammar.rules) {
1033
+ if (rule.pattern) {
1034
+ rule.pattern.lastIndex = i;
1035
+ const m = rule.pattern.exec(source);
1036
+ if (m && m.index === i && m[0].length > 0) {
1037
+ tokens.push({ type: rule.type, content: m[0] });
1038
+ i += m[0].length;
1039
+ continue outer;
1040
+ }
1041
+ } else if (rule.match) {
1042
+ const result = rule.match(source, i, tokens);
1043
+ if (result && result.length > 0) {
1044
+ tokens.push(...result.tokens);
1045
+ i += result.length;
1046
+ continue outer;
1047
+ }
1048
+ }
1049
+ }
1050
+ const ch = source[i];
1051
+ const last = tokens[tokens.length - 1];
1052
+ if (last && last.type === "plain") last.content += ch;
1053
+ else tokens.push({ type: "plain", content: ch });
1054
+ i++;
1055
+ }
1056
+ return tokens;
1057
+ }
1058
+ function splitIntoLines(tokens) {
1059
+ const lines = [[]];
1060
+ for (const tok of tokens) {
1061
+ const parts = tok.content.split("\n");
1062
+ parts.forEach((part, idx) => {
1063
+ if (part.length > 0) lines[lines.length - 1].push({ type: tok.type, content: part });
1064
+ if (idx < parts.length - 1) lines.push([]);
1065
+ });
1066
+ }
1067
+ return lines;
1068
+ }
1069
+ var KEYWORD = (words) => new RegExp(`\\b(?:${words})\\b`, "y");
1070
+ function matchTemplateLiteral(source, start, jsGrammar2) {
1071
+ if (source[start] !== "`") return null;
1072
+ const tokens = [{ type: "string", content: "`" }];
1073
+ let i = start + 1;
1074
+ let buf = "";
1075
+ const flush = () => {
1076
+ if (buf) {
1077
+ tokens.push({ type: "string", content: buf });
1078
+ buf = "";
1079
+ }
1080
+ };
1081
+ while (i < source.length) {
1082
+ const ch = source[i];
1083
+ if (ch === "\\" && i + 1 < source.length) {
1084
+ buf += ch + source[i + 1];
1085
+ i += 2;
1086
+ continue;
1087
+ }
1088
+ if (ch === "`") {
1089
+ flush();
1090
+ tokens.push({ type: "string", content: "`" });
1091
+ i++;
1092
+ return { length: i - start, tokens };
1093
+ }
1094
+ if (ch === "$" && source[i + 1] === "{") {
1095
+ flush();
1096
+ tokens.push({ type: "punctuation", content: "${" });
1097
+ i += 2;
1098
+ const exprStart = i;
1099
+ let depth = 1;
1100
+ while (i < source.length && depth > 0) {
1101
+ if (source[i] === "{") depth++;
1102
+ else if (source[i] === "}") depth--;
1103
+ if (depth > 0) i++;
1104
+ }
1105
+ const exprSource = source.slice(exprStart, i);
1106
+ tokens.push(...tokenizeFlat(exprSource, jsGrammar2));
1107
+ if (i < source.length) {
1108
+ tokens.push({ type: "punctuation", content: "}" });
1109
+ i++;
1110
+ }
1111
+ continue;
1112
+ }
1113
+ buf += ch;
1114
+ i++;
1115
+ }
1116
+ flush();
1117
+ return { length: i - start, tokens };
1118
+ }
1119
+ var REGEX_EXPRESSION_KEYWORDS = /* @__PURE__ */ new Set([
1120
+ "return",
1121
+ "typeof",
1122
+ "instanceof",
1123
+ "in",
1124
+ "of",
1125
+ "new",
1126
+ "delete",
1127
+ "void",
1128
+ "throw",
1129
+ "case",
1130
+ "do",
1131
+ "else",
1132
+ "yield",
1133
+ "await"
1134
+ ]);
1135
+ function matchRegexLiteral(source, start) {
1136
+ if (source[start] !== "/" || source[start + 1] === "/" || source[start + 1] === "*") return null;
1137
+ let j = start - 1;
1138
+ while (j >= 0 && /\s/.test(source[j])) j--;
1139
+ if (j >= 0) {
1140
+ const prevChar = source[j];
1141
+ const looksLikeValueEnd = /[)\]}\w$]/.test(prevChar) || prevChar === '"' || prevChar === "'" || prevChar === "`";
1142
+ if (looksLikeValueEnd) {
1143
+ const wordBefore = source.slice(0, j + 1).match(/([A-Za-z_$][\w$]*)$/)?.[1];
1144
+ if (!(wordBefore && REGEX_EXPRESSION_KEYWORDS.has(wordBefore))) return null;
1145
+ }
1146
+ }
1147
+ let i = start + 1;
1148
+ let inClass = false;
1149
+ while (i < source.length) {
1150
+ const ch = source[i];
1151
+ if (ch === "\\") {
1152
+ i += 2;
1153
+ continue;
1154
+ }
1155
+ if (ch === "\n") return null;
1156
+ if (ch === "[") inClass = true;
1157
+ else if (ch === "]") inClass = false;
1158
+ else if (ch === "/" && !inClass) {
1159
+ i++;
1160
+ break;
1161
+ }
1162
+ i++;
1163
+ }
1164
+ if (source[i - 1] !== "/") return null;
1165
+ while (i < source.length && /[a-z]/i.test(source[i])) i++;
1166
+ return { length: i - start, tokens: [{ type: "regex", content: source.slice(start, i) }] };
1167
+ }
1168
+ function buildJsGrammar(withTags) {
1169
+ const grammar = { rules: [] };
1170
+ const rules = grammar.rules;
1171
+ if (withTags) {
1172
+ rules.push({ type: "tag", pattern: /<\/?[A-Za-z][\w.-]*/y });
1173
+ }
1174
+ rules.push(
1175
+ { type: "comment", pattern: /\/\/[^\n]*|\/\*[\s\S]*?\*\//y },
1176
+ { type: "string", pattern: /"(?:[^"\\\n]|\\.)*"|'(?:[^'\\\n]|\\.)*'/y },
1177
+ { type: "custom-template", match: (src, idx) => matchTemplateLiteral(src, idx, grammar) },
1178
+ { type: "custom-regex", match: (src, idx) => matchRegexLiteral(src, idx) },
1179
+ { type: "decorator", pattern: /@[A-Za-z_$][\w$]*/y },
1180
+ { type: "boolean", pattern: KEYWORD("true|false|null|undefined") },
1181
+ {
1182
+ type: "keyword",
1183
+ pattern: KEYWORD(
1184
+ "const|let|var|function|return|if|else|for|while|do|switch|case|default|break|continue|class|extends|super|new|this|typeof|instanceof|in|of|try|catch|finally|throw|async|await|yield|import|export|from|as|void|delete|static|get|set|interface|type|enum|implements|public|private|protected|readonly|namespace|declare|abstract|is|keyof|infer|satisfies"
1185
+ )
1186
+ },
1187
+ {
1188
+ type: "builtin",
1189
+ pattern: KEYWORD(
1190
+ "console|Math|JSON|Promise|Array|Object|Map|Set|WeakMap|WeakSet|String|Number|Boolean|Symbol|Error|Date|RegExp|Reflect|Proxy|globalThis|Infinity|NaN|BigInt|fetch|localStorage|sessionStorage"
1191
+ )
1192
+ },
1193
+ { type: "number", pattern: /\b0[xX][0-9a-fA-F]+\b|\b\d+\.?\d*(?:[eE][+-]?\d+)?n?\b/y },
1194
+ { type: "function", pattern: /[A-Za-z_$][\w$]*(?=\s*\()/y },
1195
+ { type: "punctuation", pattern: /[{}()[\];,.:?]/y }
1196
+ );
1197
+ return grammar;
1198
+ }
1199
+ var jsGrammar = buildJsGrammar(false);
1200
+ var jsxGrammar = buildJsGrammar(true);
1201
+ var jsonGrammar = {
1202
+ rules: [
1203
+ { type: "string", pattern: /"(?:[^"\\\n]|\\.)*"/y },
1204
+ { type: "boolean", pattern: KEYWORD("true|false|null") },
1205
+ { type: "number", pattern: /-?\b\d+\.?\d*(?:[eE][+-]?\d+)?\b/y },
1206
+ { type: "punctuation", pattern: /[{}[\]:,]/y }
1207
+ ]
1208
+ };
1209
+ var cssGrammar = {
1210
+ rules: [
1211
+ { type: "comment", pattern: /\/\*[\s\S]*?\*\//y },
1212
+ { type: "string", pattern: /"(?:[^"\\\n]|\\.)*"|'(?:[^'\\\n]|\\.)*'/y },
1213
+ { type: "keyword", pattern: /!important\b/y },
1214
+ { type: "atrule", pattern: /@[a-zA-Z-]+/y },
1215
+ // Custom-property declarations/usage (--brand-color, var(--x)) —
1216
+ // checked before the generic hex-color/selector rules below.
1217
+ { type: "variable", pattern: /--[a-zA-Z_][\w-]*/y },
1218
+ { type: "function", pattern: /\b(?:var|calc|rgba?|hsla?|clamp|minmax|repeat|url|translate[XYZ]?|rotate[XYZ]?|scale[XYZ]?|linear-gradient|radial-gradient)(?=\()/y },
1219
+ // Pseudo-classes/elements (:hover, ::before) before the plain ":" punctuation.
1220
+ { type: "pseudo", pattern: /::?[a-zA-Z-]+/y },
1221
+ // Hex colors before the generic "#name" id-selector pattern below.
1222
+ { type: "builtin", pattern: /#[0-9a-fA-F]{3,8}\b/y },
1223
+ { type: "selector", pattern: /[.#][a-zA-Z_-][\w-]*/y },
1224
+ { type: "property", pattern: /[a-zA-Z-]+(?=\s*:)/y },
1225
+ { type: "number", pattern: /-?\d+\.?\d*(?:px|em|rem|%|vh|vw|s|ms|deg|fr)?\b/y },
1226
+ { type: "punctuation", pattern: /[{}:;,()]/y }
1227
+ ]
1228
+ };
1229
+ var htmlGrammar = {
1230
+ rules: [
1231
+ { type: "comment", pattern: /<!--[\s\S]*?-->/y },
1232
+ { type: "keyword", pattern: /<!DOCTYPE[^>]*>/iy },
1233
+ { type: "tag", pattern: /<\/?[a-zA-Z][\w:-]*/y },
1234
+ { type: "attrName", pattern: /[a-zA-Z-]+(?=\s*=)/y },
1235
+ { type: "string", pattern: /"(?:[^"\\\n]|\\.)*"|'(?:[^'\\\n]|\\.)*'/y },
1236
+ { type: "builtin", pattern: /&[a-zA-Z#0-9]+;/y },
1237
+ { type: "punctuation", pattern: /[<>=/]/y }
1238
+ ]
1239
+ };
1240
+ var bashGrammar = {
1241
+ rules: [
1242
+ { type: "comment", pattern: /#[^\n]*/y },
1243
+ { type: "string", pattern: /"(?:[^"\\\n]|\\.)*"|'[^'\n]*'/y },
1244
+ { type: "variable", pattern: /\$\{?\w+\}?/y },
1245
+ {
1246
+ type: "keyword",
1247
+ pattern: KEYWORD(
1248
+ "if|then|else|elif|fi|for|do|done|while|case|esac|function|return|exit|export|local|echo|cd|sudo|npm|yarn|pnpm|git|mkdir|rm|cp|mv|cat|grep|sed|awk"
1249
+ )
1250
+ },
1251
+ { type: "number", pattern: /\b\d+\b/y },
1252
+ { type: "function", pattern: /(?<=^|\s)--?[a-zA-Z][\w-]*/y },
1253
+ { type: "punctuation", pattern: /[|&;()]/y }
1254
+ ]
1255
+ };
1256
+ var pythonGrammar = {
1257
+ rules: [
1258
+ { type: "comment", pattern: /#[^\n]*/y },
1259
+ { type: "decorator", pattern: /@[A-Za-z_][\w.]*/y },
1260
+ {
1261
+ // f/r/b/u string prefixes (f"...", rb'...', etc.) before plain strings.
1262
+ type: "string",
1263
+ pattern: /[rRbBfFuU]{0,2}(?:"""[\s\S]*?"""|'''[\s\S]*?'''|"(?:[^"\\\n]|\\.)*"|'(?:[^'\\\n]|\\.)*')/y
1264
+ },
1265
+ { type: "boolean", pattern: KEYWORD("True|False|None") },
1266
+ {
1267
+ type: "keyword",
1268
+ pattern: KEYWORD(
1269
+ "def|return|if|elif|else|for|while|in|not|and|or|is|import|from|as|class|try|except|finally|raise|with|lambda|yield|pass|break|continue|global|nonlocal|assert|del|async|await|self"
1270
+ )
1271
+ },
1272
+ { type: "builtin", pattern: KEYWORD("print|len|range|str|int|float|list|dict|set|tuple|type|isinstance|super|open|input|enumerate|zip|map|filter|sorted|sum|min|max|any|all") },
1273
+ { type: "number", pattern: /\b\d+\.?\d*\b/y },
1274
+ { type: "function", pattern: /[A-Za-z_]\w*(?=\s*\()/y },
1275
+ { type: "punctuation", pattern: /[:,.()[\]{}]/y }
1276
+ ]
1277
+ };
1278
+ var markdownGrammar = {
1279
+ rules: [
1280
+ { type: "comment", pattern: /```[\s\S]*?```/y },
1281
+ { type: "keyword", pattern: /^#{1,6}[^\n]*/my },
1282
+ { type: "punctuation", pattern: /^(?:-{3,}|\*{3,}|_{3,})$/my },
1283
+ { type: "function", pattern: /`[^`\n]+`/y },
1284
+ { type: "builtin", pattern: /\*\*[^*\n]+\*\*/y },
1285
+ { type: "variable", pattern: /~~[^~\n]+~~/y },
1286
+ { type: "string", pattern: /\*[^*\n]+\*/y },
1287
+ { type: "tag", pattern: /!?\[[^\]\n]*\]\([^)\n]*\)/y },
1288
+ { type: "punctuation", pattern: /^[-*+]\s|^\d+\.\s/my }
1289
+ ]
1290
+ };
1291
+ var yamlGrammar = {
1292
+ rules: [
1293
+ { type: "comment", pattern: /#[^\n]*/y },
1294
+ { type: "property", pattern: /^[ \t]*[\w.-]+(?=\s*:)/my },
1295
+ { type: "string", pattern: /"(?:[^"\\\n]|\\.)*"|'[^'\n]*'/y },
1296
+ { type: "boolean", pattern: KEYWORD("true|false|null|yes|no|on|off|True|False|Null") },
1297
+ { type: "number", pattern: /-?\b\d+\.?\d*\b/y },
1298
+ { type: "variable", pattern: /[&*][\w-]+/y },
1299
+ { type: "punctuation", pattern: /[:\-[\]{},]/y }
1300
+ ]
1301
+ };
1302
+ var sqlGrammar = {
1303
+ rules: [
1304
+ { type: "comment", pattern: /--[^\n]*|\/\*[\s\S]*?\*\//y },
1305
+ { type: "string", pattern: /'(?:[^'\\\n]|\\.)*'/y },
1306
+ {
1307
+ type: "keyword",
1308
+ pattern: new RegExp(
1309
+ "\\b(?:SELECT|FROM|WHERE|INSERT|INTO|VALUES|UPDATE|SET|DELETE|CREATE|TABLE|ALTER|DROP|JOIN|INNER|LEFT|RIGHT|OUTER|ON|GROUP|BY|ORDER|HAVING|LIMIT|OFFSET|AS|AND|OR|NOT|NULL|IS|IN|LIKE|BETWEEN|DISTINCT|UNION|ALL|EXISTS|CASE|WHEN|THEN|ELSE|END|PRIMARY|KEY|FOREIGN|REFERENCES|DEFAULT|CONSTRAINT|INDEX|VIEW|WITH)\\b",
1310
+ "iy"
1311
+ )
1312
+ },
1313
+ { type: "number", pattern: /\b\d+\.?\d*\b/y },
1314
+ { type: "function", pattern: /\b[A-Za-z_]\w*(?=\s*\()/y },
1315
+ { type: "punctuation", pattern: /[(),;.*=<>!]/y }
1316
+ ]
1317
+ };
1318
+ var GRAMMARS = {
1319
+ javascript: jsGrammar,
1320
+ typescript: jsGrammar,
1321
+ jsx: jsxGrammar,
1322
+ tsx: jsxGrammar,
1323
+ json: jsonGrammar,
1324
+ css: cssGrammar,
1325
+ html: htmlGrammar,
1326
+ bash: bashGrammar,
1327
+ python: pythonGrammar,
1328
+ markdown: markdownGrammar,
1329
+ yaml: yamlGrammar,
1330
+ sql: sqlGrammar
1331
+ };
1332
+ var ALIASES = {
1333
+ js: "javascript",
1334
+ mjs: "javascript",
1335
+ cjs: "javascript",
1336
+ ts: "typescript",
1337
+ sh: "bash",
1338
+ shell: "bash",
1339
+ zsh: "bash",
1340
+ py: "python",
1341
+ md: "markdown",
1342
+ htm: "html",
1343
+ yml: "yaml"
1344
+ };
1345
+ var LANGUAGE_LABELS = {
1346
+ javascript: "JavaScript",
1347
+ typescript: "TypeScript",
1348
+ jsx: "JSX",
1349
+ tsx: "TSX",
1350
+ json: "JSON",
1351
+ css: "CSS",
1352
+ html: "HTML",
1353
+ bash: "Shell",
1354
+ python: "Python",
1355
+ markdown: "Markdown",
1356
+ yaml: "YAML",
1357
+ sql: "SQL",
1358
+ plaintext: "Plain text"
1359
+ };
1360
+ function normalizeLanguage(language) {
1361
+ const lower = language.trim().toLowerCase();
1362
+ return ALIASES[lower] ?? lower;
1363
+ }
1364
+ var nuvoxHighlight = (code, language) => {
1365
+ const key = normalizeLanguage(language ?? "plaintext");
1366
+ const grammar = GRAMMARS[key];
1367
+ if (!grammar) return splitIntoLines([{ type: "plain", content: code }]);
1368
+ try {
1369
+ return splitIntoLines(tokenizeFlat(code, grammar));
1370
+ } catch {
1371
+ return splitIntoLines([{ type: "plain", content: code }]);
1372
+ }
1373
+ };
1374
+
1375
+ // src/core/rich-text.ts
1376
+ var MARK_TAGS = {
1377
+ bold: "STRONG",
1378
+ italic: "EM",
1379
+ underline: "U",
1380
+ strike: "S",
1381
+ code: "CODE"
1382
+ };
1383
+ var BLOCK_TAGS = {
1384
+ paragraph: "P",
1385
+ h1: "H1",
1386
+ h2: "H2",
1387
+ h3: "H3",
1388
+ blockquote: "BLOCKQUOTE",
1389
+ bulletList: "UL",
1390
+ orderedList: "OL"
1391
+ };
1392
+ var BLOCK_TAG_NAMES = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "BLOCKQUOTE", "DIV"]);
1393
+ function isMark(command) {
1394
+ return command in MARK_TAGS;
1395
+ }
1396
+ function isBlock(command) {
1397
+ return command in BLOCK_TAGS;
1398
+ }
1399
+ function isCommandActive(ancestorTags, command) {
1400
+ if (command === "link") return ancestorTags.includes("A");
1401
+ if (command === "unlink") return false;
1402
+ if (isMark(command)) return ancestorTags.includes(MARK_TAGS[command]);
1403
+ if (isBlock(command)) return ancestorTags.includes(BLOCK_TAGS[command]);
1404
+ return false;
1405
+ }
1406
+ function closestWithinRoot(node, tag, root) {
1407
+ let n = node;
1408
+ while (n && n !== root) {
1409
+ if (n.nodeType === Node.ELEMENT_NODE && n.tagName === tag) return n;
1410
+ n = n.parentNode;
1411
+ }
1412
+ return null;
1413
+ }
1414
+ function closestBlock(node, root) {
1415
+ let n = node && node.nodeType === Node.ELEMENT_NODE ? node : node?.parentNode ?? null;
1416
+ while (n && n !== root) {
1417
+ if (n.nodeType === Node.ELEMENT_NODE && BLOCK_TAG_NAMES.has(n.tagName)) return n;
1418
+ n = n.parentNode;
1419
+ }
1420
+ return null;
1421
+ }
1422
+ function unwrapElement(el) {
1423
+ const parent = el.parentNode;
1424
+ if (!parent) return;
1425
+ while (el.firstChild) parent.insertBefore(el.firstChild, el);
1426
+ parent.removeChild(el);
1427
+ }
1428
+ function replaceTag(el, tag) {
1429
+ const next = document.createElement(tag);
1430
+ while (el.firstChild) next.appendChild(el.firstChild);
1431
+ el.parentNode?.replaceChild(next, el);
1432
+ return next;
1433
+ }
1434
+ function selectNodeContents(node, collapseToEnd = false) {
1435
+ const sel = window.getSelection();
1436
+ if (!sel) return;
1437
+ const range = document.createRange();
1438
+ range.selectNodeContents(node);
1439
+ if (collapseToEnd) range.collapse(false);
1440
+ sel.removeAllRanges();
1441
+ sel.addRange(range);
1442
+ }
1443
+ var ZERO_WIDTH_SPACE = "\u200B";
1444
+ function selectAtMarker(sel, marker, offset) {
1445
+ const range = document.createRange();
1446
+ range.setStart(marker, offset);
1447
+ range.collapse(true);
1448
+ sel.removeAllRanges();
1449
+ sel.addRange(range);
1450
+ }
1451
+ function togglePendingMark(root, tag) {
1452
+ const sel = window.getSelection();
1453
+ if (!sel || sel.rangeCount === 0) return;
1454
+ const range = sel.getRangeAt(0);
1455
+ const existing = closestWithinRoot(range.startContainer, tag, root);
1456
+ if (existing) {
1457
+ const marker2 = document.createTextNode(ZERO_WIDTH_SPACE);
1458
+ existing.parentNode?.insertBefore(marker2, existing.nextSibling);
1459
+ selectAtMarker(sel, marker2, 1);
1460
+ return;
1461
+ }
1462
+ const wrapper = document.createElement(tag);
1463
+ const marker = document.createTextNode(ZERO_WIDTH_SPACE);
1464
+ wrapper.appendChild(marker);
1465
+ range.insertNode(wrapper);
1466
+ selectAtMarker(sel, marker, 1);
1467
+ }
1468
+ function toggleMark(root, tag) {
1469
+ const sel = window.getSelection();
1470
+ if (!sel || sel.rangeCount === 0) return;
1471
+ if (sel.isCollapsed) {
1472
+ togglePendingMark(root, tag);
1473
+ return;
1474
+ }
1475
+ const range = sel.getRangeAt(0);
1476
+ const existing = closestWithinRoot(range.commonAncestorContainer, tag, root);
1477
+ if (existing) {
1478
+ unwrapElement(existing);
1479
+ return;
1480
+ }
1481
+ const wrapper = document.createElement(tag);
1482
+ wrapper.appendChild(range.extractContents());
1483
+ range.insertNode(wrapper);
1484
+ selectNodeContents(wrapper);
1485
+ }
1486
+ function setBlockTag(root, targetTag) {
1487
+ const sel = window.getSelection();
1488
+ if (!sel || sel.rangeCount === 0) return;
1489
+ const block = closestBlock(sel.getRangeAt(0).startContainer, root);
1490
+ if (!block) return;
1491
+ const next = replaceTag(block, block.tagName === targetTag ? "P" : targetTag);
1492
+ selectNodeContents(next, true);
1493
+ }
1494
+ function toggleList(root, listTag) {
1495
+ const sel = window.getSelection();
1496
+ if (!sel || sel.rangeCount === 0) return;
1497
+ const range = sel.getRangeAt(0);
1498
+ const li = closestWithinRoot(range.startContainer, "LI", root);
1499
+ if (li && li.parentElement?.tagName === listTag) {
1500
+ const list2 = li.parentElement;
1501
+ const p = document.createElement("P");
1502
+ while (li.firstChild) p.appendChild(li.firstChild);
1503
+ list2.parentNode?.replaceChild(p, list2);
1504
+ selectNodeContents(p, true);
1505
+ return;
1506
+ }
1507
+ const block = closestBlock(range.startContainer, root);
1508
+ if (!block) return;
1509
+ const list = document.createElement(listTag);
1510
+ const item = document.createElement("LI");
1511
+ while (block.firstChild) item.appendChild(block.firstChild);
1512
+ list.appendChild(item);
1513
+ block.parentNode?.replaceChild(list, block);
1514
+ selectNodeContents(item, true);
1515
+ }
1516
+ function setLink(root, url) {
1517
+ const sel = window.getSelection();
1518
+ if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return;
1519
+ const range = sel.getRangeAt(0);
1520
+ const existing = closestWithinRoot(range.commonAncestorContainer, "A", root);
1521
+ if (existing) {
1522
+ existing.setAttribute("href", url);
1523
+ return;
1524
+ }
1525
+ const a = document.createElement("A");
1526
+ a.setAttribute("href", url);
1527
+ a.setAttribute("rel", "noopener noreferrer");
1528
+ a.appendChild(range.extractContents());
1529
+ range.insertNode(a);
1530
+ selectNodeContents(a);
1531
+ }
1532
+ function unlink(root) {
1533
+ const sel = window.getSelection();
1534
+ if (!sel || sel.rangeCount === 0) return;
1535
+ const a = closestWithinRoot(sel.getRangeAt(0).commonAncestorContainer, "A", root);
1536
+ if (a) unwrapElement(a);
1537
+ }
1538
+ function findStyledSpanWithinRoot(node, property, root) {
1539
+ let n = node;
1540
+ while (n && n !== root) {
1541
+ if (n.nodeType === Node.ELEMENT_NODE) {
1542
+ const el = n;
1543
+ if (el.tagName === "SPAN" && el.style.getPropertyValue(property)) return el;
1544
+ }
1545
+ n = n.parentNode;
1546
+ }
1547
+ return null;
1548
+ }
1549
+ function setInlineStyle(root, property, value) {
1550
+ const sel = window.getSelection();
1551
+ if (!sel || sel.rangeCount === 0) return;
1552
+ const range = sel.getRangeAt(0);
1553
+ if (sel.isCollapsed) {
1554
+ const existing2 = findStyledSpanWithinRoot(range.startContainer, property, root);
1555
+ if (existing2) {
1556
+ existing2.style.setProperty(property, value);
1557
+ return;
1558
+ }
1559
+ const wrapper2 = document.createElement("span");
1560
+ wrapper2.style.setProperty(property, value);
1561
+ const marker = document.createTextNode(ZERO_WIDTH_SPACE);
1562
+ wrapper2.appendChild(marker);
1563
+ range.insertNode(wrapper2);
1564
+ selectAtMarker(sel, marker, 1);
1565
+ return;
1566
+ }
1567
+ const existing = findStyledSpanWithinRoot(range.commonAncestorContainer, property, root);
1568
+ if (existing) {
1569
+ existing.style.setProperty(property, value);
1570
+ return;
1571
+ }
1572
+ const wrapper = document.createElement("span");
1573
+ wrapper.style.setProperty(property, value);
1574
+ wrapper.appendChild(range.extractContents());
1575
+ range.insertNode(wrapper);
1576
+ selectNodeContents(wrapper);
1577
+ }
1578
+ function clearInlineStyle(root, property) {
1579
+ const sel = window.getSelection();
1580
+ if (!sel || sel.rangeCount === 0) return;
1581
+ const el = findStyledSpanWithinRoot(sel.getRangeAt(0).commonAncestorContainer, property, root);
1582
+ if (!el) return;
1583
+ el.style.removeProperty(property);
1584
+ if (!el.getAttribute("style")) unwrapElement(el);
1585
+ }
1586
+ function execRichTextCommand(root, command, value) {
1587
+ if (isMark(command)) toggleMark(root, MARK_TAGS[command]);
1588
+ else if (command === "bulletList") toggleList(root, "UL");
1589
+ else if (command === "orderedList") toggleList(root, "OL");
1590
+ else if (isBlock(command)) setBlockTag(root, BLOCK_TAGS[command]);
1591
+ else if (command === "link" && value) setLink(root, value);
1592
+ else if (command === "unlink") unlink(root);
1593
+ else if (command === "textColor" && value) setInlineStyle(root, "color", value);
1594
+ else if (command === "clearTextColor") clearInlineStyle(root, "color");
1595
+ else if (command === "highlight" && value) setInlineStyle(root, "background-color", value);
1596
+ else if (command === "clearHighlight") clearInlineStyle(root, "background-color");
1597
+ }
1598
+ function getActiveCommands(root) {
1599
+ const result = /* @__PURE__ */ new Set();
1600
+ if (typeof window === "undefined") return result;
1601
+ const sel = window.getSelection();
1602
+ if (!sel || sel.rangeCount === 0) return result;
1603
+ const tags = [];
1604
+ let node = sel.anchorNode;
1605
+ while (node && node !== root) {
1606
+ if (node.nodeType === Node.ELEMENT_NODE) tags.push(node.tagName);
1607
+ node = node.parentNode;
1608
+ }
1609
+ const commands = [...Object.keys(MARK_TAGS), ...Object.keys(BLOCK_TAGS), "link"];
1610
+ for (const command of commands) {
1611
+ if (isCommandActive(tags, command)) result.add(command);
1612
+ }
1613
+ return result;
1614
+ }
1615
+ var ALLOWED_TAGS = /* @__PURE__ */ new Set([
1616
+ "P",
1617
+ "BR",
1618
+ "STRONG",
1619
+ "B",
1620
+ "EM",
1621
+ "I",
1622
+ "U",
1623
+ "S",
1624
+ "STRIKE",
1625
+ "CODE",
1626
+ "A",
1627
+ "H1",
1628
+ "H2",
1629
+ "H3",
1630
+ "BLOCKQUOTE",
1631
+ "UL",
1632
+ "OL",
1633
+ "LI",
1634
+ "SPAN"
1635
+ ]);
1636
+ var ALLOWED_ATTRS = {
1637
+ A: ["href"],
1638
+ SPAN: ["style"]
1639
+ };
1640
+ var ALLOWED_STYLE_PROPS = /* @__PURE__ */ new Set(["color", "background-color"]);
1641
+ var SAFE_COLOR_VALUE = /^(#[0-9a-fA-F]{3,8}|rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)|rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)|hsl\([^();]*\)|hsla\([^();]*\)|[a-zA-Z]+)$/;
1642
+ function sanitizeStyleAttr(value) {
1643
+ const out = [];
1644
+ for (const decl of value.split(";")) {
1645
+ const colon = decl.indexOf(":");
1646
+ if (colon === -1) continue;
1647
+ const prop = decl.slice(0, colon).trim().toLowerCase();
1648
+ const val = decl.slice(colon + 1).trim();
1649
+ if (ALLOWED_STYLE_PROPS.has(prop) && SAFE_COLOR_VALUE.test(val)) {
1650
+ out.push(`${prop}: ${val}`);
1651
+ }
1652
+ }
1653
+ return out.join("; ");
1654
+ }
1655
+ var STRIP_ENTIRELY = /* @__PURE__ */ new Set(["SCRIPT", "STYLE", "IFRAME", "OBJECT", "EMBED"]);
1656
+ function sanitizeElement(el) {
1657
+ for (const child of Array.from(el.childNodes)) {
1658
+ if (child.nodeType === Node.TEXT_NODE) continue;
1659
+ if (child.nodeType !== Node.ELEMENT_NODE) {
1660
+ child.parentNode?.removeChild(child);
1661
+ continue;
1662
+ }
1663
+ const childEl = child;
1664
+ if (STRIP_ENTIRELY.has(childEl.tagName)) {
1665
+ childEl.parentNode?.removeChild(childEl);
1666
+ continue;
1667
+ }
1668
+ if (!ALLOWED_TAGS.has(childEl.tagName)) {
1669
+ sanitizeElement(childEl);
1670
+ const parent = childEl.parentNode;
1671
+ while (childEl.firstChild) parent?.insertBefore(childEl.firstChild, childEl);
1672
+ parent?.removeChild(childEl);
1673
+ continue;
1674
+ }
1675
+ const allowedAttrs = ALLOWED_ATTRS[childEl.tagName] ?? [];
1676
+ for (const attr of Array.from(childEl.attributes)) {
1677
+ const name = attr.name.toLowerCase();
1678
+ if (!allowedAttrs.includes(name)) {
1679
+ childEl.removeAttribute(attr.name);
1680
+ continue;
1681
+ }
1682
+ if (name === "style") {
1683
+ const cleaned = sanitizeStyleAttr(attr.value);
1684
+ if (cleaned) childEl.setAttribute("style", cleaned);
1685
+ else childEl.removeAttribute("style");
1686
+ }
1687
+ }
1688
+ if (childEl.tagName === "A") {
1689
+ const href = childEl.getAttribute("href") ?? "";
1690
+ const safe = /^https?:\/\//i.test(href) || href.startsWith("/") || href.startsWith("#") || href.startsWith("mailto:");
1691
+ if (!safe) childEl.removeAttribute("href");
1692
+ childEl.setAttribute("rel", "noopener noreferrer");
1693
+ childEl.setAttribute("target", "_blank");
1694
+ }
1695
+ sanitizeElement(childEl);
1696
+ }
1697
+ }
1698
+ function sanitizeHtml(html) {
1699
+ if (typeof DOMParser === "undefined") return "";
1700
+ const doc = new DOMParser().parseFromString(html, "text/html");
1701
+ sanitizeElement(doc.body);
1702
+ return doc.body.innerHTML;
1703
+ }
1704
+ var HISTORY_LIMIT = 100;
1705
+ function createHistory() {
1706
+ return { past: [], future: [] };
1707
+ }
1708
+ function pushHistory(history, previousValue) {
1709
+ return { past: [...history.past, previousValue].slice(-HISTORY_LIMIT), future: [] };
1710
+ }
1711
+ function undoHistory(history, currentValue) {
1712
+ if (history.past.length === 0) return null;
1713
+ const value = history.past[history.past.length - 1];
1714
+ return {
1715
+ history: { past: history.past.slice(0, -1), future: [currentValue, ...history.future] },
1716
+ value
1717
+ };
1718
+ }
1719
+ function redoHistory(history, currentValue) {
1720
+ if (history.future.length === 0) return null;
1721
+ const value = history.future[0];
1722
+ return {
1723
+ history: { past: [...history.past, currentValue], future: history.future.slice(1) },
1724
+ value
1725
+ };
1726
+ }
1727
+
1728
+ // src/core/gallery.ts
1729
+ function aspectRatioFromDims(width, height) {
1730
+ if (!width || !height || width <= 0 || height <= 0) return 1;
1731
+ return width / height;
1732
+ }
1733
+ function computeJustifiedRows(aspectRatios, containerWidth, targetRowHeight, gap) {
1734
+ if (aspectRatios.length === 0 || containerWidth <= 0 || targetRowHeight <= 0) return [];
1735
+ const rows = [];
1736
+ let rowIndices = [];
1737
+ let rowNaturalWidths = [];
1738
+ let rowWidthSum = 0;
1739
+ function flushRow(scale) {
1740
+ if (rowIndices.length === 0) return;
1741
+ const gapsWidth = gap * (rowIndices.length - 1);
1742
+ const availableWidth = containerWidth - gapsWidth;
1743
+ const naturalTotal = rowWidthSum;
1744
+ const scaleFactor = scale ? availableWidth / naturalTotal : 1;
1745
+ rows.push({
1746
+ indices: rowIndices,
1747
+ height: targetRowHeight * scaleFactor,
1748
+ widths: rowNaturalWidths.map((w) => w * scaleFactor)
1749
+ });
1750
+ rowIndices = [];
1751
+ rowNaturalWidths = [];
1752
+ rowWidthSum = 0;
1753
+ }
1754
+ for (let i = 0; i < aspectRatios.length; i++) {
1755
+ const naturalWidth = aspectRatios[i] * targetRowHeight;
1756
+ const gapsWidth = gap * rowIndices.length;
1757
+ if (rowIndices.length > 0 && rowWidthSum + naturalWidth + gapsWidth > containerWidth) {
1758
+ flushRow(true);
1759
+ }
1760
+ rowIndices.push(i);
1761
+ rowNaturalWidths.push(naturalWidth);
1762
+ rowWidthSum += naturalWidth;
1763
+ }
1764
+ const finalGapsWidth = gap * (rowIndices.length - 1);
1765
+ const overflows = rowWidthSum + finalGapsWidth > containerWidth;
1766
+ flushRow(overflows);
1767
+ return rows;
1768
+ }
1769
+
1770
+ // src/core/media.ts
1771
+ var PLAYBACK_RATES = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
1772
+ function formatMediaTime(seconds) {
1773
+ if (!Number.isFinite(seconds) || seconds < 0) return "0:00";
1774
+ const total = Math.floor(seconds);
1775
+ const h = Math.floor(total / 3600);
1776
+ const m = Math.floor(total % 3600 / 60);
1777
+ const s = total % 60;
1778
+ const paddedS = String(s).padStart(2, "0");
1779
+ if (h > 0) return `${h}:${String(m).padStart(2, "0")}:${paddedS}`;
1780
+ return `${m}:${paddedS}`;
1781
+ }
1782
+ var SKIP_SECONDS = 10;
1783
+ var LABELED_SKIP_SECONDS = [5, 10, 15, 30];
1784
+ function hasLabeledSkipIcon(seconds) {
1785
+ return LABELED_SKIP_SECONDS.includes(seconds);
1786
+ }
1787
+ function resolveSkipSeconds(skipSeconds) {
1788
+ if (skipSeconds === void 0) return SKIP_SECONDS;
1789
+ if (!Number.isFinite(skipSeconds) || skipSeconds <= 0) return SKIP_SECONDS;
1790
+ return skipSeconds;
1791
+ }
1792
+ function resolveMediaTransport(props) {
1793
+ const showNext = props.onNext !== void 0;
1794
+ const showPrevious = props.onPrevious !== void 0;
1795
+ return {
1796
+ skipSeconds: resolveSkipSeconds(props.skipSeconds),
1797
+ showNext,
1798
+ showPrevious,
1799
+ nextDisabled: showNext && (props.hasNext ?? true) === false,
1800
+ previousDisabled: showPrevious && (props.hasPrevious ?? true) === false
1801
+ };
1802
+ }
1803
+ function getMediaKeyAction(key) {
1804
+ switch (key) {
1805
+ case " ":
1806
+ case "Spacebar":
1807
+ return "toggle-play";
1808
+ case "ArrowLeft":
1809
+ return "seek-back";
1810
+ case "ArrowRight":
1811
+ return "seek-forward";
1812
+ case "ArrowUp":
1813
+ return "volume-up";
1814
+ case "ArrowDown":
1815
+ return "volume-down";
1816
+ default:
1817
+ return null;
1818
+ }
1819
+ }
1820
+
1821
+ // src/core/pdf-viewer.ts
1822
+ function formatZoomPercent(scale) {
1823
+ return scale === "auto" ? "Fit" : `${Math.round(scale * 100)}%`;
1824
+ }
893
1825
  // Annotate the CommonJS export names for ESM import in node:
894
1826
  0 && (module.exports = {
895
1827
  DEFAULT_COLOR_PRESETS,
1828
+ DRAG_START_THRESHOLD_PX,
1829
+ LABELED_SKIP_SECONDS,
1830
+ LANGUAGE_LABELS,
1831
+ PLAYBACK_RATES,
896
1832
  REQUIRED_TOKEN_PATHS,
1833
+ SKIP_SECONDS,
897
1834
  TOKEN_CATEGORIES,
898
1835
  amber,
1836
+ aspectRatioFromDims,
899
1837
  brutalism,
1838
+ computeColumnDropIndex,
1839
+ computeDropColumn,
1840
+ computeDropIndex,
1841
+ computeJustifiedRows,
900
1842
  copper,
1843
+ createHistory,
901
1844
  cyberpunk,
902
1845
  dark,
903
1846
  darkGlass,
904
1847
  defineTheme,
905
1848
  emerald,
1849
+ execRichTextCommand,
1850
+ findCardLocation,
906
1851
  findMissingTokenPaths,
1852
+ formatMediaTime,
1853
+ formatZoomPercent,
907
1854
  getAccent,
1855
+ getActiveCommands,
1856
+ getAdjacentColumnId,
1857
+ getColumnKeyboardMoveTarget,
1858
+ getKeyboardMoveTarget,
1859
+ getMediaKeyAction,
908
1860
  getNextSortDirection,
909
1861
  getSelectAllState,
910
1862
  getTheme,
911
1863
  glass,
912
1864
  gradient,
913
1865
  graphite,
1866
+ hasLabeledSkipIcon,
914
1867
  indigo,
915
1868
  light,
916
1869
  listAccents,
@@ -918,12 +1871,23 @@ function getSelectAllState(totalCount, selectedCount) {
918
1871
  magenta,
919
1872
  material,
920
1873
  minimalism,
1874
+ moveCard,
1875
+ moveColumn,
921
1876
  neobrutalism,
1877
+ nuvoxHighlight,
1878
+ pushHistory,
1879
+ redoHistory,
922
1880
  registerAccent,
923
1881
  registerTheme,
1882
+ removeCard,
1883
+ removeColumn,
1884
+ resolveMediaTransport,
1885
+ resolveSkipSeconds,
924
1886
  rose,
1887
+ sanitizeHtml,
925
1888
  skeuomorphism,
926
1889
  teal,
1890
+ undoHistory,
927
1891
  violet
928
1892
  });
929
1893
  //# sourceMappingURL=index.cjs.map