bun-docx 0.16.0 → 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.
Files changed (3) hide show
  1. package/README.md +27 -6
  2. package/dist/index.js +2366 -690
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4710,12 +4710,15 @@ var init_jsx = __esm(() => {
4710
4710
  "type",
4711
4711
  "tbl",
4712
4712
  "tblPr",
4713
+ "tblStyle",
4713
4714
  "tblPrChange",
4714
4715
  "tblGrid",
4715
4716
  "tblGridChange",
4716
4717
  "gridCol",
4717
4718
  "tr",
4718
4719
  "trPr",
4720
+ "trHeight",
4721
+ "tblHeader",
4719
4722
  "tc",
4720
4723
  "tcPr",
4721
4724
  "tcPrChange",
@@ -4761,6 +4764,7 @@ var init_jsx = __esm(() => {
4761
4764
  "tcW",
4762
4765
  "tblLayout",
4763
4766
  "vMerge",
4767
+ "vAlign",
4764
4768
  "gridSpan",
4765
4769
  "numbering",
4766
4770
  "num",
@@ -18088,9 +18092,25 @@ function previewTrackedChanges(document2, target, verb) {
18088
18092
  }
18089
18093
  function applyTrackedChanges(document2, target, verb) {
18090
18094
  const targets = resolveTargets(document2, target);
18091
- const records = targets.map((found) => recordFor(found, verb));
18092
- const affectedNotes = collectAffectedNotes(targets);
18093
- for (const found of [...targets].reverse()) {
18095
+ return applyResolvedTargets(document2, targets.map((found) => ({ found, verb })));
18096
+ }
18097
+ function applyTrackedDecisions(document2, accepts, rejects) {
18098
+ const acceptTargets = resolveTargets(document2, accepts).map((found) => ({
18099
+ found,
18100
+ verb: "accept"
18101
+ }));
18102
+ const rejectTargets = resolveTargets(document2, rejects).map((found) => ({
18103
+ found,
18104
+ verb: "reject"
18105
+ }));
18106
+ return applyResolvedTargets(document2, [...acceptTargets, ...rejectTargets]);
18107
+ }
18108
+ function applyResolvedTargets(document2, decisions) {
18109
+ const order = collectTrackedChanges(document2);
18110
+ const sorted = [...decisions].sort((left, right) => indexOfFound(order, left.found) - indexOfFound(order, right.found));
18111
+ const records = sorted.map(({ found, verb }) => recordFor(found, verb));
18112
+ const affectedNotes = collectAffectedNotes(sorted.map(({ found }) => found));
18113
+ for (const { found, verb } of [...sorted].reverse()) {
18094
18114
  if (verb === "accept")
18095
18115
  applyAccept(found);
18096
18116
  else
@@ -18100,6 +18120,9 @@ function applyTrackedChanges(document2, target, verb) {
18100
18120
  applyNotePairing(document2, affectedNotes);
18101
18121
  return records;
18102
18122
  }
18123
+ function indexOfFound(inventory, found) {
18124
+ return inventory.findIndex((change) => change.node === found.node);
18125
+ }
18103
18126
  function resolveTargets(document2, target) {
18104
18127
  const allChanges = collectTrackedChanges(document2);
18105
18128
  if (target === "all")
@@ -18602,6 +18625,9 @@ class TrackChanges {
18602
18625
  reject(target) {
18603
18626
  return applyTrackedChanges(this.document, target, "reject");
18604
18627
  }
18628
+ apply(accepts, rejects) {
18629
+ return applyTrackedDecisions(this.document, accepts, rejects);
18630
+ }
18605
18631
  applyInsertion(paragraph, authorFlag, allocator) {
18606
18632
  const mintMeta = this.metaMinter(authorFlag, allocator);
18607
18633
  paragraph.children = wrapContiguousTrackable(paragraph.children, (runs) => /* @__PURE__ */ jsxDEV(Ins, {
@@ -21585,6 +21611,481 @@ var init_body = __esm(() => {
21585
21611
  };
21586
21612
  });
21587
21613
 
21614
+ // src/core/ast/document/numbering.tsx
21615
+ function numFmtToFormat(numFmt) {
21616
+ return NUMFMT_TO_FORMAT[numFmt] ?? numFmt;
21617
+ }
21618
+
21619
+ class NumberingView {
21620
+ tree;
21621
+ constructor(tree = XmlNode2.parse(EMPTY_NUMBERING_XML)) {
21622
+ this.tree = tree;
21623
+ }
21624
+ static async fromPackage(pkg) {
21625
+ const tree = await pkg.readPart(NUMBERING_PART_NAME);
21626
+ return tree ? new NumberingView(tree) : undefined;
21627
+ }
21628
+ static fromXml(xml) {
21629
+ return xml ? new NumberingView(XmlNode2.parse(xml)) : undefined;
21630
+ }
21631
+ writeTo(pkg) {
21632
+ pkg.writeText(NUMBERING_PART_NAME, XmlNode2.serialize(this.tree));
21633
+ }
21634
+ static register(deps) {
21635
+ if (!deps.relationships.hasTarget("numbering.xml")) {
21636
+ deps.relationships.add(NUMBERING_RELATIONSHIP_TYPE, "numbering.xml");
21637
+ }
21638
+ deps.contentTypes.registerPart(NUMBERING_PART_NAME, NUMBERING_CONTENT_TYPE);
21639
+ return new NumberingView;
21640
+ }
21641
+ listNumIds() {
21642
+ const root = XmlNode2.findRoot(this.tree, "w:numbering");
21643
+ if (!root)
21644
+ return [];
21645
+ const out = [];
21646
+ for (const child2 of root.findChildren("w:num")) {
21647
+ const id = child2.getAttribute("w:numId");
21648
+ if (id)
21649
+ out.push(id);
21650
+ }
21651
+ return out;
21652
+ }
21653
+ listAbstractNumIds() {
21654
+ const root = XmlNode2.findRoot(this.tree, "w:numbering");
21655
+ if (!root)
21656
+ return [];
21657
+ const out = [];
21658
+ for (const child2 of root.findChildren("w:abstractNum")) {
21659
+ const id = child2.getAttribute("w:abstractNumId");
21660
+ if (id)
21661
+ out.push(id);
21662
+ }
21663
+ return out;
21664
+ }
21665
+ allocate(kind, start = 1) {
21666
+ const root = this.ensureNumberingRoot();
21667
+ const abstractNumId = this.ensureAbstractNum(root, kind);
21668
+ const numId = nextNumId(root);
21669
+ root.children.push(/* @__PURE__ */ jsxDEV(NumElement, {
21670
+ numId,
21671
+ abstractNumId,
21672
+ start
21673
+ }, undefined, false, undefined, this));
21674
+ return numId;
21675
+ }
21676
+ getLevelInfo(numId, level) {
21677
+ const num = this.findNum(numId);
21678
+ const lvlOverride = num ? this.findLvlOverride(num, level) : undefined;
21679
+ const override = lvlOverride?.findChild("w:lvl")?.findChild("w:numFmt")?.getAttribute("w:val");
21680
+ const abstractNum = this.resolveAbstractNum(numId);
21681
+ const abstractLvl = abstractNum ? findLevel(abstractNum, level) ?? findLevel(abstractNum, 0) : undefined;
21682
+ const format = override ?? abstractLvl?.findChild("w:numFmt")?.getAttribute("w:val");
21683
+ const startRaw = lvlOverride?.findChild("w:startOverride")?.getAttribute("w:val") ?? abstractLvl?.findChild("w:start")?.getAttribute("w:val");
21684
+ const startNum = Number(startRaw);
21685
+ const start = startRaw !== undefined && Number.isFinite(startNum) ? startNum : 1;
21686
+ return { format, override, start };
21687
+ }
21688
+ getFormat(numId, level) {
21689
+ return this.getLevelInfo(numId, level).format;
21690
+ }
21691
+ getBulletText(numId, level) {
21692
+ const fromOverride = this.overrideLevel(numId, level)?.findChild("w:lvlText")?.getAttribute("w:val");
21693
+ if (fromOverride !== undefined)
21694
+ return fromOverride;
21695
+ const abstractNum = this.resolveAbstractNum(numId);
21696
+ if (!abstractNum)
21697
+ return;
21698
+ const lvl = findLevel(abstractNum, level) ?? findLevel(abstractNum, 0);
21699
+ return lvl?.findChild("w:lvlText")?.getAttribute("w:val") ?? undefined;
21700
+ }
21701
+ getStart(numId, level) {
21702
+ return this.getLevelInfo(numId, level).start;
21703
+ }
21704
+ setStart(numId, level, start) {
21705
+ const num = this.findNum(numId);
21706
+ if (!num)
21707
+ return false;
21708
+ const lvlOverride = this.ensureLvlOverride(num, level);
21709
+ const existing = lvlOverride.findChild("w:startOverride");
21710
+ if (existing)
21711
+ existing.setAttribute("w:val", String(start));
21712
+ else
21713
+ insertLvlOverrideChildInOrder(lvlOverride, /* @__PURE__ */ jsxDEV(w.startOverride, {
21714
+ "w-val": String(start)
21715
+ }, undefined, false, undefined, this));
21716
+ return true;
21717
+ }
21718
+ setFormat(numId, level, numFmt) {
21719
+ const num = this.findNum(numId);
21720
+ if (!num)
21721
+ return false;
21722
+ const lvl = this.buildOverrideLevel(numId, level, numFmt);
21723
+ const lvlOverride = this.ensureLvlOverride(num, level);
21724
+ const existing = lvlOverride.findChild("w:lvl");
21725
+ if (existing) {
21726
+ lvlOverride.children.splice(lvlOverride.children.indexOf(existing), 1, lvl);
21727
+ } else {
21728
+ insertLvlOverrideChildInOrder(lvlOverride, lvl);
21729
+ }
21730
+ return true;
21731
+ }
21732
+ cloneListDefinition(srcNumId, start) {
21733
+ const root = this.ensureNumberingRoot();
21734
+ const src = this.findNum(srcNumId);
21735
+ const abstractNumId = src?.findChild("w:abstractNumId")?.getAttribute("w:val") ?? "0";
21736
+ const numId = nextNumId(root);
21737
+ const num = /* @__PURE__ */ jsxDEV(w.num, {
21738
+ "w-numId": String(numId)
21739
+ }, undefined, false, undefined, this);
21740
+ num.children.push(/* @__PURE__ */ jsxDEV(w.abstractNumId, {
21741
+ "w-val": abstractNumId
21742
+ }, undefined, false, undefined, this));
21743
+ if (src) {
21744
+ for (const lvlOverride of src.findChildren("w:lvlOverride")) {
21745
+ const lvl = lvlOverride.findChild("w:lvl");
21746
+ if (!lvl)
21747
+ continue;
21748
+ const carried = /* @__PURE__ */ jsxDEV(w.lvlOverride, {
21749
+ "w-ilvl": lvlOverride.getAttribute("w:ilvl") ?? "0"
21750
+ }, undefined, false, undefined, this);
21751
+ carried.children.push(lvl.clone());
21752
+ num.children.push(carried);
21753
+ }
21754
+ }
21755
+ root.children.push(num);
21756
+ this.setStart(String(numId), 0, start);
21757
+ return numId;
21758
+ }
21759
+ findNum(numId) {
21760
+ const root = XmlNode2.findRoot(this.tree, "w:numbering");
21761
+ return root?.findChildren("w:num").find((node) => node.getAttribute("w:numId") === numId);
21762
+ }
21763
+ findLvlOverride(num, level) {
21764
+ const target = String(level);
21765
+ return num.findChildren("w:lvlOverride").find((node) => node.getAttribute("w:ilvl") === target);
21766
+ }
21767
+ ensureLvlOverride(num, level) {
21768
+ const existing = this.findLvlOverride(num, level);
21769
+ if (existing)
21770
+ return existing;
21771
+ const created = /* @__PURE__ */ jsxDEV(w.lvlOverride, {
21772
+ "w-ilvl": String(level)
21773
+ }, undefined, false, undefined, this);
21774
+ const abstractIdx = num.children.findIndex((child2) => child2.tag === "w:abstractNumId");
21775
+ num.children.splice(abstractIdx + 1, 0, created);
21776
+ return created;
21777
+ }
21778
+ overrideLevel(numId, level) {
21779
+ const num = this.findNum(numId);
21780
+ const lvlOverride = num ? this.findLvlOverride(num, level) : undefined;
21781
+ return lvlOverride?.findChild("w:lvl");
21782
+ }
21783
+ buildOverrideLevel(numId, level, numFmt) {
21784
+ const abstractNum = this.resolveAbstractNum(numId);
21785
+ const base = abstractNum && (findLevel(abstractNum, level) ?? findLevel(abstractNum, 0));
21786
+ const lvl = base ? base.clone() : /* @__PURE__ */ jsxDEV(OrderedLevel, {
21787
+ ilvl: level,
21788
+ text: `%${level + 1}.`,
21789
+ fmt: numFmt
21790
+ }, undefined, false, undefined, this);
21791
+ lvl.setAttribute("w:ilvl", String(level));
21792
+ lvl.findChild("w:numFmt")?.setAttribute("w:val", numFmt);
21793
+ lvl.children = lvl.children.filter((child2) => child2.tag !== "w:start");
21794
+ return lvl;
21795
+ }
21796
+ resolveAbstractNum(numId) {
21797
+ const root = XmlNode2.findRoot(this.tree, "w:numbering");
21798
+ if (!root)
21799
+ return;
21800
+ const num = root.findChildren("w:num").find((node) => node.getAttribute("w:numId") === numId);
21801
+ if (!num)
21802
+ return;
21803
+ const abstractNumId = num.findChild("w:abstractNumId")?.getAttribute("w:val");
21804
+ if (!abstractNumId)
21805
+ return;
21806
+ return root.findChildren("w:abstractNum").find((node) => node.getAttribute("w:abstractNumId") === abstractNumId);
21807
+ }
21808
+ ensureNumberingRoot() {
21809
+ const root = XmlNode2.findRoot(this.tree, "w:numbering");
21810
+ if (!root) {
21811
+ throw new Error("expected <w:numbering> root in numbering tree");
21812
+ }
21813
+ return root;
21814
+ }
21815
+ ensureAbstractNum(root, kind) {
21816
+ const targetFormat = kind === "bullet" ? "bullet" : "decimal";
21817
+ for (const child2 of root.findChildren("w:abstractNum")) {
21818
+ const lvl0 = findLevel(child2, 0);
21819
+ const numFmt = lvl0?.findChild("w:numFmt");
21820
+ if (numFmt?.getAttribute("w:val") === targetFormat) {
21821
+ const id = child2.getAttribute("w:abstractNumId");
21822
+ if (id)
21823
+ return Number(id);
21824
+ }
21825
+ }
21826
+ const newId = nextAbstractNumId(root);
21827
+ const def = /* @__PURE__ */ jsxDEV(AbstractNum, {
21828
+ kind,
21829
+ id: newId
21830
+ }, undefined, false, undefined, this);
21831
+ const firstNumIdx = root.children.findIndex((child2) => child2.tag === "w:num");
21832
+ if (firstNumIdx === -1)
21833
+ root.children.push(def);
21834
+ else
21835
+ root.children.splice(firstNumIdx, 0, def);
21836
+ return newId;
21837
+ }
21838
+ }
21839
+ function nextAbstractNumId(root) {
21840
+ let max = -1;
21841
+ for (const child2 of root.findChildren("w:abstractNum")) {
21842
+ const id = child2.getAttribute("w:abstractNumId");
21843
+ if (id) {
21844
+ const numeric = Number(id);
21845
+ if (Number.isFinite(numeric) && numeric > max)
21846
+ max = numeric;
21847
+ }
21848
+ }
21849
+ return max + 1;
21850
+ }
21851
+ function nextNumId(root) {
21852
+ let max = 0;
21853
+ for (const child2 of root.findChildren("w:num")) {
21854
+ const id = child2.getAttribute("w:numId");
21855
+ if (id) {
21856
+ const numeric = Number(id);
21857
+ if (Number.isFinite(numeric) && numeric > max)
21858
+ max = numeric;
21859
+ }
21860
+ }
21861
+ return max + 1;
21862
+ }
21863
+ function insertLvlOverrideChildInOrder(lvlOverride, child2) {
21864
+ const order = ["w:startOverride", "w:lvl"];
21865
+ const rank = order.indexOf(child2.tag);
21866
+ const at = lvlOverride.children.findIndex((existing) => !existing.isText && order.indexOf(existing.tag) > rank);
21867
+ if (at < 0)
21868
+ lvlOverride.children.push(child2);
21869
+ else
21870
+ lvlOverride.children.splice(at, 0, child2);
21871
+ }
21872
+ function findLevel(abstractNum, ilvl) {
21873
+ const target = String(ilvl);
21874
+ return abstractNum.findChildren("w:lvl").find((lvl) => lvl.getAttribute("w:ilvl") === target);
21875
+ }
21876
+ function NumElement({
21877
+ numId,
21878
+ abstractNumId,
21879
+ start
21880
+ }) {
21881
+ return /* @__PURE__ */ jsxDEV(w.num, {
21882
+ "w-numId": String(numId),
21883
+ children: [
21884
+ /* @__PURE__ */ jsxDEV(w.abstractNumId, {
21885
+ "w-val": String(abstractNumId)
21886
+ }, undefined, false, undefined, this),
21887
+ /* @__PURE__ */ jsxDEV(w.lvlOverride, {
21888
+ "w-ilvl": "0",
21889
+ children: /* @__PURE__ */ jsxDEV(w.startOverride, {
21890
+ "w-val": String(start)
21891
+ }, undefined, false, undefined, this)
21892
+ }, undefined, false, undefined, this)
21893
+ ]
21894
+ }, undefined, true, undefined, this);
21895
+ }
21896
+ function AbstractNum({
21897
+ kind,
21898
+ id
21899
+ }) {
21900
+ return kind === "bullet" ? /* @__PURE__ */ jsxDEV(BulletAbstractNum, {
21901
+ id
21902
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV(OrderedAbstractNum, {
21903
+ id
21904
+ }, undefined, false, undefined, this);
21905
+ }
21906
+ function BulletAbstractNum({ id }) {
21907
+ return /* @__PURE__ */ jsxDEV(w.abstractNum, {
21908
+ "w-abstractNumId": String(id),
21909
+ children: [
21910
+ /* @__PURE__ */ jsxDEV(w.multiLevelType, {
21911
+ "w-val": "hybridMultilevel"
21912
+ }, undefined, false, undefined, this),
21913
+ /* @__PURE__ */ jsxDEV(BulletLevel, {
21914
+ ilvl: 0,
21915
+ glyph: "\u2022"
21916
+ }, undefined, false, undefined, this),
21917
+ /* @__PURE__ */ jsxDEV(BulletLevel, {
21918
+ ilvl: 1,
21919
+ glyph: "\u25E6"
21920
+ }, undefined, false, undefined, this),
21921
+ /* @__PURE__ */ jsxDEV(BulletLevel, {
21922
+ ilvl: 2,
21923
+ glyph: "\u25AA"
21924
+ }, undefined, false, undefined, this),
21925
+ /* @__PURE__ */ jsxDEV(BulletLevel, {
21926
+ ilvl: 3,
21927
+ glyph: "\u2022"
21928
+ }, undefined, false, undefined, this),
21929
+ /* @__PURE__ */ jsxDEV(BulletLevel, {
21930
+ ilvl: 4,
21931
+ glyph: "\u25E6"
21932
+ }, undefined, false, undefined, this),
21933
+ /* @__PURE__ */ jsxDEV(BulletLevel, {
21934
+ ilvl: 5,
21935
+ glyph: "\u25AA"
21936
+ }, undefined, false, undefined, this),
21937
+ /* @__PURE__ */ jsxDEV(BulletLevel, {
21938
+ ilvl: 6,
21939
+ glyph: "\u2022"
21940
+ }, undefined, false, undefined, this),
21941
+ /* @__PURE__ */ jsxDEV(BulletLevel, {
21942
+ ilvl: 7,
21943
+ glyph: "\u25E6"
21944
+ }, undefined, false, undefined, this),
21945
+ /* @__PURE__ */ jsxDEV(BulletLevel, {
21946
+ ilvl: 8,
21947
+ glyph: "\u25AA"
21948
+ }, undefined, false, undefined, this)
21949
+ ]
21950
+ }, undefined, true, undefined, this);
21951
+ }
21952
+ function BulletLevel({
21953
+ ilvl,
21954
+ glyph
21955
+ }) {
21956
+ return /* @__PURE__ */ jsxDEV(w.lvl, {
21957
+ "w-ilvl": String(ilvl),
21958
+ children: [
21959
+ /* @__PURE__ */ jsxDEV(w.start, {
21960
+ "w-val": "1"
21961
+ }, undefined, false, undefined, this),
21962
+ /* @__PURE__ */ jsxDEV(w.numFmt, {
21963
+ "w-val": "bullet"
21964
+ }, undefined, false, undefined, this),
21965
+ /* @__PURE__ */ jsxDEV(w.lvlText, {
21966
+ "w-val": glyph
21967
+ }, undefined, false, undefined, this),
21968
+ /* @__PURE__ */ jsxDEV(w.lvlJc, {
21969
+ "w-val": "left"
21970
+ }, undefined, false, undefined, this),
21971
+ /* @__PURE__ */ jsxDEV(w.pPr, {
21972
+ children: /* @__PURE__ */ jsxDEV(w.ind, {
21973
+ "w-left": String(levelIndent(ilvl)),
21974
+ "w-hanging": HANGING
21975
+ }, undefined, false, undefined, this)
21976
+ }, undefined, false, undefined, this)
21977
+ ]
21978
+ }, undefined, true, undefined, this);
21979
+ }
21980
+ function OrderedAbstractNum({ id }) {
21981
+ return /* @__PURE__ */ jsxDEV(w.abstractNum, {
21982
+ "w-abstractNumId": String(id),
21983
+ children: [
21984
+ /* @__PURE__ */ jsxDEV(w.multiLevelType, {
21985
+ "w-val": "hybridMultilevel"
21986
+ }, undefined, false, undefined, this),
21987
+ /* @__PURE__ */ jsxDEV(OrderedLevel, {
21988
+ ilvl: 0,
21989
+ text: "%1.",
21990
+ fmt: "decimal"
21991
+ }, undefined, false, undefined, this),
21992
+ /* @__PURE__ */ jsxDEV(OrderedLevel, {
21993
+ ilvl: 1,
21994
+ text: "%2.",
21995
+ fmt: "lowerLetter"
21996
+ }, undefined, false, undefined, this),
21997
+ /* @__PURE__ */ jsxDEV(OrderedLevel, {
21998
+ ilvl: 2,
21999
+ text: "%3.",
22000
+ fmt: "lowerRoman"
22001
+ }, undefined, false, undefined, this),
22002
+ /* @__PURE__ */ jsxDEV(OrderedLevel, {
22003
+ ilvl: 3,
22004
+ text: "%4.",
22005
+ fmt: "decimal"
22006
+ }, undefined, false, undefined, this),
22007
+ /* @__PURE__ */ jsxDEV(OrderedLevel, {
22008
+ ilvl: 4,
22009
+ text: "%5.",
22010
+ fmt: "lowerLetter"
22011
+ }, undefined, false, undefined, this),
22012
+ /* @__PURE__ */ jsxDEV(OrderedLevel, {
22013
+ ilvl: 5,
22014
+ text: "%6.",
22015
+ fmt: "lowerRoman"
22016
+ }, undefined, false, undefined, this),
22017
+ /* @__PURE__ */ jsxDEV(OrderedLevel, {
22018
+ ilvl: 6,
22019
+ text: "%7.",
22020
+ fmt: "decimal"
22021
+ }, undefined, false, undefined, this),
22022
+ /* @__PURE__ */ jsxDEV(OrderedLevel, {
22023
+ ilvl: 7,
22024
+ text: "%8.",
22025
+ fmt: "lowerLetter"
22026
+ }, undefined, false, undefined, this),
22027
+ /* @__PURE__ */ jsxDEV(OrderedLevel, {
22028
+ ilvl: 8,
22029
+ text: "%9.",
22030
+ fmt: "lowerRoman"
22031
+ }, undefined, false, undefined, this)
22032
+ ]
22033
+ }, undefined, true, undefined, this);
22034
+ }
22035
+ function OrderedLevel({
22036
+ ilvl,
22037
+ text: text2,
22038
+ fmt
22039
+ }) {
22040
+ return /* @__PURE__ */ jsxDEV(w.lvl, {
22041
+ "w-ilvl": String(ilvl),
22042
+ children: [
22043
+ /* @__PURE__ */ jsxDEV(w.start, {
22044
+ "w-val": "1"
22045
+ }, undefined, false, undefined, this),
22046
+ /* @__PURE__ */ jsxDEV(w.numFmt, {
22047
+ "w-val": fmt
22048
+ }, undefined, false, undefined, this),
22049
+ /* @__PURE__ */ jsxDEV(w.lvlText, {
22050
+ "w-val": text2
22051
+ }, undefined, false, undefined, this),
22052
+ /* @__PURE__ */ jsxDEV(w.lvlJc, {
22053
+ "w-val": "left"
22054
+ }, undefined, false, undefined, this),
22055
+ /* @__PURE__ */ jsxDEV(w.pPr, {
22056
+ children: /* @__PURE__ */ jsxDEV(w.ind, {
22057
+ "w-left": String(levelIndent(ilvl)),
22058
+ "w-hanging": HANGING
22059
+ }, undefined, false, undefined, this)
22060
+ }, undefined, false, undefined, this)
22061
+ ]
22062
+ }, undefined, true, undefined, this);
22063
+ }
22064
+ function levelIndent(ilvl) {
22065
+ return (ilvl + 1) * 300;
22066
+ }
22067
+ var FORMAT_TO_NUMFMT, NUMFMT_TO_FORMAT, NUMBERING_PART_NAME = "word/numbering.xml", NUMBERING_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering", NUMBERING_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml", EMPTY_NUMBERING_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
22068
+ <w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"/>`, HANGING = "240";
22069
+ var init_numbering = __esm(() => {
22070
+ init_jsx();
22071
+ init_parser();
22072
+ init_jsx_dev_runtime();
22073
+ FORMAT_TO_NUMFMT = {
22074
+ decimal: "decimal",
22075
+ "lower-alpha": "lowerLetter",
22076
+ "upper-alpha": "upperLetter",
22077
+ "lower-roman": "lowerRoman",
22078
+ "upper-roman": "upperRoman"
22079
+ };
22080
+ NUMFMT_TO_FORMAT = {
22081
+ decimal: "decimal",
22082
+ lowerLetter: "lower-alpha",
22083
+ upperLetter: "upper-alpha",
22084
+ lowerRoman: "lower-roman",
22085
+ upperRoman: "upper-roman"
22086
+ };
22087
+ });
22088
+
21588
22089
  // src/core/ast/sym.ts
21589
22090
  function decodeSym(font, charHex) {
21590
22091
  const codepoint = Number.parseInt(charHex, 16);
@@ -22358,9 +22859,13 @@ function applyParagraphProperties(document2, paragraph, paragraphProperties) {
22358
22859
  level,
22359
22860
  numId: id
22360
22861
  };
22361
- const format = id ? document2.numbering?.getFormat(id, level) : undefined;
22362
- if (format !== undefined && format !== "bullet" && format !== "none") {
22862
+ const info = id ? document2.numbering?.getLevelInfo(id, level) : undefined;
22863
+ if (info?.format !== undefined && info.format !== "bullet" && info.format !== "none") {
22363
22864
  list.ordered = true;
22865
+ if (info.override !== undefined)
22866
+ list.format = numFmtToFormat(info.override);
22867
+ if (info.start !== 1)
22868
+ list.start = info.start;
22364
22869
  }
22365
22870
  paragraph.list = list;
22366
22871
  }
@@ -22670,6 +23175,7 @@ function readTable(document2, node, id, state) {
22670
23175
  const width = readTableWidth(node);
22671
23176
  const borders = readTableBorders(node);
22672
23177
  const style = readTableStyle(node);
23178
+ const align = readTableAlign(node);
22673
23179
  readTablePropertyRevision(document2, node, id, state);
22674
23180
  readGridRevision(document2, node, id, state);
22675
23181
  const rows = [];
@@ -22689,6 +23195,11 @@ function readTable(document2, node, id, state) {
22689
23195
  const row = { cells };
22690
23196
  if (rowChange)
22691
23197
  row.trackedChange = rowChange;
23198
+ const height = readRowHeight(child2);
23199
+ if (height)
23200
+ row.height = height;
23201
+ if (readRepeatHeader(child2))
23202
+ row.repeatHeader = true;
22692
23203
  rows.push(row);
22693
23204
  rowIndex++;
22694
23205
  }
@@ -22699,8 +23210,35 @@ function readTable(document2, node, id, state) {
22699
23210
  table.borders = borders;
22700
23211
  if (style)
22701
23212
  table.style = style;
23213
+ if (align)
23214
+ table.align = align;
22702
23215
  return table;
22703
23216
  }
23217
+ function readTableAlign(table) {
23218
+ const val = table.findChild("w:tblPr")?.findChild("w:jc")?.getAttribute("w:val");
23219
+ return val === "center" || val === "right" ? val : undefined;
23220
+ }
23221
+ function readRowHeight(row) {
23222
+ const trHeight = row.findChild("w:trPr")?.findChild("w:trHeight");
23223
+ if (!trHeight)
23224
+ return;
23225
+ const raw = trHeight.getAttribute("w:val");
23226
+ const value = raw ? Number(raw) : NaN;
23227
+ if (!Number.isFinite(value))
23228
+ return;
23229
+ const rule = trHeight.getAttribute("w:hRule");
23230
+ return {
23231
+ value,
23232
+ rule: rule === "exact" || rule === "auto" ? rule : "atLeast"
23233
+ };
23234
+ }
23235
+ function readRepeatHeader(row) {
23236
+ const marker = row.findChild("w:trPr")?.findChild("w:tblHeader");
23237
+ if (!marker)
23238
+ return false;
23239
+ const val = marker.getAttribute("w:val");
23240
+ return val !== "false" && val !== "0" && val !== "off";
23241
+ }
22704
23242
  function readTableStyle(table) {
22705
23243
  return table.findChild("w:tblPr")?.findChild("w:tblStyle")?.getAttribute("w:val") ?? undefined;
22706
23244
  }
@@ -22832,8 +23370,39 @@ function readTableCell(document2, cellNode, rowChildren, tableId, rowIndex, colu
22832
23370
  if (fill && fill.toLowerCase() !== "auto")
22833
23371
  cell.shading = fill.toUpperCase();
22834
23372
  }
23373
+ const vAlignNode = tcPr.findChild("w:vAlign");
23374
+ if (vAlignNode) {
23375
+ const raw = vAlignNode.getAttribute("w:val");
23376
+ if (raw === "center" || raw === "bottom")
23377
+ cell.vAlign = raw;
23378
+ }
23379
+ const cellBorders = readCellBorders(tcPr);
23380
+ if (cellBorders)
23381
+ cell.borders = cellBorders;
22835
23382
  return cell;
22836
23383
  }
23384
+ function readCellBorders(tcPr) {
23385
+ const tcBorders = tcPr.findChild("w:tcBorders");
23386
+ if (!tcBorders)
23387
+ return;
23388
+ const byStyle = new Map;
23389
+ for (const edge of CELL_BORDER_EDGES) {
23390
+ const val = tcBorders.findChild(`w:${edge}`)?.getAttribute("w:val");
23391
+ if (!val || val === "nil" || val === "none")
23392
+ continue;
23393
+ const sides = byStyle.get(val) ?? [];
23394
+ sides.push(edge);
23395
+ byStyle.set(val, sides);
23396
+ }
23397
+ if (byStyle.size === 0)
23398
+ return;
23399
+ const parts = [];
23400
+ for (const [style, sides] of byStyle) {
23401
+ const label = sides.length === CELL_BORDER_EDGES.length ? "all" : sides.join(",");
23402
+ parts.push(`${label}:${style}`);
23403
+ }
23404
+ return parts.join(" ");
23405
+ }
22837
23406
  function readCellPropertyRevision(document2, cell, tableId, state) {
22838
23407
  const tcPr = cell.findChild("w:tcPr");
22839
23408
  const change = tcPr?.findChild("w:tcPrChange");
@@ -22869,7 +23438,7 @@ function readCellBlocks(document2, cell, tableId, rowIndex, columnIndex, state)
22869
23438
  }
22870
23439
  return blocks;
22871
23440
  }
22872
- var TRACKED_CHANGE_KIND_BY_TAG, WRAP_TAGS, TABLE_BORDER_EDGES;
23441
+ var TRACKED_CHANGE_KIND_BY_TAG, WRAP_TAGS, TABLE_BORDER_EDGES, CELL_BORDER_EDGES;
22873
23442
  var init_read2 = __esm(() => {
22874
23443
  init_blocks();
22875
23444
  init_equation();
@@ -22880,6 +23449,7 @@ var init_read2 = __esm(() => {
22880
23449
  init_sections();
22881
23450
  init_task_list();
22882
23451
  init_body();
23452
+ init_numbering();
22883
23453
  init_sym();
22884
23454
  TRACKED_CHANGE_KIND_BY_TAG = {
22885
23455
  "w:ins": "ins",
@@ -22902,6 +23472,14 @@ var init_read2 = __esm(() => {
22902
23472
  "w:insideH",
22903
23473
  "w:insideV"
22904
23474
  ];
23475
+ CELL_BORDER_EDGES = [
23476
+ "top",
23477
+ "left",
23478
+ "bottom",
23479
+ "right",
23480
+ "insideH",
23481
+ "insideV"
23482
+ ];
22905
23483
  });
22906
23484
 
22907
23485
  // src/core/ast/document/comments.tsx
@@ -23709,348 +24287,6 @@ var init_notes2 = __esm(() => {
23709
24287
  init_relationships();
23710
24288
  });
23711
24289
 
23712
- // src/core/ast/document/numbering.tsx
23713
- class NumberingView {
23714
- tree;
23715
- constructor(tree = XmlNode2.parse(EMPTY_NUMBERING_XML)) {
23716
- this.tree = tree;
23717
- }
23718
- static async fromPackage(pkg) {
23719
- const tree = await pkg.readPart(NUMBERING_PART_NAME);
23720
- return tree ? new NumberingView(tree) : undefined;
23721
- }
23722
- static fromXml(xml) {
23723
- return xml ? new NumberingView(XmlNode2.parse(xml)) : undefined;
23724
- }
23725
- writeTo(pkg) {
23726
- pkg.writeText(NUMBERING_PART_NAME, XmlNode2.serialize(this.tree));
23727
- }
23728
- static register(deps) {
23729
- if (!deps.relationships.hasTarget("numbering.xml")) {
23730
- deps.relationships.add(NUMBERING_RELATIONSHIP_TYPE, "numbering.xml");
23731
- }
23732
- deps.contentTypes.registerPart(NUMBERING_PART_NAME, NUMBERING_CONTENT_TYPE);
23733
- return new NumberingView;
23734
- }
23735
- listNumIds() {
23736
- const root = XmlNode2.findRoot(this.tree, "w:numbering");
23737
- if (!root)
23738
- return [];
23739
- const out = [];
23740
- for (const child2 of root.findChildren("w:num")) {
23741
- const id = child2.getAttribute("w:numId");
23742
- if (id)
23743
- out.push(id);
23744
- }
23745
- return out;
23746
- }
23747
- listAbstractNumIds() {
23748
- const root = XmlNode2.findRoot(this.tree, "w:numbering");
23749
- if (!root)
23750
- return [];
23751
- const out = [];
23752
- for (const child2 of root.findChildren("w:abstractNum")) {
23753
- const id = child2.getAttribute("w:abstractNumId");
23754
- if (id)
23755
- out.push(id);
23756
- }
23757
- return out;
23758
- }
23759
- allocate(kind, start = 1) {
23760
- const root = this.ensureNumberingRoot();
23761
- const abstractNumId = this.ensureAbstractNum(root, kind);
23762
- const numId = nextNumId(root);
23763
- root.children.push(/* @__PURE__ */ jsxDEV(NumElement, {
23764
- numId,
23765
- abstractNumId,
23766
- start
23767
- }, undefined, false, undefined, this));
23768
- return numId;
23769
- }
23770
- getFormat(numId, level) {
23771
- const abstractNum = this.resolveAbstractNum(numId);
23772
- if (!abstractNum)
23773
- return;
23774
- const lvl = findLevel(abstractNum, level) ?? findLevel(abstractNum, 0);
23775
- return lvl?.findChild("w:numFmt")?.getAttribute("w:val") ?? undefined;
23776
- }
23777
- getBulletText(numId, level) {
23778
- const abstractNum = this.resolveAbstractNum(numId);
23779
- if (!abstractNum)
23780
- return;
23781
- const lvl = findLevel(abstractNum, level) ?? findLevel(abstractNum, 0);
23782
- return lvl?.findChild("w:lvlText")?.getAttribute("w:val") ?? undefined;
23783
- }
23784
- resolveAbstractNum(numId) {
23785
- const root = XmlNode2.findRoot(this.tree, "w:numbering");
23786
- if (!root)
23787
- return;
23788
- const num = root.findChildren("w:num").find((node) => node.getAttribute("w:numId") === numId);
23789
- if (!num)
23790
- return;
23791
- const abstractNumId = num.findChild("w:abstractNumId")?.getAttribute("w:val");
23792
- if (!abstractNumId)
23793
- return;
23794
- return root.findChildren("w:abstractNum").find((node) => node.getAttribute("w:abstractNumId") === abstractNumId);
23795
- }
23796
- ensureNumberingRoot() {
23797
- const root = XmlNode2.findRoot(this.tree, "w:numbering");
23798
- if (!root) {
23799
- throw new Error("expected <w:numbering> root in numbering tree");
23800
- }
23801
- return root;
23802
- }
23803
- ensureAbstractNum(root, kind) {
23804
- const targetFormat = kind === "bullet" ? "bullet" : "decimal";
23805
- for (const child2 of root.findChildren("w:abstractNum")) {
23806
- const lvl0 = findLevel(child2, 0);
23807
- const numFmt = lvl0?.findChild("w:numFmt");
23808
- if (numFmt?.getAttribute("w:val") === targetFormat) {
23809
- const id = child2.getAttribute("w:abstractNumId");
23810
- if (id)
23811
- return Number(id);
23812
- }
23813
- }
23814
- const newId = nextAbstractNumId(root);
23815
- const def = /* @__PURE__ */ jsxDEV(AbstractNum, {
23816
- kind,
23817
- id: newId
23818
- }, undefined, false, undefined, this);
23819
- const firstNumIdx = root.children.findIndex((child2) => child2.tag === "w:num");
23820
- if (firstNumIdx === -1)
23821
- root.children.push(def);
23822
- else
23823
- root.children.splice(firstNumIdx, 0, def);
23824
- return newId;
23825
- }
23826
- }
23827
- function nextAbstractNumId(root) {
23828
- let max = -1;
23829
- for (const child2 of root.findChildren("w:abstractNum")) {
23830
- const id = child2.getAttribute("w:abstractNumId");
23831
- if (id) {
23832
- const numeric = Number(id);
23833
- if (Number.isFinite(numeric) && numeric > max)
23834
- max = numeric;
23835
- }
23836
- }
23837
- return max + 1;
23838
- }
23839
- function nextNumId(root) {
23840
- let max = 0;
23841
- for (const child2 of root.findChildren("w:num")) {
23842
- const id = child2.getAttribute("w:numId");
23843
- if (id) {
23844
- const numeric = Number(id);
23845
- if (Number.isFinite(numeric) && numeric > max)
23846
- max = numeric;
23847
- }
23848
- }
23849
- return max + 1;
23850
- }
23851
- function findLevel(abstractNum, ilvl) {
23852
- const target = String(ilvl);
23853
- return abstractNum.findChildren("w:lvl").find((lvl) => lvl.getAttribute("w:ilvl") === target);
23854
- }
23855
- function NumElement({
23856
- numId,
23857
- abstractNumId,
23858
- start
23859
- }) {
23860
- return /* @__PURE__ */ jsxDEV(w.num, {
23861
- "w-numId": String(numId),
23862
- children: [
23863
- /* @__PURE__ */ jsxDEV(w.abstractNumId, {
23864
- "w-val": String(abstractNumId)
23865
- }, undefined, false, undefined, this),
23866
- /* @__PURE__ */ jsxDEV(w.lvlOverride, {
23867
- "w-ilvl": "0",
23868
- children: /* @__PURE__ */ jsxDEV(w.startOverride, {
23869
- "w-val": String(start)
23870
- }, undefined, false, undefined, this)
23871
- }, undefined, false, undefined, this)
23872
- ]
23873
- }, undefined, true, undefined, this);
23874
- }
23875
- function AbstractNum({
23876
- kind,
23877
- id
23878
- }) {
23879
- return kind === "bullet" ? /* @__PURE__ */ jsxDEV(BulletAbstractNum, {
23880
- id
23881
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV(OrderedAbstractNum, {
23882
- id
23883
- }, undefined, false, undefined, this);
23884
- }
23885
- function BulletAbstractNum({ id }) {
23886
- return /* @__PURE__ */ jsxDEV(w.abstractNum, {
23887
- "w-abstractNumId": String(id),
23888
- children: [
23889
- /* @__PURE__ */ jsxDEV(w.multiLevelType, {
23890
- "w-val": "hybridMultilevel"
23891
- }, undefined, false, undefined, this),
23892
- /* @__PURE__ */ jsxDEV(BulletLevel, {
23893
- ilvl: 0,
23894
- glyph: "\u2022"
23895
- }, undefined, false, undefined, this),
23896
- /* @__PURE__ */ jsxDEV(BulletLevel, {
23897
- ilvl: 1,
23898
- glyph: "\u25E6"
23899
- }, undefined, false, undefined, this),
23900
- /* @__PURE__ */ jsxDEV(BulletLevel, {
23901
- ilvl: 2,
23902
- glyph: "\u25AA"
23903
- }, undefined, false, undefined, this),
23904
- /* @__PURE__ */ jsxDEV(BulletLevel, {
23905
- ilvl: 3,
23906
- glyph: "\u2022"
23907
- }, undefined, false, undefined, this),
23908
- /* @__PURE__ */ jsxDEV(BulletLevel, {
23909
- ilvl: 4,
23910
- glyph: "\u25E6"
23911
- }, undefined, false, undefined, this),
23912
- /* @__PURE__ */ jsxDEV(BulletLevel, {
23913
- ilvl: 5,
23914
- glyph: "\u25AA"
23915
- }, undefined, false, undefined, this),
23916
- /* @__PURE__ */ jsxDEV(BulletLevel, {
23917
- ilvl: 6,
23918
- glyph: "\u2022"
23919
- }, undefined, false, undefined, this),
23920
- /* @__PURE__ */ jsxDEV(BulletLevel, {
23921
- ilvl: 7,
23922
- glyph: "\u25E6"
23923
- }, undefined, false, undefined, this),
23924
- /* @__PURE__ */ jsxDEV(BulletLevel, {
23925
- ilvl: 8,
23926
- glyph: "\u25AA"
23927
- }, undefined, false, undefined, this)
23928
- ]
23929
- }, undefined, true, undefined, this);
23930
- }
23931
- function BulletLevel({
23932
- ilvl,
23933
- glyph
23934
- }) {
23935
- return /* @__PURE__ */ jsxDEV(w.lvl, {
23936
- "w-ilvl": String(ilvl),
23937
- children: [
23938
- /* @__PURE__ */ jsxDEV(w.start, {
23939
- "w-val": "1"
23940
- }, undefined, false, undefined, this),
23941
- /* @__PURE__ */ jsxDEV(w.numFmt, {
23942
- "w-val": "bullet"
23943
- }, undefined, false, undefined, this),
23944
- /* @__PURE__ */ jsxDEV(w.lvlText, {
23945
- "w-val": glyph
23946
- }, undefined, false, undefined, this),
23947
- /* @__PURE__ */ jsxDEV(w.lvlJc, {
23948
- "w-val": "left"
23949
- }, undefined, false, undefined, this),
23950
- /* @__PURE__ */ jsxDEV(w.pPr, {
23951
- children: /* @__PURE__ */ jsxDEV(w.ind, {
23952
- "w-left": String(levelIndent(ilvl)),
23953
- "w-hanging": HANGING
23954
- }, undefined, false, undefined, this)
23955
- }, undefined, false, undefined, this)
23956
- ]
23957
- }, undefined, true, undefined, this);
23958
- }
23959
- function OrderedAbstractNum({ id }) {
23960
- return /* @__PURE__ */ jsxDEV(w.abstractNum, {
23961
- "w-abstractNumId": String(id),
23962
- children: [
23963
- /* @__PURE__ */ jsxDEV(w.multiLevelType, {
23964
- "w-val": "hybridMultilevel"
23965
- }, undefined, false, undefined, this),
23966
- /* @__PURE__ */ jsxDEV(OrderedLevel, {
23967
- ilvl: 0,
23968
- text: "%1.",
23969
- fmt: "decimal"
23970
- }, undefined, false, undefined, this),
23971
- /* @__PURE__ */ jsxDEV(OrderedLevel, {
23972
- ilvl: 1,
23973
- text: "%2.",
23974
- fmt: "lowerLetter"
23975
- }, undefined, false, undefined, this),
23976
- /* @__PURE__ */ jsxDEV(OrderedLevel, {
23977
- ilvl: 2,
23978
- text: "%3.",
23979
- fmt: "lowerRoman"
23980
- }, undefined, false, undefined, this),
23981
- /* @__PURE__ */ jsxDEV(OrderedLevel, {
23982
- ilvl: 3,
23983
- text: "%4.",
23984
- fmt: "decimal"
23985
- }, undefined, false, undefined, this),
23986
- /* @__PURE__ */ jsxDEV(OrderedLevel, {
23987
- ilvl: 4,
23988
- text: "%5.",
23989
- fmt: "lowerLetter"
23990
- }, undefined, false, undefined, this),
23991
- /* @__PURE__ */ jsxDEV(OrderedLevel, {
23992
- ilvl: 5,
23993
- text: "%6.",
23994
- fmt: "lowerRoman"
23995
- }, undefined, false, undefined, this),
23996
- /* @__PURE__ */ jsxDEV(OrderedLevel, {
23997
- ilvl: 6,
23998
- text: "%7.",
23999
- fmt: "decimal"
24000
- }, undefined, false, undefined, this),
24001
- /* @__PURE__ */ jsxDEV(OrderedLevel, {
24002
- ilvl: 7,
24003
- text: "%8.",
24004
- fmt: "lowerLetter"
24005
- }, undefined, false, undefined, this),
24006
- /* @__PURE__ */ jsxDEV(OrderedLevel, {
24007
- ilvl: 8,
24008
- text: "%9.",
24009
- fmt: "lowerRoman"
24010
- }, undefined, false, undefined, this)
24011
- ]
24012
- }, undefined, true, undefined, this);
24013
- }
24014
- function OrderedLevel({
24015
- ilvl,
24016
- text: text2,
24017
- fmt
24018
- }) {
24019
- return /* @__PURE__ */ jsxDEV(w.lvl, {
24020
- "w-ilvl": String(ilvl),
24021
- children: [
24022
- /* @__PURE__ */ jsxDEV(w.start, {
24023
- "w-val": "1"
24024
- }, undefined, false, undefined, this),
24025
- /* @__PURE__ */ jsxDEV(w.numFmt, {
24026
- "w-val": fmt
24027
- }, undefined, false, undefined, this),
24028
- /* @__PURE__ */ jsxDEV(w.lvlText, {
24029
- "w-val": text2
24030
- }, undefined, false, undefined, this),
24031
- /* @__PURE__ */ jsxDEV(w.lvlJc, {
24032
- "w-val": "left"
24033
- }, undefined, false, undefined, this),
24034
- /* @__PURE__ */ jsxDEV(w.pPr, {
24035
- children: /* @__PURE__ */ jsxDEV(w.ind, {
24036
- "w-left": String(levelIndent(ilvl)),
24037
- "w-hanging": HANGING
24038
- }, undefined, false, undefined, this)
24039
- }, undefined, false, undefined, this)
24040
- ]
24041
- }, undefined, true, undefined, this);
24042
- }
24043
- function levelIndent(ilvl) {
24044
- return (ilvl + 1) * 300;
24045
- }
24046
- var NUMBERING_PART_NAME = "word/numbering.xml", NUMBERING_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering", NUMBERING_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml", EMPTY_NUMBERING_XML = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
24047
- <w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"/>`, HANGING = "240";
24048
- var init_numbering = __esm(() => {
24049
- init_jsx();
24050
- init_parser();
24051
- init_jsx_dev_runtime();
24052
- });
24053
-
24054
24290
  // node_modules/process-nextick-args/index.js
24055
24291
  var require_process_nextick_args = __commonJS((exports, module) => {
24056
24292
  if (typeof process === "undefined" || !process.version || process.version.indexOf("v0.") === 0 || process.version.indexOf("v1.") === 0 && process.version.indexOf("v1.8.") !== 0) {
@@ -33807,6 +34043,13 @@ function NormalStyle() {
33807
34043
  ]
33808
34044
  }, undefined, true, undefined, this);
33809
34045
  }
34046
+ function HeadingThemeFonts() {
34047
+ return /* @__PURE__ */ jsxDEV(w.rFonts, {
34048
+ "w-asciiTheme": "majorHAnsi",
34049
+ "w-hAnsiTheme": "majorHAnsi",
34050
+ "w-cstheme": "majorBidi"
34051
+ }, undefined, false, undefined, this);
34052
+ }
33810
34053
  function TitleStyle() {
33811
34054
  return /* @__PURE__ */ jsxDEV(w.style, {
33812
34055
  "w-type": "paragraph",
@@ -33829,10 +34072,7 @@ function TitleStyle() {
33829
34072
  }, undefined, false, undefined, this),
33830
34073
  /* @__PURE__ */ jsxDEV(w.rPr, {
33831
34074
  children: [
33832
- /* @__PURE__ */ jsxDEV(w.rFonts, {
33833
- "w-ascii": "Calibri Light",
33834
- "w-hAnsi": "Calibri Light"
33835
- }, undefined, false, undefined, this),
34075
+ /* @__PURE__ */ jsxDEV(HeadingThemeFonts, {}, undefined, false, undefined, this),
33836
34076
  /* @__PURE__ */ jsxDEV(w.color, {
33837
34077
  "w-val": "1F3864"
33838
34078
  }, undefined, false, undefined, this),
@@ -33866,10 +34106,7 @@ function SubtitleStyle() {
33866
34106
  }, undefined, false, undefined, this),
33867
34107
  /* @__PURE__ */ jsxDEV(w.rPr, {
33868
34108
  children: [
33869
- /* @__PURE__ */ jsxDEV(w.rFonts, {
33870
- "w-ascii": "Calibri Light",
33871
- "w-hAnsi": "Calibri Light"
33872
- }, undefined, false, undefined, this),
34109
+ /* @__PURE__ */ jsxDEV(HeadingThemeFonts, {}, undefined, false, undefined, this),
33873
34110
  /* @__PURE__ */ jsxDEV(w.color, {
33874
34111
  "w-val": "5A5A5A"
33875
34112
  }, undefined, false, undefined, this),
@@ -33919,10 +34156,7 @@ function HeadingStyle({
33919
34156
  }, undefined, true, undefined, this),
33920
34157
  /* @__PURE__ */ jsxDEV(w.rPr, {
33921
34158
  children: [
33922
- /* @__PURE__ */ jsxDEV(w.rFonts, {
33923
- "w-ascii": "Calibri Light",
33924
- "w-hAnsi": "Calibri Light"
33925
- }, undefined, false, undefined, this),
34159
+ /* @__PURE__ */ jsxDEV(HeadingThemeFonts, {}, undefined, false, undefined, this),
33926
34160
  bold2 && /* @__PURE__ */ jsxDEV(w.b, {}, undefined, false, undefined, this),
33927
34161
  italic && /* @__PURE__ */ jsxDEV(w.i, {}, undefined, false, undefined, this),
33928
34162
  color && /* @__PURE__ */ jsxDEV(w.color, {
@@ -72465,6 +72699,69 @@ function setCellWidth(cell, width) {
72465
72699
  }, undefined, false, undefined, this) : null);
72466
72700
  pruneEmptyTcPr(cell, tcPr);
72467
72701
  }
72702
+ function setCellShading(cell, hex) {
72703
+ const tcPr = ensureTcPr(cell);
72704
+ setTcPrChild(tcPr, "w:shd", hex ? /* @__PURE__ */ jsxDEV(w.shd, {
72705
+ "w-val": "clear",
72706
+ "w-color": "auto",
72707
+ "w-fill": hex
72708
+ }, undefined, false, undefined, this) : null);
72709
+ pruneEmptyTcPr(cell, tcPr);
72710
+ }
72711
+ function setCellVAlign(cell, value) {
72712
+ const tcPr = ensureTcPr(cell);
72713
+ setTcPrChild(tcPr, "w:vAlign", value && value !== "top" ? /* @__PURE__ */ jsxDEV(w.vAlign, {
72714
+ "w-val": value
72715
+ }, undefined, false, undefined, this) : null);
72716
+ pruneEmptyTcPr(cell, tcPr);
72717
+ }
72718
+ function setCellBorders(cell, updates, clearAll = false) {
72719
+ const tcPr = ensureTcPr(cell);
72720
+ if (clearAll) {
72721
+ setTcPrChild(tcPr, "w:tcBorders", null);
72722
+ pruneEmptyTcPr(cell, tcPr);
72723
+ return;
72724
+ }
72725
+ let tcBorders = tcPr.findChild("w:tcBorders");
72726
+ if (!tcBorders) {
72727
+ if (updates.every((update) => update.edge === null)) {
72728
+ pruneEmptyTcPr(cell, tcPr);
72729
+ return;
72730
+ }
72731
+ tcBorders = /* @__PURE__ */ jsxDEV(w.tcBorders, {}, undefined, false, undefined, this);
72732
+ setTcPrChild(tcPr, "w:tcBorders", tcBorders);
72733
+ }
72734
+ for (const { side, edge } of updates) {
72735
+ const tag = `w:${side}`;
72736
+ tcBorders.children = tcBorders.children.filter((child2) => child2.tag !== tag);
72737
+ if (edge)
72738
+ insertEdgeInOrder(tcBorders, tag, borderEdge(tag, edge));
72739
+ }
72740
+ if (tcBorders.children.length === 0)
72741
+ setTcPrChild(tcPr, "w:tcBorders", null);
72742
+ pruneEmptyTcPr(cell, tcPr);
72743
+ }
72744
+ function borderEdge(tag, edge) {
72745
+ const attributes = edge.style === "none" ? { "w:val": "none" } : {
72746
+ "w:val": edge.style,
72747
+ "w:sz": String(edge.sizeEighths),
72748
+ "w:space": "0",
72749
+ "w:color": edge.color
72750
+ };
72751
+ return XmlNode2.element(tag, attributes);
72752
+ }
72753
+ function insertEdgeInOrder(parent, tag, node2) {
72754
+ const target = orderIndex(CELL_BORDER_ORDER, tag);
72755
+ let insertAt = parent.children.length;
72756
+ for (let index2 = 0;index2 < parent.children.length; index2++) {
72757
+ const child2 = parent.children[index2];
72758
+ if (child2 && orderIndex(CELL_BORDER_ORDER, child2.tag) > target) {
72759
+ insertAt = index2;
72760
+ break;
72761
+ }
72762
+ }
72763
+ parent.children.splice(insertAt, 0, node2);
72764
+ }
72468
72765
  function markRowTracked(row, kind, meta) {
72469
72766
  const trPr = ensureTrPr(row);
72470
72767
  trPr.children = trPr.children.filter((child2) => child2.tag !== "w:ins" && child2.tag !== "w:del");
@@ -72495,6 +72792,24 @@ function ensureTrPr(row) {
72495
72792
  row.children.unshift(trPr);
72496
72793
  return trPr;
72497
72794
  }
72795
+ function setRowHeight(row, height) {
72796
+ const trPr = ensureTrPr(row);
72797
+ setTrPrChild(trPr, "w:trHeight", height ? /* @__PURE__ */ jsxDEV(w.trHeight, {
72798
+ "w-val": String(height.value),
72799
+ "w-hRule": height.rule
72800
+ }, undefined, false, undefined, this) : null);
72801
+ pruneEmptyTrPr(row, trPr);
72802
+ }
72803
+ function setRepeatHeader(row, on) {
72804
+ const trPr = ensureTrPr(row);
72805
+ setTrPrChild(trPr, "w:tblHeader", on ? /* @__PURE__ */ jsxDEV(w.tblHeader, {}, undefined, false, undefined, this) : null);
72806
+ pruneEmptyTrPr(row, trPr);
72807
+ }
72808
+ function pruneEmptyTrPr(row, trPr) {
72809
+ if (trPr.children.length === 0) {
72810
+ row.children = row.children.filter((child2) => child2 !== trPr);
72811
+ }
72812
+ }
72498
72813
  function appendTblGridChange(tblGrid, priorCols, meta) {
72499
72814
  tblGrid.children = tblGrid.children.filter((child2) => child2.tag !== "w:tblGridChange");
72500
72815
  tblGrid.children.push(/* @__PURE__ */ jsxDEV(w.tblGridChange, {
@@ -72546,6 +72861,16 @@ function setTableLayout(table, layout) {
72546
72861
  function setTablePropertiesChild(table, tag, node2) {
72547
72862
  setTblPrChild(ensureTblPr(table), tag, node2);
72548
72863
  }
72864
+ function setTableJustification(table, value) {
72865
+ setTablePropertiesChild(table, "w:jc", value && value !== "left" ? /* @__PURE__ */ jsxDEV(w.jc, {
72866
+ "w-val": value
72867
+ }, undefined, false, undefined, this) : null);
72868
+ }
72869
+ function setTableStyle(table, styleId) {
72870
+ setTablePropertiesChild(table, "w:tblStyle", styleId ? /* @__PURE__ */ jsxDEV(w.tblStyle, {
72871
+ "w-val": styleId
72872
+ }, undefined, false, undefined, this) : null);
72873
+ }
72549
72874
  function setTblPrChild(tblPr, tag, node2) {
72550
72875
  tblPr.children = tblPr.children.filter((child2) => child2.tag !== tag);
72551
72876
  if (!node2)
@@ -72580,13 +72905,37 @@ function setTcPrChild(tcPr, tag, node2) {
72580
72905
  }
72581
72906
  tcPr.children.splice(insertAt, 0, node2);
72582
72907
  }
72583
- var TBL_PR_ORDER, TC_PR_ORDER;
72908
+ function setTrPrChild(trPr, tag, node2) {
72909
+ trPr.children = trPr.children.filter((child2) => child2.tag !== tag);
72910
+ if (!node2)
72911
+ return;
72912
+ const target = orderIndex(TR_PR_ORDER, tag);
72913
+ let insertAt = trPr.children.length;
72914
+ for (let index2 = 0;index2 < trPr.children.length; index2++) {
72915
+ const child2 = trPr.children[index2];
72916
+ if (child2 && orderIndex(TR_PR_ORDER, child2.tag) > target) {
72917
+ insertAt = index2;
72918
+ break;
72919
+ }
72920
+ }
72921
+ trPr.children.splice(insertAt, 0, node2);
72922
+ }
72923
+ var CELL_BORDER_ORDER, TBL_PR_ORDER, TC_PR_ORDER, TR_PR_ORDER;
72584
72924
  var init_mutate = __esm(() => {
72585
72925
  init_blocks();
72586
72926
  init_jsx();
72927
+ init_parser();
72587
72928
  init_emit2();
72588
72929
  init_table();
72589
72930
  init_jsx_dev_runtime();
72931
+ CELL_BORDER_ORDER = [
72932
+ "w:top",
72933
+ "w:left",
72934
+ "w:bottom",
72935
+ "w:right",
72936
+ "w:insideH",
72937
+ "w:insideV"
72938
+ ];
72590
72939
  TBL_PR_ORDER = [
72591
72940
  "w:tblStyle",
72592
72941
  "w:tblpPr",
@@ -72624,6 +72973,23 @@ var init_mutate = __esm(() => {
72624
72973
  "w:cellMerge",
72625
72974
  "w:tcPrChange"
72626
72975
  ];
72976
+ TR_PR_ORDER = [
72977
+ "w:cnfStyle",
72978
+ "w:divId",
72979
+ "w:gridBefore",
72980
+ "w:gridAfter",
72981
+ "w:wBefore",
72982
+ "w:wAfter",
72983
+ "w:cantSplit",
72984
+ "w:trHeight",
72985
+ "w:tblHeader",
72986
+ "w:tblCellSpacing",
72987
+ "w:jc",
72988
+ "w:hidden",
72989
+ "w:ins",
72990
+ "w:del",
72991
+ "w:trPrChange"
72992
+ ];
72627
72993
  });
72628
72994
 
72629
72995
  // src/core/table/index.tsx
@@ -73721,6 +74087,99 @@ var init_insert = __esm(() => {
73721
74087
  };
73722
74088
  });
73723
74089
 
74090
+ // src/core/lists/index.ts
74091
+ class Lists {
74092
+ document;
74093
+ constructor(document4) {
74094
+ this.document = document4;
74095
+ }
74096
+ setStart(blockRef, start) {
74097
+ const list3 = this.requireList(blockRef.node);
74098
+ this.numbering().setStart(list3.numId, list3.level, start);
74099
+ }
74100
+ setFormat(blockRef, format) {
74101
+ const list3 = this.requireList(blockRef.node);
74102
+ this.numbering().setFormat(list3.numId, list3.level, FORMAT_TO_NUMFMT[format]);
74103
+ }
74104
+ restart(blockRef, start) {
74105
+ const list3 = this.requireList(blockRef.node);
74106
+ const newNumId = String(this.numbering().cloneListDefinition(list3.numId, start));
74107
+ const startIdx = blockRef.parent.indexOf(blockRef.node);
74108
+ this.repointFrom(blockRef.parent, startIdx, list3.numId, newNumId);
74109
+ }
74110
+ continue(blockRef) {
74111
+ const list3 = this.requireList(blockRef.node);
74112
+ const siblings = blockRef.parent;
74113
+ const startIdx = siblings.indexOf(blockRef.node);
74114
+ let precedingNumId;
74115
+ for (let i = startIdx - 1;i >= 0; i--) {
74116
+ const sibling = siblings[i];
74117
+ if (!sibling)
74118
+ continue;
74119
+ const numbered = readNumPr(sibling);
74120
+ if (!numbered)
74121
+ continue;
74122
+ if (numbered.numId !== list3.numId && this.isOrdered(numbered)) {
74123
+ precedingNumId = numbered.numId;
74124
+ break;
74125
+ }
74126
+ }
74127
+ if (!precedingNumId) {
74128
+ throw new ListOperationError("no preceding list to continue from");
74129
+ }
74130
+ this.repointFrom(siblings, startIdx, list3.numId, precedingNumId);
74131
+ }
74132
+ repointFrom(siblings, startIdx, oldNumId, newNumId) {
74133
+ for (let i = startIdx;i < siblings.length; i++) {
74134
+ const sibling = siblings[i];
74135
+ if (!sibling)
74136
+ continue;
74137
+ if (readNumPr(sibling)?.numId === oldNumId)
74138
+ setNumId(sibling, newNumId);
74139
+ }
74140
+ }
74141
+ isOrdered(numbered) {
74142
+ const format = this.numbering().getFormat(numbered.numId, numbered.level);
74143
+ return format !== undefined && format !== "bullet" && format !== "none";
74144
+ }
74145
+ requireList(paragraph2) {
74146
+ const numbered = readNumPr(paragraph2);
74147
+ if (!numbered) {
74148
+ throw new ListOperationError("paragraph is not a list item");
74149
+ }
74150
+ return numbered;
74151
+ }
74152
+ numbering() {
74153
+ if (!this.document.numbering) {
74154
+ throw new ListOperationError("document has no numbering definitions");
74155
+ }
74156
+ return this.document.numbering;
74157
+ }
74158
+ }
74159
+ function readNumPr(paragraph2) {
74160
+ const numPr = paragraph2.findChild("w:pPr")?.findChild("w:numPr");
74161
+ if (!numPr)
74162
+ return;
74163
+ const numId = numPr.findChild("w:numId")?.getAttribute("w:val");
74164
+ if (numId === undefined)
74165
+ return;
74166
+ const level = Number(numPr.findChild("w:ilvl")?.getAttribute("w:val") ?? "0");
74167
+ return { numId, level };
74168
+ }
74169
+ function setNumId(paragraph2, numId) {
74170
+ paragraph2.findChild("w:pPr")?.findChild("w:numPr")?.findChild("w:numId")?.setAttribute("w:val", numId);
74171
+ }
74172
+ var ListOperationError;
74173
+ var init_lists = __esm(() => {
74174
+ init_numbering();
74175
+ ListOperationError = class ListOperationError extends Error {
74176
+ constructor(message) {
74177
+ super(message);
74178
+ this.name = "ListOperationError";
74179
+ }
74180
+ };
74181
+ });
74182
+
73724
74183
  // src/core/marginals/index.tsx
73725
74184
  class Marginals {
73726
74185
  document;
@@ -82062,11 +82521,13 @@ var init_render = __esm(() => {
82062
82521
  // src/core/index.ts
82063
82522
  var init_core2 = __esm(() => {
82064
82523
  init_ast();
82524
+ init_numbering();
82065
82525
  init_package();
82066
82526
  init_comments2();
82067
82527
  init_edit();
82068
82528
  init_fonts();
82069
82529
  init_insert();
82530
+ init_lists();
82070
82531
  init_literal_text();
82071
82532
  init_locators();
82072
82533
  init_marginals2();
@@ -89549,7 +90010,19 @@ export type Paragraph = {
89549
90010
  type: "paragraph";
89550
90011
  style?: string;
89551
90012
  alignment?: "left" | "center" | "right" | "justify";
89552
- list?: { level: number; numId: string; ordered?: boolean };
90013
+ /** List membership from \`<w:pPr><w:numPr>\`. \`start\`/\`format\` are the
90014
+ * numbering-control properties \`docx lists set\` authors: \`start\` is the
90015
+ * effective level-start (omitted when 1), \`format\` the friendly
90016
+ * \`--format\` glyph vocabulary (decimal/lower-alpha/upper-roman/\u2026, omitted
90017
+ * when the default \`decimal\`). Two paragraphs sharing a \`numId\` are the same
90018
+ * (or continued) list, so a \`--continue\` link needs no field of its own. */
90019
+ list?: {
90020
+ level: number;
90021
+ numId: string;
90022
+ ordered?: boolean;
90023
+ start?: number;
90024
+ format?: string;
90025
+ };
89553
90026
  /** GFM task-list marker. Set when the paragraph's first content is a Word
89554
90027
  * checkbox content control (\`<w:sdt><w14:checkbox/></w:sdt>\`); the SDT itself
89555
90028
  * plus the leading whitespace run after it are stripped from \`runs\` so the
@@ -89622,6 +90095,10 @@ export type Table = {
89622
90095
  * \`borders\` summary. Surfaced so \`styles --used\` can report the table styles
89623
90096
  * a document actually applies. Present only when the table references one. */
89624
90097
  style?: string;
90098
+ /** Justification of the whole table on the page, from \`<w:tblPr><w:jc w:val="\u2026"/>\`
90099
+ * (\`"center"\` / \`"right"\`). Absent \u21D2 the default \`"left"\`. Authorable via
90100
+ * \`docx tables format --at tN --align\`. */
90101
+ align?: "left" | "center" | "right";
89625
90102
  rows: TableRow[];
89626
90103
  };
89627
90104
 
@@ -89630,6 +90107,15 @@ export type TableRow = {
89630
90107
  /** Tracked row insertion/deletion from <w:trPr><w:ins/> or <w:del/>
89631
90108
  * (kind "rowIns" / "rowDel"). Present only under track-changes. */
89632
90109
  trackedChange?: TrackedChange;
90110
+ /** Row height from \`<w:trPr><w:trHeight w:val="\u2026" w:hRule="\u2026"/>\`. \`value\` is
90111
+ * in twips; \`rule\` is \`atLeast\` (minimum, the default), \`exact\` (fixed), or
90112
+ * \`auto\` (fit content). Present only when the row declares an explicit height.
90113
+ * Authorable via \`docx tables format --at tN:rR --row-height\`. */
90114
+ height?: { value: number; rule: "atLeast" | "exact" | "auto" };
90115
+ /** Whether the row repeats as a header at the top of each page that the table
90116
+ * spans, from \`<w:trPr><w:tblHeader/>\`. Present (true) only when the marker is
90117
+ * set. Authorable via \`docx tables format --at tN:rR --repeat-header\`. */
90118
+ repeatHeader?: boolean;
89633
90119
  };
89634
90120
 
89635
90121
  export type TableCell = {
@@ -89654,6 +90140,17 @@ export type TableCell = {
89654
90140
  * hint \u2014 GFM can't show cell shading; the fill survives edits via in-place
89655
90141
  * mutation. */
89656
90142
  shading?: string;
90143
+ /** Vertical alignment of the cell's content from \`<w:tcPr><w:vAlign w:val="\u2026"/>\`
90144
+ * (\`"center"\` / \`"bottom"\`). Absent \u21D2 the default \`"top"\`. Authorable via
90145
+ * \`docx tables format --at \u2026 --valign\`. (Horizontal alignment is NOT a cell
90146
+ * property \u2014 it lives on each paragraph's \`<w:jc>\`, surfaced as \`docx:p align\`.) */
90147
+ vAlign?: "top" | "center" | "bottom";
90148
+ /** Summary of \`<w:tcPr><w:tcBorders>\` \u2014 the set edges and their dominant style,
90149
+ * as a compact \`side:style\` string (e.g. \`"bottom:double"\`, \`"all:single"\`).
90150
+ * A read-time hint mirroring \`Table.borders\`; full per-edge fidelity stays in
90151
+ * the XML via in-place mutation. Authorable via \`docx tables format --at \u2026
90152
+ * --cell-borders\`. Present only when the cell declares explicit borders. */
90153
+ borders?: string;
89657
90154
  };
89658
90155
 
89659
90156
  export type TableWidth = {
@@ -90022,7 +90519,10 @@ var init_schema = __esm(() => {
90022
90519
  required: ["level", "numId"],
90023
90520
  properties: {
90024
90521
  level: { type: "number" },
90025
- numId: { type: "string" }
90522
+ numId: { type: "string" },
90523
+ ordered: { type: "boolean" },
90524
+ start: { type: "number" },
90525
+ format: { type: "string" }
90026
90526
  }
90027
90527
  },
90028
90528
  taskState: { enum: ["checked", "unchecked"] },
@@ -90216,6 +90716,7 @@ var init_schema = __esm(() => {
90216
90716
  width: { $ref: "#/$defs/TableWidth" },
90217
90717
  borders: { type: "string" },
90218
90718
  style: { type: "string" },
90719
+ align: { enum: ["left", "center", "right"] },
90219
90720
  rows: {
90220
90721
  type: "array",
90221
90722
  items: {
@@ -90234,6 +90735,8 @@ var init_schema = __esm(() => {
90234
90735
  vMerge: { enum: ["restart", "continue"] },
90235
90736
  width: { $ref: "#/$defs/TableWidth" },
90236
90737
  shading: { type: "string" },
90738
+ vAlign: { enum: ["top", "center", "bottom"] },
90739
+ borders: { type: "string" },
90237
90740
  trackedChange: {
90238
90741
  $ref: "#/$defs/TableRevision",
90239
90742
  description: "cellIns / cellDel (tracked column change)"
@@ -90244,7 +90747,15 @@ var init_schema = __esm(() => {
90244
90747
  trackedChange: {
90245
90748
  $ref: "#/$defs/TableRevision",
90246
90749
  description: "rowIns / rowDel (tracked row change)"
90247
- }
90750
+ },
90751
+ height: {
90752
+ type: "object",
90753
+ properties: {
90754
+ value: { type: "number" },
90755
+ rule: { enum: ["atLeast", "exact", "auto"] }
90756
+ }
90757
+ },
90758
+ repeatHeader: { type: "boolean" }
90248
90759
  }
90249
90760
  }
90250
90761
  }
@@ -90556,6 +91067,216 @@ var init_info = __esm(() => {
90556
91067
  };
90557
91068
  });
90558
91069
 
91070
+ // src/cli/lists/set.ts
91071
+ var exports_set = {};
91072
+ __export(exports_set, {
91073
+ run: () => run34
91074
+ });
91075
+ async function run34(args) {
91076
+ const parsed = await tryParseArgs(args, {
91077
+ at: { type: "string" },
91078
+ start: { type: "string" },
91079
+ format: { type: "string" },
91080
+ restart: { type: "boolean" },
91081
+ continue: { type: "boolean" },
91082
+ ...SAVE_FLAGS
91083
+ }, HELP30);
91084
+ if (typeof parsed === "number")
91085
+ return parsed;
91086
+ if (parsed.values.help) {
91087
+ await writeStdout(HELP30);
91088
+ return EXIT2.OK;
91089
+ }
91090
+ setVerboseAck(Boolean(parsed.values.verbose));
91091
+ const path2 = parsed.positionals[0];
91092
+ if (!path2)
91093
+ return fail("USAGE", "Missing FILE argument", HELP30);
91094
+ const at = parsed.values.at;
91095
+ if (!at) {
91096
+ return fail("USAGE", "Missing --at LOCATOR (a list item, e.g. p5)", HELP30);
91097
+ }
91098
+ const plan = buildPlan(parsed.values);
91099
+ if (typeof plan === "string")
91100
+ return fail("USAGE", plan);
91101
+ const document4 = await openOrFail(path2);
91102
+ if (typeof document4 === "number")
91103
+ return document4;
91104
+ const blockRef = await resolveBlockOrFail(document4, at);
91105
+ if (typeof blockRef === "number")
91106
+ return blockRef;
91107
+ const orderedError = validateOrderedList(document4, at);
91108
+ if (orderedError)
91109
+ return fail("USAGE", orderedError);
91110
+ const outputPath = parsed.values.output;
91111
+ if (parsed.values["dry-run"]) {
91112
+ await respond({
91113
+ operation: "lists.set",
91114
+ dryRun: true,
91115
+ path: path2,
91116
+ at,
91117
+ applied: appliedList(plan),
91118
+ ...outputPath ? { output: outputPath } : {}
91119
+ });
91120
+ return EXIT2.OK;
91121
+ }
91122
+ const lists = new Lists(document4);
91123
+ try {
91124
+ if (plan.continue) {
91125
+ lists.continue(blockRef);
91126
+ } else if (plan.restart) {
91127
+ lists.restart(blockRef, plan.start ?? 1);
91128
+ if (plan.format)
91129
+ lists.setFormat(blockRef, plan.format);
91130
+ } else {
91131
+ if (plan.start !== undefined)
91132
+ lists.setStart(blockRef, plan.start);
91133
+ if (plan.format)
91134
+ lists.setFormat(blockRef, plan.format);
91135
+ }
91136
+ } catch (error) {
91137
+ if (error instanceof ListOperationError) {
91138
+ return fail("BLOCK_NOT_FOUND", error.message);
91139
+ }
91140
+ throw error;
91141
+ }
91142
+ await document4.save(outputPath);
91143
+ const destination = outputPath ?? path2;
91144
+ await respondAck({
91145
+ ok: true,
91146
+ operation: "lists.set",
91147
+ path: destination,
91148
+ locator: at,
91149
+ applied: appliedList(plan)
91150
+ });
91151
+ return EXIT2.OK;
91152
+ }
91153
+ function buildPlan(values2) {
91154
+ const restart = Boolean(values2.restart);
91155
+ const continueFlag = Boolean(values2.continue);
91156
+ if (restart && continueFlag) {
91157
+ return "Pass only one of --restart / --continue";
91158
+ }
91159
+ let start;
91160
+ if (values2.start !== undefined) {
91161
+ const parsedStart = Number(values2.start);
91162
+ if (!Number.isInteger(parsedStart) || parsedStart < 1) {
91163
+ return `--start must be a positive integer (got ${values2.start})`;
91164
+ }
91165
+ start = parsedStart;
91166
+ }
91167
+ let format;
91168
+ if (values2.format !== undefined) {
91169
+ const candidate = String(values2.format);
91170
+ if (!Object.hasOwn(FORMAT_TO_NUMFMT, candidate)) {
91171
+ return `--format must be one of ${Object.keys(FORMAT_TO_NUMFMT).join(", ")} (got ${candidate})`;
91172
+ }
91173
+ format = candidate;
91174
+ }
91175
+ if (continueFlag && (start !== undefined || format !== undefined)) {
91176
+ return "--continue adopts the previous list's numbering \u2014 it can't combine with --start/--format";
91177
+ }
91178
+ if (!restart && !continueFlag && start === undefined && format === undefined) {
91179
+ return "Nothing to do \u2014 pass --start, --format, --restart, or --continue";
91180
+ }
91181
+ return { start, format, restart, continue: continueFlag };
91182
+ }
91183
+ function validateOrderedList(document4, at) {
91184
+ const block = document4.body.findBlockById(at);
91185
+ if (!block || block.type !== "paragraph" || !block.list) {
91186
+ return `${at} is not a list item \u2014 list numbering controls only apply to numbered lists`;
91187
+ }
91188
+ if (!block.list.ordered) {
91189
+ return `${at} is a bulleted list \u2014 numbering controls (start/format/restart/continue) apply to numbered (ordered) lists`;
91190
+ }
91191
+ return null;
91192
+ }
91193
+ function appliedList(plan) {
91194
+ const applied = [];
91195
+ if (plan.continue)
91196
+ applied.push("continue");
91197
+ if (plan.restart)
91198
+ applied.push("restart");
91199
+ if (plan.start !== undefined)
91200
+ applied.push(`start=${plan.start}`);
91201
+ if (plan.format)
91202
+ applied.push(`format=${plan.format}`);
91203
+ return applied;
91204
+ }
91205
+ var HELP30 = `docx lists set \u2014 renumber a numbered list (start value, glyph format, restart/continue)
91206
+
91207
+ Usage:
91208
+ docx lists set FILE --at pN [options]
91209
+
91210
+ --at names any item of a NUMBERED (ordered) list. --start/--format change the whole
91211
+ list (every paragraph sharing its numbering); --restart/--continue act from the
91212
+ addressed item onward. Bulleted lists aren't numbered, so they're rejected.
91213
+
91214
+ Options:
91215
+ --start N Start the list's numbering at N (a positive integer)
91216
+ --format FMT Glyph style: decimal | lower-alpha | upper-alpha | lower-roman | upper-roman
91217
+ (decimal = 1.2.3., lower-alpha = a.b.c., upper-roman = I.II.III., \u2026)
91218
+ --restart Begin a FRESH list at this item: split it off with its own numbering
91219
+ (combine with --start/--format to set the new list's first number/style)
91220
+ --continue Continue the PREVIOUS list's numbering here instead of restarting at 1
91221
+ -o, --output PATH / --dry-run / -v, --verbose / -h, --help
91222
+
91223
+ --restart and --continue are mutually exclusive; --continue can't combine with
91224
+ --start/--format (it adopts the previous list's numbering). List numbering edits
91225
+ are applied directly (untracked) \u2014 Word records no revision for them.
91226
+
91227
+ Examples:
91228
+ docx lists set report.docx --at p12 --start 5
91229
+ docx lists set report.docx --at p12 --format upper-roman
91230
+ docx lists set report.docx --at p20 --restart --start 1
91231
+ docx lists set report.docx --at p20 --continue
91232
+ `;
91233
+ var init_set2 = __esm(() => {
91234
+ init_core2();
91235
+ init_respond();
91236
+ });
91237
+
91238
+ // src/cli/lists/index.ts
91239
+ var exports_lists = {};
91240
+ __export(exports_lists, {
91241
+ run: () => run35
91242
+ });
91243
+ async function run35(args) {
91244
+ const verb = args[0];
91245
+ if (!verb || verb === "--help" || verb === "-h" || verb === "help") {
91246
+ await writeStdout(HELP31);
91247
+ return verb ? 0 : 2;
91248
+ }
91249
+ const loader = SUBCOMMANDS9[verb];
91250
+ if (!loader) {
91251
+ return fail("USAGE", `Unknown lists subcommand: ${verb}`, 'Run "docx lists --help".');
91252
+ }
91253
+ const module_ = await loader();
91254
+ return module_.run(args.slice(1));
91255
+ }
91256
+ var SUBCOMMANDS9, HELP31 = `docx lists \u2014 control list numbering (start value, glyph format, restart/continue)
91257
+
91258
+ Usage:
91259
+ docx lists set FILE --at pN [options]
91260
+
91261
+ Verbs:
91262
+ set Renumber a numbered list \u2014 set its start value or glyph format, or make it
91263
+ restart vs. continue the previous list
91264
+ (--at pN [--start N] [--format FMT] [--restart] [--continue])
91265
+
91266
+ Lists are otherwise handled by the standard verbs:
91267
+ create a list docx insert FILE --after pN --list "first,second" (or markdown "1. \u2026")
91268
+ edit an item docx edit FILE --at pN --text "..."
91269
+ inspect docx read FILE --ast (list.numId / level / ordered / start / format)
91270
+
91271
+ Run "docx lists set --help" for option detail.
91272
+ `;
91273
+ var init_lists2 = __esm(() => {
91274
+ init_respond();
91275
+ SUBCOMMANDS9 = {
91276
+ set: () => Promise.resolve().then(() => (init_set2(), exports_set))
91277
+ };
91278
+ });
91279
+
90559
91280
  // src/cli/outline/build.ts
90560
91281
  function buildOutline(doc, options = {}) {
90561
91282
  const stylePrefix = options.stylePrefix ?? "Heading";
@@ -90617,23 +91338,23 @@ var init_build = __esm(() => {
90617
91338
  // src/cli/outline/index.ts
90618
91339
  var exports_outline = {};
90619
91340
  __export(exports_outline, {
90620
- run: () => run34
91341
+ run: () => run36
90621
91342
  });
90622
- async function run34(args) {
91343
+ async function run36(args) {
90623
91344
  const parsed = await tryParseArgs(args, {
90624
91345
  "style-prefix": { type: "string" },
90625
91346
  json: { type: "boolean" },
90626
91347
  help: { type: "boolean", short: "h" }
90627
- }, HELP30);
91348
+ }, HELP32);
90628
91349
  if (typeof parsed === "number")
90629
91350
  return parsed;
90630
91351
  if (parsed.values.help) {
90631
- await writeStdout(HELP30);
91352
+ await writeStdout(HELP32);
90632
91353
  return EXIT2.OK;
90633
91354
  }
90634
91355
  const path2 = parsed.positionals[0];
90635
91356
  if (!path2)
90636
- return fail("USAGE", "Missing FILE argument", HELP30);
91357
+ return fail("USAGE", "Missing FILE argument", HELP32);
90637
91358
  const stylePrefix = parsed.values["style-prefix"] ?? "Heading";
90638
91359
  if (stylePrefix.length === 0) {
90639
91360
  return fail("USAGE", "--style-prefix cannot be empty");
@@ -90661,7 +91382,7 @@ function renderOutlineText(entries, depth = 0) {
90661
91382
  }
90662
91383
  return lines;
90663
91384
  }
90664
- var HELP30 = `docx outline \u2014 list headings as a hierarchical tree
91385
+ var HELP32 = `docx outline \u2014 list headings as a hierarchical tree
90665
91386
 
90666
91387
  Usage:
90667
91388
  docx outline FILE [options]
@@ -90741,6 +91462,8 @@ function renderMarkdown(doc, options = {}) {
90741
91462
  referencedEndnoteIds: new Set,
90742
91463
  referencedTrackedChanges: new Map,
90743
91464
  orderedCounters: new Map,
91465
+ prevListNumId: null,
91466
+ seenListNumIds: new Set,
90744
91467
  contentWidthEmu: contentWidthEmu(documentGeometry(blocks)?.geometry),
90745
91468
  governingColumns: computeGoverningColumns(blocks),
90746
91469
  wrappingTabLines: [],
@@ -90827,17 +91550,17 @@ function detectFormatBaseline(blocks) {
90827
91550
  const sizeChars = new Map;
90828
91551
  let total = 0;
90829
91552
  for (const paragraph2 of flattenParagraphs(blocks)) {
90830
- for (const run35 of paragraph2.runs) {
90831
- if (run35.type !== "text")
91553
+ for (const run37 of paragraph2.runs) {
91554
+ if (run37.type !== "text")
90832
91555
  continue;
90833
- const length = run35.text.length;
91556
+ const length = run37.text.length;
90834
91557
  if (length === 0)
90835
91558
  continue;
90836
91559
  total += length;
90837
- if (run35.font)
90838
- fontChars.set(run35.font, (fontChars.get(run35.font) ?? 0) + length);
90839
- if (run35.sizeHalfPoints !== undefined) {
90840
- sizeChars.set(run35.sizeHalfPoints, (sizeChars.get(run35.sizeHalfPoints) ?? 0) + length);
91560
+ if (run37.font)
91561
+ fontChars.set(run37.font, (fontChars.get(run37.font) ?? 0) + length);
91562
+ if (run37.sizeHalfPoints !== undefined) {
91563
+ sizeChars.set(run37.sizeHalfPoints, (sizeChars.get(run37.sizeHalfPoints) ?? 0) + length);
90841
91564
  }
90842
91565
  }
90843
91566
  }
@@ -90871,8 +91594,8 @@ function emptyCommentIndex() {
90871
91594
  orderedIds: []
90872
91595
  };
90873
91596
  }
90874
- function isRunVisible(run35, view) {
90875
- const kind = run35.trackedChange?.kind;
91597
+ function isRunVisible(run37, view) {
91598
+ const kind = run37.trackedChange?.kind;
90876
91599
  if (!kind)
90877
91600
  return true;
90878
91601
  if (view === "accepted" && (kind === "del" || kind === "moveFrom"))
@@ -90887,13 +91610,13 @@ function buildCommentIndex(blocks, options) {
90887
91610
  const spanText = new Map;
90888
91611
  const orderedIds = [];
90889
91612
  for (const paragraph2 of flattenParagraphs(blocks)) {
90890
- paragraph2.runs.forEach((run35, index2) => {
90891
- const comments = runComments(run35);
91613
+ paragraph2.runs.forEach((run37, index2) => {
91614
+ const comments = runComments(run37);
90892
91615
  if (!comments)
90893
91616
  return;
90894
- if (run35.type === "text" && !isRunVisible(run35, view))
91617
+ if (run37.type === "text" && !isRunVisible(run37, view))
90895
91618
  return;
90896
- const spanContribution = run35.type === "text" ? run35.text : run35.type === "equation" ? run35.text : "";
91619
+ const spanContribution = run37.type === "text" ? run37.text : run37.type === "equation" ? run37.text : "";
90897
91620
  for (const commentId of comments) {
90898
91621
  if (!spanText.has(commentId))
90899
91622
  orderedIds.push(commentId);
@@ -90913,11 +91636,11 @@ function buildCommentIndex(blocks, options) {
90913
91636
  }
90914
91637
  return { endingsByRun, spanText, orderedIds };
90915
91638
  }
90916
- function runComments(run35) {
90917
- if (run35.type === "text")
90918
- return run35.comments;
90919
- if (run35.type === "equation")
90920
- return run35.comments;
91639
+ function runComments(run37) {
91640
+ if (run37.type === "text")
91641
+ return run37.comments;
91642
+ if (run37.type === "equation")
91643
+ return run37.comments;
90921
91644
  return;
90922
91645
  }
90923
91646
  function slotKey(paragraphId, runIndex) {
@@ -90926,6 +91649,7 @@ function slotKey(paragraphId, runIndex) {
90926
91649
  function renderBlock(block, ctx) {
90927
91650
  if (block.type === "paragraph")
90928
91651
  return renderParagraph(block, ctx);
91652
+ ctx.prevListNumId = null;
90929
91653
  if (block.type === "table")
90930
91654
  return renderTable(block, ctx);
90931
91655
  return null;
@@ -90938,8 +91662,7 @@ function computeSectionStarts(blocks) {
90938
91662
  continue;
90939
91663
  const entry = {
90940
91664
  block: blocks[index2],
90941
- breakIndex: index2,
90942
- isTrailing: index2 === blocks.length - 1
91665
+ breakIndex: index2
90943
91666
  };
90944
91667
  const group = starts.get(sectionStart) ?? [];
90945
91668
  group.push(entry);
@@ -90949,12 +91672,7 @@ function computeSectionStarts(blocks) {
90949
91672
  return starts;
90950
91673
  }
90951
91674
  function renderSectionStart(entry, blocks, ctx) {
90952
- const marginalLines = ctx.marginalsBySection.get(entry.block.id);
90953
- if (entry.isTrailing) {
90954
- return marginalLines && marginalLines.length > 0 ? marginalLines.join(`
90955
- `) : null;
90956
- }
90957
- return renderSectionBreak(entry.block, governedRange(blocks, entry.breakIndex), marginalLines);
91675
+ return renderSectionBreak(entry.block, governedRange(blocks, entry.breakIndex), ctx.marginalsBySection.get(entry.block.id));
90958
91676
  }
90959
91677
  function computeGoverningColumns(blocks) {
90960
91678
  const map3 = new Map;
@@ -90995,7 +91713,7 @@ function tabCureRange(ids) {
90995
91713
  return min === max ? `p${min}` : `p${min}-p${max}`;
90996
91714
  }
90997
91715
  function layoutHazardNote(paragraph2, ctx) {
90998
- if (!paragraph2.runs.some((run35) => run35.type === "tab"))
91716
+ if (!paragraph2.runs.some((run37) => run37.type === "tab"))
90999
91717
  return "";
91000
91718
  const cols = ctx.governingColumns.get(paragraph2.id) ?? 1;
91001
91719
  if (cols > 1) {
@@ -91068,25 +91786,25 @@ function contentWidthEmu(geometry) {
91068
91786
  const fallback = (DEFAULT_PAGE.width - 2 * DEFAULT_PAGE.margin) * EMU_PER_TWIP2;
91069
91787
  return contentTwips > 0 ? contentTwips * EMU_PER_TWIP2 : fallback;
91070
91788
  }
91071
- function formatImageNote(run35, contentEmu) {
91789
+ function formatImageNote(run37, contentEmu) {
91072
91790
  const pairs = [];
91073
- if (run35.widthEmu && run35.heightEmu) {
91791
+ if (run37.widthEmu && run37.heightEmu) {
91074
91792
  pairs.push([
91075
91793
  "size",
91076
- `${emuToInches(run35.widthEmu)}x${emuToInches(run35.heightEmu)}in`
91794
+ `${emuToInches(run37.widthEmu)}x${emuToInches(run37.heightEmu)}in`
91077
91795
  ]);
91078
91796
  }
91079
- if (run35.floating)
91797
+ if (run37.floating)
91080
91798
  pairs.push(["float", "yes"]);
91081
- if (run35.wrap)
91082
- pairs.push(["wrap", run35.wrap]);
91083
- if (run35.align)
91084
- pairs.push(["align", run35.align]);
91085
- if (run35.widthEmu && run35.widthEmu > contentEmu)
91799
+ if (run37.wrap)
91800
+ pairs.push(["wrap", run37.wrap]);
91801
+ if (run37.align)
91802
+ pairs.push(["align", run37.align]);
91803
+ if (run37.widthEmu && run37.widthEmu > contentEmu)
91086
91804
  pairs.push(["overflow", "yes"]);
91087
91805
  if (pairs.length === 0)
91088
91806
  return "";
91089
- return ` ${formatNote("image", pairs, [run35.id])}`;
91807
+ return ` ${formatNote("image", pairs, [run37.id])}`;
91090
91808
  }
91091
91809
  function documentGeometry(blocks) {
91092
91810
  const geometric = blocks.filter((block) => block.type === "sectionBreak" && hasGeometry(block));
@@ -91192,14 +91910,14 @@ function isCodeBlockParagraph(block) {
91192
91910
  function renderCodeBlockGroup(paragraphs, ctx) {
91193
91911
  if (ctx.options.view !== "baseline" && ctx.options.view !== "accepted") {
91194
91912
  for (const paragraph2 of paragraphs) {
91195
- for (const run35 of paragraph2.runs) {
91196
- if (run35.type === "text" && run35.trackedChange) {
91197
- ctx.referencedTrackedChanges.set(run35.trackedChange.id, run35.trackedChange);
91913
+ for (const run37 of paragraph2.runs) {
91914
+ if (run37.type === "text" && run37.trackedChange) {
91915
+ ctx.referencedTrackedChanges.set(run37.trackedChange.id, run37.trackedChange);
91198
91916
  }
91199
91917
  }
91200
91918
  }
91201
91919
  }
91202
- const lines = paragraphs.map((paragraph2) => paragraph2.runs.filter((run35) => run35.type === "text" && typeof run35.text === "string").map((run35) => run35.text).join(""));
91920
+ const lines = paragraphs.map((paragraph2) => paragraph2.runs.filter((run37) => run37.type === "text" && typeof run37.text === "string").map((run37) => run37.text).join(""));
91203
91921
  const firstId = paragraphs[0]?.id ?? "";
91204
91922
  const lastId = paragraphs[paragraphs.length - 1]?.id ?? firstId;
91205
91923
  const language = codeBlockLanguageFromStyleId(paragraphs[0]?.style) ?? "";
@@ -91213,11 +91931,14 @@ function renderParagraph(paragraph2, ctx) {
91213
91931
  const view = ctx.options.view ?? "accepted";
91214
91932
  const mask = inlineEscapeMask(paragraphContent(paragraph2.runs, view), hasEquationRun(paragraph2.runs));
91215
91933
  const rendered = renderRuns(paragraph2.id, paragraph2.runs, ctx, mask, 0);
91216
- if (rendered.length === 0)
91934
+ if (rendered.length === 0) {
91935
+ ctx.prevListNumId = paragraph2.list?.numId ?? null;
91217
91936
  return null;
91937
+ }
91218
91938
  const prefix = paragraphPrefix(paragraph2, orderedOrdinal(paragraph2, ctx));
91219
91939
  const body = rendered.replace(/[ \t]+$/, "");
91220
- const note = formatParagraphNote(paragraph2);
91940
+ const listNote = listAnnotation(paragraph2, ctx);
91941
+ const note = listNote !== "" ? listNote : formatParagraphNote(paragraph2);
91221
91942
  const locatorOrNote = note !== "" ? note : ` <!-- ${paragraph2.id} -->`;
91222
91943
  const trailing = `${locatorOrNote}${layoutHazardNote(paragraph2, ctx)}`;
91223
91944
  if (isDisplayEquationOnly(body)) {
@@ -91282,7 +92003,8 @@ function orderedOrdinal(paragraph2, ctx) {
91282
92003
  return 1;
91283
92004
  const { numId, level } = paragraph2.list;
91284
92005
  const key = `${numId}:${level}`;
91285
- const next = (ctx.orderedCounters.get(key) ?? 0) + 1;
92006
+ const base = ctx.orderedCounters.get(key) ?? (paragraph2.list.start ?? 1) - 1;
92007
+ const next = base + 1;
91286
92008
  ctx.orderedCounters.set(key, next);
91287
92009
  for (const existing of ctx.orderedCounters.keys()) {
91288
92010
  const [keyNumId, keyLevel] = existing.split(":");
@@ -91292,6 +92014,32 @@ function orderedOrdinal(paragraph2, ctx) {
91292
92014
  }
91293
92015
  return next;
91294
92016
  }
92017
+ function listAnnotation(paragraph2, ctx) {
92018
+ const list3 = paragraph2.list;
92019
+ if (!list3) {
92020
+ ctx.prevListNumId = null;
92021
+ return "";
92022
+ }
92023
+ const isRunStart = ctx.prevListNumId !== list3.numId;
92024
+ ctx.prevListNumId = list3.numId;
92025
+ if (!isRunStart)
92026
+ return "";
92027
+ const isContinuation = ctx.seenListNumIds.has(list3.numId);
92028
+ ctx.seenListNumIds.add(list3.numId);
92029
+ if (!list3.ordered)
92030
+ return "";
92031
+ if (isContinuation) {
92032
+ return ` ${formatNote("list", [], [paragraph2.id, "continues"])}`;
92033
+ }
92034
+ const pairs = [];
92035
+ if (list3.start !== undefined && list3.start !== 1)
92036
+ pairs.push(["start", list3.start]);
92037
+ if (list3.format)
92038
+ pairs.push(["format", list3.format]);
92039
+ if (pairs.length === 0)
92040
+ return "";
92041
+ return ` ${formatNote("list", pairs, [paragraph2.id])}`;
92042
+ }
91295
92043
  function paragraphPrefix(paragraph2, ordinal) {
91296
92044
  const quotePrefix = paragraph2.quoteDepth ? "> ".repeat(paragraph2.quoteDepth) : "";
91297
92045
  const headingLevel2 = headingLevelFor(paragraph2.style);
@@ -91322,10 +92070,10 @@ function headingLevelFor(style) {
91322
92070
  function renderRuns(paragraphId, runs, ctx, mask, baseOffset) {
91323
92071
  const view = ctx.options.view ?? "accepted";
91324
92072
  const visibleEntries = [];
91325
- runs.forEach((run35, index2) => {
91326
- if (run35.type === "text" && !isRunVisible(run35, view))
92073
+ runs.forEach((run37, index2) => {
92074
+ if (run37.type === "text" && !isRunVisible(run37, view))
91327
92075
  return;
91328
- visibleEntries.push({ run: run35, originalIndex: index2 });
92076
+ visibleEntries.push({ run: run37, originalIndex: index2 });
91329
92077
  });
91330
92078
  let out = "";
91331
92079
  let cursor = 0;
@@ -91336,14 +92084,14 @@ function renderRuns(paragraphId, runs, ctx, mask, baseOffset) {
91336
92084
  cursor++;
91337
92085
  continue;
91338
92086
  }
91339
- const { run: run35 } = entry;
91340
- if (run35.type === "text") {
92087
+ const { run: run37 } = entry;
92088
+ if (run37.type === "text") {
91341
92089
  let lookahead2 = cursor + 1;
91342
92090
  while (lookahead2 < visibleEntries.length) {
91343
92091
  const next = visibleEntries[lookahead2];
91344
92092
  if (!next || next.run.type !== "text")
91345
92093
  break;
91346
- if (!sameDecoration(run35, next.run))
92094
+ if (!sameDecoration(run37, next.run))
91347
92095
  break;
91348
92096
  lookahead2++;
91349
92097
  }
@@ -91364,29 +92112,29 @@ function renderRuns(paragraphId, runs, ctx, mask, baseOffset) {
91364
92112
  cursor = lookahead2;
91365
92113
  continue;
91366
92114
  }
91367
- if (run35.type === "image") {
91368
- const alt = sanitizeAltText(run35.alt ?? run35.id);
91369
- const extension2 = extensionForImageMime(run35.contentType) ?? "bin";
91370
- out += `![${alt}](${run35.hash}.${extension2})`;
91371
- out += formatImageNote(run35, ctx.contentWidthEmu);
91372
- } else if (run35.type === "break") {
91373
- if (run35.kind === "line")
92115
+ if (run37.type === "image") {
92116
+ const alt = sanitizeAltText(run37.alt ?? run37.id);
92117
+ const extension2 = extensionForImageMime(run37.contentType) ?? "bin";
92118
+ out += `![${alt}](${run37.hash}.${extension2})`;
92119
+ out += formatImageNote(run37, ctx.contentWidthEmu);
92120
+ } else if (run37.type === "break") {
92121
+ if (run37.kind === "line")
91374
92122
  out += `
91375
92123
  `;
91376
- } else if (run35.type === "tab") {
92124
+ } else if (run37.type === "tab") {
91377
92125
  out += "\t";
91378
- } else if (run35.type === "equation") {
91379
- const body = run35.latex.length > 0 ? run35.latex : run35.text;
91380
- out += run35.display ? `$$${body}$$` : `$${body}$`;
92126
+ } else if (run37.type === "equation") {
92127
+ const body = run37.latex.length > 0 ? run37.latex : run37.text;
92128
+ out += run37.display ? `$$${body}$$` : `$${body}$`;
91381
92129
  out += commentEndingsFor(paragraphId, [{ originalIndex: cursor }], ctx.commentIndex);
91382
- } else if (run35.type === "noteRef") {
91383
- if (run35.kind === "footnote")
91384
- ctx.referencedFootnoteIds.add(run35.id);
92130
+ } else if (run37.type === "noteRef") {
92131
+ if (run37.kind === "footnote")
92132
+ ctx.referencedFootnoteIds.add(run37.id);
91385
92133
  else
91386
- ctx.referencedEndnoteIds.add(run35.id);
91387
- out += `[^${run35.id}]`;
91388
- } else if (run35.type === "chart") {
91389
- out += `\`[${run35.kind}]\``;
92134
+ ctx.referencedEndnoteIds.add(run37.id);
92135
+ out += `[^${run37.id}]`;
92136
+ } else if (run37.type === "chart") {
92137
+ out += `\`[${run37.kind}]\``;
91390
92138
  }
91391
92139
  cursor++;
91392
92140
  }
@@ -91420,7 +92168,7 @@ function sameCommentSet(left, right) {
91420
92168
  return true;
91421
92169
  }
91422
92170
  function renderTextSegment(runs, view, baseline, mask, offset2) {
91423
- const text6 = runs.map((run35) => run35.text).join("");
92171
+ const text6 = runs.map((run37) => run37.text).join("");
91424
92172
  if (text6.length === 0)
91425
92173
  return "";
91426
92174
  const first = runs[0];
@@ -91464,33 +92212,33 @@ function criticMarkerFor(kind) {
91464
92212
  return "++";
91465
92213
  return "--";
91466
92214
  }
91467
- function needsHtmlWrap(run35, baseline) {
91468
- return Boolean(run35.color && !isDefaultColor(run35.color) || run35.colorTheme && !isDefaultThemeColor(run35) || run35.shade || run35.font && run35.font !== baseline.font || run35.sizeHalfPoints !== undefined && run35.sizeHalfPoints !== baseline.sizeHalfPoints || run35.smallCaps || run35.allCaps || run35.underline || run35.vertAlign === "superscript" || run35.vertAlign === "subscript" || run35.highlight);
92215
+ function needsHtmlWrap(run37, baseline) {
92216
+ return Boolean(run37.color && !isDefaultColor(run37.color) || run37.colorTheme && !isDefaultThemeColor(run37) || run37.shade || run37.font && run37.font !== baseline.font || run37.sizeHalfPoints !== undefined && run37.sizeHalfPoints !== baseline.sizeHalfPoints || run37.smallCaps || run37.allCaps || run37.underline || run37.vertAlign === "superscript" || run37.vertAlign === "subscript" || run37.highlight);
91469
92217
  }
91470
- function wrapRunFormatting(body, run35, baseline) {
92218
+ function wrapRunFormatting(body, run37, baseline) {
91471
92219
  const styles = [];
91472
92220
  const attrs = [];
91473
- if (run35.color && !isDefaultColor(run35.color))
91474
- styles.push(`color:#${run35.color}`);
91475
- if (run35.shade)
91476
- styles.push(`background-color:#${run35.shade}`);
91477
- if (run35.font && run35.font !== baseline.font) {
91478
- styles.push(`font-family:${cssFontFamily(run35.font)}`);
92221
+ if (run37.color && !isDefaultColor(run37.color))
92222
+ styles.push(`color:#${run37.color}`);
92223
+ if (run37.shade)
92224
+ styles.push(`background-color:#${run37.shade}`);
92225
+ if (run37.font && run37.font !== baseline.font) {
92226
+ styles.push(`font-family:${cssFontFamily(run37.font)}`);
91479
92227
  }
91480
- if (run35.sizeHalfPoints !== undefined && run35.sizeHalfPoints !== baseline.sizeHalfPoints) {
91481
- styles.push(`font-size:${run35.sizeHalfPoints / 2}pt`);
92228
+ if (run37.sizeHalfPoints !== undefined && run37.sizeHalfPoints !== baseline.sizeHalfPoints) {
92229
+ styles.push(`font-size:${run37.sizeHalfPoints / 2}pt`);
91482
92230
  }
91483
- if (run35.smallCaps)
92231
+ if (run37.smallCaps)
91484
92232
  styles.push("font-variant:small-caps");
91485
- if (run35.allCaps)
92233
+ if (run37.allCaps)
91486
92234
  styles.push("text-transform:uppercase");
91487
- if (run35.colorTheme && !isDefaultThemeColor(run35)) {
91488
- attrs.push(htmlAttr("data-color-theme", run35.colorTheme));
91489
- if (run35.colorThemeTint) {
91490
- attrs.push(htmlAttr("data-color-theme-tint", run35.colorThemeTint));
92235
+ if (run37.colorTheme && !isDefaultThemeColor(run37)) {
92236
+ attrs.push(htmlAttr("data-color-theme", run37.colorTheme));
92237
+ if (run37.colorThemeTint) {
92238
+ attrs.push(htmlAttr("data-color-theme-tint", run37.colorThemeTint));
91491
92239
  }
91492
- if (run35.colorThemeShade) {
91493
- attrs.push(htmlAttr("data-color-theme-shade", run35.colorThemeShade));
92240
+ if (run37.colorThemeShade) {
92241
+ attrs.push(htmlAttr("data-color-theme-shade", run37.colorThemeShade));
91494
92242
  }
91495
92243
  }
91496
92244
  let out = body;
@@ -91499,18 +92247,18 @@ function wrapRunFormatting(body, run35, baseline) {
91499
92247
  const attrPart = attrs.length > 0 ? ` ${attrs.join(" ")}` : "";
91500
92248
  out = `<span${stylePart}${attrPart}>${out}</span>`;
91501
92249
  }
91502
- if (run35.underline === "single") {
92250
+ if (run37.underline === "single") {
91503
92251
  out = `<u>${out}</u>`;
91504
- } else if (run35.underline) {
91505
- const color2 = run35.underlineColor ? ` ${htmlAttr("data-underline-color", run35.underlineColor)}` : "";
91506
- out = `<u ${htmlAttr("data-underline", run35.underline)}${color2}>${out}</u>`;
92252
+ } else if (run37.underline) {
92253
+ const color2 = run37.underlineColor ? ` ${htmlAttr("data-underline-color", run37.underlineColor)}` : "";
92254
+ out = `<u ${htmlAttr("data-underline", run37.underline)}${color2}>${out}</u>`;
91507
92255
  }
91508
- if (run35.vertAlign === "superscript")
92256
+ if (run37.vertAlign === "superscript")
91509
92257
  out = `<sup>${out}</sup>`;
91510
- else if (run35.vertAlign === "subscript")
92258
+ else if (run37.vertAlign === "subscript")
91511
92259
  out = `<sub>${out}</sub>`;
91512
- if (run35.highlight) {
91513
- const named = run35.highlight === "yellow" ? "" : ` ${htmlAttr("data-highlight", run35.highlight)}`;
92260
+ if (run37.highlight) {
92261
+ const named = run37.highlight === "yellow" ? "" : ` ${htmlAttr("data-highlight", run37.highlight)}`;
91514
92262
  out = `<mark${named}>${out}</mark>`;
91515
92263
  }
91516
92264
  return out;
@@ -91519,8 +92267,8 @@ function isDefaultColor(color2) {
91519
92267
  const normalized = color2.toLowerCase();
91520
92268
  return normalized === "000000" || normalized === "auto";
91521
92269
  }
91522
- function isDefaultThemeColor(run35) {
91523
- return (run35.colorTheme === "text1" || run35.colorTheme === "dark1") && !run35.colorThemeTint && !run35.colorThemeShade;
92270
+ function isDefaultThemeColor(run37) {
92271
+ return (run37.colorTheme === "text1" || run37.colorTheme === "dark1") && !run37.colorThemeTint && !run37.colorThemeShade;
91524
92272
  }
91525
92273
  function cssFontFamily(font) {
91526
92274
  return /\s/.test(font) ? `'${font}'` : font;
@@ -91537,19 +92285,19 @@ function applyEscapeMask(text6, mask, offset2) {
91537
92285
  }
91538
92286
  function paragraphContent(runs, view) {
91539
92287
  let content3 = "";
91540
- for (const run35 of runs) {
91541
- if (run35.type !== "text")
92288
+ for (const run37 of runs) {
92289
+ if (run37.type !== "text")
91542
92290
  continue;
91543
- if (run35.runStyle === "Code")
92291
+ if (run37.runStyle === "Code")
91544
92292
  continue;
91545
- if (!isRunVisible(run35, view))
92293
+ if (!isRunVisible(run37, view))
91546
92294
  continue;
91547
- content3 += run35.text;
92295
+ content3 += run37.text;
91548
92296
  }
91549
92297
  return content3;
91550
92298
  }
91551
92299
  function hasEquationRun(runs) {
91552
- return runs.some((run35) => run35.type === "equation");
92300
+ return runs.some((run37) => run37.type === "equation");
91553
92301
  }
91554
92302
  function renderTable(table, ctx) {
91555
92303
  const view = ctx.options.view ?? "accepted";
@@ -91593,10 +92341,24 @@ function formatTableNote(table) {
91593
92341
  if (table.borders && table.borders !== "single") {
91594
92342
  pairs.push(["borders", table.borders]);
91595
92343
  }
92344
+ if (table.align && table.align !== "left")
92345
+ pairs.push(["align", table.align]);
92346
+ if (table.style)
92347
+ pairs.push(["style", table.style]);
92348
+ const repeatHeaderRows = table.rows.map((row, index2) => row.repeatHeader ? `r${index2}` : null).filter((value) => value !== null);
92349
+ if (repeatHeaderRows.length > 0)
92350
+ pairs.push(["repeat-header", repeatHeaderRows.join(",")]);
92351
+ const rowHeights = table.rows.map((row, index2) => row.height ? `r${index2}:${formatRowHeight(row.height)}` : null).filter((value) => value !== null);
92352
+ if (rowHeights.length > 0)
92353
+ pairs.push(["row-heights", rowHeights.join(",")]);
91596
92354
  if (pairs.length === 0)
91597
92355
  return "";
91598
92356
  return formatNote("table", pairs, [table.id]);
91599
92357
  }
92358
+ function formatRowHeight(height) {
92359
+ const inches = `${twipsToInches(height.value)}in`;
92360
+ return height.rule === "atLeast" ? inches : `${inches}(${height.rule})`;
92361
+ }
91600
92362
  function unevenWidths(grid) {
91601
92363
  if (grid.length < 2)
91602
92364
  return;
@@ -91653,11 +92415,27 @@ function cellNote(cell) {
91653
92415
  pairs.push(["vMerge", cell.vMerge]);
91654
92416
  if (cell.shading)
91655
92417
  pairs.push(["shading", cell.shading]);
92418
+ if (cell.vAlign)
92419
+ pairs.push(["vAlign", cell.vAlign]);
92420
+ if (cell.borders)
92421
+ pairs.push(["borders", cell.borders]);
92422
+ const halign = uniformCellAlignment(cell);
92423
+ if (halign)
92424
+ pairs.push(["halign", halign]);
91656
92425
  if (pairs.length === 0)
91657
92426
  return "";
91658
92427
  const address = cellAddress(cell);
91659
92428
  return formatNote("cell", pairs, address ? [address] : []);
91660
92429
  }
92430
+ function uniformCellAlignment(cell) {
92431
+ const aligns = cell.blocks.filter((block) => block.type === "paragraph").map((paragraph2) => paragraph2.alignment ?? "left");
92432
+ if (aligns.length === 0)
92433
+ return;
92434
+ const first = aligns[0];
92435
+ if (!first || first === "left")
92436
+ return;
92437
+ return aligns.every((align) => align === first) ? first : undefined;
92438
+ }
91661
92439
  function cellAddress(cell) {
91662
92440
  return cell.blocks[0]?.id.replace(/:(?:p|t)\d+$/, "");
91663
92441
  }
@@ -91835,9 +92613,9 @@ var init_markdown3 = __esm(() => {
91835
92613
  // src/cli/read/index.ts
91836
92614
  var exports_read = {};
91837
92615
  __export(exports_read, {
91838
- run: () => run35
92616
+ run: () => run37
91839
92617
  });
91840
- async function run35(args) {
92618
+ async function run37(args) {
91841
92619
  const parsed = await tryParseArgs(args, {
91842
92620
  ast: { type: "boolean" },
91843
92621
  from: { type: "string" },
@@ -91847,16 +92625,16 @@ async function run35(args) {
91847
92625
  current: { type: "boolean" },
91848
92626
  comments: { type: "boolean" },
91849
92627
  help: { type: "boolean", short: "h" }
91850
- }, HELP31);
92628
+ }, HELP33);
91851
92629
  if (typeof parsed === "number")
91852
92630
  return parsed;
91853
92631
  if (parsed.values.help) {
91854
- await writeStdout(HELP31);
92632
+ await writeStdout(HELP33);
91855
92633
  return EXIT2.OK;
91856
92634
  }
91857
92635
  const path2 = parsed.positionals[0];
91858
92636
  if (!path2)
91859
- return fail("USAGE", "Missing FILE argument", HELP31);
92637
+ return fail("USAGE", "Missing FILE argument", HELP33);
91860
92638
  const ast = Boolean(parsed.values.ast);
91861
92639
  const from = parsed.values.from;
91862
92640
  const to = parsed.values.to;
@@ -91865,11 +92643,11 @@ async function run35(args) {
91865
92643
  const current = Boolean(parsed.values.current);
91866
92644
  const showComments = Boolean(parsed.values.comments);
91867
92645
  if (ast && (from || to || accepted || baseline || current || showComments)) {
91868
- return fail("USAGE", "--from, --to, --accepted, --baseline, --current, and --comments are Markdown-only and cannot be combined with --ast", HELP31);
92646
+ return fail("USAGE", "--from, --to, --accepted, --baseline, --current, and --comments are Markdown-only and cannot be combined with --ast", HELP33);
91869
92647
  }
91870
92648
  const view = resolveView({ accepted, baseline, current });
91871
92649
  if (!view) {
91872
- return fail("USAGE", "--accepted, --baseline, and --current are mutually exclusive", HELP31);
92650
+ return fail("USAGE", "--accepted, --baseline, and --current are mutually exclusive", HELP33);
91873
92651
  }
91874
92652
  const docView = await openOrFail(path2);
91875
92653
  if (typeof docView === "number")
@@ -91898,7 +92676,7 @@ async function run35(args) {
91898
92676
  throw err;
91899
92677
  }
91900
92678
  }
91901
- var HELP31 = `docx read \u2014 render document body as Markdown, or print AST as JSON
92679
+ var HELP33 = `docx read \u2014 render document body as Markdown, or print AST as JSON
91902
92680
 
91903
92681
  Usage:
91904
92682
  docx read FILE [options]
@@ -91988,20 +92766,20 @@ function parsePagesSpec(spec) {
91988
92766
  // src/cli/render/index.ts
91989
92767
  var exports_render = {};
91990
92768
  __export(exports_render, {
91991
- run: () => run36
92769
+ run: () => run38
91992
92770
  });
91993
92771
  import { basename as basename2, extname as extname2, resolve as resolve2 } from "path";
91994
- async function run36(args) {
91995
- const parsed = await tryParseArgs(args, OPTION_SPEC6, HELP32);
92772
+ async function run38(args) {
92773
+ const parsed = await tryParseArgs(args, OPTION_SPEC6, HELP34);
91996
92774
  if (typeof parsed === "number")
91997
92775
  return parsed;
91998
92776
  if (parsed.values.help) {
91999
- await writeStdout(HELP32);
92777
+ await writeStdout(HELP34);
92000
92778
  return EXIT2.OK;
92001
92779
  }
92002
92780
  const filePath = parsed.positionals[0];
92003
92781
  if (!filePath)
92004
- return fail("USAGE", "Missing FILE argument", HELP32);
92782
+ return fail("USAGE", "Missing FILE argument", HELP34);
92005
92783
  if (!await Bun.file(filePath).exists()) {
92006
92784
  return fail("FILE_NOT_FOUND", `File not found: ${filePath}`);
92007
92785
  }
@@ -92081,7 +92859,7 @@ function availabilityHint(installed) {
92081
92859
  }
92082
92860
  return `Detected engines: ${installed.join(", ")} \u2014 but none chose auto-select; pass --engine explicitly.`;
92083
92861
  }
92084
- var HELP32 = `docx render \u2014 render each page of a .docx as a PNG/JPG image
92862
+ var HELP34 = `docx render \u2014 render each page of a .docx as a PNG/JPG image
92085
92863
 
92086
92864
  Usage:
92087
92865
  docx render FILE [options]
@@ -92148,6 +92926,55 @@ var init_render2 = __esm(() => {
92148
92926
  };
92149
92927
  });
92150
92928
 
92929
+ // src/cli/replace/scope.ts
92930
+ function validateScopeShape(at) {
92931
+ let parsed;
92932
+ try {
92933
+ parsed = parseLocator(at);
92934
+ } catch (error) {
92935
+ if (error instanceof LocatorParseError) {
92936
+ throw new ScopeError("INVALID_LOCATOR", error.message);
92937
+ }
92938
+ throw error;
92939
+ }
92940
+ if (!isParagraphLocator(parsed)) {
92941
+ throw new ScopeError("INVALID_LOCATOR", `--at scope must be a single paragraph (pN) or cell paragraph (tT:rRcC:pN), got "${at}" \u2014 replace targets text within one paragraph`);
92942
+ }
92943
+ return at;
92944
+ }
92945
+ function isParagraphLocator(parsed) {
92946
+ if (parsed.kind === "block")
92947
+ return parsed.blockId[0] === "p";
92948
+ let inner2 = parsed;
92949
+ while (inner2?.kind === "cell")
92950
+ inner2 = inner2.inner;
92951
+ return inner2?.kind === "block" && inner2.blockId[0] === "p";
92952
+ }
92953
+ function resolveReplaceScope(document4, at) {
92954
+ const blockId = validateScopeShape(at);
92955
+ try {
92956
+ document4.body.resolveBlock(at);
92957
+ } catch (error) {
92958
+ throw new ScopeError("BLOCK_NOT_FOUND", error.message);
92959
+ }
92960
+ return blockId;
92961
+ }
92962
+ function matchesInScope(matches, blockId) {
92963
+ return matches.filter((match) => match.blockId === blockId);
92964
+ }
92965
+ var ScopeError;
92966
+ var init_scope = __esm(() => {
92967
+ init_core2();
92968
+ ScopeError = class ScopeError extends Error {
92969
+ code;
92970
+ constructor(code3, message) {
92971
+ super(message);
92972
+ this.code = code3;
92973
+ this.name = "ScopeError";
92974
+ }
92975
+ };
92976
+ });
92977
+
92151
92978
  // src/cli/replace/batch.ts
92152
92979
  async function runReplaceBatch(filePath, batchSource, values2) {
92153
92980
  const authorFlag = values2.author;
@@ -92181,6 +93008,13 @@ async function runReplaceBatch(filePath, batchSource, values2) {
92181
93008
  const spec = specs[index2];
92182
93009
  if (!spec)
92183
93010
  continue;
93011
+ if (spec.at !== undefined) {
93012
+ try {
93013
+ document4.body.resolveBlock(spec.at);
93014
+ } catch {
93015
+ return fail("BLOCK_NOT_FOUND", `entry ${index2}: scope "${spec.at}" not found`);
93016
+ }
93017
+ }
92184
93018
  let findResult;
92185
93019
  try {
92186
93020
  findResult = findTextSpans(document4.body, spec.pattern, {
@@ -92193,7 +93027,7 @@ async function runReplaceBatch(filePath, batchSource, values2) {
92193
93027
  const message = matcherError instanceof Error ? matcherError.message : String(matcherError);
92194
93028
  return fail("USAGE", `entry ${index2}: invalid pattern: ${message}`);
92195
93029
  }
92196
- const all2 = findResult.matches;
93030
+ const all2 = spec.at !== undefined ? matchesInScope(findResult.matches, spec.at) : findResult.matches;
92197
93031
  const selected = spec.limit !== undefined ? all2.slice(0, spec.limit) : spec.all ? all2 : all2.slice(0, 1);
92198
93032
  const tracked = allocator ? {
92199
93033
  meta: {
@@ -92265,6 +93099,20 @@ function validateSpec(raw, index2) {
92265
93099
  }
92266
93100
  limit = value;
92267
93101
  }
93102
+ let at;
93103
+ if (raw.at !== undefined) {
93104
+ if (typeof raw.at !== "string") {
93105
+ throw new EntryError3("USAGE", `entry ${index2}: "at" must be a string`);
93106
+ }
93107
+ try {
93108
+ at = validateScopeShape(raw.at);
93109
+ } catch (error) {
93110
+ if (error instanceof ScopeError) {
93111
+ throw new EntryError3(error.code, `entry ${index2}: ${error.message}`);
93112
+ }
93113
+ throw error;
93114
+ }
93115
+ }
92268
93116
  return {
92269
93117
  pattern: raw.pattern,
92270
93118
  replacement: raw.replacement,
@@ -92274,7 +93122,8 @@ function validateSpec(raw, index2) {
92274
93122
  all: Boolean(raw.all),
92275
93123
  ...limit !== undefined ? { limit } : {},
92276
93124
  view: wantCurrent ? "current" : wantBaseline ? "baseline" : "accepted",
92277
- ...typeof raw.author === "string" ? { author: raw.author } : {}
93125
+ ...typeof raw.author === "string" ? { author: raw.author } : {},
93126
+ ...at !== undefined ? { at } : {}
92278
93127
  };
92279
93128
  }
92280
93129
  var EntryError3;
@@ -92283,6 +93132,7 @@ var init_batch4 = __esm(() => {
92283
93132
  init_find();
92284
93133
  init_parse_helpers();
92285
93134
  init_respond();
93135
+ init_scope();
92286
93136
  EntryError3 = class EntryError3 extends Error {
92287
93137
  code;
92288
93138
  hint;
@@ -92298,11 +93148,12 @@ var init_batch4 = __esm(() => {
92298
93148
  // src/cli/replace/index.ts
92299
93149
  var exports_replace3 = {};
92300
93150
  __export(exports_replace3, {
92301
- run: () => run37
93151
+ run: () => run39
92302
93152
  });
92303
- async function run37(args) {
93153
+ async function run39(args) {
92304
93154
  const parsed = await tryParseArgs(args, {
92305
93155
  batch: { type: "string" },
93156
+ at: { type: "string" },
92306
93157
  regex: { type: "boolean" },
92307
93158
  "ignore-case": { type: "boolean" },
92308
93159
  all: { type: "boolean" },
@@ -92313,30 +93164,33 @@ async function run37(args) {
92313
93164
  baseline: { type: "boolean" },
92314
93165
  exact: { type: "boolean" },
92315
93166
  ...SAVE_FLAGS
92316
- }, HELP33);
93167
+ }, HELP35);
92317
93168
  if (typeof parsed === "number")
92318
93169
  return parsed;
92319
93170
  if (parsed.values.help) {
92320
- await writeStdout(HELP33);
93171
+ await writeStdout(HELP35);
92321
93172
  return EXIT2.OK;
92322
93173
  }
92323
93174
  setVerboseAck(Boolean(parsed.values.verbose));
92324
93175
  const path2 = parsed.positionals[0];
92325
93176
  if (!path2)
92326
- return fail("USAGE", "Missing FILE argument", HELP33);
93177
+ return fail("USAGE", "Missing FILE argument", HELP35);
92327
93178
  const batchInput = parsed.values.batch;
92328
93179
  if (batchInput !== undefined) {
92329
93180
  if (parsed.positionals.length > 1) {
92330
- return fail("USAGE", "--batch reads pattern/replacement from the JSONL file; don't also pass them as positionals", HELP33);
93181
+ return fail("USAGE", "--batch reads pattern/replacement from the JSONL file; don't also pass them as positionals", HELP35);
93182
+ }
93183
+ if (parsed.values.at !== undefined) {
93184
+ return fail("USAGE", '--at is per-entry in batch mode: put "at" on each JSONL line, not on the command', HELP35);
92331
93185
  }
92332
93186
  return runReplaceBatch(path2, batchInput, parsed.values);
92333
93187
  }
92334
93188
  const pattern = parsed.positionals[1];
92335
93189
  const replacement = parsed.positionals[2];
92336
93190
  if (pattern == null)
92337
- return fail("USAGE", "Missing PATTERN argument", HELP33);
93191
+ return fail("USAGE", "Missing PATTERN argument", HELP35);
92338
93192
  if (replacement == null) {
92339
- return fail("USAGE", "Missing REPLACEMENT argument", HELP33);
93193
+ return fail("USAGE", "Missing REPLACEMENT argument", HELP35);
92340
93194
  }
92341
93195
  const ignoreCase = Boolean(parsed.values["ignore-case"]);
92342
93196
  const useRegex = Boolean(parsed.values.regex);
@@ -92366,7 +93220,19 @@ async function run37(args) {
92366
93220
  const message = matcherError instanceof Error ? matcherError.message : String(matcherError);
92367
93221
  return fail("USAGE", `Invalid pattern: ${message}`);
92368
93222
  }
92369
- const allMatches = findResult.matches;
93223
+ const atScope = parsed.values.at;
93224
+ let allMatches = findResult.matches;
93225
+ if (atScope !== undefined) {
93226
+ try {
93227
+ const blockId = resolveReplaceScope(document4, atScope);
93228
+ allMatches = matchesInScope(allMatches, blockId);
93229
+ } catch (scopeError) {
93230
+ if (scopeError instanceof ScopeError) {
93231
+ return fail(scopeError.code, scopeError.message);
93232
+ }
93233
+ throw scopeError;
93234
+ }
93235
+ }
92370
93236
  const normalizationFields = findResult.normalizedQuery !== undefined ? {
92371
93237
  normalizedPattern: findResult.normalizedQuery,
92372
93238
  normalizationApplied: findResult.normalizationApplied
@@ -92397,6 +93263,7 @@ async function run37(args) {
92397
93263
  regex: useRegex,
92398
93264
  ignoreCase,
92399
93265
  view: findView,
93266
+ ...atScope ? { at: atScope } : {},
92400
93267
  totalMatches: allMatches.length,
92401
93268
  replaced: selected.length,
92402
93269
  matches: matchesPayload,
@@ -92415,6 +93282,7 @@ async function run37(args) {
92415
93282
  regex: useRegex,
92416
93283
  ignoreCase,
92417
93284
  view: findView,
93285
+ ...atScope ? { at: atScope } : {},
92418
93286
  totalMatches: 0,
92419
93287
  replaced: 0,
92420
93288
  matches: [],
@@ -92451,6 +93319,7 @@ async function run37(args) {
92451
93319
  regex: useRegex,
92452
93320
  ignoreCase,
92453
93321
  view: findView,
93322
+ ...atScope ? { at: atScope } : {},
92454
93323
  totalMatches: allMatches.length,
92455
93324
  replaced: selected.length,
92456
93325
  matches: matchesPayload,
@@ -92458,7 +93327,7 @@ async function run37(args) {
92458
93327
  }, partialHint);
92459
93328
  return EXIT2.OK;
92460
93329
  }
92461
- var HELP33 = `docx replace \u2014 substitute text spans (sed for docx)
93330
+ var HELP35 = `docx replace \u2014 substitute text spans (sed for docx)
92462
93331
 
92463
93332
  Usage:
92464
93333
  docx replace FILE PATTERN REPLACEMENT [options]
@@ -92466,9 +93335,16 @@ Usage:
92466
93335
  docx replace FILE --batch - [options] # read JSONL from stdin
92467
93336
 
92468
93337
  Options:
93338
+ --at LOCATOR confine the replace to ONE paragraph: a body pN or a cell
93339
+ paragraph tT:rRcC:pN. Use this when the same placeholder
93340
+ repeats across the document (a r\xE9sum\xE9's "City, State" /
93341
+ "Position Title" in every entry) and you want THE one in a
93342
+ specific paragraph \u2014 no find + offset-span edit needed:
93343
+ docx replace doc.docx --at p20 "City, State" "San Francisco, CA"
92469
93344
  --regex treat PATTERN as a JavaScript regular expression
92470
93345
  --ignore-case case-insensitive match
92471
- --all replace every match (default: just the first)
93346
+ --all replace every match (default: just the first; with --at,
93347
+ scoped to that paragraph)
92472
93348
  --limit N replace at most N matches (in document order)
92473
93349
  --author NAME author for tracked changes (default: $DOCX_AUTHOR)
92474
93350
  --track record substitutions as tracked changes even when the
@@ -92539,28 +93415,29 @@ var init_replace4 = __esm(() => {
92539
93415
  init_parse_helpers();
92540
93416
  init_respond();
92541
93417
  init_batch4();
93418
+ init_scope();
92542
93419
  });
92543
93420
 
92544
93421
  // src/cli/sections/index.tsx
92545
93422
  var exports_sections = {};
92546
93423
  __export(exports_sections, {
92547
- run: () => run38
93424
+ run: () => run40
92548
93425
  });
92549
93426
  function hasPageGeometry(flags) {
92550
93427
  return flags.pageSize !== undefined || flags.orientation !== undefined || flags.margins !== undefined;
92551
93428
  }
92552
- async function run38(args) {
92553
- const parsed = await tryParseArgs(args, OPTION_SPEC7, HELP34);
93429
+ async function run40(args) {
93430
+ const parsed = await tryParseArgs(args, OPTION_SPEC7, HELP36);
92554
93431
  if (typeof parsed === "number")
92555
93432
  return parsed;
92556
93433
  if (parsed.values.help) {
92557
- await writeStdout(HELP34);
93434
+ await writeStdout(HELP36);
92558
93435
  return EXIT2.OK;
92559
93436
  }
92560
93437
  setVerboseAck(Boolean(parsed.values.verbose));
92561
93438
  const filePath = parsed.positionals[0];
92562
93439
  if (!filePath)
92563
- return fail("USAGE", "Missing FILE argument", HELP34);
93440
+ return fail("USAGE", "Missing FILE argument", HELP36);
92564
93441
  const at = parsed.values.at;
92565
93442
  const flags = await parseSectionFlags(parsed.values);
92566
93443
  if (typeof flags === "number")
@@ -92580,22 +93457,22 @@ async function run38(args) {
92580
93457
  if (hasPageGeometry(flags) && flags.columns === undefined && flags.sectionType === undefined) {
92581
93458
  return editAllSections(document4, opts);
92582
93459
  }
92583
- return fail("USAGE", "Missing --at LOCATOR (a section sN, or a range pN-pM to wrap in columns). To set PAGE GEOMETRY for the whole document, omit --at and pass only --margins/--orientation/--size.", HELP34);
93460
+ return fail("USAGE", "Missing --at LOCATOR (a section sN, or a range pN-pM to wrap in columns). To set PAGE GEOMETRY for the whole document, omit --at and pass only --margins/--orientation/--size.", HELP36);
92584
93461
  }
92585
93462
  let locator;
92586
93463
  try {
92587
93464
  locator = parseLocator(at);
92588
93465
  } catch (error) {
92589
93466
  if (error instanceof LocatorParseError) {
92590
- return fail("INVALID_LOCATOR", error.message, HELP34);
93467
+ return fail("INVALID_LOCATOR", error.message, HELP36);
92591
93468
  }
92592
93469
  throw error;
92593
93470
  }
92594
93471
  if (locator.kind === "blockRange") {
92595
93472
  if (hasPageGeometry(flags))
92596
- return fail("USAGE", WRAP_REJECTS_GEOMETRY, HELP34);
93473
+ return fail("USAGE", WRAP_REJECTS_GEOMETRY, HELP36);
92597
93474
  if (flags.columns === undefined) {
92598
- return fail("USAGE", "Wrapping a range in a section needs --columns N", HELP34);
93475
+ return fail("USAGE", "Wrapping a range in a section needs --columns N", HELP36);
92599
93476
  }
92600
93477
  const range = await resolveBlockRangeOrFail(document4, at);
92601
93478
  if (typeof range === "number")
@@ -92607,20 +93484,20 @@ async function run38(args) {
92607
93484
  return blockRef;
92608
93485
  if (blockRef.node.tag === "w:sectPr") {
92609
93486
  if (flags.columns === undefined && flags.sectionType === undefined && !hasPageGeometry(flags)) {
92610
- return fail("USAGE", "Section edit needs --columns, --type, --orientation, --size, or --margins", HELP34);
93487
+ return fail("USAGE", "Section edit needs --columns, --type, --orientation, --size, or --margins", HELP36);
92611
93488
  }
92612
93489
  return editSection(document4, blockRef, at, opts);
92613
93490
  }
92614
93491
  if (blockRef.node.tag === "w:p") {
92615
93492
  if (hasPageGeometry(flags))
92616
- return fail("USAGE", WRAP_REJECTS_GEOMETRY, HELP34);
93493
+ return fail("USAGE", WRAP_REJECTS_GEOMETRY, HELP36);
92617
93494
  if (flags.columns === undefined) {
92618
- return fail("USAGE", "Wrapping a paragraph in a section needs --columns N", HELP34);
93495
+ return fail("USAGE", "Wrapping a paragraph in a section needs --columns N", HELP36);
92619
93496
  }
92620
93497
  const index2 = blockRef.parent.indexOf(blockRef.node);
92621
93498
  return wrapRange(document4, blockRef.parent, index2, index2, at, opts);
92622
93499
  }
92623
- return fail("INVALID_LOCATOR", `--at needs a section (sN) or a paragraph range (pN-pM); ${at} is neither`, HELP34);
93500
+ return fail("INVALID_LOCATOR", `--at needs a section (sN) or a paragraph range (pN-pM); ${at} is neither`, HELP36);
92624
93501
  }
92625
93502
  async function editSection(document4, blockRef, at, opts) {
92626
93503
  const track = resolveTracked(document4, opts.trackFlag);
@@ -92873,7 +93750,7 @@ async function commit(document4, opts, meta) {
92873
93750
  }, realignedNote + renderVerifyHint(destination));
92874
93751
  return EXIT2.OK;
92875
93752
  }
92876
- var HELP34 = `docx sections \u2014 multi-column layout, section breaks & page setup
93753
+ var HELP36 = `docx sections \u2014 multi-column layout, section breaks & page setup
92877
93754
 
92878
93755
  Usage:
92879
93756
  docx sections FILE --at LOCATOR (--columns N | page setup) [options]
@@ -93366,9 +94243,9 @@ function appliedStyleIds(document4) {
93366
94243
  continue;
93367
94244
  if (block.style)
93368
94245
  used.add(block.style);
93369
- for (const run39 of block.runs) {
93370
- if (run39.type === "text" && run39.runStyle)
93371
- used.add(run39.runStyle);
94246
+ for (const run41 of block.runs) {
94247
+ if (run41.type === "text" && run41.runStyle)
94248
+ used.add(run41.runStyle);
93372
94249
  }
93373
94250
  }
93374
94251
  return used;
@@ -93524,8 +94401,8 @@ function countStyleUsage(document4, styleId) {
93524
94401
  continue;
93525
94402
  if (block.style === styleId)
93526
94403
  count++;
93527
- for (const run39 of block.runs) {
93528
- if (run39.type === "text" && run39.runStyle === styleId)
94404
+ for (const run41 of block.runs) {
94405
+ if (run41.type === "text" && run41.runStyle === styleId)
93529
94406
  count++;
93530
94407
  }
93531
94408
  }
@@ -93577,7 +94454,7 @@ Examples:
93577
94454
  docx styles set report.docx --at Normal --font "Times New Roman" --size 12
93578
94455
  docx styles set report.docx --at Quote --italic --indent-left 0.5 --space-after 6
93579
94456
  `;
93580
- var init_set2 = __esm(() => {
94457
+ var init_set3 = __esm(() => {
93581
94458
  init_core2();
93582
94459
  init_respond();
93583
94460
  init_shared2();
@@ -93663,6 +94540,11 @@ theme-following headings adopt the font. Styles/runs that pin their OWN font
93663
94540
  (e.g. a code block's monospace, a deliberately-Arial run) are preserved; pass
93664
94541
  --all to repoint those too.
93665
94542
 
94543
+ Theme-following headings only adopt the font if the document HAS a theme part
94544
+ (every doc this CLI creates does; Word docs do too). The ack's "themeUpdated"
94545
+ is false for the rare theme-less doc \u2014 there the body changes but headings keep
94546
+ their fallback font; run with --all to force the headings onto the new font.
94547
+
93666
94548
  Options:
93667
94549
  --size N Also set the default font size, in points (e.g. 12).
93668
94550
  --all Repoint EVERY explicit font \u2014 styles, body runs, and notes \u2014
@@ -93686,18 +94568,18 @@ var init_set_default_font = __esm(() => {
93686
94568
  // src/cli/styles/index.ts
93687
94569
  var exports_styles = {};
93688
94570
  __export(exports_styles, {
93689
- run: () => run39
94571
+ run: () => run41
93690
94572
  });
93691
- async function run39(args) {
94573
+ async function run41(args) {
93692
94574
  if (args[0] === "set-default-font")
93693
94575
  return runSetDefaultFont(args.slice(1));
93694
94576
  if (args[0] === "set")
93695
94577
  return runStylesSet(args.slice(1));
93696
94578
  if (args[0] === "create")
93697
94579
  return runStylesCreate(args.slice(1));
93698
- return runStylesRead(args, HELP35);
94580
+ return runStylesRead(args, HELP37);
93699
94581
  }
93700
- var HELP35 = `docx styles \u2014 inspect, edit, and create the styles a document can apply
94582
+ var HELP37 = `docx styles \u2014 inspect, edit, and create the styles a document can apply
93701
94583
 
93702
94584
  Usage:
93703
94585
  docx styles FILE [--used] [--at STYLEID] [--json] # list / describe (read)
@@ -93740,16 +94622,16 @@ See \`docx styles set --help\`, \`docx styles create --help\`, and
93740
94622
  var init_styles2 = __esm(() => {
93741
94623
  init_create3();
93742
94624
  init_read4();
93743
- init_set2();
94625
+ init_set3();
93744
94626
  init_set_default_font();
93745
94627
  });
93746
94628
 
93747
94629
  // src/cli/tables/insert-row.tsx
93748
94630
  var exports_insert_row = {};
93749
94631
  __export(exports_insert_row, {
93750
- run: () => run40
94632
+ run: () => run42
93751
94633
  });
93752
- async function run40(args) {
94634
+ async function run42(args) {
93753
94635
  const parsed = await tryParseArgs(args, {
93754
94636
  at: { type: "string" },
93755
94637
  position: { type: "string" },
@@ -93757,20 +94639,20 @@ async function run40(args) {
93757
94639
  author: { type: "string" },
93758
94640
  track: { type: "boolean" },
93759
94641
  ...SAVE_FLAGS
93760
- }, HELP36);
94642
+ }, HELP38);
93761
94643
  if (typeof parsed === "number")
93762
94644
  return parsed;
93763
94645
  if (parsed.values.help) {
93764
- await writeStdout(HELP36);
94646
+ await writeStdout(HELP38);
93765
94647
  return EXIT2.OK;
93766
94648
  }
93767
94649
  setVerboseAck(Boolean(parsed.values.verbose));
93768
94650
  const path2 = parsed.positionals[0];
93769
94651
  if (!path2)
93770
- return fail("USAGE", "Missing FILE argument", HELP36);
94652
+ return fail("USAGE", "Missing FILE argument", HELP38);
93771
94653
  const at = parsed.values.at;
93772
94654
  if (!at)
93773
- return fail("USAGE", "Missing --at tN", HELP36);
94655
+ return fail("USAGE", "Missing --at tN", HELP38);
93774
94656
  const tableId = parseTableAt(at);
93775
94657
  if (!tableId) {
93776
94658
  return fail("INVALID_LOCATOR", `--at must be a table id like t0 (got ${at})`);
@@ -93791,7 +94673,7 @@ async function run40(args) {
93791
94673
  }
93792
94674
  const cellTexts = parsed.values.cells ? parsed.values.cells.split(",") : [];
93793
94675
  for (const cell of cellTexts) {
93794
- const mangled = await rejectShellMangledValue(cell, HELP36, "--cells");
94676
+ const mangled = await rejectShellMangledValue(cell, HELP38, "--cells");
93795
94677
  if (typeof mangled === "number")
93796
94678
  return mangled;
93797
94679
  }
@@ -93892,7 +94774,7 @@ function rowChildIndex(table, grid, position2) {
93892
94774
  const lastRow = grid.rows[grid.rows.length - 1]?.node;
93893
94775
  return lastRow ? table.children.indexOf(lastRow) + 1 : table.children.length;
93894
94776
  }
93895
- var AT_FORMS6, HELP36;
94777
+ var AT_FORMS6, HELP38;
93896
94778
  var init_insert_row = __esm(() => {
93897
94779
  init_core2();
93898
94780
  init_blocks();
@@ -93903,7 +94785,7 @@ var init_insert_row = __esm(() => {
93903
94785
  init_respond();
93904
94786
  init_jsx_dev_runtime();
93905
94787
  AT_FORMS6 = describeForms(["table"], " ");
93906
- HELP36 = `docx tables insert-row \u2014 insert a table row
94788
+ HELP38 = `docx tables insert-row \u2014 insert a table row
93907
94789
 
93908
94790
  Usage:
93909
94791
  docx tables insert-row FILE --at tN [options]
@@ -93952,28 +94834,28 @@ Examples:
93952
94834
  // src/cli/tables/delete-row.ts
93953
94835
  var exports_delete_row = {};
93954
94836
  __export(exports_delete_row, {
93955
- run: () => run41
94837
+ run: () => run43
93956
94838
  });
93957
- async function run41(args) {
94839
+ async function run43(args) {
93958
94840
  const parsed = await tryParseArgs(args, {
93959
94841
  at: { type: "string" },
93960
94842
  author: { type: "string" },
93961
94843
  track: { type: "boolean" },
93962
94844
  ...SAVE_FLAGS
93963
- }, HELP37);
94845
+ }, HELP39);
93964
94846
  if (typeof parsed === "number")
93965
94847
  return parsed;
93966
94848
  if (parsed.values.help) {
93967
- await writeStdout(HELP37);
94849
+ await writeStdout(HELP39);
93968
94850
  return EXIT2.OK;
93969
94851
  }
93970
94852
  setVerboseAck(Boolean(parsed.values.verbose));
93971
94853
  const path2 = parsed.positionals[0];
93972
94854
  if (!path2)
93973
- return fail("USAGE", "Missing FILE argument", HELP37);
94855
+ return fail("USAGE", "Missing FILE argument", HELP39);
93974
94856
  const at = parsed.values.at;
93975
94857
  if (!at)
93976
- return fail("USAGE", "Missing --at tN:rR", HELP37);
94858
+ return fail("USAGE", "Missing --at tN:rR", HELP39);
93977
94859
  const target = parseRowAt(at);
93978
94860
  if (!target) {
93979
94861
  return fail("INVALID_LOCATOR", `--at must be a row locator like t0:r1 (got ${at})`);
@@ -94040,14 +94922,14 @@ function findVMergeOrphan(grid, rowIndex) {
94040
94922
  }
94041
94923
  return null;
94042
94924
  }
94043
- var AT_FORMS7, HELP37;
94925
+ var AT_FORMS7, HELP39;
94044
94926
  var init_delete_row = __esm(() => {
94045
94927
  init_core2();
94046
94928
  init_locators();
94047
94929
  init_table();
94048
94930
  init_respond();
94049
94931
  AT_FORMS7 = describeForms(["tableRow"], " ");
94050
- HELP37 = `docx tables delete-row \u2014 delete a table row
94932
+ HELP39 = `docx tables delete-row \u2014 delete a table row
94051
94933
 
94052
94934
  Usage:
94053
94935
  docx tables delete-row FILE --at tN:rR [options]
@@ -94083,9 +94965,9 @@ Examples:
94083
94965
  // src/cli/tables/insert-column.tsx
94084
94966
  var exports_insert_column = {};
94085
94967
  __export(exports_insert_column, {
94086
- run: () => run42
94968
+ run: () => run44
94087
94969
  });
94088
- async function run42(args) {
94970
+ async function run44(args) {
94089
94971
  const parsed = await tryParseArgs(args, {
94090
94972
  at: { type: "string" },
94091
94973
  position: { type: "string" },
@@ -94093,20 +94975,20 @@ async function run42(args) {
94093
94975
  author: { type: "string" },
94094
94976
  track: { type: "boolean" },
94095
94977
  ...SAVE_FLAGS
94096
- }, HELP38);
94978
+ }, HELP40);
94097
94979
  if (typeof parsed === "number")
94098
94980
  return parsed;
94099
94981
  if (parsed.values.help) {
94100
- await writeStdout(HELP38);
94982
+ await writeStdout(HELP40);
94101
94983
  return EXIT2.OK;
94102
94984
  }
94103
94985
  setVerboseAck(Boolean(parsed.values.verbose));
94104
94986
  const path2 = parsed.positionals[0];
94105
94987
  if (!path2)
94106
- return fail("USAGE", "Missing FILE argument", HELP38);
94988
+ return fail("USAGE", "Missing FILE argument", HELP40);
94107
94989
  const at = parsed.values.at;
94108
94990
  if (!at)
94109
- return fail("USAGE", "Missing --at tN", HELP38);
94991
+ return fail("USAGE", "Missing --at tN", HELP40);
94110
94992
  const tableId = parseTableAt(at);
94111
94993
  if (!tableId) {
94112
94994
  return fail("INVALID_LOCATOR", `--at must be a table id like t0 (got ${at})`);
@@ -94221,14 +95103,14 @@ function insertCellAtColumn(row, position2, cell) {
94221
95103
  const at = lastCell ? row.node.children.indexOf(lastCell.node) + 1 : row.node.children.length;
94222
95104
  row.node.children.splice(at, 0, cell);
94223
95105
  }
94224
- var AT_FORMS8, HELP38;
95106
+ var AT_FORMS8, HELP40;
94225
95107
  var init_insert_column = __esm(() => {
94226
95108
  init_core2();
94227
95109
  init_locators();
94228
95110
  init_table();
94229
95111
  init_respond();
94230
95112
  AT_FORMS8 = describeForms(["table"], " ");
94231
- HELP38 = `docx tables insert-column \u2014 insert a table column
95113
+ HELP40 = `docx tables insert-column \u2014 insert a table column
94232
95114
 
94233
95115
  Usage:
94234
95116
  docx tables insert-column FILE --at tN [options]
@@ -94266,28 +95148,28 @@ Examples:
94266
95148
  // src/cli/tables/delete-column.ts
94267
95149
  var exports_delete_column = {};
94268
95150
  __export(exports_delete_column, {
94269
- run: () => run43
95151
+ run: () => run45
94270
95152
  });
94271
- async function run43(args) {
95153
+ async function run45(args) {
94272
95154
  const parsed = await tryParseArgs(args, {
94273
95155
  at: { type: "string" },
94274
95156
  author: { type: "string" },
94275
95157
  track: { type: "boolean" },
94276
95158
  ...SAVE_FLAGS
94277
- }, HELP39);
95159
+ }, HELP41);
94278
95160
  if (typeof parsed === "number")
94279
95161
  return parsed;
94280
95162
  if (parsed.values.help) {
94281
- await writeStdout(HELP39);
95163
+ await writeStdout(HELP41);
94282
95164
  return EXIT2.OK;
94283
95165
  }
94284
95166
  setVerboseAck(Boolean(parsed.values.verbose));
94285
95167
  const path2 = parsed.positionals[0];
94286
95168
  if (!path2)
94287
- return fail("USAGE", "Missing FILE argument", HELP39);
95169
+ return fail("USAGE", "Missing FILE argument", HELP41);
94288
95170
  const at = parsed.values.at;
94289
95171
  if (!at)
94290
- return fail("USAGE", "Missing --at tN:cC", HELP39);
95172
+ return fail("USAGE", "Missing --at tN:cC", HELP41);
94291
95173
  const target = parseColumnAt(at);
94292
95174
  if (!target) {
94293
95175
  return fail("INVALID_LOCATOR", `--at must be a column locator like t0:c2 (got ${at})`);
@@ -94371,14 +95253,14 @@ function removeGridColumn(tblGrid, col) {
94371
95253
  if (index2 !== -1)
94372
95254
  tblGrid.children.splice(index2, 1);
94373
95255
  }
94374
- var AT_FORMS9, HELP39;
95256
+ var AT_FORMS9, HELP41;
94375
95257
  var init_delete_column = __esm(() => {
94376
95258
  init_core2();
94377
95259
  init_locators();
94378
95260
  init_table();
94379
95261
  init_respond();
94380
95262
  AT_FORMS9 = describeForms(["tableColumn"], " ");
94381
- HELP39 = `docx tables delete-column \u2014 delete a table column
95263
+ HELP41 = `docx tables delete-column \u2014 delete a table column
94382
95264
 
94383
95265
  Usage:
94384
95266
  docx tables delete-column FILE --at tN:cC [options]
@@ -94413,36 +95295,36 @@ Examples:
94413
95295
  // src/cli/tables/set-widths.ts
94414
95296
  var exports_set_widths = {};
94415
95297
  __export(exports_set_widths, {
94416
- run: () => run44
95298
+ run: () => run46
94417
95299
  });
94418
- async function run44(args) {
95300
+ async function run46(args) {
94419
95301
  const parsed = await tryParseArgs(args, {
94420
95302
  at: { type: "string" },
94421
95303
  widths: { type: "string" },
94422
95304
  author: { type: "string" },
94423
95305
  track: { type: "boolean" },
94424
95306
  ...SAVE_FLAGS
94425
- }, HELP40);
95307
+ }, HELP42);
94426
95308
  if (typeof parsed === "number")
94427
95309
  return parsed;
94428
95310
  if (parsed.values.help) {
94429
- await writeStdout(HELP40);
95311
+ await writeStdout(HELP42);
94430
95312
  return EXIT2.OK;
94431
95313
  }
94432
95314
  setVerboseAck(Boolean(parsed.values.verbose));
94433
95315
  const path2 = parsed.positionals[0];
94434
95316
  if (!path2)
94435
- return fail("USAGE", "Missing FILE argument", HELP40);
95317
+ return fail("USAGE", "Missing FILE argument", HELP42);
94436
95318
  const at = parsed.values.at;
94437
95319
  if (!at)
94438
- return fail("USAGE", "Missing --at tN", HELP40);
95320
+ return fail("USAGE", "Missing --at tN", HELP42);
94439
95321
  const tableId = parseTableAt(at);
94440
95322
  if (!tableId) {
94441
95323
  return fail("INVALID_LOCATOR", `--at must be a table id like t0 (got ${at})`);
94442
95324
  }
94443
95325
  const widthsSpec = parsed.values.widths;
94444
95326
  if (!widthsSpec)
94445
- return fail("USAGE", "Missing --widths", HELP40);
95327
+ return fail("USAGE", "Missing --widths", HELP42);
94446
95328
  const document4 = await openOrFail(path2);
94447
95329
  if (typeof document4 === "number")
94448
95330
  return document4;
@@ -94591,14 +95473,14 @@ function describeColumnWidths(twips) {
94591
95473
  const cells = twips.map((value, index2) => `g${index2}=${twipsToInches(value)}in`);
94592
95474
  return `widths: ${cells.join(" ")}`;
94593
95475
  }
94594
- var AT_FORMS10, HELP40, MIN_COL_TWIPS = 288;
95476
+ var AT_FORMS10, HELP42, MIN_COL_TWIPS = 288;
94595
95477
  var init_set_widths = __esm(() => {
94596
95478
  init_core2();
94597
95479
  init_locators();
94598
95480
  init_table();
94599
95481
  init_respond();
94600
95482
  AT_FORMS10 = describeForms(["table"], " ");
94601
- HELP40 = `docx tables set-widths \u2014 set column widths
95483
+ HELP42 = `docx tables set-widths \u2014 set column widths
94602
95484
 
94603
95485
  Usage:
94604
95486
  docx tables set-widths FILE --at tN --widths SPEC [options]
@@ -94667,28 +95549,28 @@ var init_common2 = __esm(() => {
94667
95549
  // src/cli/tables/merge.tsx
94668
95550
  var exports_merge = {};
94669
95551
  __export(exports_merge, {
94670
- run: () => run45
95552
+ run: () => run47
94671
95553
  });
94672
- async function run45(args) {
95554
+ async function run47(args) {
94673
95555
  const parsed = await tryParseArgs(args, {
94674
95556
  at: { type: "string" },
94675
95557
  author: { type: "string" },
94676
95558
  track: { type: "boolean" },
94677
95559
  ...SAVE_FLAGS
94678
- }, HELP41);
95560
+ }, HELP43);
94679
95561
  if (typeof parsed === "number")
94680
95562
  return parsed;
94681
95563
  if (parsed.values.help) {
94682
- await writeStdout(HELP41);
95564
+ await writeStdout(HELP43);
94683
95565
  return EXIT2.OK;
94684
95566
  }
94685
95567
  setVerboseAck(Boolean(parsed.values.verbose));
94686
95568
  const path2 = parsed.positionals[0];
94687
95569
  if (!path2)
94688
- return fail("USAGE", "Missing FILE argument", HELP41);
95570
+ return fail("USAGE", "Missing FILE argument", HELP43);
94689
95571
  const at = parsed.values.at;
94690
95572
  if (!at)
94691
- return fail("USAGE", "Missing --at tN:rR1cC1-rR2cC2", HELP41);
95573
+ return fail("USAGE", "Missing --at tN:rR1cC1-rR2cC2", HELP43);
94692
95574
  const region = parseCellRangeAt(at);
94693
95575
  if (!region) {
94694
95576
  return fail("INVALID_LOCATOR", `--at must be a cell-range locator like t0:r0c0-r1c1 (got ${at})`);
@@ -94781,7 +95663,7 @@ function mergeRow(row, c1, c2, width, isTop, vertical) {
94781
95663
  if (vertical && !isTop)
94782
95664
  clearCellContent(anchor.node);
94783
95665
  }
94784
- var AT_FORMS11, HELP41;
95666
+ var AT_FORMS11, HELP43;
94785
95667
  var init_merge = __esm(() => {
94786
95668
  init_core2();
94787
95669
  init_locators();
@@ -94789,7 +95671,7 @@ var init_merge = __esm(() => {
94789
95671
  init_respond();
94790
95672
  init_common2();
94791
95673
  AT_FORMS11 = describeForms(["cellRange"], " ");
94792
- HELP41 = `docx tables merge \u2014 merge a rectangular cell region
95674
+ HELP43 = `docx tables merge \u2014 merge a rectangular cell region
94793
95675
 
94794
95676
  Usage:
94795
95677
  docx tables merge FILE --at tN:rR1cC1-rR2cC2 [options]
@@ -94828,28 +95710,28 @@ Examples:
94828
95710
  // src/cli/tables/unmerge.tsx
94829
95711
  var exports_unmerge = {};
94830
95712
  __export(exports_unmerge, {
94831
- run: () => run46
95713
+ run: () => run48
94832
95714
  });
94833
- async function run46(args) {
95715
+ async function run48(args) {
94834
95716
  const parsed = await tryParseArgs(args, {
94835
95717
  at: { type: "string" },
94836
95718
  author: { type: "string" },
94837
95719
  track: { type: "boolean" },
94838
95720
  ...SAVE_FLAGS
94839
- }, HELP42);
95721
+ }, HELP44);
94840
95722
  if (typeof parsed === "number")
94841
95723
  return parsed;
94842
95724
  if (parsed.values.help) {
94843
- await writeStdout(HELP42);
95725
+ await writeStdout(HELP44);
94844
95726
  return EXIT2.OK;
94845
95727
  }
94846
95728
  setVerboseAck(Boolean(parsed.values.verbose));
94847
95729
  const path2 = parsed.positionals[0];
94848
95730
  if (!path2)
94849
- return fail("USAGE", "Missing FILE argument", HELP42);
95731
+ return fail("USAGE", "Missing FILE argument", HELP44);
94850
95732
  const at = parsed.values.at;
94851
95733
  if (!at)
94852
- return fail("USAGE", "Missing --at tN:rRcC", HELP42);
95734
+ return fail("USAGE", "Missing --at tN:rRcC", HELP44);
94853
95735
  const target = parseCellAt(at);
94854
95736
  if (!target) {
94855
95737
  return fail("INVALID_LOCATOR", `--at must be a cell locator like t0:r0c0 (got ${at})`);
@@ -94924,7 +95806,7 @@ function verticalSpanRows(grid, row, col, vertical) {
94924
95806
  }
94925
95807
  return rows;
94926
95808
  }
94927
- var AT_FORMS12, HELP42;
95809
+ var AT_FORMS12, HELP44;
94928
95810
  var init_unmerge = __esm(() => {
94929
95811
  init_core2();
94930
95812
  init_locators();
@@ -94932,7 +95814,7 @@ var init_unmerge = __esm(() => {
94932
95814
  init_respond();
94933
95815
  init_common2();
94934
95816
  AT_FORMS12 = describeForms(["cell"], " ");
94935
- HELP42 = `docx tables unmerge \u2014 split a merged cell back into individual cells
95817
+ HELP44 = `docx tables unmerge \u2014 split a merged cell back into individual cells
94936
95818
 
94937
95819
  Usage:
94938
95820
  docx tables unmerge FILE --at tN:rRcC [options]
@@ -94969,9 +95851,9 @@ Examples:
94969
95851
  // src/cli/tables/borders.tsx
94970
95852
  var exports_borders = {};
94971
95853
  __export(exports_borders, {
94972
- run: () => run47
95854
+ run: () => run49
94973
95855
  });
94974
- async function run47(args) {
95856
+ async function run49(args) {
94975
95857
  const parsed = await tryParseArgs(args, {
94976
95858
  at: { type: "string" },
94977
95859
  style: { type: "string" },
@@ -94980,20 +95862,20 @@ async function run47(args) {
94980
95862
  author: { type: "string" },
94981
95863
  track: { type: "boolean" },
94982
95864
  ...SAVE_FLAGS
94983
- }, HELP43);
95865
+ }, HELP45);
94984
95866
  if (typeof parsed === "number")
94985
95867
  return parsed;
94986
95868
  if (parsed.values.help) {
94987
- await writeStdout(HELP43);
95869
+ await writeStdout(HELP45);
94988
95870
  return EXIT2.OK;
94989
95871
  }
94990
95872
  setVerboseAck(Boolean(parsed.values.verbose));
94991
95873
  const path2 = parsed.positionals[0];
94992
95874
  if (!path2)
94993
- return fail("USAGE", "Missing FILE argument", HELP43);
95875
+ return fail("USAGE", "Missing FILE argument", HELP45);
94994
95876
  const at = parsed.values.at;
94995
95877
  if (!at)
94996
- return fail("USAGE", "Missing --at tN", HELP43);
95878
+ return fail("USAGE", "Missing --at tN", HELP45);
94997
95879
  const tableId = parseTableAt(at);
94998
95880
  if (!tableId) {
94999
95881
  return fail("INVALID_LOCATOR", `--at must be a table id like t0 (got ${at})`);
@@ -95070,7 +95952,7 @@ function buildBorders(style, sizeEighths, color2) {
95070
95952
  ]
95071
95953
  }, undefined, true, undefined, this);
95072
95954
  }
95073
- var STYLES, AT_FORMS13, HELP43;
95955
+ var STYLES, AT_FORMS13, HELP45;
95074
95956
  var init_borders = __esm(() => {
95075
95957
  init_core2();
95076
95958
  init_jsx();
@@ -95081,7 +95963,7 @@ var init_borders = __esm(() => {
95081
95963
  init_jsx_dev_runtime();
95082
95964
  STYLES = new Set(["single", "double", "none"]);
95083
95965
  AT_FORMS13 = describeForms(["table"], " ");
95084
- HELP43 = `docx tables borders \u2014 set table borders
95966
+ HELP45 = `docx tables borders \u2014 set table borders
95085
95967
 
95086
95968
  Usage:
95087
95969
  docx tables borders FILE --at tN [options]
@@ -95118,25 +96000,486 @@ Examples:
95118
96000
  `;
95119
96001
  });
95120
96002
 
96003
+ // src/cli/tables/format.tsx
96004
+ var exports_format = {};
96005
+ __export(exports_format, {
96006
+ run: () => run50
96007
+ });
96008
+ async function run50(args) {
96009
+ const parsed = await tryParseArgs(args, {
96010
+ at: { type: "string" },
96011
+ shade: { type: "string" },
96012
+ valign: { type: "string" },
96013
+ halign: { type: "string" },
96014
+ "cell-borders": { type: "string" },
96015
+ "border-style": { type: "string" },
96016
+ "border-size": { type: "string" },
96017
+ "border-color": { type: "string" },
96018
+ align: { type: "string" },
96019
+ style: { type: "string" },
96020
+ "row-height": { type: "string" },
96021
+ "height-rule": { type: "string" },
96022
+ "repeat-header": { type: "boolean" },
96023
+ "no-repeat-header": { type: "boolean" },
96024
+ author: { type: "string" },
96025
+ track: { type: "boolean" },
96026
+ ...SAVE_FLAGS
96027
+ }, HELP46);
96028
+ if (typeof parsed === "number")
96029
+ return parsed;
96030
+ if (parsed.values.help) {
96031
+ await writeStdout(HELP46);
96032
+ return EXIT2.OK;
96033
+ }
96034
+ setVerboseAck(Boolean(parsed.values.verbose));
96035
+ const path2 = parsed.positionals[0];
96036
+ if (!path2)
96037
+ return fail("USAGE", "Missing FILE argument", HELP46);
96038
+ const at = parsed.values.at;
96039
+ if (!at)
96040
+ return fail("USAGE", "Missing --at LOCATOR", HELP46);
96041
+ const scope = resolveScope(at);
96042
+ if (!scope) {
96043
+ return fail("INVALID_LOCATOR", `--at must address a table, row, column, cell, or cell range (got ${at})`, "e.g. t0 (table), t0:r0 (row), t0:c1 (column), t0:r0c0 (cell), t0:r0c0-r1c2 (range).");
96044
+ }
96045
+ const plan = buildPlan2(parsed.values);
96046
+ if (typeof plan === "string")
96047
+ return fail("USAGE", plan);
96048
+ if (planIsEmpty(plan)) {
96049
+ return fail("USAGE", "Nothing to format \u2014 pass at least one of --shade/--valign/--halign/--cell-borders/--align/--style/--row-height/--repeat-header");
96050
+ }
96051
+ const scopeError = validateScope(scope, plan);
96052
+ if (scopeError)
96053
+ return fail("USAGE", scopeError);
96054
+ const document4 = await openOrFail(path2);
96055
+ if (typeof document4 === "number")
96056
+ return document4;
96057
+ const tableNode = resolveTableNode(document4, scope.tableId);
96058
+ if (!tableNode)
96059
+ return fail("BLOCK_NOT_FOUND", `Table not found: ${scope.tableId}`);
96060
+ const grid = buildGrid(tableNode);
96061
+ const cells = selectCells(grid, scope);
96062
+ const rows = selectRows(grid, scope);
96063
+ const targetError = validateTargets(scope, plan, cells, rows);
96064
+ if (targetError)
96065
+ return fail("BLOCK_NOT_FOUND", targetError);
96066
+ const outputPath = parsed.values.output;
96067
+ if (parsed.values["dry-run"]) {
96068
+ await respond({
96069
+ operation: "tables.format",
96070
+ dryRun: true,
96071
+ path: path2,
96072
+ at,
96073
+ applied: appliedList2(plan),
96074
+ ...outputPath ? { output: outputPath } : {}
96075
+ });
96076
+ return EXIT2.OK;
96077
+ }
96078
+ const tracking = resolveTracked(document4, parsed.values.track);
96079
+ const author = parsed.values.author;
96080
+ applyCellProps(document4, cells, plan, tracking, author);
96081
+ if (plan.halign !== undefined)
96082
+ applyHalign(document4, cells, plan.halign, tracking, author);
96083
+ applyTableProps(tableNode, plan);
96084
+ applyRowProps(rows, plan);
96085
+ const untracked = untrackedSummary(plan);
96086
+ if (untracked)
96087
+ noteStructuralChange(document4, cells[0]?.node, untracked, author, parsed.values.track);
96088
+ await document4.save(outputPath);
96089
+ const destination = outputPath ?? path2;
96090
+ await respondAck({
96091
+ ok: true,
96092
+ operation: "tables.format",
96093
+ path: destination,
96094
+ table: at,
96095
+ applied: appliedList2(plan)
96096
+ }, renderVerifyHint(destination));
96097
+ return EXIT2.OK;
96098
+ }
96099
+ function resolveScope(at) {
96100
+ const cell = parseCellAt(at);
96101
+ if (cell)
96102
+ return { kind: "cell", ...cell };
96103
+ const range = parseCellRangeAt(at);
96104
+ if (range)
96105
+ return { kind: "range", ...range };
96106
+ const row = parseRowAt(at);
96107
+ if (row)
96108
+ return { kind: "row", ...row };
96109
+ const column = parseColumnAt(at);
96110
+ if (column)
96111
+ return { kind: "column", ...column };
96112
+ const tableId = parseTableAt(at);
96113
+ if (tableId)
96114
+ return { kind: "table", tableId };
96115
+ return null;
96116
+ }
96117
+ function buildPlan2(values2) {
96118
+ const plan = {};
96119
+ const shade = values2.shade;
96120
+ if (shade !== undefined) {
96121
+ if (isClear(shade))
96122
+ plan.shade = null;
96123
+ else {
96124
+ const hex = resolveColor(shade);
96125
+ if (!hex)
96126
+ return colorError("--shade", shade);
96127
+ plan.shade = hex;
96128
+ }
96129
+ }
96130
+ const valign = values2.valign;
96131
+ if (valign !== undefined) {
96132
+ if (!VALIGNS.has(valign))
96133
+ return "--valign must be top, center, or bottom";
96134
+ plan.valign = valign;
96135
+ }
96136
+ const halign = values2.halign;
96137
+ if (halign !== undefined) {
96138
+ if (!HALIGNS.has(halign))
96139
+ return "--halign must be left, center, right, or justify";
96140
+ plan.halign = halign;
96141
+ }
96142
+ const cellBorders = values2["cell-borders"];
96143
+ if (cellBorders !== undefined) {
96144
+ const built = buildCellBorders(values2, cellBorders);
96145
+ if (typeof built === "string")
96146
+ return built;
96147
+ plan.cellBorders = built;
96148
+ }
96149
+ const align = values2.align;
96150
+ if (align !== undefined) {
96151
+ if (!TABLE_ALIGNS.has(align))
96152
+ return "--align must be left, center, or right";
96153
+ plan.align = align;
96154
+ }
96155
+ const style = values2.style;
96156
+ if (style !== undefined)
96157
+ plan.style = isClear(style) ? null : style;
96158
+ const rowHeight = values2["row-height"];
96159
+ const heightRule = values2["height-rule"];
96160
+ if (heightRule !== undefined && !HEIGHT_RULES.has(heightRule))
96161
+ return "--height-rule must be atLeast, exact, or auto";
96162
+ if (heightRule !== undefined && rowHeight === undefined)
96163
+ return "--height-rule has no effect without --row-height";
96164
+ if (rowHeight !== undefined) {
96165
+ const twips = parseMeasureToTwips(rowHeight);
96166
+ if (twips === null)
96167
+ return `--row-height must be a positive measure WITH a unit, e.g. 0.4in or 28pt (got ${rowHeight})`;
96168
+ plan.rowHeight = {
96169
+ value: twips,
96170
+ rule: heightRule ?? "atLeast"
96171
+ };
96172
+ }
96173
+ if (values2["repeat-header"] && values2["no-repeat-header"])
96174
+ return "--repeat-header and --no-repeat-header are mutually exclusive";
96175
+ if (values2["repeat-header"])
96176
+ plan.repeatHeader = true;
96177
+ if (values2["no-repeat-header"])
96178
+ plan.repeatHeader = false;
96179
+ return plan;
96180
+ }
96181
+ function buildCellBorders(values2, sidesRaw) {
96182
+ if (isClear(sidesRaw))
96183
+ return { updates: [], clearAll: true };
96184
+ const style = values2["border-style"] ?? "single";
96185
+ if (!BORDER_STYLES.has(style))
96186
+ return "--border-style must be single, double, or none";
96187
+ const sizeRaw = values2["border-size"];
96188
+ if (sizeRaw !== undefined && (!Number.isInteger(Number(sizeRaw)) || Number(sizeRaw) <= 0))
96189
+ return "--border-size must be a positive integer (eighths of a point)";
96190
+ const sizeEighths = sizeRaw ? Number(sizeRaw) : 4;
96191
+ const colorRaw = values2["border-color"] ?? "auto";
96192
+ const color2 = colorRaw === "auto" ? "auto" : resolveColor(colorRaw);
96193
+ if (!color2)
96194
+ return colorError("--border-color", colorRaw);
96195
+ const edge = { style, sizeEighths, color: color2 };
96196
+ const sides = new Set;
96197
+ for (const token of sidesRaw.split(",").map((value) => value.trim())) {
96198
+ if (token === "all") {
96199
+ for (const side of ALL_SIDES)
96200
+ sides.add(side);
96201
+ continue;
96202
+ }
96203
+ if (!ALL_SIDES.includes(token))
96204
+ return `--cell-borders side "${token}" must be one of ${ALL_SIDES.join(", ")}, all, or none`;
96205
+ sides.add(token);
96206
+ }
96207
+ return {
96208
+ updates: [...sides].map((side) => ({ side, edge })),
96209
+ clearAll: false
96210
+ };
96211
+ }
96212
+ function selectCells(grid, scope) {
96213
+ if (scope.kind === "table")
96214
+ return grid.rows.flatMap((row) => row.cells);
96215
+ if (scope.kind === "row")
96216
+ return grid.rows[scope.row]?.cells ?? [];
96217
+ if (scope.kind === "cell") {
96218
+ const cell = cellAt(grid.rows[scope.row], scope.col);
96219
+ return cell ? [cell] : [];
96220
+ }
96221
+ if (scope.kind === "column") {
96222
+ const out2 = [];
96223
+ for (const row of grid.rows) {
96224
+ const cell = cellAt(row, scope.col);
96225
+ if (cell && !out2.includes(cell))
96226
+ out2.push(cell);
96227
+ }
96228
+ return out2;
96229
+ }
96230
+ const r1 = Math.min(scope.start.row, scope.end.row);
96231
+ const r2 = Math.max(scope.start.row, scope.end.row);
96232
+ const c1 = Math.min(scope.start.col, scope.end.col);
96233
+ const c2 = Math.max(scope.start.col, scope.end.col);
96234
+ const out = [];
96235
+ for (let row = r1;row <= r2; row++) {
96236
+ for (const cell of grid.rows[row]?.cells ?? []) {
96237
+ if (cell.colStart <= c2 && cell.colStart + cell.colSpan - 1 >= c1)
96238
+ out.push(cell);
96239
+ }
96240
+ }
96241
+ return out;
96242
+ }
96243
+ function selectRows(grid, scope) {
96244
+ if (scope.kind === "table")
96245
+ return grid.rows;
96246
+ if (scope.kind === "row") {
96247
+ const row = grid.rows[scope.row];
96248
+ return row ? [row] : [];
96249
+ }
96250
+ return [];
96251
+ }
96252
+ function applyCellProps(document4, cells, plan, tracking, author) {
96253
+ if (plan.shade === undefined && plan.valign === undefined && plan.cellBorders === undefined)
96254
+ return;
96255
+ for (const cell of cells) {
96256
+ const prior = tracking ? (cell.node.findChild("w:tcPr")?.children ?? []).map((child2) => child2.clone()) : [];
96257
+ if (plan.shade !== undefined)
96258
+ setCellShading(cell.node, plan.shade);
96259
+ if (plan.valign !== undefined)
96260
+ setCellVAlign(cell.node, plan.valign);
96261
+ if (plan.cellBorders !== undefined)
96262
+ setCellBorders(cell.node, plan.cellBorders.updates, plan.cellBorders.clearAll);
96263
+ if (tracking)
96264
+ appendTcPrChange(cell.node, prior, new TrackChanges(document4).mintMeta(author));
96265
+ }
96266
+ }
96267
+ function applyHalign(document4, cells, alignment, tracking, author) {
96268
+ const edit = new Edit(document4);
96269
+ for (const cell of cells) {
96270
+ for (const paragraph2 of cell.node.findChildren("w:p")) {
96271
+ edit.paragraphProperties({ node: paragraph2, parent: cell.node.children }, { alignment }, { authorFlag: author, track: tracking });
96272
+ }
96273
+ }
96274
+ }
96275
+ function applyTableProps(tableNode, plan) {
96276
+ if (plan.align !== undefined)
96277
+ setTableJustification(tableNode, plan.align);
96278
+ if (plan.style !== undefined)
96279
+ setTableStyle(tableNode, plan.style);
96280
+ }
96281
+ function applyRowProps(rows, plan) {
96282
+ if (plan.rowHeight === undefined && plan.repeatHeader === undefined)
96283
+ return;
96284
+ for (const row of rows) {
96285
+ if (plan.rowHeight !== undefined)
96286
+ setRowHeight(row.node, plan.rowHeight);
96287
+ if (plan.repeatHeader !== undefined)
96288
+ setRepeatHeader(row.node, plan.repeatHeader);
96289
+ }
96290
+ }
96291
+ function validateScope(scope, plan) {
96292
+ const hasTableFlag = plan.align !== undefined || plan.style !== undefined;
96293
+ if (hasTableFlag && scope.kind !== "table")
96294
+ return "--align/--style position or restyle the whole table \u2014 use --at tN";
96295
+ const hasRowFlag = plan.rowHeight !== undefined || plan.repeatHeader !== undefined;
96296
+ if (hasRowFlag && scope.kind !== "table" && scope.kind !== "row")
96297
+ return "--row-height/--repeat-header apply to a row \u2014 use --at tN:rR (or --at tN for every row)";
96298
+ return null;
96299
+ }
96300
+ function validateTargets(scope, plan, cells, rows) {
96301
+ const hasCellFlag = plan.shade !== undefined || plan.valign !== undefined || plan.halign !== undefined || plan.cellBorders !== undefined;
96302
+ if (hasCellFlag && cells.length === 0)
96303
+ return `No cells matched ${describeScope(scope)}`;
96304
+ const hasRowFlag = plan.rowHeight !== undefined || plan.repeatHeader !== undefined;
96305
+ if (hasRowFlag && rows.length === 0)
96306
+ return `No rows matched ${describeScope(scope)}`;
96307
+ return null;
96308
+ }
96309
+ function describeScope(scope) {
96310
+ if (scope.kind === "table")
96311
+ return scope.tableId;
96312
+ if (scope.kind === "row")
96313
+ return `${scope.tableId}:r${scope.row}`;
96314
+ if (scope.kind === "column")
96315
+ return `${scope.tableId}:c${scope.col}`;
96316
+ if (scope.kind === "cell")
96317
+ return `${scope.tableId}:r${scope.row}c${scope.col}`;
96318
+ return `${scope.tableId}:r${scope.start.row}c${scope.start.col}-r${scope.end.row}c${scope.end.col}`;
96319
+ }
96320
+ function appliedList2(plan) {
96321
+ const out = [];
96322
+ if (plan.shade !== undefined)
96323
+ out.push("shade");
96324
+ if (plan.valign !== undefined)
96325
+ out.push("valign");
96326
+ if (plan.halign !== undefined)
96327
+ out.push("halign");
96328
+ if (plan.cellBorders !== undefined)
96329
+ out.push("cell-borders");
96330
+ if (plan.align !== undefined)
96331
+ out.push("align");
96332
+ if (plan.style !== undefined)
96333
+ out.push("style");
96334
+ if (plan.rowHeight !== undefined)
96335
+ out.push("row-height");
96336
+ if (plan.repeatHeader !== undefined)
96337
+ out.push("repeat-header");
96338
+ return out;
96339
+ }
96340
+ function untrackedSummary(plan) {
96341
+ const parts = [];
96342
+ if (plan.align !== undefined)
96343
+ parts.push(`table align ${plan.align ?? "left"}`);
96344
+ if (plan.style !== undefined)
96345
+ parts.push(plan.style ? `table style ${plan.style}` : "table style cleared");
96346
+ if (plan.rowHeight !== undefined)
96347
+ parts.push("row height set");
96348
+ if (plan.repeatHeader !== undefined)
96349
+ parts.push(plan.repeatHeader ? "repeat-header on" : "repeat-header off");
96350
+ return parts.length > 0 ? `set ${parts.join("; ")}` : "";
96351
+ }
96352
+ function planIsEmpty(plan) {
96353
+ return appliedList2(plan).length === 0;
96354
+ }
96355
+ function isClear(value) {
96356
+ const lower = value.toLowerCase();
96357
+ return lower === "none" || lower === "auto";
96358
+ }
96359
+ function resolveColor(value) {
96360
+ const named = COLOR_NAMES[value.toLowerCase()];
96361
+ if (named)
96362
+ return named;
96363
+ const hex = normalizeHexColor(value).toUpperCase();
96364
+ return /^[0-9A-F]{6}$/.test(hex) ? hex : null;
96365
+ }
96366
+ function colorError(flag, value) {
96367
+ return `${flag} must be a 6-digit hex (e.g. D9D9D9) or a name (${Object.keys(COLOR_NAMES).slice(0, 6).join(", ")}, \u2026) \u2014 got ${value}`;
96368
+ }
96369
+ function parseMeasureToTwips(raw) {
96370
+ const match = raw.trim().match(/^(\d*\.?\d+)\s*(in|pt)$/i);
96371
+ if (!match)
96372
+ return null;
96373
+ const value = Number.parseFloat(match[1]);
96374
+ if (!Number.isFinite(value) || value <= 0)
96375
+ return null;
96376
+ const unit = match[2].toLowerCase();
96377
+ return Math.round(unit === "pt" ? value * 20 : value * 1440);
96378
+ }
96379
+ var HELP46 = `docx tables format \u2014 shade, align, border, and size table cells/rows/tables
96380
+
96381
+ Usage:
96382
+ docx tables format FILE --at LOCATOR [formatting options]
96383
+
96384
+ The --at locator picks WHAT to format; its granularity picks which options apply.
96385
+ --at t0 whole table
96386
+ --at t0:r2 a row --at t0:c1 a column
96387
+ --at t0:r1c2 a single cell --at t0:r1c0-r3c2 a rectangle of cells
96388
+
96389
+ Cell options (any locator \u2014 broadcast to every cell it covers):
96390
+ --shade HEX|NAME|none Cell background fill (e.g. D9D9D9, "grey", or none to clear)
96391
+ --valign top|center|bottom Vertical alignment of cell content
96392
+ --halign left|center|right|justify
96393
+ Horizontal alignment of cell TEXT (a paragraph property \u2014
96394
+ not the same as --align, which moves the whole table)
96395
+ --cell-borders SIDES Comma list of top,bottom,left,right,all,insideH,insideV
96396
+ (or none to clear). Styled by the --border-* options:
96397
+ --border-style single|double|none (default: single)
96398
+ --border-size EIGHTHS Thickness in eighths of a point (default: 4 = 0.5pt)
96399
+ --border-color HEX|NAME (default: auto)
96400
+
96401
+ Row options (--at t0:rR, or --at t0 for every row):
96402
+ --row-height MEASURE a unit is required: 0.4in or 28pt (a bare number is rejected)
96403
+ --height-rule atLeast|exact|auto (default: atLeast)
96404
+ --repeat-header / --no-repeat-header
96405
+ Repeat the row as a header atop each page the table spans
96406
+
96407
+ Table options (--at t0 only):
96408
+ --align left|center|right Position the whole table on the page
96409
+ --style STYLEID|none Apply (or clear) a table style from styles.xml
96410
+
96411
+ Common:
96412
+ --author NAME Author for tracked changes / audit comments (default: $DOCX_AUTHOR)
96413
+ --track Record as a tracked change even if the doc toggle is off
96414
+ -o, --output PATH / --dry-run / -v, --verbose / -h, --help
96415
+
96416
+ Tracking: cell shading/vAlign/borders record as a real <w:tcPrChange> and --halign
96417
+ as a <w:pPrChange> (both round-trip in Word). Table align/style and row height/
96418
+ repeat-header have no tracked-change construct Word will revert, so under tracking
96419
+ they apply in place with a [docx-cli] audit comment (same policy as tables borders).
96420
+
96421
+ Examples:
96422
+ docx tables format invoice.docx --at t0:r0 --shade D9D9D9 --valign center
96423
+ docx tables format invoice.docx --at t0:c2 --halign right
96424
+ docx tables format invoice.docx --at t0:r1c0-r3c2 --cell-borders bottom
96425
+ docx tables format invoice.docx --at t0 --align center --style LightGrid
96426
+ docx tables format invoice.docx --at t0:r0 --repeat-header --row-height 0.4in
96427
+ `, VALIGNS, HALIGNS, TABLE_ALIGNS, BORDER_STYLES, HEIGHT_RULES, ALL_SIDES, COLOR_NAMES;
96428
+ var init_format = __esm(() => {
96429
+ init_core2();
96430
+ init_locators();
96431
+ init_table();
96432
+ init_parse_helpers();
96433
+ init_respond();
96434
+ init_common2();
96435
+ VALIGNS = new Set(["top", "center", "bottom"]);
96436
+ HALIGNS = new Set(["left", "center", "right", "justify"]);
96437
+ TABLE_ALIGNS = new Set(["left", "center", "right"]);
96438
+ BORDER_STYLES = new Set(["single", "double", "none"]);
96439
+ HEIGHT_RULES = new Set(["atLeast", "exact", "auto"]);
96440
+ ALL_SIDES = [
96441
+ "top",
96442
+ "left",
96443
+ "bottom",
96444
+ "right",
96445
+ "insideH",
96446
+ "insideV"
96447
+ ];
96448
+ COLOR_NAMES = {
96449
+ white: "FFFFFF",
96450
+ black: "000000",
96451
+ gray: "808080",
96452
+ grey: "808080",
96453
+ lightgray: "D9D9D9",
96454
+ lightgrey: "D9D9D9",
96455
+ darkgray: "A6A6A6",
96456
+ darkgrey: "A6A6A6",
96457
+ red: "FF0000",
96458
+ green: "00B050",
96459
+ blue: "0070C0",
96460
+ yellow: "FFFF00"
96461
+ };
96462
+ });
96463
+
95121
96464
  // src/cli/tables/index.ts
95122
96465
  var exports_tables = {};
95123
96466
  __export(exports_tables, {
95124
- run: () => run48
96467
+ run: () => run51
95125
96468
  });
95126
- async function run48(args) {
96469
+ async function run51(args) {
95127
96470
  const verb = args[0];
95128
96471
  if (!verb || verb === "--help" || verb === "-h" || verb === "help") {
95129
- await writeStdout(HELP44);
96472
+ await writeStdout(HELP47);
95130
96473
  return verb ? 0 : 2;
95131
96474
  }
95132
- const loader = SUBCOMMANDS9[verb];
96475
+ const loader = SUBCOMMANDS10[verb];
95133
96476
  if (!loader) {
95134
96477
  return fail("USAGE", `Unknown tables subcommand: ${verb}`, 'Run "docx tables --help".');
95135
96478
  }
95136
96479
  const module_ = await loader();
95137
96480
  return module_.run(args.slice(1));
95138
96481
  }
95139
- var SUBCOMMANDS9, HELP44 = `docx tables \u2014 restructure tables (rows, columns, merges, widths, borders)
96482
+ var SUBCOMMANDS10, HELP47 = `docx tables \u2014 restructure & format tables (rows, columns, merges, widths, shading)
95140
96483
 
95141
96484
  Usage:
95142
96485
  docx tables <verb> FILE [options]
@@ -95150,6 +96493,9 @@ Verbs:
95150
96493
  merge Merge a cell region (--at tN:rR1cC1-rR2cC2)
95151
96494
  unmerge Split a merge anchor (--at tN:rRcC)
95152
96495
  borders Set table borders (--at tN [--style] [--size] [--color])
96496
+ format Shade/align/border/size cells, rows, or the table
96497
+ (--at LOCATOR [--shade] [--valign] [--halign] [--cell-borders]
96498
+ [--align] [--style] [--row-height] [--repeat-header])
95153
96499
 
95154
96500
  These verbs restructure an existing table. The rest of the table lifecycle uses
95155
96501
  the standard verbs:
@@ -95162,7 +96508,7 @@ Run "docx tables <verb> --help" for verb-specific help.
95162
96508
  `;
95163
96509
  var init_tables = __esm(() => {
95164
96510
  init_respond();
95165
- SUBCOMMANDS9 = {
96511
+ SUBCOMMANDS10 = {
95166
96512
  "insert-row": () => Promise.resolve().then(() => (init_insert_row(), exports_insert_row)),
95167
96513
  "delete-row": () => Promise.resolve().then(() => (init_delete_row(), exports_delete_row)),
95168
96514
  "insert-column": () => Promise.resolve().then(() => (init_insert_column(), exports_insert_column)),
@@ -95170,7 +96516,8 @@ var init_tables = __esm(() => {
95170
96516
  "set-widths": () => Promise.resolve().then(() => (init_set_widths(), exports_set_widths)),
95171
96517
  merge: () => Promise.resolve().then(() => (init_merge(), exports_merge)),
95172
96518
  unmerge: () => Promise.resolve().then(() => (init_unmerge(), exports_unmerge)),
95173
- borders: () => Promise.resolve().then(() => (init_borders(), exports_borders))
96519
+ borders: () => Promise.resolve().then(() => (init_borders(), exports_borders)),
96520
+ format: () => Promise.resolve().then(() => (init_format(), exports_format))
95174
96521
  };
95175
96522
  });
95176
96523
 
@@ -95232,42 +96579,23 @@ var init_groups = __esm(() => {
95232
96579
  };
95233
96580
  });
95234
96581
 
95235
- // src/cli/track-changes/list.ts
95236
- var exports_list5 = {};
95237
- __export(exports_list5, {
95238
- run: () => run49
95239
- });
95240
- async function run49(args) {
95241
- const parsed = await tryParseArgs(args, {
95242
- help: { type: "boolean", short: "h" }
95243
- }, HELP45);
95244
- if (typeof parsed === "number")
95245
- return parsed;
95246
- if (parsed.values.help) {
95247
- await writeStdout(HELP45);
95248
- return EXIT2.OK;
95249
- }
95250
- const path2 = parsed.positionals[0];
95251
- if (!path2)
95252
- return fail("USAGE", "Missing FILE argument", HELP45);
95253
- const document4 = await openOrFail(path2);
95254
- if (typeof document4 === "number")
95255
- return document4;
96582
+ // src/cli/track-changes/list-view.ts
96583
+ function collectTrackedChangeRecords(document4) {
95256
96584
  const byId = new Map;
95257
96585
  for (const paragraph2 of flattenParagraphs(document4.body.blocks)) {
95258
- for (const run50 of paragraph2.runs) {
95259
- if (run50.type !== "text" || !run50.trackedChange)
96586
+ for (const run52 of paragraph2.runs) {
96587
+ if (run52.type !== "text" || !run52.trackedChange)
95260
96588
  continue;
95261
- const change = run50.trackedChange;
96589
+ const change = run52.trackedChange;
95262
96590
  const existing = byId.get(change.id);
95263
96591
  if (existing) {
95264
- existing.text += run50.text;
96592
+ existing.text += run52.text;
95265
96593
  continue;
95266
96594
  }
95267
96595
  byId.set(change.id, {
95268
96596
  ...change,
95269
96597
  blockId: paragraph2.id,
95270
- text: run50.text
96598
+ text: run52.text
95271
96599
  });
95272
96600
  }
95273
96601
  }
@@ -95304,8 +96632,154 @@ async function run49(args) {
95304
96632
  if (group)
95305
96633
  record.group = group;
95306
96634
  }
95307
- await respond(sorted);
95308
- return EXIT2.OK;
96635
+ return sorted;
96636
+ }
96637
+ function renderTrackedChangeTable(records) {
96638
+ if (records.length === 0)
96639
+ return `no tracked changes
96640
+ `;
96641
+ const byGroup = new Map;
96642
+ for (const record of records) {
96643
+ if (!record.group)
96644
+ continue;
96645
+ const members = byGroup.get(record.group) ?? [];
96646
+ members.push(record);
96647
+ byGroup.set(record.group, members);
96648
+ }
96649
+ const rows = [];
96650
+ const consumed = new Set;
96651
+ for (const record of records) {
96652
+ if (record.group) {
96653
+ if (consumed.has(record.group))
96654
+ continue;
96655
+ consumed.add(record.group);
96656
+ const members = byGroup.get(record.group) ?? [record];
96657
+ const del = members.find((member) => member.kind === "del");
96658
+ const ins = members.find((member) => member.kind === "ins");
96659
+ rows.push({
96660
+ handle: record.group,
96661
+ verb: "replace",
96662
+ block: record.blockId,
96663
+ desc: `${quote(del?.text ?? "")} \u2192 ${quote(ins?.text ?? "")}`
96664
+ });
96665
+ continue;
96666
+ }
96667
+ rows.push({
96668
+ handle: record.id,
96669
+ verb: verbLabel(record.kind),
96670
+ block: record.blockId,
96671
+ desc: describeSolo(record)
96672
+ });
96673
+ }
96674
+ const handleWidth = Math.max(...rows.map((row) => row.handle.length));
96675
+ const verbWidth = Math.max(...rows.map((row) => row.verb.length));
96676
+ const blockWidth = Math.max(...rows.map((row) => row.block.length));
96677
+ const body = rows.map((row) => ` ${row.handle.padEnd(handleWidth)} ${row.verb.padEnd(verbWidth)} ${row.block.padEnd(blockWidth)} ${row.desc}`).join(`
96678
+ `);
96679
+ const total = records.length;
96680
+ const header = `${total} tracked change${total === 1 ? "" : "s"}${rows.length === total ? "" : ` (${rows.length} logical)`}:`;
96681
+ const footer = `Address by the leftmost handle: accept/reject --at <handle> (repeatable).
96682
+ ` + "A revN handle resolves both halves of a replace in one call; --json for full detail.";
96683
+ return `${header}
96684
+
96685
+ ${body}
96686
+
96687
+ ${footer}
96688
+ `;
96689
+ }
96690
+ async function remainingTrackedChangesBlock(path2, verb) {
96691
+ let document4;
96692
+ try {
96693
+ document4 = await Document.open(path2);
96694
+ } catch {
96695
+ return "";
96696
+ }
96697
+ const remaining = collectTrackedChangeRecords(document4);
96698
+ if (remaining.length === 0)
96699
+ return "";
96700
+ return `
96701
+ Remaining (ids renumbered after this ${verb}):
96702
+
96703
+ ${renderTrackedChangeTable(remaining)}`;
96704
+ }
96705
+ function quote(text6, max = 44) {
96706
+ const collapsed = text6.replace(/\s+/g, " ").trim();
96707
+ if (collapsed === "")
96708
+ return "\xB6";
96709
+ const clipped = collapsed.length > max ? `${collapsed.slice(0, max - 1)}\u2026` : collapsed;
96710
+ return `"${clipped}"`;
96711
+ }
96712
+ function verbLabel(kind) {
96713
+ const labels = {
96714
+ ins: "insert",
96715
+ del: "delete",
96716
+ moveFrom: "move-from",
96717
+ moveTo: "move-to",
96718
+ sectPrChange: "section",
96719
+ pPrChange: "format",
96720
+ rowIns: "row-insert",
96721
+ rowDel: "row-delete",
96722
+ cellIns: "cell-insert",
96723
+ cellDel: "cell-delete",
96724
+ tblGridChange: "grid",
96725
+ tblPrChange: "table-fmt",
96726
+ tcPrChange: "cell-fmt",
96727
+ checkboxToggle: "checkbox"
96728
+ };
96729
+ return labels[kind] ?? kind;
96730
+ }
96731
+ function describeSolo(record) {
96732
+ if (record.kind === "ins" || record.kind === "del" || record.kind === "moveFrom" || record.kind === "moveTo") {
96733
+ return record.text === "" ? "\xB6 paragraph mark" : quote(record.text);
96734
+ }
96735
+ if (record.kind === "pPrChange" || record.kind === "sectPrChange") {
96736
+ const diff2 = propDiff(record.prior, record.current);
96737
+ return diff2 || (record.kind === "pPrChange" ? "paragraph format" : "layout");
96738
+ }
96739
+ const notes = {
96740
+ rowIns: "row inserted",
96741
+ rowDel: "row deleted",
96742
+ cellIns: "cell inserted",
96743
+ cellDel: "cell deleted",
96744
+ tblGridChange: "grid widths",
96745
+ tblPrChange: "table properties",
96746
+ tcPrChange: "cell properties",
96747
+ checkboxToggle: "checkbox toggled"
96748
+ };
96749
+ return notes[record.kind] ?? "";
96750
+ }
96751
+ function propDiff(prior, current) {
96752
+ const before = flattenProps(prior);
96753
+ const after = flattenProps(current);
96754
+ const keys = new Set([...before.keys(), ...after.keys()]);
96755
+ const parts = [];
96756
+ for (const key of keys) {
96757
+ const from = before.get(key);
96758
+ const to = after.get(key);
96759
+ if (from === to)
96760
+ continue;
96761
+ parts.push(`${key} ${from ?? "\xB7"}\u2192${to ?? "\xB7"}`);
96762
+ }
96763
+ if (parts.length === 0)
96764
+ return "";
96765
+ if (parts.length > 3)
96766
+ return `${parts.slice(0, 3).join(", ")}, \u2026`;
96767
+ return parts.join(", ");
96768
+ }
96769
+ function flattenProps(obj, prefix = "") {
96770
+ const out = new Map;
96771
+ if (obj === null || typeof obj !== "object")
96772
+ return out;
96773
+ for (const [key, value] of Object.entries(obj)) {
96774
+ const path2 = prefix ? `${prefix}.${key}` : key;
96775
+ if (value !== null && typeof value === "object") {
96776
+ for (const [k, v] of flattenProps(value, path2))
96777
+ out.set(k, v);
96778
+ } else if (typeof value === "string" || typeof value === "number") {
96779
+ out.set(path2, value);
96780
+ }
96781
+ }
96782
+ return out;
95309
96783
  }
95310
96784
  function trackedChangeIndex(id) {
95311
96785
  const match = id.match(/^tc(\d+)$/);
@@ -95355,12 +96829,50 @@ function readParagraphPropsSummary(children) {
95355
96829
  }
95356
96830
  return out;
95357
96831
  }
95358
- var HELP45 = `docx track-changes list \u2014 inventory every revision wrapper
96832
+ var init_list_view = __esm(() => {
96833
+ init_core2();
96834
+ init_track_changes();
96835
+ init_groups();
96836
+ });
96837
+
96838
+ // src/cli/track-changes/list.ts
96839
+ var exports_list5 = {};
96840
+ __export(exports_list5, {
96841
+ run: () => run52
96842
+ });
96843
+ async function run52(args) {
96844
+ const parsed = await tryParseArgs(args, {
96845
+ help: { type: "boolean", short: "h" },
96846
+ json: { type: "boolean" }
96847
+ }, HELP48);
96848
+ if (typeof parsed === "number")
96849
+ return parsed;
96850
+ if (parsed.values.help) {
96851
+ await writeStdout(HELP48);
96852
+ return EXIT2.OK;
96853
+ }
96854
+ const path2 = parsed.positionals[0];
96855
+ if (!path2)
96856
+ return fail("USAGE", "Missing FILE argument", HELP48);
96857
+ const document4 = await openOrFail(path2);
96858
+ if (typeof document4 === "number")
96859
+ return document4;
96860
+ const records = collectTrackedChangeRecords(document4);
96861
+ if (parsed.values.json) {
96862
+ await respond(records);
96863
+ return EXIT2.OK;
96864
+ }
96865
+ await writeStdout(renderTrackedChangeTable(records));
96866
+ return EXIT2.OK;
96867
+ }
96868
+ var HELP48 = `docx track-changes list \u2014 inventory every revision wrapper
95359
96869
 
95360
96870
  Usage:
95361
96871
  docx track-changes list FILE [options]
95362
96872
 
95363
96873
  Options:
96874
+ --json Emit the full revision objects as a JSON array (default: a
96875
+ text table, one LOGICAL change per line)
95364
96876
  -h, --help Show this help
95365
96877
 
95366
96878
  Lists every revision wrapper with stable tcN ids \u2014 run-level <w:ins>, <w:del>,
@@ -95370,25 +96882,35 @@ paragraph-mark <w:ins>/<w:del> markers (a self-closing element inside
95370
96882
  of the same logical move appear as separate entries; their kind tells them
95371
96883
  apart.
95372
96884
 
95373
- Output: a bare JSON array of { id, kind, author, date, revisionId, blockId,
95374
- text } sorted by id (document order). Each item's "id" (e.g. tc0) is its
95375
- addressable handle \u2014 pass it to \`accept\`/\`reject --at tcN\`. When a del and an
95376
- ins are an adjacent REPLACE pair on the same paragraph, BOTH carry a shared
95377
- "group": "revN" \u2014 accept/reject the whole logical change in one call with
95378
- \`--at revN\` instead of accepting each half separately (tcN ids renumber after
95379
- each single accept, so the revN handle avoids the re-list ping-pong). Errors print
95380
- {code, error, hint?} with a nonzero exit. kind is one of: "ins", "del", "moveFrom",
95381
- "moveTo", "sectPrChange", "pPrChange", "rowIns", "rowDel", "cellIns", "cellDel",
95382
- "tblGridChange", "tblPrChange", "tcPrChange", "checkboxToggle". Paragraph-mark
95383
- entries have kind "ins"/"del" with text "" \u2014 their blockId is the owning
95384
- paragraph's pN. Table-structural entries (rowIns/rowDel/cellIns/cellDel and
95385
- the property revisions tblGridChange/tblPrChange/tcPrChange) have text "" and
95386
- blockId set to the owning table's tN. checkboxToggle entries surface a Word
95387
- checkbox content control's tracked toggle (\u2610\u2194\u2612): metadata comes from the
95388
- inner <w:ins> (the new glyph); reject restores the prior glyph and flips
95389
- the w14:checked attribute back. Structural inserts/deletes of a checkbox
95390
- (Word emits <w:customXmlDel/InsRangeStart/End> around the SDT) round-trip
95391
- through the XmlNode tree but aren't yet enumerated as a dedicated kind.
96885
+ Output: a text table, ONE LOGICAL CHANGE per line \u2014
96886
+
96887
+ rev0 replace p7 "Net 90 from the Company" \u2192 "Net 30 from the Company"
96888
+ tc4 format p22 spacing.line \u2192360
96889
+ tc7 delete p27 "Personal Guarantee."
96890
+
96891
+ The leftmost token is the handle you pass to \`accept\`/\`reject --at\` (repeatable,
96892
+ e.g. \`--at rev0 --at tc4\`). A del+ins REPLACE pair on the same paragraph is
96893
+ collapsed onto ONE line under its shared revN handle, so accepting/rejecting the
96894
+ whole logical change is a single call \u2014 addressing the two tcN halves separately
96895
+ forces a re-list, because tcN ids renumber after each accept. All --at targets in
96896
+ one call resolve against the pre-mutation tree, so the renumbering never bites a
96897
+ batch.
96898
+
96899
+ --json gives a bare JSON array of { id, kind, author, date, revisionId, blockId,
96900
+ text } sorted by id (document order). Each item's "id" (e.g. tc0) is its granular
96901
+ handle; paired halves additionally carry "group": "revN". kind is one of: "ins",
96902
+ "del", "moveFrom", "moveTo", "sectPrChange", "pPrChange", "rowIns", "rowDel",
96903
+ "cellIns", "cellDel", "tblGridChange", "tblPrChange", "tcPrChange",
96904
+ "checkboxToggle". Paragraph-mark entries have kind "ins"/"del" with text "" \u2014
96905
+ their blockId is the owning paragraph's pN. Table-structural entries
96906
+ (rowIns/rowDel/cellIns/cellDel and the property revisions
96907
+ tblGridChange/tblPrChange/tcPrChange) have text "" and blockId set to the owning
96908
+ table's tN. checkboxToggle entries surface a Word checkbox content control's
96909
+ tracked toggle (\u2610\u2194\u2612): metadata comes from the inner <w:ins> (the new glyph);
96910
+ reject restores the prior glyph and flips the w14:checked attribute back.
96911
+ Structural inserts/deletes of a checkbox (Word emits
96912
+ <w:customXmlDel/InsRangeStart/End> around the SDT) round-trip through the
96913
+ XmlNode tree but aren't yet enumerated as a dedicated kind.
95392
96914
 
95393
96915
  Property revisions (kind="sectPrChange" or "pPrChange") additionally include
95394
96916
  { prior, current } objects from before and after the tracked edit, so agents
@@ -95398,19 +96920,17 @@ style/alignment/spacing/indent.
95398
96920
 
95399
96921
  Examples:
95400
96922
  docx track-changes list doc.docx
95401
- docx track-changes list doc.docx | jq '.[] | select(.kind == "del")'
95402
- docx track-changes list doc.docx | jq '.[] | select(.kind | test("move"))'
95403
- docx track-changes list doc.docx | jq '.[] | select(.kind == "sectPrChange") | .prior, .current'
95404
- docx track-changes list doc.docx | jq '.[] | select(.kind == "pPrChange") | .prior, .current'
96923
+ docx track-changes accept doc.docx --at rev0 --at tc4
96924
+ docx track-changes list doc.docx --json | jq '.[] | select(.kind == "del")'
96925
+ docx track-changes list doc.docx --json | jq '.[] | select(.kind | test("move"))'
96926
+ docx track-changes list doc.docx --json | jq '.[] | select(.kind == "pPrChange") | .prior, .current'
95405
96927
  `;
95406
96928
  var init_list8 = __esm(() => {
95407
- init_core2();
95408
- init_track_changes();
95409
96929
  init_respond();
95410
- init_groups();
96930
+ init_list_view();
95411
96931
  });
95412
96932
 
95413
- // src/cli/track-changes/apply.ts
96933
+ // src/cli/track-changes/run-apply.ts
95414
96934
  async function runApply(args, verb, help) {
95415
96935
  const parsed = await tryParseArgs(args, {
95416
96936
  at: { type: "string", multiple: true },
@@ -95472,6 +96992,11 @@ async function runApply(args, verb, help) {
95472
96992
  path: outputPath ?? path2,
95473
96993
  applied
95474
96994
  });
96995
+ if (!all2 && !parsed.values.verbose) {
96996
+ const remaining = await remainingTrackedChangesBlock(outputPath ?? path2, verb);
96997
+ if (remaining)
96998
+ await writeStdout(remaining);
96999
+ }
95475
97000
  return EXIT2.OK;
95476
97001
  } catch (error) {
95477
97002
  if (error instanceof TrackedChangeNotFoundError) {
@@ -95480,26 +97005,27 @@ async function runApply(args, verb, help) {
95480
97005
  throw error;
95481
97006
  }
95482
97007
  }
95483
- var init_apply2 = __esm(() => {
97008
+ var init_run_apply = __esm(() => {
95484
97009
  init_track_changes();
95485
97010
  init_respond();
95486
97011
  init_groups();
97012
+ init_list_view();
95487
97013
  });
95488
97014
 
95489
97015
  // src/cli/track-changes/accept.ts
95490
97016
  var exports_accept = {};
95491
97017
  __export(exports_accept, {
95492
- run: () => run50
97018
+ run: () => run53
95493
97019
  });
95494
- async function run50(args) {
95495
- return runApply(args, "accept", HELP46);
97020
+ async function run53(args) {
97021
+ return runApply(args, "accept", HELP49);
95496
97022
  }
95497
- var AT_FORMS14, HELP46;
97023
+ var AT_FORMS14, HELP49;
95498
97024
  var init_accept = __esm(() => {
95499
97025
  init_core2();
95500
- init_apply2();
97026
+ init_run_apply();
95501
97027
  AT_FORMS14 = describeForms(["trackedChange"], " ");
95502
- HELP46 = `docx track-changes accept \u2014 accept tracked changes (incorporate into the doc)
97028
+ HELP49 = `docx track-changes accept \u2014 accept tracked changes (incorporate into the doc)
95503
97029
 
95504
97030
  Usage:
95505
97031
  docx track-changes accept FILE --at tcN [options]
@@ -95560,17 +97086,17 @@ Examples:
95560
97086
  // src/cli/track-changes/reject.ts
95561
97087
  var exports_reject = {};
95562
97088
  __export(exports_reject, {
95563
- run: () => run51
97089
+ run: () => run54
95564
97090
  });
95565
- async function run51(args) {
95566
- return runApply(args, "reject", HELP47);
97091
+ async function run54(args) {
97092
+ return runApply(args, "reject", HELP50);
95567
97093
  }
95568
- var AT_FORMS15, HELP47;
97094
+ var AT_FORMS15, HELP50;
95569
97095
  var init_reject = __esm(() => {
95570
97096
  init_core2();
95571
- init_apply2();
97097
+ init_run_apply();
95572
97098
  AT_FORMS15 = describeForms(["trackedChange"], " ");
95573
- HELP47 = `docx track-changes reject \u2014 reject tracked changes (revert to pre-change state)
97099
+ HELP50 = `docx track-changes reject \u2014 reject tracked changes (revert to pre-change state)
95574
97100
 
95575
97101
  Usage:
95576
97102
  docx track-changes reject FILE --at tcN [options]
@@ -95636,19 +97162,157 @@ Examples:
95636
97162
  `;
95637
97163
  });
95638
97164
 
97165
+ // src/cli/track-changes/apply.ts
97166
+ var exports_apply = {};
97167
+ __export(exports_apply, {
97168
+ run: () => run55
97169
+ });
97170
+ async function run55(args) {
97171
+ const parsed = await tryParseArgs(args, {
97172
+ accept: { type: "string", multiple: true },
97173
+ reject: { type: "string", multiple: true },
97174
+ ...SAVE_FLAGS
97175
+ }, HELP51);
97176
+ if (typeof parsed === "number")
97177
+ return parsed;
97178
+ if (parsed.values.help) {
97179
+ await writeStdout(HELP51);
97180
+ return EXIT2.OK;
97181
+ }
97182
+ setVerboseAck(Boolean(parsed.values.verbose));
97183
+ const path2 = parsed.positionals[0];
97184
+ if (!path2)
97185
+ return fail("USAGE", "Missing FILE argument", HELP51);
97186
+ const acceptRaw = parsed.values.accept ?? [];
97187
+ const rejectRaw = parsed.values.reject ?? [];
97188
+ if (acceptRaw.length === 0 && rejectRaw.length === 0) {
97189
+ return fail("USAGE", "Specify --accept and/or --reject (handle)", HELP51);
97190
+ }
97191
+ const document4 = await openOrFail(path2);
97192
+ if (typeof document4 === "number")
97193
+ return document4;
97194
+ const trackChanges = new TrackChanges(document4);
97195
+ const groups = revisionGroups(trackChanges.list());
97196
+ let accepts;
97197
+ let rejects;
97198
+ try {
97199
+ accepts = expandRevisionTargets(acceptRaw, groups);
97200
+ rejects = expandRevisionTargets(rejectRaw, groups);
97201
+ } catch (error) {
97202
+ if (error instanceof UnknownRevisionError) {
97203
+ return fail("TRACKED_CHANGE_NOT_FOUND", error.message, "Run 'docx track-changes list FILE' \u2014 revN handles appear as the `group` field on paired changes.");
97204
+ }
97205
+ throw error;
97206
+ }
97207
+ const rejectSet = new Set(rejects);
97208
+ const conflict = accepts.find((id) => rejectSet.has(id));
97209
+ if (conflict) {
97210
+ return fail("USAGE", `${conflict} is named in both --accept and --reject`, HELP51);
97211
+ }
97212
+ const outputPath = parsed.values.output;
97213
+ try {
97214
+ if (parsed.values["dry-run"]) {
97215
+ const previewApplied = [
97216
+ ...trackChanges.preview(accepts, "accept"),
97217
+ ...trackChanges.preview(rejects, "reject")
97218
+ ].sort((a2, b) => trackedChangeIndex2(a2.id) - trackedChangeIndex2(b.id));
97219
+ await respond({
97220
+ operation: "track-changes.apply",
97221
+ dryRun: true,
97222
+ path: path2,
97223
+ ...outputPath ? { output: outputPath } : {},
97224
+ applied: previewApplied
97225
+ });
97226
+ return EXIT2.OK;
97227
+ }
97228
+ const applied = trackChanges.apply(accepts, rejects);
97229
+ await document4.save(outputPath);
97230
+ await respondAck({
97231
+ ok: true,
97232
+ operation: "track-changes.apply",
97233
+ path: outputPath ?? path2,
97234
+ applied
97235
+ });
97236
+ if (!parsed.values.verbose) {
97237
+ const remaining = await remainingTrackedChangesBlock(outputPath ?? path2, "apply");
97238
+ if (remaining)
97239
+ await writeStdout(remaining);
97240
+ }
97241
+ return EXIT2.OK;
97242
+ } catch (error) {
97243
+ if (error instanceof TrackedChangeNotFoundError) {
97244
+ return fail("TRACKED_CHANGE_NOT_FOUND", error.message, "Run 'docx track-changes list FILE' to see available handles.");
97245
+ }
97246
+ throw error;
97247
+ }
97248
+ }
97249
+ function trackedChangeIndex2(id) {
97250
+ const match = id.match(/^tc(\d+)$/);
97251
+ return match?.[1] ? Number(match[1]) : 0;
97252
+ }
97253
+ var HELP51 = `docx track-changes apply \u2014 finalize: accept AND reject in one atomic call
97254
+
97255
+ Usage:
97256
+ docx track-changes apply FILE (--accept H ... | --reject H ...) [options]
97257
+
97258
+ A document review ends in a finalize: accept the changes you want, reject the
97259
+ rest. Doing that as separate \`accept\` and \`reject\` calls is a trap \u2014 tcN/revN
97260
+ ids renumber after every accept/reject, so the SECOND command addresses a
97261
+ moved target ("tc5 not found", or worse, silently the wrong change). \`apply\`
97262
+ takes BOTH decisions at once and resolves EVERY handle against the original
97263
+ pre-mutation tree, so nothing renumbers mid-operation and the file is never
97264
+ left half-finalized (there is no undo).
97265
+
97266
+ Handles are the same ones \`track-changes list\` prints: a tcN, or a revN that
97267
+ covers both halves of a del+ins replace pair. Both flags repeat.
97268
+
97269
+ Targets (at least one required):
97270
+ --accept H A handle (tcN or revN) to accept. Repeat for several
97271
+ (--accept rev0 --accept rev1 --accept tc4).
97272
+ --reject H A handle (tcN or revN) to reject. Repeat for several.
97273
+
97274
+ A handle may not appear in both lists. Unknown handles error before anything is
97275
+ written. Leftover changes you name in neither list stay tracked (apply finalizes
97276
+ only what you address); the confirmation re-lists them so you can see what's left.
97277
+
97278
+ Options:
97279
+ -o, --output PATH Write to PATH instead of overwriting FILE
97280
+ --dry-run Print what would change; do not write the file
97281
+ -v, --verbose Print the success ack JSON (default: a one-line confirmation)
97282
+ -h, --help Show this help
97283
+
97284
+ Output:
97285
+ Prints a one-line confirmation on success (exit 0); when changes remain it
97286
+ also re-lists them with their renumbered handles. --verbose prints
97287
+ {ok:true, operation, path, applied}. --dry-run previews. Errors print
97288
+ {code, error, hint?} with a nonzero exit. Discover handles with
97289
+ \`docx track-changes list FILE\`.
97290
+
97291
+ Examples:
97292
+ docx track-changes apply doc.docx --accept rev0 --accept rev1 --accept tc4 \\
97293
+ --reject rev2 --reject tc7
97294
+ docx track-changes apply doc.docx --reject rev0 --dry-run
97295
+ `;
97296
+ var init_apply2 = __esm(() => {
97297
+ init_track_changes();
97298
+ init_respond();
97299
+ init_groups();
97300
+ init_list_view();
97301
+ });
97302
+
95639
97303
  // src/cli/track-changes/toggle.tsx
95640
97304
  var exports_toggle = {};
95641
97305
  __export(exports_toggle, {
95642
- run: () => run52
97306
+ run: () => run56
95643
97307
  });
95644
- async function run52(args) {
97308
+ async function run56(args) {
95645
97309
  const parsed = await tryParseArgs(args, {
95646
97310
  ...SAVE_FLAGS
95647
- }, HELP48);
97311
+ }, HELP52);
95648
97312
  if (typeof parsed === "number")
95649
97313
  return parsed;
95650
97314
  if (parsed.values.help) {
95651
- await writeStdout(HELP48);
97315
+ await writeStdout(HELP52);
95652
97316
  return EXIT2.OK;
95653
97317
  }
95654
97318
  setVerboseAck(Boolean(parsed.values.verbose));
@@ -95657,10 +97321,10 @@ async function run52(args) {
95657
97321
  const mode = modeFirst ? first : second;
95658
97322
  const path2 = modeFirst ? second : first;
95659
97323
  if (mode !== "on" && mode !== "off") {
95660
- return fail("USAGE", `Expected "on" or "off" (e.g. \`docx track-changes on FILE\`), got: ${parsed.positionals.join(" ") || "<nothing>"}`, HELP48);
97324
+ return fail("USAGE", `Expected "on" or "off" (e.g. \`docx track-changes on FILE\`), got: ${parsed.positionals.join(" ") || "<nothing>"}`, HELP52);
95661
97325
  }
95662
97326
  if (!path2)
95663
- return fail("USAGE", "Missing FILE argument", HELP48);
97327
+ return fail("USAGE", "Missing FILE argument", HELP52);
95664
97328
  const document4 = await openOrFail(path2);
95665
97329
  if (typeof document4 === "number")
95666
97330
  return document4;
@@ -95690,7 +97354,7 @@ async function run52(args) {
95690
97354
  });
95691
97355
  return EXIT2.OK;
95692
97356
  }
95693
- var HELP48 = `docx track-changes \u2014 toggle the document's tracked-changes mode
97357
+ var HELP52 = `docx track-changes \u2014 toggle the document's tracked-changes mode
95694
97358
 
95695
97359
  Usage:
95696
97360
  docx track-changes on|off FILE [options]
@@ -95728,16 +97392,16 @@ var init_toggle2 = __esm(() => {
95728
97392
  // src/cli/track-changes/index.ts
95729
97393
  var exports_track_changes = {};
95730
97394
  __export(exports_track_changes, {
95731
- run: () => run53
97395
+ run: () => run57
95732
97396
  });
95733
- async function run53(args) {
97397
+ async function run57(args) {
95734
97398
  const first = args[0];
95735
97399
  if (first === "--help" || first === "-h" || first === "help") {
95736
- await writeStdout(HELP49);
97400
+ await writeStdout(HELP53);
95737
97401
  return 0;
95738
97402
  }
95739
97403
  if (!first) {
95740
- return fail("USAGE", "Missing arguments", HELP49);
97404
+ return fail("USAGE", "Missing arguments", HELP53);
95741
97405
  }
95742
97406
  if (first === "list") {
95743
97407
  const module_2 = await Promise.resolve().then(() => (init_list8(), exports_list5));
@@ -95751,16 +97415,21 @@ async function run53(args) {
95751
97415
  const module_2 = await Promise.resolve().then(() => (init_reject(), exports_reject));
95752
97416
  return module_2.run(args.slice(1));
95753
97417
  }
97418
+ if (first === "apply") {
97419
+ const module_2 = await Promise.resolve().then(() => (init_apply2(), exports_apply));
97420
+ return module_2.run(args.slice(1));
97421
+ }
95754
97422
  const module_ = await Promise.resolve().then(() => (init_toggle2(), exports_toggle));
95755
97423
  return module_.run(args);
95756
97424
  }
95757
- var HELP49 = `docx track-changes \u2014 manage tracked-changes
97425
+ var HELP53 = `docx track-changes \u2014 manage tracked-changes
95758
97426
 
95759
97427
  Usage:
95760
97428
  docx track-changes on|off FILE [options]
95761
97429
  docx track-changes list FILE [options]
95762
97430
  docx track-changes accept FILE (--at tcN | --all) [options]
95763
97431
  docx track-changes reject FILE (--at tcN | --all) [options]
97432
+ docx track-changes apply FILE (--accept H ... | --reject H ...) [options]
95764
97433
 
95765
97434
  Verbs:
95766
97435
  on Set <w:trackChanges/> in word/settings.xml
@@ -95775,9 +97444,14 @@ Verbs:
95775
97444
  paragraph-mark ins the entire paragraph is removed); del/moveFrom
95776
97445
  unwrap (with <w:delText> \u2192 <w:t> rename); sectPrChange restores
95777
97446
  its snapshot
97447
+ apply Finalize: accept AND reject in ONE atomic call, every handle
97448
+ resolved against the original tree \u2014 the safe way to apply a
97449
+ review, since separate accept/reject calls renumber ids between
97450
+ them
95778
97451
 
95779
97452
  Exact-change addressing is always --at tcN (repeatable); --all targets every
95780
- change. Discover ids with "docx track-changes list FILE".
97453
+ change; \`apply\` takes --accept/--reject handle lists. Discover ids with
97454
+ "docx track-changes list FILE".
95781
97455
 
95782
97456
  When tracking is on, the SUBSEQUENT insert/edit/delete/replace commands emit
95783
97457
  <w:ins>/<w:del> markers (attributed via --author or $DOCX_AUTHOR on those
@@ -95894,29 +97568,29 @@ var init_count = __esm(() => {
95894
97568
  // src/cli/wc/index.ts
95895
97569
  var exports_wc = {};
95896
97570
  __export(exports_wc, {
95897
- run: () => run54
97571
+ run: () => run58
95898
97572
  });
95899
- async function run54(args) {
97573
+ async function run58(args) {
95900
97574
  const parsed = await tryParseArgs(args, {
95901
97575
  accepted: { type: "boolean" },
95902
97576
  baseline: { type: "boolean" },
95903
97577
  current: { type: "boolean" },
95904
97578
  json: { type: "boolean" },
95905
97579
  help: { type: "boolean", short: "h" }
95906
- }, HELP50);
97580
+ }, HELP54);
95907
97581
  if (typeof parsed === "number")
95908
97582
  return parsed;
95909
97583
  if (parsed.values.help) {
95910
- await writeStdout(HELP50);
97584
+ await writeStdout(HELP54);
95911
97585
  return EXIT2.OK;
95912
97586
  }
95913
97587
  const path2 = parsed.positionals[0];
95914
97588
  const locatorInput = parsed.positionals[1];
95915
97589
  if (!path2)
95916
- return fail("USAGE", "Missing FILE argument", HELP50);
97590
+ return fail("USAGE", "Missing FILE argument", HELP54);
95917
97591
  const view = resolveView(parsed.values);
95918
97592
  if (!view) {
95919
- return fail("USAGE", "--accepted, --baseline, and --current are mutually exclusive", HELP50);
97593
+ return fail("USAGE", "--accepted, --baseline, and --current are mutually exclusive", HELP54);
95920
97594
  }
95921
97595
  const json2 = Boolean(parsed.values.json);
95922
97596
  const pickText = paragraphTextFor(view);
@@ -96094,13 +97768,13 @@ function paragraphTextFor(view) {
96094
97768
  return paragraphTextBaseline;
96095
97769
  return paragraphText2;
96096
97770
  }
96097
- var HELP50;
97771
+ var HELP54;
96098
97772
  var init_wc = __esm(() => {
96099
97773
  init_core2();
96100
97774
  init_parse_helpers();
96101
97775
  init_respond();
96102
97776
  init_count();
96103
- HELP50 = `docx wc \u2014 count words in a document or a locator-addressed slice
97777
+ HELP54 = `docx wc \u2014 count words in a document or a locator-addressed slice
96104
97778
 
96105
97779
  Usage:
96106
97780
  docx wc FILE [LOCATOR] [options]
@@ -96164,7 +97838,7 @@ Examples:
96164
97838
  // package.json
96165
97839
  var package_default = {
96166
97840
  name: "bun-docx",
96167
- version: "0.16.0",
97841
+ version: "0.18.0",
96168
97842
  description: "CLI for AI agents (Claude, Codex) to read, edit, and comment on .docx files with full format fidelity.",
96169
97843
  keywords: [
96170
97844
  "docx",
@@ -96272,6 +97946,7 @@ Commands (each one-liner names capabilities you'd otherwise miss; see <command>
96272
97946
  images \u2026 Add (--caption "Figure 1: \u2026" for a captioned figure), extract, replace, delete, list images
96273
97947
  hyperlinks \u2026 Add, list, replace, delete hyperlinks (add uses --url; replace uses --with)
96274
97948
  tables \u2026 Restructure tables \u2014 insert/delete rows & columns, merge/unmerge, set widths, borders
97949
+ lists FILE Renumber a numbered list \u2014 "lists set --at pN --start 5" / "--format upper-roman" / "--restart" / "--continue"
96275
97950
  track-changes \u2026 Toggle (on|off FILE); list / accept / reject revisions; "read" shows them as CriticMarkup
96276
97951
  info \u2026 Reference material, no FILE needed (schema for read --ast, locator grammar)
96277
97952
 
@@ -96332,6 +98007,7 @@ var COMMANDS = {
96332
98007
  images: () => Promise.resolve().then(() => (init_images(), exports_images)),
96333
98008
  info: () => Promise.resolve().then(() => (init_info(), exports_info)),
96334
98009
  insert: () => Promise.resolve().then(() => (init_insert2(), exports_insert)),
98010
+ lists: () => Promise.resolve().then(() => (init_lists2(), exports_lists)),
96335
98011
  outline: () => Promise.resolve().then(() => (init_outline(), exports_outline)),
96336
98012
  read: () => Promise.resolve().then(() => (init_read3(), exports_read)),
96337
98013
  render: () => Promise.resolve().then(() => (init_render2(), exports_render)),