@shadow-garden/bapbong-ui 0.9.0 → 0.10.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/dist/index.cjs +460 -89
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +455 -89
- package/dist/lib/menubar.d.ts +26 -0
- package/dist/lib/menubar.d.ts.map +1 -1
- package/dist/lib/page-setup.d.ts +55 -0
- package/dist/lib/page-setup.d.ts.map +1 -1
- package/dist/lib/section-chip.d.ts +27 -0
- package/dist/lib/section-chip.d.ts.map +1 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -899,10 +899,185 @@ var STYLE4 = `
|
|
|
899
899
|
.bb-menu-shortcut{flex:none;opacity:.5;font-size:12px;padding-left:24px}
|
|
900
900
|
.bb-menu-arrow{flex:none;opacity:.55;padding-left:12px}
|
|
901
901
|
.bb-menu-sep{height:1px;margin:4px 6px;background:var(--bb-ui-border,#e3e3e0)}
|
|
902
|
+
.bb-popup{position:fixed;top:auto;left:auto;margin-top:0;z-index:1200;font-family:var(--bb-ui-font,system-ui,-apple-system,sans-serif);color:var(--bb-ui-fg,#2c2c2a);font-size:13px}
|
|
902
903
|
.bb-menubar-v{flex-direction:column;align-items:stretch;gap:1px;border-bottom:none;padding:4px}
|
|
903
904
|
.bb-menubar-v .bb-menubar-title{text-align:left;width:100%}
|
|
904
905
|
.bb-menubar-v .bb-menu{top:auto;bottom:0;left:100%;margin-top:0;margin-left:4px}
|
|
905
906
|
`;
|
|
907
|
+
function makeRow(label, opts) {
|
|
908
|
+
const item = document.createElement("button");
|
|
909
|
+
item.type = "button";
|
|
910
|
+
item.className = "bb-menu-item" + (opts.hasSub ? " bb-has-sub" : "");
|
|
911
|
+
item.addEventListener("mousedown", (e) => e.preventDefault());
|
|
912
|
+
const check = document.createElement("span");
|
|
913
|
+
check.className = "bb-menu-check";
|
|
914
|
+
const text = document.createElement("span");
|
|
915
|
+
text.className = "bb-menu-label";
|
|
916
|
+
text.textContent = label;
|
|
917
|
+
item.append(check, text);
|
|
918
|
+
if (opts.shortcut) {
|
|
919
|
+
const sc = document.createElement("span");
|
|
920
|
+
sc.className = "bb-menu-shortcut";
|
|
921
|
+
sc.textContent = opts.shortcut;
|
|
922
|
+
item.appendChild(sc);
|
|
923
|
+
}
|
|
924
|
+
if (opts.hasSub) {
|
|
925
|
+
const arrow = document.createElement("span");
|
|
926
|
+
arrow.className = "bb-menu-arrow";
|
|
927
|
+
arrow.textContent = "\u203A";
|
|
928
|
+
item.appendChild(arrow);
|
|
929
|
+
}
|
|
930
|
+
return { item, check };
|
|
931
|
+
}
|
|
932
|
+
function buildMenuEntries(entries, container, ctx) {
|
|
933
|
+
for (const entry of entries) {
|
|
934
|
+
if (entry === "separator") {
|
|
935
|
+
const sep = document.createElement("div");
|
|
936
|
+
sep.className = "bb-menu-sep";
|
|
937
|
+
sep.setAttribute("role", "separator");
|
|
938
|
+
container.appendChild(sep);
|
|
939
|
+
} else if ("submenu" in entry || "widget" in entry) {
|
|
940
|
+
const wrap = document.createElement("div");
|
|
941
|
+
wrap.className = "bb-menu-sub";
|
|
942
|
+
const { item } = makeRow(entry.label, { hasSub: true });
|
|
943
|
+
item.setAttribute("aria-haspopup", "true");
|
|
944
|
+
const flyout = document.createElement("div");
|
|
945
|
+
flyout.className = "bb-menu bb-submenu";
|
|
946
|
+
flyout.setAttribute("role", "menu");
|
|
947
|
+
if ("widget" in entry) {
|
|
948
|
+
flyout.classList.add("bb-submenu-widget");
|
|
949
|
+
const build = () => flyout.replaceChildren(entry.widget(() => ctx.close()));
|
|
950
|
+
wrap.addEventListener("mouseenter", build);
|
|
951
|
+
wrap.addEventListener("focusin", build);
|
|
952
|
+
} else {
|
|
953
|
+
buildMenuEntries(entry.submenu, flyout, ctx);
|
|
954
|
+
}
|
|
955
|
+
wrap.append(item, flyout);
|
|
956
|
+
container.appendChild(wrap);
|
|
957
|
+
} else if ("command" in entry) {
|
|
958
|
+
const editor = ctx.editor;
|
|
959
|
+
const cmd = editor?.commands.get(entry.command);
|
|
960
|
+
if (!editor || !cmd) continue;
|
|
961
|
+
const { item, check } = makeRow(
|
|
962
|
+
entry.label ?? ctx.labels[entry.command] ?? entry.command,
|
|
963
|
+
{}
|
|
964
|
+
);
|
|
965
|
+
item.setAttribute("role", "menuitemcheckbox");
|
|
966
|
+
item.addEventListener("click", () => {
|
|
967
|
+
const s = ctx.state();
|
|
968
|
+
if (s)
|
|
969
|
+
editor.commands.get(entry.command)?.run(s, (tr) => editor.dispatch(tr));
|
|
970
|
+
ctx.close();
|
|
971
|
+
editor.focus();
|
|
972
|
+
});
|
|
973
|
+
ctx.check(check, (s) => cmd.isActive?.(s) ?? false);
|
|
974
|
+
if (cmd.isEnabled) ctx.enable(item, (s) => cmd.isEnabled(s));
|
|
975
|
+
container.appendChild(item);
|
|
976
|
+
} else {
|
|
977
|
+
const { item, check } = makeRow(entry.label, {
|
|
978
|
+
shortcut: entry.shortcut
|
|
979
|
+
});
|
|
980
|
+
item.setAttribute(
|
|
981
|
+
"role",
|
|
982
|
+
entry.isActive ? "menuitemcheckbox" : "menuitem"
|
|
983
|
+
);
|
|
984
|
+
item.addEventListener("click", () => {
|
|
985
|
+
entry.run();
|
|
986
|
+
ctx.close();
|
|
987
|
+
});
|
|
988
|
+
if (entry.isActive) ctx.check(check, () => entry.isActive());
|
|
989
|
+
if (entry.isEnabled) ctx.enable(item, () => entry.isEnabled());
|
|
990
|
+
container.appendChild(item);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
var currentPopup = null;
|
|
995
|
+
function closeCurrentPopup() {
|
|
996
|
+
if (currentPopup) {
|
|
997
|
+
const dispose = currentPopup;
|
|
998
|
+
currentPopup = null;
|
|
999
|
+
dispose();
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
function showPopup(content, at, onClose) {
|
|
1003
|
+
injectStyle("bb-ui-menubar-styles", STYLE4);
|
|
1004
|
+
closeCurrentPopup();
|
|
1005
|
+
const el2 = document.createElement("div");
|
|
1006
|
+
el2.className = "bb-menu bb-popup";
|
|
1007
|
+
el2.setAttribute("role", "menu");
|
|
1008
|
+
el2.appendChild(content);
|
|
1009
|
+
document.body.appendChild(el2);
|
|
1010
|
+
const place = () => {
|
|
1011
|
+
const r = el2.getBoundingClientRect();
|
|
1012
|
+
el2.style.left = `${Math.max(4, Math.min(at.x, window.innerWidth - r.width - 4))}px`;
|
|
1013
|
+
el2.style.top = `${Math.max(4, Math.min(at.y, window.innerHeight - r.height - 4))}px`;
|
|
1014
|
+
};
|
|
1015
|
+
place();
|
|
1016
|
+
let disposed = false;
|
|
1017
|
+
const dispose = () => {
|
|
1018
|
+
if (disposed) return;
|
|
1019
|
+
disposed = true;
|
|
1020
|
+
document.removeEventListener("pointerdown", onPointer, true);
|
|
1021
|
+
document.removeEventListener("keydown", onKey, true);
|
|
1022
|
+
document.removeEventListener("scroll", onScroll, true);
|
|
1023
|
+
el2.remove();
|
|
1024
|
+
onClose?.();
|
|
1025
|
+
};
|
|
1026
|
+
const close = () => {
|
|
1027
|
+
if (currentPopup === dispose) currentPopup = null;
|
|
1028
|
+
dispose();
|
|
1029
|
+
};
|
|
1030
|
+
const onPointer = (e) => {
|
|
1031
|
+
if (!el2.contains(e.target)) close();
|
|
1032
|
+
};
|
|
1033
|
+
const onKey = (e) => {
|
|
1034
|
+
if (e.key === "Escape") {
|
|
1035
|
+
e.preventDefault();
|
|
1036
|
+
close();
|
|
1037
|
+
}
|
|
1038
|
+
};
|
|
1039
|
+
const onScroll = (e) => {
|
|
1040
|
+
if (!el2.contains(e.target)) close();
|
|
1041
|
+
};
|
|
1042
|
+
document.addEventListener("pointerdown", onPointer, true);
|
|
1043
|
+
document.addEventListener("keydown", onKey, true);
|
|
1044
|
+
document.addEventListener("scroll", onScroll, true);
|
|
1045
|
+
currentPopup = dispose;
|
|
1046
|
+
return { close, el: el2 };
|
|
1047
|
+
}
|
|
1048
|
+
function showMenu(entries, at, options = {}) {
|
|
1049
|
+
const labels = { ...DEFAULT_LABELS, ...options.labels ?? {} };
|
|
1050
|
+
const stateOf = () => {
|
|
1051
|
+
try {
|
|
1052
|
+
return options.editor?.state ?? null;
|
|
1053
|
+
} catch {
|
|
1054
|
+
return null;
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
const container = document.createElement("div");
|
|
1058
|
+
let handle = null;
|
|
1059
|
+
const evalNow = (fn, fallback) => {
|
|
1060
|
+
try {
|
|
1061
|
+
return fn(stateOf());
|
|
1062
|
+
} catch {
|
|
1063
|
+
return fallback;
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
1066
|
+
buildMenuEntries(entries, container, {
|
|
1067
|
+
close: () => handle?.close(),
|
|
1068
|
+
labels,
|
|
1069
|
+
editor: options.editor,
|
|
1070
|
+
state: stateOf,
|
|
1071
|
+
check: (el2, active) => {
|
|
1072
|
+
el2.textContent = evalNow(active, false) ? "\u2713" : "";
|
|
1073
|
+
},
|
|
1074
|
+
enable: (el2, enabled) => {
|
|
1075
|
+
el2.disabled = !evalNow(enabled, true);
|
|
1076
|
+
}
|
|
1077
|
+
});
|
|
1078
|
+
handle = showPopup(container, at, options.onClose);
|
|
1079
|
+
return handle;
|
|
1080
|
+
}
|
|
906
1081
|
function defaultMenus(commands) {
|
|
907
1082
|
const names = [...commands].map((c) => c.name);
|
|
908
1083
|
const marks = ["bold", "italic", "underline", "strike"].filter(
|
|
@@ -949,94 +1124,15 @@ function mountMenubar(host, editor, options = {}) {
|
|
|
949
1124
|
if (focusFirst)
|
|
950
1125
|
p.dropdown.querySelector(".bb-menu-item")?.focus();
|
|
951
1126
|
};
|
|
952
|
-
const
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
const text = document.createElement("span");
|
|
960
|
-
text.className = "bb-menu-label";
|
|
961
|
-
text.textContent = label;
|
|
962
|
-
item.append(check, text);
|
|
963
|
-
if (opts.shortcut) {
|
|
964
|
-
const sc = document.createElement("span");
|
|
965
|
-
sc.className = "bb-menu-shortcut";
|
|
966
|
-
sc.textContent = opts.shortcut;
|
|
967
|
-
item.appendChild(sc);
|
|
968
|
-
}
|
|
969
|
-
if (opts.hasSub) {
|
|
970
|
-
const arrow = document.createElement("span");
|
|
971
|
-
arrow.className = "bb-menu-arrow";
|
|
972
|
-
arrow.textContent = "\u203A";
|
|
973
|
-
item.appendChild(arrow);
|
|
974
|
-
}
|
|
975
|
-
return { item, check };
|
|
976
|
-
};
|
|
977
|
-
const buildEntries = (entries, container) => {
|
|
978
|
-
for (const entry of entries) {
|
|
979
|
-
if (entry === "separator") {
|
|
980
|
-
const sep = document.createElement("div");
|
|
981
|
-
sep.className = "bb-menu-sep";
|
|
982
|
-
sep.setAttribute("role", "separator");
|
|
983
|
-
container.appendChild(sep);
|
|
984
|
-
} else if ("submenu" in entry || "widget" in entry) {
|
|
985
|
-
const wrap = document.createElement("div");
|
|
986
|
-
wrap.className = "bb-menu-sub";
|
|
987
|
-
const { item } = makeRow(entry.label, { hasSub: true });
|
|
988
|
-
item.setAttribute("aria-haspopup", "true");
|
|
989
|
-
const flyout = document.createElement("div");
|
|
990
|
-
flyout.className = "bb-menu bb-submenu";
|
|
991
|
-
flyout.setAttribute("role", "menu");
|
|
992
|
-
if ("widget" in entry) {
|
|
993
|
-
flyout.classList.add("bb-submenu-widget");
|
|
994
|
-
const build = () => flyout.replaceChildren(entry.widget(() => close()));
|
|
995
|
-
wrap.addEventListener("mouseenter", build);
|
|
996
|
-
wrap.addEventListener("focusin", build);
|
|
997
|
-
} else {
|
|
998
|
-
buildEntries(entry.submenu, flyout);
|
|
999
|
-
}
|
|
1000
|
-
wrap.append(item, flyout);
|
|
1001
|
-
container.appendChild(wrap);
|
|
1002
|
-
} else if ("command" in entry) {
|
|
1003
|
-
const cmd = editor.commands.get(entry.command);
|
|
1004
|
-
if (!cmd) continue;
|
|
1005
|
-
const { item, check } = makeRow(
|
|
1006
|
-
entry.label ?? labels[entry.command] ?? entry.command,
|
|
1007
|
-
{}
|
|
1008
|
-
);
|
|
1009
|
-
item.setAttribute("role", "menuitemcheckbox");
|
|
1010
|
-
item.addEventListener("click", () => {
|
|
1011
|
-
if (latest)
|
|
1012
|
-
editor.commands.get(entry.command)?.run(latest, (tr) => editor.dispatch(tr));
|
|
1013
|
-
close();
|
|
1014
|
-
editor.focus();
|
|
1015
|
-
});
|
|
1016
|
-
checks.push({ el: check, active: (s) => cmd.isActive?.(s) ?? false });
|
|
1017
|
-
if (cmd.isEnabled)
|
|
1018
|
-
enables.push({ el: item, enabled: (s) => cmd.isEnabled(s) });
|
|
1019
|
-
container.appendChild(item);
|
|
1020
|
-
} else {
|
|
1021
|
-
const { item, check } = makeRow(entry.label, {
|
|
1022
|
-
shortcut: entry.shortcut
|
|
1023
|
-
});
|
|
1024
|
-
item.setAttribute(
|
|
1025
|
-
"role",
|
|
1026
|
-
entry.isActive ? "menuitemcheckbox" : "menuitem"
|
|
1027
|
-
);
|
|
1028
|
-
item.addEventListener("click", () => {
|
|
1029
|
-
entry.run();
|
|
1030
|
-
close();
|
|
1031
|
-
});
|
|
1032
|
-
if (entry.isActive)
|
|
1033
|
-
checks.push({ el: check, active: () => entry.isActive() });
|
|
1034
|
-
if (entry.isEnabled)
|
|
1035
|
-
enables.push({ el: item, enabled: () => entry.isEnabled() });
|
|
1036
|
-
container.appendChild(item);
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1127
|
+
const buildCtx = {
|
|
1128
|
+
close: () => close(),
|
|
1129
|
+
labels,
|
|
1130
|
+
editor,
|
|
1131
|
+
state: () => latest,
|
|
1132
|
+
check: (el2, active) => checks.push({ el: el2, active }),
|
|
1133
|
+
enable: (el2, enabled) => enables.push({ el: el2, enabled })
|
|
1039
1134
|
};
|
|
1135
|
+
const buildEntries = (entries, container) => buildMenuEntries(entries, container, buildCtx);
|
|
1040
1136
|
menus.forEach((menu, idx) => {
|
|
1041
1137
|
const wrap = document.createElement("div");
|
|
1042
1138
|
wrap.className = "bb-menubar-menu";
|
|
@@ -1809,6 +1905,7 @@ function fmtCm(cm) {
|
|
|
1809
1905
|
}
|
|
1810
1906
|
var STYLE10 = `
|
|
1811
1907
|
.bb-ps{display:flex;flex-direction:column;min-width:250px;max-height:min(70vh,460px);overflow-y:auto}
|
|
1908
|
+
.bb-ps,.bb-ps *{box-sizing:border-box}
|
|
1812
1909
|
.bb-ps-row{display:flex;align-items:center;gap:11px;width:100%;padding:7px 10px;border:0;border-radius:6px;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer}
|
|
1813
1910
|
.bb-ps-row:hover,.bb-ps-row:focus{background:var(--bb-ui-hover,#f1efe8);outline:none}
|
|
1814
1911
|
.bb-ps-row[aria-checked="true"]{background:var(--bb-ui-active-bg,#e6f1fb)}
|
|
@@ -1825,6 +1922,16 @@ var STYLE10 = `
|
|
|
1825
1922
|
.bb-pd-input{flex:1 1 auto;min-width:0;width:100%;height:30px;padding:0 8px;border:1px solid var(--bb-ui-control-border,var(--bb-ui-border,#d8d6cf));border-radius:6px;background:var(--bb-ui-control-bg,var(--bb-ui-bg,#fff));color:inherit;font:inherit;font-size:13px}
|
|
1826
1923
|
.bb-pd-input:focus{outline:2px solid var(--bb-ui-active-border,#7fb2ec);outline-offset:-1px}
|
|
1827
1924
|
.bb-pd-actions{display:flex;justify-content:flex-end;gap:8px}
|
|
1925
|
+
.bb-pn-input{width:66px;height:24px;padding:0 6px;border:1px solid var(--bb-ui-control-border,var(--bb-ui-border,#d8d6cf));border-radius:5px;background:var(--bb-ui-control-bg,var(--bb-ui-bg,#fff));color:inherit;font:inherit;font-size:12px}
|
|
1926
|
+
.bb-pn-input:focus{outline:2px solid var(--bb-ui-active-border,#7fb2ec);outline-offset:-1px}
|
|
1927
|
+
.bb-pn-check{flex:none;width:15px;height:15px;display:inline-flex;align-items:center;justify-content:center;border:1.5px solid var(--bb-ui-border,#b4b2a9);border-radius:4px;background:var(--bb-ui-bg,#fff);color:#fff;font-size:10px;line-height:1}
|
|
1928
|
+
.bb-pn-check[data-on="true"]{background:var(--bb-ui-active-fg,#0c447c);border-color:var(--bb-ui-active-fg,#0c447c)}
|
|
1929
|
+
.bb-pn-body[data-disabled="true"]{opacity:.35;pointer-events:none}
|
|
1930
|
+
.bb-ps-group{padding:5px 10px 2px;font-size:11px;font-weight:600;letter-spacing:.4px;text-transform:uppercase;opacity:.55}
|
|
1931
|
+
.bb-ps-tiles{display:flex;gap:6px;padding:2px 6px 4px}
|
|
1932
|
+
.bb-ps-tile{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;padding:7px 0 5px;border:0;border-radius:6px;background:transparent;color:inherit;font:inherit;font-size:12px;font-weight:600;cursor:pointer}
|
|
1933
|
+
.bb-ps-tile:hover,.bb-ps-tile:focus{background:var(--bb-ui-hover,#f1efe8);outline:none}
|
|
1934
|
+
.bb-ps-tile[aria-checked="true"]{background:var(--bb-ui-active-bg,#e6f1fb)}
|
|
1828
1935
|
`;
|
|
1829
1936
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
1830
1937
|
function svgEl(name, attrs) {
|
|
@@ -2111,6 +2218,260 @@ function openMarginsDialog(options) {
|
|
|
2111
2218
|
top.input.focus();
|
|
2112
2219
|
top.input.select();
|
|
2113
2220
|
}
|
|
2221
|
+
function numberPreview(sample) {
|
|
2222
|
+
const svg = pagePreview(0.773);
|
|
2223
|
+
const t = svgEl("text", {
|
|
2224
|
+
x: 17,
|
|
2225
|
+
y: 25,
|
|
2226
|
+
"text-anchor": "middle",
|
|
2227
|
+
"font-size": 11,
|
|
2228
|
+
fill: "var(--bb-ui-fg,#2c2c2a)",
|
|
2229
|
+
"fill-opacity": 0.75
|
|
2230
|
+
});
|
|
2231
|
+
t.textContent = sample;
|
|
2232
|
+
svg.appendChild(t);
|
|
2233
|
+
return svg;
|
|
2234
|
+
}
|
|
2235
|
+
var PGNUM_FORMATS = [
|
|
2236
|
+
[void 0, "1, 2, 3, 4\u2026", "1"],
|
|
2237
|
+
["lowerRoman", "i, ii, iii, iv\u2026", "i"],
|
|
2238
|
+
["upperRoman", "I, II, III, IV\u2026", "I"],
|
|
2239
|
+
["lowerLetter", "a, b, c, d\u2026", "a"],
|
|
2240
|
+
["upperLetter", "A, B, C, D\u2026", "A"]
|
|
2241
|
+
];
|
|
2242
|
+
function pageNumberPicker(options) {
|
|
2243
|
+
injectStyle("bb-ui-pagesetup-styles", STYLE10);
|
|
2244
|
+
const root = document.createElement("div");
|
|
2245
|
+
root.className = "bb-ps";
|
|
2246
|
+
root.setAttribute("role", "menu");
|
|
2247
|
+
let body = root;
|
|
2248
|
+
if (options.onToggleShown) {
|
|
2249
|
+
const on = options.shown !== false;
|
|
2250
|
+
const row = document.createElement("button");
|
|
2251
|
+
row.type = "button";
|
|
2252
|
+
row.className = "bb-ps-row";
|
|
2253
|
+
row.setAttribute("role", "menuitemcheckbox");
|
|
2254
|
+
row.setAttribute("aria-checked", String(on));
|
|
2255
|
+
const box = document.createElement("span");
|
|
2256
|
+
box.className = "bb-pn-check";
|
|
2257
|
+
box.dataset["on"] = String(on);
|
|
2258
|
+
box.textContent = on ? "\u2713" : "";
|
|
2259
|
+
const name = document.createElement("span");
|
|
2260
|
+
name.className = "bb-ps-name";
|
|
2261
|
+
name.textContent = options.labels?.shown ?? "Show page numbers";
|
|
2262
|
+
row.append(box, name);
|
|
2263
|
+
row.addEventListener("mousedown", (e) => e.preventDefault());
|
|
2264
|
+
row.addEventListener("click", () => options.onToggleShown?.(!on));
|
|
2265
|
+
root.appendChild(row);
|
|
2266
|
+
const sep0 = document.createElement("div");
|
|
2267
|
+
sep0.className = "bb-ps-sep";
|
|
2268
|
+
root.appendChild(sep0);
|
|
2269
|
+
body = document.createElement("div");
|
|
2270
|
+
body.className = "bb-pn-body";
|
|
2271
|
+
if (!on) body.dataset["disabled"] = "true";
|
|
2272
|
+
root.appendChild(body);
|
|
2273
|
+
}
|
|
2274
|
+
const curFmt = options.fmt === "decimal" ? void 0 : options.fmt;
|
|
2275
|
+
const emit = (fmt, start) => {
|
|
2276
|
+
options.onPick(
|
|
2277
|
+
fmt == null && start == null ? null : {
|
|
2278
|
+
...fmt != null ? { fmt } : {},
|
|
2279
|
+
...start != null ? { start } : {}
|
|
2280
|
+
}
|
|
2281
|
+
);
|
|
2282
|
+
};
|
|
2283
|
+
for (const [key, label, sample] of PGNUM_FORMATS) {
|
|
2284
|
+
body.appendChild(
|
|
2285
|
+
presetRow(
|
|
2286
|
+
numberPreview(sample),
|
|
2287
|
+
label,
|
|
2288
|
+
captionLine(""),
|
|
2289
|
+
curFmt === key,
|
|
2290
|
+
() => emit(key, options.start)
|
|
2291
|
+
)
|
|
2292
|
+
);
|
|
2293
|
+
}
|
|
2294
|
+
const sep = document.createElement("div");
|
|
2295
|
+
sep.className = "bb-ps-sep";
|
|
2296
|
+
root.appendChild(sep);
|
|
2297
|
+
const restart = document.createElement("div");
|
|
2298
|
+
restart.className = "bb-ps-row";
|
|
2299
|
+
restart.setAttribute("role", "menuitemradio");
|
|
2300
|
+
restart.setAttribute("aria-checked", String(options.start != null));
|
|
2301
|
+
const restartName = document.createElement("span");
|
|
2302
|
+
restartName.className = "bb-ps-name";
|
|
2303
|
+
restartName.style.flex = "1 1 auto";
|
|
2304
|
+
restartName.textContent = options.labels?.restart ?? "Restart at";
|
|
2305
|
+
const input = document.createElement("input");
|
|
2306
|
+
input.type = "number";
|
|
2307
|
+
input.min = "0";
|
|
2308
|
+
input.step = "1";
|
|
2309
|
+
input.className = "bb-pn-input";
|
|
2310
|
+
input.value = String(options.start ?? 1);
|
|
2311
|
+
const readStart = () => {
|
|
2312
|
+
const v = Math.floor(Number(input.value));
|
|
2313
|
+
return Number.isFinite(v) && v >= 0 && input.value.trim() !== "" ? v : options.start ?? 1;
|
|
2314
|
+
};
|
|
2315
|
+
restart.append(restartName, input);
|
|
2316
|
+
restart.addEventListener("mousedown", (e) => {
|
|
2317
|
+
if (e.target !== input) e.preventDefault();
|
|
2318
|
+
});
|
|
2319
|
+
restart.addEventListener("click", (e) => {
|
|
2320
|
+
if (e.target !== input) emit(curFmt, readStart());
|
|
2321
|
+
});
|
|
2322
|
+
input.addEventListener("keydown", (e) => {
|
|
2323
|
+
if (e.key === "Enter") {
|
|
2324
|
+
e.preventDefault();
|
|
2325
|
+
emit(curFmt, readStart());
|
|
2326
|
+
}
|
|
2327
|
+
});
|
|
2328
|
+
input.addEventListener("wheel", (e) => e.preventDefault(), {
|
|
2329
|
+
passive: false
|
|
2330
|
+
});
|
|
2331
|
+
body.appendChild(restart);
|
|
2332
|
+
body.appendChild(
|
|
2333
|
+
presetRow(
|
|
2334
|
+
numberPreview("\u2192"),
|
|
2335
|
+
options.labels?.continueFrom ?? "Continue from previous section",
|
|
2336
|
+
captionLine(options.continueHint ?? ""),
|
|
2337
|
+
options.start == null,
|
|
2338
|
+
() => emit(curFmt, void 0)
|
|
2339
|
+
)
|
|
2340
|
+
);
|
|
2341
|
+
return root;
|
|
2342
|
+
}
|
|
2343
|
+
function sectionPaperPanel(options) {
|
|
2344
|
+
injectStyle("bb-ui-pagesetup-styles", STYLE10);
|
|
2345
|
+
const root = document.createElement("div");
|
|
2346
|
+
root.className = "bb-ps";
|
|
2347
|
+
root.setAttribute("role", "menu");
|
|
2348
|
+
const group = (text) => {
|
|
2349
|
+
const el2 = document.createElement("div");
|
|
2350
|
+
el2.className = "bb-ps-group";
|
|
2351
|
+
el2.textContent = text;
|
|
2352
|
+
return el2;
|
|
2353
|
+
};
|
|
2354
|
+
const sep = () => {
|
|
2355
|
+
const el2 = document.createElement("div");
|
|
2356
|
+
el2.className = "bb-ps-sep";
|
|
2357
|
+
return el2;
|
|
2358
|
+
};
|
|
2359
|
+
root.appendChild(group(options.labels?.orientation ?? "Orientation"));
|
|
2360
|
+
const tiles = document.createElement("div");
|
|
2361
|
+
tiles.className = "bb-ps-tiles";
|
|
2362
|
+
const landscapeNow = options.page.width > options.page.height;
|
|
2363
|
+
const short = Math.min(options.page.width, options.page.height);
|
|
2364
|
+
const long = Math.max(options.page.width, options.page.height);
|
|
2365
|
+
for (const [key, label, ratio] of [
|
|
2366
|
+
["portrait", "Portrait", short / long],
|
|
2367
|
+
["landscape", "Landscape", long / short]
|
|
2368
|
+
]) {
|
|
2369
|
+
const tile = document.createElement("button");
|
|
2370
|
+
tile.type = "button";
|
|
2371
|
+
tile.className = "bb-ps-tile";
|
|
2372
|
+
tile.setAttribute("role", "menuitemradio");
|
|
2373
|
+
tile.setAttribute(
|
|
2374
|
+
"aria-checked",
|
|
2375
|
+
String(landscapeNow === (key === "landscape"))
|
|
2376
|
+
);
|
|
2377
|
+
const icon = pagePreview(ratio);
|
|
2378
|
+
icon.setAttribute("style", "width:26px;height:32px");
|
|
2379
|
+
const name = document.createElement("span");
|
|
2380
|
+
name.textContent = label;
|
|
2381
|
+
tile.append(icon, name);
|
|
2382
|
+
tile.addEventListener("mousedown", (e) => e.preventDefault());
|
|
2383
|
+
tile.addEventListener("click", () => options.onOrientation(key));
|
|
2384
|
+
tiles.appendChild(tile);
|
|
2385
|
+
}
|
|
2386
|
+
root.appendChild(tiles);
|
|
2387
|
+
root.appendChild(sep());
|
|
2388
|
+
root.appendChild(group(options.labels?.pageSize ?? "Page size"));
|
|
2389
|
+
for (const item of options.items) {
|
|
2390
|
+
root.appendChild(
|
|
2391
|
+
presetRow(
|
|
2392
|
+
pagePreview(item.px[0] / item.px[1]),
|
|
2393
|
+
item.label,
|
|
2394
|
+
captionLine(`${fmtCm(item.cm[0])} x ${fmtCm(item.cm[1])}`),
|
|
2395
|
+
!!item.active,
|
|
2396
|
+
() => options.onPick(item.key)
|
|
2397
|
+
)
|
|
2398
|
+
);
|
|
2399
|
+
}
|
|
2400
|
+
root.appendChild(sep());
|
|
2401
|
+
root.appendChild(
|
|
2402
|
+
customRow(
|
|
2403
|
+
pagePreview(0.773),
|
|
2404
|
+
options.labels?.custom ?? "Custom page size",
|
|
2405
|
+
"Define custom page size",
|
|
2406
|
+
options.onCustom
|
|
2407
|
+
)
|
|
2408
|
+
);
|
|
2409
|
+
return root;
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2412
|
+
// packages/ui/src/lib/section-chip.ts
|
|
2413
|
+
var STYLE11 = `
|
|
2414
|
+
.bb-secchip{position:absolute;z-index:8;display:inline-flex;align-items:center;transform:translate(-50%,-50%);white-space:nowrap;background:var(--bb-ui-menu-bg,#fff);-webkit-backdrop-filter:var(--bb-ui-pop-filter,none);backdrop-filter:var(--bb-ui-pop-filter,none);border:1px solid var(--bb-ui-pop-border,var(--bb-ui-border,#e3e3e0));border-radius:10px;padding:1px 2px;box-shadow:0 2px 10px rgba(0,0,0,.12);font-family:var(--bb-ui-font,system-ui,-apple-system,sans-serif);font-size:11px;color:var(--bb-ui-fg,#2c2c2a)}
|
|
2415
|
+
.bb-secchip *{box-sizing:border-box}
|
|
2416
|
+
.bb-secchip-title{padding:0 7px;font-size:11px;font-weight:600;opacity:.8}
|
|
2417
|
+
.bb-secchip-seg{display:inline-flex;align-items:center;gap:4px;height:16px;padding:0 7px;border:0;border-radius:6px;background:transparent;color:inherit;font:inherit;font-size:11px;cursor:pointer}
|
|
2418
|
+
.bb-secchip-seg:hover,.bb-secchip-seg[aria-expanded="true"]{background:var(--bb-ui-hover,#f1efe8)}
|
|
2419
|
+
.bb-secchip-caret{font-size:8px;opacity:.55}
|
|
2420
|
+
.bb-secchip-seg[data-muted="true"] .bb-secchip-seglabel{font-style:italic;opacity:.55}
|
|
2421
|
+
.bb-secchip-div{flex:none;width:1px;height:11px;margin:0 2px;background:var(--bb-ui-border,#e3e3e0)}
|
|
2422
|
+
.bb-secchip-x{display:inline-flex;align-items:center;justify-content:center;width:20px;height:16px;padding:0;border:0;border-radius:6px;background:transparent;color:inherit;font:inherit;opacity:.65;cursor:pointer}
|
|
2423
|
+
.bb-secchip-x:hover{background:var(--bb-ui-hover,#f1efe8);opacity:1}
|
|
2424
|
+
`;
|
|
2425
|
+
function createSectionChip(options) {
|
|
2426
|
+
injectStyle("bb-ui-section-chip-styles", STYLE11);
|
|
2427
|
+
const el2 = document.createElement("div");
|
|
2428
|
+
el2.className = "bb-secchip";
|
|
2429
|
+
const title = document.createElement("span");
|
|
2430
|
+
title.className = "bb-secchip-title";
|
|
2431
|
+
title.textContent = options.title;
|
|
2432
|
+
const divider = () => {
|
|
2433
|
+
const d = document.createElement("span");
|
|
2434
|
+
d.className = "bb-secchip-div";
|
|
2435
|
+
return d;
|
|
2436
|
+
};
|
|
2437
|
+
const segment = (aria, onOpen) => {
|
|
2438
|
+
const btn = document.createElement("button");
|
|
2439
|
+
btn.type = "button";
|
|
2440
|
+
btn.className = "bb-secchip-seg";
|
|
2441
|
+
btn.setAttribute("aria-haspopup", "true");
|
|
2442
|
+
if (aria) btn.setAttribute("aria-label", aria);
|
|
2443
|
+
const label = document.createElement("span");
|
|
2444
|
+
label.className = "bb-secchip-seglabel";
|
|
2445
|
+
const caret = document.createElement("span");
|
|
2446
|
+
caret.className = "bb-secchip-caret";
|
|
2447
|
+
caret.textContent = "\u25BE";
|
|
2448
|
+
btn.append(label, caret);
|
|
2449
|
+
btn.addEventListener("mousedown", (e) => e.preventDefault());
|
|
2450
|
+
btn.addEventListener("click", () => onOpen(btn));
|
|
2451
|
+
return { btn, label };
|
|
2452
|
+
};
|
|
2453
|
+
const nums = segment(options.ariaPageNumbers, options.onPageNumbers);
|
|
2454
|
+
const paper = segment(options.ariaPaper, options.onPaper);
|
|
2455
|
+
const x = document.createElement("button");
|
|
2456
|
+
x.type = "button";
|
|
2457
|
+
x.className = "bb-secchip-x";
|
|
2458
|
+
x.setAttribute("aria-label", options.ariaDelete ?? "Remove section break");
|
|
2459
|
+
x.innerHTML = '<svg viewBox="0 0 16 16" width="9" height="9" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M3 3l10 10M13 3 3 13"/></svg>';
|
|
2460
|
+
x.addEventListener("mousedown", (e) => e.preventDefault());
|
|
2461
|
+
x.addEventListener("click", () => options.onDelete());
|
|
2462
|
+
el2.append(title, divider(), nums.btn, divider(), paper.btn, divider(), x);
|
|
2463
|
+
return {
|
|
2464
|
+
el: el2,
|
|
2465
|
+
update(data) {
|
|
2466
|
+
nums.label.textContent = data.pageNumbers;
|
|
2467
|
+
nums.btn.dataset["muted"] = String(!!data.pageNumbersMuted);
|
|
2468
|
+
paper.label.textContent = data.paper;
|
|
2469
|
+
},
|
|
2470
|
+
destroy() {
|
|
2471
|
+
el2.remove();
|
|
2472
|
+
}
|
|
2473
|
+
};
|
|
2474
|
+
}
|
|
2114
2475
|
|
|
2115
2476
|
// packages/ui/src/lib/font-dialog.ts
|
|
2116
2477
|
var twipsToPt = (tw) => tw / 20;
|
|
@@ -2119,7 +2480,7 @@ var halfToPt = (hp) => hp / 2;
|
|
|
2119
2480
|
var ptToHalf = (pt) => Math.round(pt * 2);
|
|
2120
2481
|
var SCALE_PRESETS = [200, 150, 100, 90, 80, 66, 50, 33];
|
|
2121
2482
|
var SUPERSUB_SCALE = 0.66;
|
|
2122
|
-
var
|
|
2483
|
+
var STYLE12 = `
|
|
2123
2484
|
.bb-fd{display:flex;flex-direction:column;gap:15px;min-width:396px;max-width:430px;color:var(--bb-ui-fg,#2c2c2a)}
|
|
2124
2485
|
.bb-fd *{box-sizing:border-box}
|
|
2125
2486
|
/* A segmented control, not a "tab joined to its pane": that pattern needs the
|
|
@@ -2201,7 +2562,7 @@ function openFontDialog({
|
|
|
2201
2562
|
sizes,
|
|
2202
2563
|
onApply
|
|
2203
2564
|
}) {
|
|
2204
|
-
injectStyle("bb-font-dialog",
|
|
2565
|
+
injectStyle("bb-font-dialog", STYLE12);
|
|
2205
2566
|
const dialog = new Dialog({ title: "Font", modal: true });
|
|
2206
2567
|
const root = el("div", "bb-fd");
|
|
2207
2568
|
const tabs = el("div", "bb-fd-tabs");
|
|
@@ -2446,6 +2807,7 @@ export {
|
|
|
2446
2807
|
cmToPx,
|
|
2447
2808
|
colorButton,
|
|
2448
2809
|
createFindDialog,
|
|
2810
|
+
createSectionChip,
|
|
2449
2811
|
defaultMenus,
|
|
2450
2812
|
defaultToolbarGroups,
|
|
2451
2813
|
marginPresetPicker,
|
|
@@ -2457,10 +2819,14 @@ export {
|
|
|
2457
2819
|
openMarginsDialog,
|
|
2458
2820
|
openPageSizeDialog,
|
|
2459
2821
|
orientationPicker,
|
|
2822
|
+
pageNumberPicker,
|
|
2460
2823
|
pageSizePicker,
|
|
2461
2824
|
promptDialog,
|
|
2462
2825
|
pxToCm,
|
|
2826
|
+
sectionPaperPanel,
|
|
2463
2827
|
showContextMenu,
|
|
2464
2828
|
showLinkPanel,
|
|
2829
|
+
showMenu,
|
|
2830
|
+
showPopup,
|
|
2465
2831
|
tableGridPicker
|
|
2466
2832
|
};
|
package/dist/lib/menubar.d.ts
CHANGED
|
@@ -42,6 +42,32 @@ export interface MenubarOptions {
|
|
|
42
42
|
export interface MenubarHandle {
|
|
43
43
|
destroy(): void;
|
|
44
44
|
}
|
|
45
|
+
export interface PopupHandle {
|
|
46
|
+
close(): void;
|
|
47
|
+
/** The popup root, for a host that needs to reposition or inspect it. */
|
|
48
|
+
el: HTMLElement;
|
|
49
|
+
}
|
|
50
|
+
/** Mount `el` as a fixed one-shot popup at viewport point `at` (clamped to
|
|
51
|
+
* the viewport), closing on outside pointerdown, Escape, or scroll. Only one
|
|
52
|
+
* popup is open at a time. */
|
|
53
|
+
export declare function showPopup(content: HTMLElement, at: {
|
|
54
|
+
x: number;
|
|
55
|
+
y: number;
|
|
56
|
+
}, onClose?: () => void): PopupHandle;
|
|
57
|
+
export interface ShowMenuOptions {
|
|
58
|
+
/** Resolves CommandEntry rows (state, dispatch, focus). Without it they are
|
|
59
|
+
* skipped; Action/Submenu/Widget entries need nothing. */
|
|
60
|
+
editor?: EditorHandle;
|
|
61
|
+
labels?: Record<string, string>;
|
|
62
|
+
onClose?: () => void;
|
|
63
|
+
}
|
|
64
|
+
/** A one-shot dropdown at viewport point `at`, rendered by the SAME builder as
|
|
65
|
+
* the menubar's menus — identical rows, checkmarks, submenu and widget
|
|
66
|
+
* flyouts. Check/enabled state is evaluated once, when the menu opens. */
|
|
67
|
+
export declare function showMenu(entries: MenuEntry[], at: {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
}, options?: ShowMenuOptions): PopupHandle;
|
|
45
71
|
/** Default menus: a "Format" menu of marks, a separator, then alignments —
|
|
46
72
|
* only the commands the registry actually has. */
|
|
47
73
|
export declare function defaultMenus(commands: Collection<Command>): Menu[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menubar.d.ts","sourceRoot":"","sources":["../../src/lib/menubar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AAEvB,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AACD,yBAAyB;AACzB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AACD,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,WAAW,CAAC;CAC5C;AACD,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,YAAY,GACZ,WAAW,GACX,YAAY,GACZ,WAAW,CAAC;AAEhB,uDAAuD;AACvD,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC;;+EAE2E;IAC3E,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,IAAI,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"menubar.d.ts","sourceRoot":"","sources":["../../src/lib/menubar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AAEvB,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AACD,yBAAyB;AACzB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AACD,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,WAAW,CAAC;CAC5C;AACD,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,YAAY,GACZ,WAAW,GACX,YAAY,GACZ,WAAW,CAAC;AAEhB,uDAAuD;AACvD,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC;;+EAE2E;IAC3E,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,IAAI,CAAC;CACjB;AAgLD,MAAM,WAAW,WAAW;IAC1B,KAAK,IAAI,IAAI,CAAC;IACd,yEAAyE;IACzE,EAAE,EAAE,WAAW,CAAC;CACjB;AAWD;;+BAE+B;AAC/B,wBAAgB,SAAS,CACvB,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5B,OAAO,CAAC,EAAE,MAAM,IAAI,GACnB,WAAW,CAkDb;AAED,MAAM,WAAW,eAAe;IAC9B;+DAC2D;IAC3D,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;2EAE2E;AAC3E,wBAAgB,QAAQ,CACtB,OAAO,EAAE,SAAS,EAAE,EACpB,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5B,OAAO,GAAE,eAAoB,GAC5B,WAAW,CAgCb;AAED;mDACmD;AACnD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAYlE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,cAAmB,GAC3B,aAAa,CAsIf"}
|