@reteps/tree-sitter-htmlmustache 0.7.3 → 0.8.1

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 +68 -22
  2. package/cli/out/main.js +946 -429
  3. package/package.json +2 -1
package/cli/out/main.js CHANGED
@@ -542,8 +542,8 @@ function parseDocument(source) {
542
542
  }
543
543
 
544
544
  // lsp/server/src/configFile.ts
545
- var fs = __toESM(require("fs"));
546
- var path2 = __toESM(require("path"));
545
+ var fs = __toESM(require("fs"), 1);
546
+ var path2 = __toESM(require("path"), 1);
547
547
 
548
548
  // lsp/server/src/ruleMetadata.ts
549
549
  var RULES = [
@@ -586,11 +586,16 @@ var RULES = [
586
586
  name: "unrecognizedHtmlTags",
587
587
  defaultSeverity: "error",
588
588
  description: "Flags HTML tags that are not standard HTML elements or valid custom elements"
589
+ },
590
+ {
591
+ name: "elementContentTooLong",
592
+ defaultSeverity: "off",
593
+ description: "Flags configured elements whose inner content exceeds a byte-length threshold (opt-in; requires `elements: [{ tag, maxBytes }]` option)"
589
594
  }
590
595
  ];
591
- var KNOWN_RULE_NAMES = new Set(RULES.map((r) => r.name));
596
+ var KNOWN_RULE_NAMES = new Set(RULES.map((r2) => r2.name));
592
597
  var RULE_DEFAULTS = Object.fromEntries(
593
- RULES.map((r) => [r.name, r.defaultSeverity])
598
+ RULES.map((r2) => [r2.name, r2.defaultSeverity])
594
599
  );
595
600
 
596
601
  // lsp/server/src/configFile.ts
@@ -614,41 +619,70 @@ var VALID_CSS_DISPLAY_VALUES = /* @__PURE__ */ new Set([
614
619
  "none"
615
620
  ]);
616
621
  var VALID_RULE_SEVERITIES = /* @__PURE__ */ new Set(["error", "warning", "off"]);
622
+ function parseElementContentTooLongOptions(raw) {
623
+ if (!Array.isArray(raw.elements)) return null;
624
+ const elements = [];
625
+ for (const entry of raw.elements) {
626
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
627
+ const e2 = entry;
628
+ if (typeof e2.tag !== "string" || e2.tag.length === 0) continue;
629
+ if (typeof e2.maxBytes !== "number" || !Number.isFinite(e2.maxBytes) || e2.maxBytes < 0) continue;
630
+ elements.push({ tag: e2.tag, maxBytes: e2.maxBytes });
631
+ }
632
+ return { elements };
633
+ }
634
+ var OPTION_PARSERS = {
635
+ elementContentTooLong: parseElementContentTooLongOptions
636
+ };
637
+ function parseRuleEntry(key, value) {
638
+ if (typeof value === "string") {
639
+ return VALID_RULE_SEVERITIES.has(value) ? value : null;
640
+ }
641
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
642
+ const obj = value;
643
+ if (typeof obj.severity !== "string" || !VALID_RULE_SEVERITIES.has(obj.severity)) return null;
644
+ const severity = obj.severity;
645
+ const parser2 = OPTION_PARSERS[key];
646
+ if (!parser2) return { severity };
647
+ const options = parser2(obj);
648
+ if (!options) return { severity };
649
+ return { severity, ...options };
650
+ }
617
651
  var CONFIG_FILENAME = ".htmlmustache.jsonc";
618
652
  function parseJsonc(text2) {
619
653
  let result = "";
620
- let i = 0;
621
- while (i < text2.length) {
622
- if (text2[i] === '"') {
654
+ let i2 = 0;
655
+ while (i2 < text2.length) {
656
+ if (text2[i2] === '"') {
623
657
  result += '"';
624
- i++;
625
- while (i < text2.length && text2[i] !== '"') {
626
- if (text2[i] === "\\") {
627
- result += text2[i] + (text2[i + 1] ?? "");
628
- i += 2;
658
+ i2++;
659
+ while (i2 < text2.length && text2[i2] !== '"') {
660
+ if (text2[i2] === "\\") {
661
+ result += text2[i2] + (text2[i2 + 1] ?? "");
662
+ i2 += 2;
629
663
  } else {
630
- result += text2[i];
631
- i++;
664
+ result += text2[i2];
665
+ i2++;
632
666
  }
633
667
  }
634
- if (i < text2.length) {
668
+ if (i2 < text2.length) {
635
669
  result += '"';
636
- i++;
670
+ i2++;
637
671
  }
638
672
  continue;
639
673
  }
640
- if (text2[i] === "/" && text2[i + 1] === "/") {
641
- while (i < text2.length && text2[i] !== "\n") i++;
674
+ if (text2[i2] === "/" && text2[i2 + 1] === "/") {
675
+ while (i2 < text2.length && text2[i2] !== "\n") i2++;
642
676
  continue;
643
677
  }
644
- if (text2[i] === "/" && text2[i + 1] === "*") {
645
- i += 2;
646
- while (i < text2.length && !(text2[i] === "*" && text2[i + 1] === "/")) i++;
647
- i += 2;
678
+ if (text2[i2] === "/" && text2[i2 + 1] === "*") {
679
+ i2 += 2;
680
+ while (i2 < text2.length && !(text2[i2] === "*" && text2[i2 + 1] === "/")) i2++;
681
+ i2 += 2;
648
682
  continue;
649
683
  }
650
- result += text2[i];
651
- i++;
684
+ result += text2[i2];
685
+ i2++;
652
686
  }
653
687
  result = result.replace(/,\s*([}\]])/g, "$1");
654
688
  return JSON.parse(result);
@@ -674,21 +708,21 @@ function parseCustomTagArray(arr) {
674
708
  const tags = [];
675
709
  for (const entry of arr) {
676
710
  if (entry && typeof entry === "object" && "name" in entry) {
677
- const e = entry;
678
- if (typeof e.name !== "string" || e.name.length === 0) continue;
679
- const tag = { name: e.name };
680
- if (typeof e.display === "string" && VALID_CSS_DISPLAY_VALUES.has(e.display)) {
681
- tag.display = e.display;
711
+ const e2 = entry;
712
+ if (typeof e2.name !== "string" || e2.name.length === 0) continue;
713
+ const tag = { name: e2.name };
714
+ if (typeof e2.display === "string" && VALID_CSS_DISPLAY_VALUES.has(e2.display)) {
715
+ tag.display = e2.display;
682
716
  }
683
- if (typeof e.languageAttribute === "string") tag.languageAttribute = e.languageAttribute;
684
- if (e.languageMap && typeof e.languageMap === "object" && !Array.isArray(e.languageMap)) {
685
- tag.languageMap = e.languageMap;
717
+ if (typeof e2.languageAttribute === "string") tag.languageAttribute = e2.languageAttribute;
718
+ if (e2.languageMap && typeof e2.languageMap === "object" && !Array.isArray(e2.languageMap)) {
719
+ tag.languageMap = e2.languageMap;
686
720
  }
687
- if (typeof e.languageDefault === "string") tag.languageDefault = e.languageDefault;
688
- if (typeof e.indent === "string" && VALID_INDENT_MODES.has(e.indent)) {
689
- tag.indent = e.indent;
721
+ if (typeof e2.languageDefault === "string") tag.languageDefault = e2.languageDefault;
722
+ if (typeof e2.indent === "string" && VALID_INDENT_MODES.has(e2.indent)) {
723
+ tag.indent = e2.indent;
690
724
  }
691
- if (typeof e.indentAttribute === "string") tag.indentAttribute = e.indentAttribute;
725
+ if (typeof e2.indentAttribute === "string") tag.indentAttribute = e2.indentAttribute;
692
726
  tags.push(tag);
693
727
  }
694
728
  }
@@ -717,11 +751,11 @@ function validateConfig(raw) {
717
751
  if (items.length > 0) config.noBreakDelimiters = items;
718
752
  }
719
753
  if (Array.isArray(obj.include)) {
720
- const items = obj.include.filter((s) => typeof s === "string" && s.length > 0);
754
+ const items = obj.include.filter((s2) => typeof s2 === "string" && s2.length > 0);
721
755
  if (items.length > 0) config.include = items;
722
756
  }
723
757
  if (Array.isArray(obj.exclude)) {
724
- const items = obj.exclude.filter((s) => typeof s === "string" && s.length > 0);
758
+ const items = obj.exclude.filter((s2) => typeof s2 === "string" && s2.length > 0);
725
759
  if (items.length > 0) config.exclude = items;
726
760
  }
727
761
  const parsedCodeTags = parseCustomTagArray(obj.customCodeTags);
@@ -741,10 +775,11 @@ function validateConfig(raw) {
741
775
  const rules = {};
742
776
  let hasRules = false;
743
777
  for (const [key, value] of Object.entries(rawRules)) {
744
- if (KNOWN_RULE_NAMES.has(key) && typeof value === "string" && VALID_RULE_SEVERITIES.has(value)) {
745
- rules[key] = value;
746
- hasRules = true;
747
- }
778
+ if (!KNOWN_RULE_NAMES.has(key)) continue;
779
+ const entry = parseRuleEntry(key, value);
780
+ if (entry === null) continue;
781
+ rules[key] = entry;
782
+ hasRules = true;
748
783
  }
749
784
  if (hasRules) config.rules = rules;
750
785
  }
@@ -752,13 +787,13 @@ function validateConfig(raw) {
752
787
  const rules = [];
753
788
  for (const entry of obj.customRules) {
754
789
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
755
- const e = entry;
756
- if (typeof e.id !== "string" || e.id.length === 0) continue;
757
- if (typeof e.selector !== "string" || e.selector.length === 0) continue;
758
- if (typeof e.message !== "string" || e.message.length === 0) continue;
759
- const rule = { id: e.id, selector: e.selector, message: e.message };
760
- if (typeof e.severity === "string" && VALID_RULE_SEVERITIES.has(e.severity)) {
761
- rule.severity = e.severity;
790
+ const e2 = entry;
791
+ if (typeof e2.id !== "string" || e2.id.length === 0) continue;
792
+ if (typeof e2.selector !== "string" || e2.selector.length === 0) continue;
793
+ if (typeof e2.message !== "string" || e2.message.length === 0) continue;
794
+ const rule = { id: e2.id, selector: e2.selector, message: e2.message };
795
+ if (typeof e2.severity === "string" && VALID_RULE_SEVERITIES.has(e2.severity)) {
796
+ rule.severity = e2.severity;
762
797
  }
763
798
  rules.push(rule);
764
799
  }
@@ -807,7 +842,7 @@ function isHtmlElementType(node) {
807
842
  function getTagName(node) {
808
843
  for (const child of node.children) {
809
844
  if (child.type === "html_start_tag" || child.type === "html_self_closing_tag") {
810
- const tagNameNode = child.children.find((c) => c.type === "html_tag_name");
845
+ const tagNameNode = child.children.find((c2) => c2.type === "html_tag_name");
811
846
  if (tagNameNode) return tagNameNode.text;
812
847
  }
813
848
  }
@@ -815,16 +850,33 @@ function getTagName(node) {
815
850
  }
816
851
  function getSectionName(node) {
817
852
  const beginNode = node.children.find(
818
- (c) => c.type === "mustache_section_begin" || c.type === "mustache_inverted_section_begin"
853
+ (c2) => c2.type === "mustache_section_begin" || c2.type === "mustache_inverted_section_begin"
819
854
  );
820
855
  if (!beginNode) return null;
821
- const tagNameNode = beginNode.children.find((c) => c.type === "mustache_tag_name");
856
+ const tagNameNode = beginNode.children.find((c2) => c2.type === "mustache_tag_name");
822
857
  return tagNameNode?.text ?? null;
823
858
  }
824
859
  function getErroneousEndTagName(node) {
825
- const nameNode = node.children.find((c) => c.type === "html_erroneous_end_tag_name");
860
+ const nameNode = node.children.find((c2) => c2.type === "html_erroneous_end_tag_name");
826
861
  return nameNode?.text?.toLowerCase() ?? null;
827
862
  }
863
+ function getInterpolationPath(node) {
864
+ for (const child of node.children) {
865
+ if (child.type === "mustache_path_expression" || child.type === "mustache_identifier") {
866
+ return child.text;
867
+ }
868
+ if (child.type === ".") return ".";
869
+ }
870
+ return null;
871
+ }
872
+ function getCommentContent(node) {
873
+ const child = node.children.find((c2) => c2.type === "mustache_comment_content");
874
+ return child ? child.text.trim() : null;
875
+ }
876
+ function getPartialName(node) {
877
+ const child = node.children.find((c2) => c2.type === "mustache_partial_content");
878
+ return child ? child.text.trim() : null;
879
+ }
828
880
 
829
881
  // lsp/server/src/htmlBalanceChecker.ts
830
882
  function getTagNameLower(element) {
@@ -834,7 +886,7 @@ function getErroneousEndTagNameLower(node) {
834
886
  return getErroneousEndTagName(node)?.toLowerCase() ?? null;
835
887
  }
836
888
  function hasForcedEndTag(element) {
837
- return element.children.some((c) => c.type === "html_forced_end_tag");
889
+ return element.children.some((c2) => c2.type === "html_forced_end_tag");
838
890
  }
839
891
  function extractFromNodes(nodes) {
840
892
  const items = [];
@@ -846,13 +898,13 @@ function extractFromNodes(nodes) {
846
898
  function extractFromNode(node) {
847
899
  if (node.type === "html_element") {
848
900
  const contentChildren = node.children.filter(
849
- (c) => c.type !== "html_start_tag" && c.type !== "html_end_tag" && c.type !== "html_forced_end_tag"
901
+ (c2) => c2.type !== "html_start_tag" && c2.type !== "html_end_tag" && c2.type !== "html_forced_end_tag"
850
902
  );
851
903
  if (hasForcedEndTag(node)) {
852
904
  const tagName = getTagNameLower(node);
853
905
  const items = [];
854
906
  if (tagName) {
855
- const startTag = node.children.find((c) => c.type === "html_start_tag");
907
+ const startTag = node.children.find((c2) => c2.type === "html_start_tag");
856
908
  items.push({ type: "open", tagName, node: startTag ?? node });
857
909
  }
858
910
  items.push(...extractFromNodes(contentChildren));
@@ -874,7 +926,7 @@ function extractFromNode(node) {
874
926
  const sectionName = getSectionName(node);
875
927
  if (sectionName) {
876
928
  const contentChildren = node.children.filter(
877
- (c) => c.type !== "mustache_section_begin" && c.type !== "mustache_section_end" && c.type !== "mustache_erroneous_section_end"
929
+ (c2) => c2.type !== "mustache_section_begin" && c2.type !== "mustache_section_end" && c2.type !== "mustache_erroneous_section_end"
878
930
  );
879
931
  return [
880
932
  {
@@ -891,7 +943,7 @@ function extractFromNode(node) {
891
943
  const sectionName = getSectionName(node);
892
944
  if (sectionName) {
893
945
  const contentChildren = node.children.filter(
894
- (c) => c.type !== "mustache_inverted_section_begin" && c.type !== "mustache_inverted_section_end" && c.type !== "mustache_erroneous_inverted_section_end"
946
+ (c2) => c2.type !== "mustache_inverted_section_begin" && c2.type !== "mustache_inverted_section_end" && c2.type !== "mustache_erroneous_inverted_section_end"
895
947
  );
896
948
  return [
897
949
  {
@@ -909,17 +961,17 @@ function extractFromNode(node) {
909
961
  function mergeAdjacentForks(items) {
910
962
  if (items.length === 0) return items;
911
963
  const result = [];
912
- let i = 0;
913
- while (i < items.length) {
914
- const item = items[i];
964
+ let i2 = 0;
965
+ while (i2 < items.length) {
966
+ const item = items[i2];
915
967
  if (item.type !== "fork") {
916
968
  result.push(item);
917
- i++;
969
+ i2++;
918
970
  continue;
919
971
  }
920
972
  const truthy = [...item.truthy];
921
973
  const falsy = [...item.falsy];
922
- let j = i + 1;
974
+ let j = i2 + 1;
923
975
  while (j < items.length) {
924
976
  const next = items[j];
925
977
  if (next.type !== "fork" || next.sectionName !== item.sectionName) break;
@@ -933,7 +985,7 @@ function mergeAdjacentForks(items) {
933
985
  truthy: mergeAdjacentForks(truthy),
934
986
  falsy: mergeAdjacentForks(falsy)
935
987
  });
936
- i = j;
988
+ i2 = j;
937
989
  }
938
990
  return result;
939
991
  }
@@ -1074,12 +1126,12 @@ function checkUnclosedTags(rootNode) {
1074
1126
  const errors = [];
1075
1127
  function visit(node) {
1076
1128
  if (node.type === "html_element") {
1077
- const hasEndTag = node.children.some((c) => c.type === "html_end_tag");
1078
- const hasForcedEnd = node.children.some((c) => c.type === "html_forced_end_tag");
1129
+ const hasEndTag = node.children.some((c2) => c2.type === "html_end_tag");
1130
+ const hasForcedEnd = node.children.some((c2) => c2.type === "html_forced_end_tag");
1079
1131
  if (!hasEndTag && !hasForcedEnd) {
1080
1132
  const tagName = getTagNameLower(node);
1081
1133
  if (tagName && !VOID_ELEMENTS.has(tagName) && !OPTIONAL_END_TAG_ELEMENTS.has(tagName)) {
1082
- const startTag = node.children.find((c) => c.type === "html_start_tag");
1134
+ const startTag = node.children.find((c2) => c2.type === "html_start_tag");
1083
1135
  errors.push({
1084
1136
  node: startTag ?? node,
1085
1137
  message: `Unclosed HTML tag: <${tagName}>`
@@ -1107,8 +1159,8 @@ function checkHtmlBalance(rootNode) {
1107
1159
  const totalPaths = 1 << sectionNames.length;
1108
1160
  for (let mask = 0; mask < totalPaths; mask++) {
1109
1161
  const assignment = /* @__PURE__ */ new Map();
1110
- for (let i = 0; i < sectionNames.length; i++) {
1111
- assignment.set(sectionNames[i], (mask & 1 << i) !== 0);
1162
+ for (let i2 = 0; i2 < sectionNames.length; i2++) {
1163
+ assignment.set(sectionNames[i2], (mask & 1 << i2) !== 0);
1112
1164
  }
1113
1165
  const events = flattenPath(items, assignment);
1114
1166
  const condition = formatCondition(assignment);
@@ -1132,7 +1184,7 @@ function checkNestedSameNameSections(rootNode) {
1132
1184
  if (name) {
1133
1185
  if (ancestors.has(name)) {
1134
1186
  const beginNode = node.children.find(
1135
- (c) => c.type === "mustache_section_begin" || c.type === "mustache_inverted_section_begin"
1187
+ (c2) => c2.type === "mustache_section_begin" || c2.type === "mustache_inverted_section_begin"
1136
1188
  );
1137
1189
  errors.push({
1138
1190
  node: beginNode ?? node,
@@ -1158,7 +1210,7 @@ function checkUnquotedMustacheAttributes(rootNode) {
1158
1210
  const errors = [];
1159
1211
  function visit(node) {
1160
1212
  if (node.type === "html_attribute") {
1161
- const mustacheNode = node.children.find((c) => c.type === "mustache_interpolation");
1213
+ const mustacheNode = node.children.find((c2) => c2.type === "mustache_interpolation");
1162
1214
  if (mustacheNode) {
1163
1215
  errors.push({
1164
1216
  node: mustacheNode,
@@ -1184,9 +1236,9 @@ function checkConsecutiveSameNameSections(rootNode, sourceText) {
1184
1236
  const errors = [];
1185
1237
  function visit(node) {
1186
1238
  const children = node.children;
1187
- for (let i = 0; i < children.length - 1; i++) {
1188
- const current = children[i];
1189
- const next = children[i + 1];
1239
+ for (let i2 = 0; i2 < children.length - 1; i2++) {
1240
+ const current = children[i2];
1241
+ const next = children[i2 + 1];
1190
1242
  if (!isMustacheSection(current) || current.type !== next.type) {
1191
1243
  continue;
1192
1244
  }
@@ -1197,12 +1249,12 @@ function checkConsecutiveSameNameSections(rootNode, sourceText) {
1197
1249
  if (gap.length > 0 && !/^\s*$/.test(gap)) continue;
1198
1250
  const endTagType = current.type === "mustache_section" ? "mustache_section_end" : "mustache_inverted_section_end";
1199
1251
  const beginTagType = next.type === "mustache_section" ? "mustache_section_begin" : "mustache_inverted_section_begin";
1200
- const currentEndTag = current.children.find((c) => c.type === endTagType);
1201
- const nextBeginTag = next.children.find((c) => c.type === beginTagType);
1252
+ const currentEndTag = current.children.find((c2) => c2.type === endTagType);
1253
+ const nextBeginTag = next.children.find((c2) => c2.type === beginTagType);
1202
1254
  if (!currentEndTag || !nextBeginTag) continue;
1203
1255
  const sectionTypeStr = current.type === "mustache_section" ? "#" : "^";
1204
1256
  const nextBeginNode = next.children.find(
1205
- (c) => c.type === "mustache_section_begin" || c.type === "mustache_inverted_section_begin"
1257
+ (c2) => c2.type === "mustache_section_begin" || c2.type === "mustache_inverted_section_begin"
1206
1258
  );
1207
1259
  errors.push({
1208
1260
  node: nextBeginNode ?? next,
@@ -1252,7 +1304,7 @@ function checkSelfClosingNonVoidTags(rootNode) {
1252
1304
  const errors = [];
1253
1305
  function visit(node) {
1254
1306
  if (node.type === "html_self_closing_tag") {
1255
- const tagNameNode = node.children.find((c) => c.type === "html_tag_name");
1307
+ const tagNameNode = node.children.find((c2) => c2.type === "html_tag_name");
1256
1308
  const tagName = tagNameNode?.text.toLowerCase();
1257
1309
  if (tagName && !VOID_ELEMENTS2.has(tagName)) {
1258
1310
  errors.push({
@@ -1275,8 +1327,8 @@ function checkSelfClosingNonVoidTags(rootNode) {
1275
1327
  visit(rootNode);
1276
1328
  return errors;
1277
1329
  }
1278
- function areMutuallyExclusive(a, b) {
1279
- for (const ac of a) {
1330
+ function areMutuallyExclusive(a2, b) {
1331
+ for (const ac of a2) {
1280
1332
  for (const bc of b) {
1281
1333
  if (ac.name === bc.name && ac.inverted !== bc.inverted) {
1282
1334
  return true;
@@ -1285,11 +1337,11 @@ function areMutuallyExclusive(a, b) {
1285
1337
  }
1286
1338
  return false;
1287
1339
  }
1288
- function formatConditionClause(a, b) {
1340
+ function formatConditionClause(a2, b) {
1289
1341
  const seen = /* @__PURE__ */ new Map();
1290
- for (const c of [...a, ...b]) {
1291
- if (!seen.has(c.name)) {
1292
- seen.set(c.name, c.inverted);
1342
+ for (const c2 of [...a2, ...b]) {
1343
+ if (!seen.has(c2.name)) {
1344
+ seen.set(c2.name, c2.inverted);
1293
1345
  }
1294
1346
  }
1295
1347
  if (seen.size === 0) return "";
@@ -1302,12 +1354,12 @@ function formatConditionClause(a, b) {
1302
1354
  function collectAttributes(node, conditions, out) {
1303
1355
  for (const child of node.children) {
1304
1356
  if (child.type === "html_attribute") {
1305
- const nameNode = child.children.find((c) => c.type === "html_attribute_name");
1357
+ const nameNode = child.children.find((c2) => c2.type === "html_attribute_name");
1306
1358
  if (nameNode) {
1307
1359
  out.push({ nameNode, conditions: [...conditions] });
1308
1360
  }
1309
1361
  } else if (child.type === "mustache_attribute") {
1310
- const section = child.children.find((c) => isMustacheSection(c));
1362
+ const section = child.children.find((c2) => isMustacheSection(c2));
1311
1363
  if (section) {
1312
1364
  const name = getSectionName(section);
1313
1365
  if (name) {
@@ -1528,15 +1580,15 @@ var KNOWN_HTML_TAGS = /* @__PURE__ */ new Set([
1528
1580
  ]);
1529
1581
  function checkUnrecognizedHtmlTags(rootNode, customTagNames) {
1530
1582
  const errors = [];
1531
- const customSet = customTagNames ? new Set(customTagNames.map((n) => n.toLowerCase())) : void 0;
1583
+ const customSet = customTagNames ? new Set(customTagNames.map((n2) => n2.toLowerCase())) : void 0;
1532
1584
  function visit(node) {
1533
1585
  if (node.type === "html_element" || node.type === "html_self_closing_tag") {
1534
- const tagNameNode = node.type === "html_self_closing_tag" ? node.children.find((c) => c.type === "html_tag_name") : node.children.find((c) => c.type === "html_start_tag")?.children.find((c) => c.type === "html_tag_name");
1586
+ const tagNameNode = node.type === "html_self_closing_tag" ? node.children.find((c2) => c2.type === "html_tag_name") : node.children.find((c2) => c2.type === "html_start_tag")?.children.find((c2) => c2.type === "html_tag_name");
1535
1587
  const tagName = tagNameNode?.text.toLowerCase();
1536
1588
  if (tagName === "svg" || tagName === "math") return;
1537
1589
  }
1538
1590
  if (node.type === "html_start_tag" || node.type === "html_self_closing_tag") {
1539
- const tagNameNode = node.children.find((c) => c.type === "html_tag_name");
1591
+ const tagNameNode = node.children.find((c2) => c2.type === "html_tag_name");
1540
1592
  if (tagNameNode) {
1541
1593
  const tagName = tagNameNode.text.toLowerCase();
1542
1594
  if (!KNOWN_HTML_TAGS.has(tagName) && !customSet?.has(tagName)) {
@@ -1573,19 +1625,19 @@ function checkDuplicateAttributes(rootNode) {
1573
1625
  }
1574
1626
  for (const [, group2] of groups) {
1575
1627
  if (group2.length < 2) continue;
1576
- for (let i = 1; i < group2.length; i++) {
1628
+ for (let i2 = 1; i2 < group2.length; i2++) {
1577
1629
  let conflictIdx = -1;
1578
- for (let j = 0; j < i; j++) {
1579
- if (!areMutuallyExclusive(group2[i].conditions, group2[j].conditions)) {
1630
+ for (let j = 0; j < i2; j++) {
1631
+ if (!areMutuallyExclusive(group2[i2].conditions, group2[j].conditions)) {
1580
1632
  conflictIdx = j;
1581
1633
  break;
1582
1634
  }
1583
1635
  }
1584
1636
  if (conflictIdx >= 0) {
1585
- const clause = formatConditionClause(group2[conflictIdx].conditions, group2[i].conditions);
1637
+ const clause = formatConditionClause(group2[conflictIdx].conditions, group2[i2].conditions);
1586
1638
  errors.push({
1587
- node: group2[i].nameNode,
1588
- message: `Duplicate attribute "${group2[i].nameNode.text}"${clause}`
1639
+ node: group2[i2].nameNode,
1640
+ message: `Duplicate attribute "${group2[i2].nameNode.text}"${clause}`
1589
1641
  });
1590
1642
  }
1591
1643
  }
@@ -1599,272 +1651,721 @@ function checkDuplicateAttributes(rootNode) {
1599
1651
  visit(rootNode);
1600
1652
  return errors;
1601
1653
  }
1654
+ function checkElementContentTooLong(rootNode, elements) {
1655
+ const errors = [];
1656
+ if (elements.length === 0) return errors;
1657
+ const thresholds = /* @__PURE__ */ new Map();
1658
+ for (const { tag, maxBytes } of elements) {
1659
+ const key = tag.toLowerCase();
1660
+ const existing = thresholds.get(key);
1661
+ if (existing === void 0 || maxBytes < existing) thresholds.set(key, maxBytes);
1662
+ }
1663
+ function visit(node) {
1664
+ if (node.type === "html_element") {
1665
+ const startTag = node.children.find((c2) => c2.type === "html_start_tag");
1666
+ const endTag = node.children.find((c2) => c2.type === "html_end_tag");
1667
+ const tagNameNode = startTag?.children.find((c2) => c2.type === "html_tag_name");
1668
+ const tagName = tagNameNode?.text.toLowerCase();
1669
+ if (tagName && startTag && endTag) {
1670
+ const maxBytes = thresholds.get(tagName);
1671
+ if (maxBytes !== void 0) {
1672
+ const innerBytes = endTag.startIndex - startTag.endIndex;
1673
+ if (innerBytes > maxBytes) {
1674
+ errors.push({
1675
+ node: startTag,
1676
+ message: `<${tagName}> content is ${innerBytes} bytes, exceeds limit of ${maxBytes}`
1677
+ });
1678
+ }
1679
+ }
1680
+ }
1681
+ }
1682
+ for (const child of node.children) {
1683
+ visit(child);
1684
+ }
1685
+ }
1686
+ visit(rootNode);
1687
+ return errors;
1688
+ }
1602
1689
 
1603
- // lsp/server/src/selectorMatcher.ts
1604
- function isNameChar(ch) {
1605
- return /[a-zA-Z0-9\-_]/.test(ch);
1690
+ // node_modules/parsel-js/dist/parsel.min.js
1691
+ var e = { attribute: /\[\s*(?:(?<namespace>\*|[-\w\P{ASCII}]*)\|)?(?<name>[-\w\P{ASCII}]+)\s*(?:(?<operator>\W?=)\s*(?<value>.+?)\s*(\s(?<caseSensitive>[iIsS]))?\s*)?\]/gu, id: /#(?<name>[-\w\P{ASCII}]+)/gu, class: /\.(?<name>[-\w\P{ASCII}]+)/gu, comma: /\s*,\s*/g, combinator: /\s*[\s>+~]\s*/g, "pseudo-element": /::(?<name>[-\w\P{ASCII}]+)(?:\((?<argument>¶*)\))?/gu, "pseudo-class": /:(?<name>[-\w\P{ASCII}]+)(?:\((?<argument>¶*)\))?/gu, universal: /(?:(?<namespace>\*|[-\w\P{ASCII}]*)\|)?\*/gu, type: /(?:(?<namespace>\*|[-\w\P{ASCII}]*)\|)?(?<name>[-\w\P{ASCII}]+)/gu };
1692
+ var t = /* @__PURE__ */ new Set(["combinator", "comma"]);
1693
+ var n = /* @__PURE__ */ new Set(["not", "is", "where", "has", "matches", "-moz-any", "-webkit-any", "nth-child", "nth-last-child"]);
1694
+ var s = /(?<index>[\dn+-]+)\s+of\s+(?<subtree>.+)/;
1695
+ var r = { "nth-child": s, "nth-last-child": s };
1696
+ var o = (t2) => {
1697
+ switch (t2) {
1698
+ case "pseudo-element":
1699
+ case "pseudo-class":
1700
+ return new RegExp(e[t2].source.replace("(?<argument>\xB6*)", "(?<argument>.*)"), "gu");
1701
+ default:
1702
+ return e[t2];
1703
+ }
1704
+ };
1705
+ function c(e2, t2) {
1706
+ let n2 = 0, s2 = "";
1707
+ for (; t2 < e2.length; t2++) {
1708
+ const r2 = e2[t2];
1709
+ switch (r2) {
1710
+ case "(":
1711
+ ++n2;
1712
+ break;
1713
+ case ")":
1714
+ --n2;
1715
+ }
1716
+ if (s2 += r2, 0 === n2) return s2;
1717
+ }
1718
+ return s2;
1719
+ }
1720
+ function i(n2, s2 = e) {
1721
+ if (!n2) return [];
1722
+ const r2 = [n2];
1723
+ for (const [e2, t2] of Object.entries(s2)) for (let n3 = 0; n3 < r2.length; n3++) {
1724
+ const s3 = r2[n3];
1725
+ if ("string" != typeof s3) continue;
1726
+ t2.lastIndex = 0;
1727
+ const o3 = t2.exec(s3);
1728
+ if (!o3) continue;
1729
+ const c2 = o3.index - 1, i2 = [], a2 = o3[0], l2 = s3.slice(0, c2 + 1);
1730
+ l2 && i2.push(l2), i2.push({ ...o3.groups, type: e2, content: a2 });
1731
+ const u2 = s3.slice(c2 + a2.length + 1);
1732
+ u2 && i2.push(u2), r2.splice(n3, 1, ...i2);
1733
+ }
1734
+ let o2 = 0;
1735
+ for (const e2 of r2) switch (typeof e2) {
1736
+ case "string":
1737
+ throw new Error(`Unexpected sequence ${e2} found at index ${o2}`);
1738
+ case "object":
1739
+ o2 += e2.content.length, e2.pos = [o2 - e2.content.length, o2], t.has(e2.type) && (e2.content = e2.content.trim() || " ");
1740
+ }
1741
+ return r2;
1742
+ }
1743
+ var a = /(['"])([^\\\n]*?)\1/g;
1744
+ var l = /\\./g;
1745
+ function u(t2, n2 = e) {
1746
+ if ("" === (t2 = t2.trim())) return [];
1747
+ const s2 = [];
1748
+ t2 = (t2 = t2.replace(l, ((e2, t3) => (s2.push({ value: e2, offset: t3 }), "\uE000".repeat(e2.length))))).replace(a, ((e2, t3, n3, r3) => (s2.push({ value: e2, offset: r3 }), `${t3}${"\uE001".repeat(n3.length)}${t3}`)));
1749
+ {
1750
+ let e2, n3 = 0;
1751
+ for (; (e2 = t2.indexOf("(", n3)) > -1; ) {
1752
+ const r3 = c(t2, e2);
1753
+ s2.push({ value: r3, offset: e2 }), t2 = `${t2.substring(0, e2)}(${"\xB6".repeat(r3.length - 2)})${t2.substring(e2 + r3.length)}`, n3 = e2 + r3.length;
1754
+ }
1755
+ }
1756
+ const r2 = i(t2, n2), u2 = /* @__PURE__ */ new Set();
1757
+ for (const e2 of s2.reverse()) for (const t3 of r2) {
1758
+ const { offset: n3, value: s3 } = e2;
1759
+ if (!(t3.pos[0] <= n3 && n3 + s3.length <= t3.pos[1])) continue;
1760
+ const { content: r3 } = t3, o2 = n3 - t3.pos[0];
1761
+ t3.content = r3.slice(0, o2) + s3 + r3.slice(o2 + s3.length), t3.content !== r3 && u2.add(t3);
1762
+ }
1763
+ for (const e2 of u2) {
1764
+ const t3 = o(e2.type);
1765
+ if (!t3) throw new Error(`Unknown token type: ${e2.type}`);
1766
+ t3.lastIndex = 0;
1767
+ const n3 = t3.exec(e2.content);
1768
+ if (!n3) throw new Error(`Unable to parse content for ${e2.type}: ${e2.content}`);
1769
+ Object.assign(e2, n3.groups);
1770
+ }
1771
+ return r2;
1772
+ }
1773
+ function f(e2, { list: t2 = true } = {}) {
1774
+ if (t2 && e2.find(((e3) => "comma" === e3.type))) {
1775
+ const t3 = [], n2 = [];
1776
+ for (let s2 = 0; s2 < e2.length; s2++) if ("comma" === e2[s2].type) {
1777
+ if (0 === n2.length) throw new Error("Incorrect comma at " + s2);
1778
+ t3.push(f(n2, { list: false })), n2.length = 0;
1779
+ } else n2.push(e2[s2]);
1780
+ if (0 === n2.length) throw new Error("Trailing comma");
1781
+ return t3.push(f(n2, { list: false })), { type: "list", list: t3 };
1782
+ }
1783
+ for (let t3 = e2.length - 1; t3 >= 0; t3--) {
1784
+ let n2 = e2[t3];
1785
+ if ("combinator" === n2.type) {
1786
+ let s2 = e2.slice(0, t3), r2 = e2.slice(t3 + 1);
1787
+ return 0 === s2.length ? { type: "relative", combinator: n2.content, right: f(r2) } : { type: "complex", combinator: n2.content, left: f(s2), right: f(r2) };
1788
+ }
1789
+ }
1790
+ switch (e2.length) {
1791
+ case 0:
1792
+ throw new Error("Could not build AST.");
1793
+ case 1:
1794
+ return e2[0];
1795
+ default:
1796
+ return { type: "compound", list: [...e2] };
1797
+ }
1606
1798
  }
1607
- function parseAttributes(raw, pos) {
1608
- const attrs = [];
1609
- while (pos.i < raw.length) {
1610
- if (raw[pos.i] === ":") {
1611
- if (raw.slice(pos.i, pos.i + 6).toLowerCase() !== ":not([") return attrs;
1612
- pos.i += 6;
1613
- const attr = parseOneAttribute(raw, pos, true);
1614
- if (!attr) return attrs;
1615
- if (raw[pos.i] !== "]" || raw[pos.i + 1] !== ")") return attrs;
1616
- pos.i += 2;
1617
- attrs.push(attr);
1618
- } else if (raw[pos.i] === "[") {
1619
- pos.i++;
1620
- const attr = parseOneAttribute(raw, pos, false);
1621
- if (!attr) return attrs;
1622
- if (raw[pos.i] !== "]") return attrs;
1623
- pos.i++;
1624
- attrs.push(attr);
1625
- } else {
1799
+ function* p(e2, t2) {
1800
+ switch (e2.type) {
1801
+ case "list":
1802
+ for (let t3 of e2.list) yield* p(t3, e2);
1803
+ break;
1804
+ case "complex":
1805
+ yield* p(e2.left, e2), yield* p(e2.right, e2);
1806
+ break;
1807
+ case "relative":
1808
+ yield* p(e2.right, e2);
1809
+ break;
1810
+ case "compound":
1811
+ yield* e2.list.map(((t3) => [t3, e2]));
1626
1812
  break;
1813
+ default:
1814
+ yield [e2, t2];
1815
+ }
1816
+ }
1817
+ function m(e2, { recursive: t2 = true, list: s2 = true } = {}) {
1818
+ const o2 = u(e2);
1819
+ if (!o2) return;
1820
+ const c2 = f(o2, { list: s2 });
1821
+ if (!t2) return c2;
1822
+ for (const [e3] of p(c2)) {
1823
+ if ("pseudo-class" !== e3.type || !e3.argument) continue;
1824
+ if (!n.has(e3.name)) continue;
1825
+ let t3 = e3.argument;
1826
+ const s3 = r[e3.name];
1827
+ if (s3) {
1828
+ const n2 = s3.exec(t3);
1829
+ if (!n2) continue;
1830
+ Object.assign(e3, n2.groups), t3 = n2.groups.subtree;
1627
1831
  }
1832
+ t3 && Object.assign(e3, { subtree: m(t3, { recursive: true, list: true }) });
1628
1833
  }
1629
- return attrs;
1834
+ return c2;
1630
1835
  }
1631
- function parseOneAttribute(raw, pos, negated) {
1632
- let name = "";
1633
- while (pos.i < raw.length && isNameChar(raw[pos.i])) {
1634
- name += raw[pos.i];
1635
- pos.i++;
1636
- }
1637
- if (name.length === 0) return null;
1638
- let value;
1639
- if (raw[pos.i] === "=") {
1640
- pos.i++;
1641
- value = "";
1642
- if (raw[pos.i] === '"' || raw[pos.i] === "'") {
1643
- const quote = raw[pos.i];
1644
- pos.i++;
1645
- while (pos.i < raw.length && raw[pos.i] !== quote) {
1646
- value += raw[pos.i];
1647
- pos.i++;
1836
+
1837
+ // lsp/server/src/selectorMatcher.ts
1838
+ var MUSTACHE_KIND_PSEUDO = /* @__PURE__ */ new Set([
1839
+ "m-section",
1840
+ "m-inverted",
1841
+ "m-variable",
1842
+ "m-raw",
1843
+ "m-comment",
1844
+ "m-partial"
1845
+ ]);
1846
+ function preprocessMustacheLiterals(raw) {
1847
+ let out = "";
1848
+ let i2 = 0;
1849
+ const len = raw.length;
1850
+ while (i2 < len) {
1851
+ const ch = raw[i2];
1852
+ if (ch === '"' || ch === "'") {
1853
+ out += ch;
1854
+ i2++;
1855
+ while (i2 < len && raw[i2] !== ch) {
1856
+ if (raw[i2] === "\\" && i2 + 1 < len) {
1857
+ out += raw[i2] + raw[i2 + 1];
1858
+ i2 += 2;
1859
+ } else {
1860
+ out += raw[i2];
1861
+ i2++;
1862
+ }
1648
1863
  }
1649
- if (pos.i < raw.length) pos.i++;
1650
- } else {
1651
- while (pos.i < raw.length && raw[pos.i] !== "]") {
1652
- value += raw[pos.i];
1653
- pos.i++;
1864
+ if (i2 < len) {
1865
+ out += raw[i2];
1866
+ i2++;
1867
+ }
1868
+ continue;
1869
+ }
1870
+ if (ch !== "{" || raw[i2 + 1] !== "{") {
1871
+ out += ch;
1872
+ i2++;
1873
+ continue;
1874
+ }
1875
+ if (raw[i2 + 2] === "{") {
1876
+ const end2 = raw.indexOf("}}}", i2 + 3);
1877
+ if (end2 < 0) return null;
1878
+ const inner = raw.slice(i2 + 3, end2).trim();
1879
+ if (inner.length === 0) return null;
1880
+ out += `:m-raw(${inner})`;
1881
+ i2 = end2 + 3;
1882
+ continue;
1883
+ }
1884
+ const end = raw.indexOf("}}", i2 + 2);
1885
+ if (end < 0) return null;
1886
+ const body = raw.slice(i2 + 2, end);
1887
+ i2 = end + 2;
1888
+ const sigil = body.trimStart()[0];
1889
+ const content = body.replace(/^\s*[#^!>/]\s*/, "").replace(/^\s+|\s+$/g, "");
1890
+ switch (sigil) {
1891
+ case "#":
1892
+ if (content.length === 0) return null;
1893
+ out += `:m-section(${content})`;
1894
+ break;
1895
+ case "^":
1896
+ if (content.length === 0) return null;
1897
+ out += `:m-inverted(${content})`;
1898
+ break;
1899
+ case "!":
1900
+ if (content.length === 0) return null;
1901
+ out += `:m-comment(${content})`;
1902
+ break;
1903
+ case ">":
1904
+ if (content.length === 0) return null;
1905
+ out += `:m-partial(${content})`;
1906
+ break;
1907
+ case "/":
1908
+ return null;
1909
+ case "=":
1910
+ return null;
1911
+ default: {
1912
+ const path5 = body.trim();
1913
+ if (path5.length === 0) return null;
1914
+ out += `:m-variable(${path5})`;
1915
+ break;
1654
1916
  }
1655
1917
  }
1656
1918
  }
1657
- return { name: name.toLowerCase(), value, negated };
1919
+ return out;
1658
1920
  }
1659
1921
  function parseSelector(raw) {
1660
- const trimmed = raw.trim();
1661
- if (trimmed.length === 0) return null;
1662
- const parts = trimmed.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
1663
- if (parts.length === 0) return null;
1664
- const alternatives = [];
1665
- for (const part of parts) {
1666
- const alt = parseSingleSelector(part);
1667
- if (!alt) return null;
1668
- alternatives.push(alt);
1669
- }
1670
- return { alternatives };
1671
- }
1672
- function parseSingleSelector(raw) {
1673
- const segments = [];
1674
- let i = 0;
1675
- let nextCombinator = "descendant";
1676
- while (i < raw.length) {
1677
- while (i < raw.length && raw[i] === " ") i++;
1678
- if (i >= raw.length) break;
1679
- if (raw[i] === ">") {
1680
- if (segments.length === 0) return null;
1681
- nextCombinator = "child";
1682
- i++;
1683
- while (i < raw.length && raw[i] === " ") i++;
1684
- if (i >= raw.length) return null;
1685
- continue;
1686
- }
1687
- const pos = { i };
1688
- const segment = parseOneSegment(raw, pos);
1689
- if (!segment) return null;
1690
- i = pos.i;
1691
- segment.combinator = nextCombinator;
1692
- nextCombinator = "descendant";
1693
- segments.push(segment);
1922
+ if (typeof raw !== "string" || raw.trim() === "") return null;
1923
+ const preprocessed = preprocessMustacheLiterals(raw);
1924
+ if (preprocessed === null) return null;
1925
+ let ast;
1926
+ try {
1927
+ ast = m(preprocessed);
1928
+ } catch {
1929
+ return null;
1694
1930
  }
1695
- if (segments.length === 0) return null;
1696
- return { segments };
1931
+ if (!ast) return null;
1932
+ const tops = ast.type === "list" ? ast.list : [ast];
1933
+ const alts = [];
1934
+ for (const top of tops) {
1935
+ const segments = [];
1936
+ if (!collectSegments(top, "descendant", segments)) return null;
1937
+ if (segments.length === 0) return null;
1938
+ alts.push(segments);
1939
+ }
1940
+ return alts.length > 0 ? alts : null;
1941
+ }
1942
+ function collectSegments(ast, combinator, out) {
1943
+ if (ast.type === "complex") {
1944
+ const mapped = mapCombinator(ast.combinator);
1945
+ if (!mapped) return false;
1946
+ return collectSegments(ast.left, "descendant", out) && collectSegments(ast.right, mapped, out);
1947
+ }
1948
+ if (ast.type === "list" || ast.type === "relative") return false;
1949
+ const segment = segmentFromCompound(ast);
1950
+ if (!segment) return false;
1951
+ segment.combinator = combinator;
1952
+ out.push(segment);
1953
+ return true;
1697
1954
  }
1698
- function parseOneSegment(raw, pos) {
1955
+ function mapCombinator(c2) {
1956
+ const trimmed = c2.trim();
1957
+ if (trimmed === "") return "descendant";
1958
+ if (trimmed === ">") return "child";
1959
+ return null;
1960
+ }
1961
+ function segmentFromCompound(ast) {
1962
+ const tokens = ast.type === "compound" ? ast.list : [ast];
1699
1963
  let kind;
1700
- let name;
1701
- if (raw[pos.i] === "#") {
1702
- kind = "mustache";
1703
- pos.i++;
1704
- name = "";
1705
- while (pos.i < raw.length && isNameChar(raw[pos.i])) {
1706
- name += raw[pos.i];
1707
- pos.i++;
1708
- }
1709
- if (name.length === 0) name = null;
1710
- else name = name.toLowerCase();
1711
- return { kind, name, attributes: [], combinator: "descendant" };
1712
- }
1713
- if (raw[pos.i] === "*") {
1714
- kind = "html";
1715
- name = null;
1716
- pos.i++;
1717
- const attrs2 = parseAttributes(raw, pos);
1718
- return { kind, name, attributes: attrs2, combinator: "descendant" };
1964
+ let name = null;
1965
+ let pathRegex;
1966
+ let rootOnly = false;
1967
+ const attributes = [];
1968
+ const descendantChecks = [];
1969
+ const forbidChange = (requested) => {
1970
+ if (kind === void 0) return false;
1971
+ if (kind === requested) return false;
1972
+ return true;
1973
+ };
1974
+ for (const token of tokens) {
1975
+ switch (token.type) {
1976
+ case "type":
1977
+ if (forbidChange("html")) return null;
1978
+ kind = "html";
1979
+ name = token.name.toLowerCase();
1980
+ break;
1981
+ case "universal":
1982
+ if (forbidChange("html")) return null;
1983
+ kind = "html";
1984
+ name = null;
1985
+ break;
1986
+ case "class":
1987
+ if (forbidChange("html")) return null;
1988
+ kind = "html";
1989
+ attributes.push(classConstraint(token, false));
1990
+ break;
1991
+ case "id":
1992
+ if (forbidChange("html")) return null;
1993
+ kind = "html";
1994
+ attributes.push(idConstraint(token, false));
1995
+ break;
1996
+ case "attribute": {
1997
+ if (forbidChange("html")) return null;
1998
+ if (kind === void 0) kind = "html";
1999
+ const c2 = attributeConstraint(token, false);
2000
+ if (!c2) return null;
2001
+ attributes.push(c2);
2002
+ break;
2003
+ }
2004
+ case "pseudo-class": {
2005
+ if (MUSTACHE_KIND_PSEUDO.has(token.name)) {
2006
+ const mustacheKind = mustacheKindFromMarker(token.name);
2007
+ if (mustacheKind === null) return null;
2008
+ if (forbidChange(mustacheKind)) return null;
2009
+ kind = mustacheKind;
2010
+ const glob = parseGlob(token.argument ?? "");
2011
+ name = glob.name;
2012
+ pathRegex = glob.pathRegex;
2013
+ break;
2014
+ }
2015
+ if (token.name === "has") {
2016
+ const sel = subtreeToSelector(token.subtree);
2017
+ if (!sel) return null;
2018
+ descendantChecks.push({ selector: sel, negated: false });
2019
+ break;
2020
+ }
2021
+ if (token.name === "not") {
2022
+ if (!applyNegatedSubtree(token.subtree, attributes, descendantChecks)) return null;
2023
+ break;
2024
+ }
2025
+ if (token.name === "root") {
2026
+ rootOnly = true;
2027
+ if (kind === void 0) kind = "html";
2028
+ break;
2029
+ }
2030
+ return null;
2031
+ }
2032
+ default:
2033
+ return null;
2034
+ }
1719
2035
  }
1720
- if (raw[pos.i] === "[" || raw[pos.i] === ":") {
2036
+ if (kind === void 0) {
1721
2037
  kind = "html";
1722
- name = null;
1723
- const attrs2 = parseAttributes(raw, pos);
1724
- if (attrs2.length === 0) return null;
1725
- return { kind, name, attributes: attrs2, combinator: "descendant" };
1726
- }
1727
- if (!isNameChar(raw[pos.i])) return null;
1728
- kind = "html";
1729
- name = "";
1730
- while (pos.i < raw.length && isNameChar(raw[pos.i])) {
1731
- name += raw[pos.i];
1732
- pos.i++;
1733
- }
1734
- name = name.toLowerCase();
1735
- const attrs = parseAttributes(raw, pos);
1736
- return { kind, name, attributes: attrs, combinator: "descendant" };
1737
- }
1738
- function getNodeAttributes(node) {
2038
+ }
2039
+ if (rootOnly) {
2040
+ if (name !== null || attributes.length > 0 || kind !== "html") return null;
2041
+ }
2042
+ const isHtml = kind === "html";
2043
+ const finalAttrs = isHtml ? attributes : [];
2044
+ return { kind, rootOnly, name, pathRegex, attributes: finalAttrs, descendantChecks, combinator: "descendant" };
2045
+ }
2046
+ function mustacheKindFromMarker(name) {
2047
+ switch (name) {
2048
+ case "m-section":
2049
+ return "section";
2050
+ case "m-inverted":
2051
+ return "inverted";
2052
+ case "m-variable":
2053
+ return "variable";
2054
+ case "m-raw":
2055
+ return "raw";
2056
+ case "m-comment":
2057
+ return "comment";
2058
+ case "m-partial":
2059
+ return "partial";
2060
+ default:
2061
+ return null;
2062
+ }
2063
+ }
2064
+ function parseGlob(arg) {
2065
+ const trimmed = arg.trim();
2066
+ if (trimmed === "" || trimmed === "*") {
2067
+ return { name: null };
2068
+ }
2069
+ if (!trimmed.includes("*")) {
2070
+ return { name: trimmed.toLowerCase() };
2071
+ }
2072
+ const escaped = trimmed.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
2073
+ const pathRegex = new RegExp(`^${escaped}$`, "i");
2074
+ return { name: trimmed.toLowerCase(), pathRegex };
2075
+ }
2076
+ function attributeConstraint(token, negated) {
2077
+ const name = token.name.toLowerCase();
2078
+ if (token.operator === void 0) {
2079
+ return { name, op: "=", value: void 0, negated };
2080
+ }
2081
+ let op;
2082
+ switch (token.operator) {
2083
+ case "=":
2084
+ op = "=";
2085
+ break;
2086
+ case "^=":
2087
+ op = "^=";
2088
+ break;
2089
+ case "*=":
2090
+ op = "*=";
2091
+ break;
2092
+ case "$=":
2093
+ op = "$=";
2094
+ break;
2095
+ case "~=":
2096
+ op = "~=";
2097
+ break;
2098
+ default:
2099
+ return null;
2100
+ }
2101
+ return { name, op, value: stripQuotes(token.value ?? ""), negated };
2102
+ }
2103
+ function classConstraint(token, negated) {
2104
+ return { name: "class", op: "~=", value: token.name, negated };
2105
+ }
2106
+ function idConstraint(token, negated) {
2107
+ return { name: "id", op: "=", value: token.name, negated };
2108
+ }
2109
+ function applyNegatedSubtree(subtree, attributes, descendantChecks) {
2110
+ if (!subtree) return false;
2111
+ if (subtree.type === "attribute") {
2112
+ const c2 = attributeConstraint(subtree, true);
2113
+ if (!c2) return false;
2114
+ attributes.push(c2);
2115
+ return true;
2116
+ }
2117
+ if (subtree.type === "class") {
2118
+ attributes.push(classConstraint(subtree, true));
2119
+ return true;
2120
+ }
2121
+ if (subtree.type === "id") {
2122
+ attributes.push(idConstraint(subtree, true));
2123
+ return true;
2124
+ }
2125
+ if (subtree.type === "pseudo-class" && subtree.name === "has") {
2126
+ const sel = subtreeToSelector(subtree.subtree);
2127
+ if (!sel) return false;
2128
+ descendantChecks.push({ selector: sel, negated: true });
2129
+ return true;
2130
+ }
2131
+ return false;
2132
+ }
2133
+ function subtreeToSelector(subtree) {
2134
+ if (!subtree) return null;
2135
+ const tops = subtree.type === "list" ? subtree.list : [subtree];
2136
+ const alts = [];
2137
+ for (const top of tops) {
2138
+ const segments = [];
2139
+ if (!collectSegments(top, "descendant", segments)) return null;
2140
+ if (segments.length === 0) return null;
2141
+ alts.push(segments);
2142
+ }
2143
+ return alts.length > 0 ? alts : null;
2144
+ }
2145
+ function stripQuotes(raw) {
2146
+ if (raw.length < 2) return raw;
2147
+ const first = raw[0];
2148
+ const last = raw[raw.length - 1];
2149
+ if ((first === '"' || first === "'") && first === last) {
2150
+ return raw.slice(1, -1);
2151
+ }
2152
+ return raw;
2153
+ }
2154
+ function ancestorKindForNode(node) {
2155
+ if (HTML_ELEMENT_TYPES.has(node.type)) return "html";
2156
+ if (node.type === "mustache_section") return "section";
2157
+ if (node.type === "mustache_inverted_section") return "inverted";
2158
+ return null;
2159
+ }
2160
+ function getHtmlAttributes(node) {
1739
2161
  const startTag = node.children.find(
1740
- (c) => c.type === "html_start_tag" || c.type === "html_self_closing_tag"
2162
+ (c2) => c2.type === "html_start_tag" || c2.type === "html_self_closing_tag"
1741
2163
  );
1742
2164
  if (!startTag) return [];
1743
2165
  const attrs = [];
1744
2166
  for (const child of startTag.children) {
1745
- if (child.type === "html_attribute") {
1746
- let attrName = "";
1747
- let attrValue;
1748
- for (const part of child.children) {
1749
- if (part.type === "html_attribute_name") {
1750
- attrName = part.text.toLowerCase();
1751
- } else if (part.type === "html_quoted_attribute_value") {
1752
- attrValue = part.text.replace(/^["']|["']$/g, "");
1753
- } else if (part.type === "html_attribute_value") {
1754
- attrValue = part.text;
1755
- }
2167
+ if (child.type !== "html_attribute") continue;
2168
+ let attrName = "";
2169
+ let attrValue;
2170
+ for (const part of child.children) {
2171
+ if (part.type === "html_attribute_name") {
2172
+ attrName = part.text.toLowerCase();
2173
+ } else if (part.type === "html_quoted_attribute_value") {
2174
+ attrValue = part.text.replace(/^["']|["']$/g, "");
2175
+ } else if (part.type === "html_attribute_value") {
2176
+ attrValue = part.text;
1756
2177
  }
1757
- if (attrName) attrs.push({ name: attrName, value: attrValue });
1758
2178
  }
2179
+ if (attrName) attrs.push({ name: attrName, value: attrValue });
1759
2180
  }
1760
2181
  return attrs;
1761
2182
  }
2183
+ function matchesAttributeValue(has, c2) {
2184
+ if (has === void 0 || c2.value === void 0) return false;
2185
+ const v = c2.value;
2186
+ if (v === "") return false;
2187
+ switch (c2.op) {
2188
+ case "=":
2189
+ return has === v;
2190
+ case "^=":
2191
+ return has.startsWith(v);
2192
+ case "*=":
2193
+ return has.includes(v);
2194
+ case "$=":
2195
+ return has.endsWith(v);
2196
+ case "~=":
2197
+ return has.split(/\s+/).includes(v);
2198
+ }
2199
+ }
1762
2200
  function checkAttributes(node, constraints) {
1763
2201
  if (constraints.length === 0) return true;
1764
- const nodeAttrs = getNodeAttributes(node);
1765
- for (const constraint of constraints) {
1766
- const found = nodeAttrs.find((a) => a.name === constraint.name);
1767
- if (constraint.negated) {
1768
- if (found) return false;
1769
- } else if (constraint.value !== void 0) {
1770
- if (!found || found.value !== constraint.value) return false;
1771
- } else {
2202
+ const nodeAttrs = getHtmlAttributes(node);
2203
+ for (const c2 of constraints) {
2204
+ const found = nodeAttrs.find((a2) => a2.name === c2.name);
2205
+ if (c2.negated) {
2206
+ if (!found) continue;
2207
+ if (c2.value === void 0) return false;
2208
+ if (matchesAttributeValue(found.value, c2)) return false;
2209
+ continue;
2210
+ }
2211
+ if (c2.value === void 0) {
1772
2212
  if (!found) return false;
2213
+ continue;
1773
2214
  }
2215
+ if (!found || !matchesAttributeValue(found.value, c2)) return false;
1774
2216
  }
1775
2217
  return true;
1776
2218
  }
1777
- function nodeMatchesSegment(node, segment) {
1778
- if (segment.kind === "html") {
1779
- if (!HTML_ELEMENT_TYPES.has(node.type)) return false;
1780
- if (segment.name !== null) {
1781
- const tagName = getTagName(node)?.toLowerCase();
1782
- if (tagName !== segment.name) return false;
1783
- }
1784
- return checkAttributes(node, segment.attributes);
1785
- }
1786
- if (!MUSTACHE_SECTION_TYPES.has(node.type)) return false;
1787
- if (segment.name !== null) {
1788
- const sectionName = getSectionName(node)?.toLowerCase();
1789
- if (sectionName !== segment.name) return false;
2219
+ function checkDescendants(node, checks) {
2220
+ if (checks.length === 0) return true;
2221
+ for (const check of checks) {
2222
+ const present = hasDescendantMatch(node, check.selector);
2223
+ if (check.negated ? present : !present) return false;
1790
2224
  }
1791
2225
  return true;
1792
2226
  }
2227
+ function hasDescendantMatch(node, selector) {
2228
+ for (const child of node.children) {
2229
+ if (matchSelector(child, selector).length > 0) return true;
2230
+ }
2231
+ return false;
2232
+ }
2233
+ function matchesName(actual, segment) {
2234
+ if (segment.name === null) return true;
2235
+ if (actual === null) return false;
2236
+ if (segment.pathRegex) return segment.pathRegex.test(actual);
2237
+ return actual === segment.name;
2238
+ }
2239
+ function nodeMatchesSegment(node, segment, rootNode) {
2240
+ if (segment.rootOnly) {
2241
+ if (node !== rootNode) return false;
2242
+ return checkDescendants(node, segment.descendantChecks);
2243
+ }
2244
+ switch (segment.kind) {
2245
+ case "html": {
2246
+ if (!HTML_ELEMENT_TYPES.has(node.type)) return false;
2247
+ if (segment.name !== null) {
2248
+ const tagName = getTagName(node)?.toLowerCase();
2249
+ if (tagName !== segment.name) return false;
2250
+ }
2251
+ return checkAttributes(node, segment.attributes) && checkDescendants(node, segment.descendantChecks);
2252
+ }
2253
+ case "section":
2254
+ if (node.type !== "mustache_section") return false;
2255
+ if (!matchesName(getSectionName(node)?.toLowerCase() ?? null, segment)) return false;
2256
+ return checkDescendants(node, segment.descendantChecks);
2257
+ case "inverted":
2258
+ if (node.type !== "mustache_inverted_section") return false;
2259
+ if (!matchesName(getSectionName(node)?.toLowerCase() ?? null, segment)) return false;
2260
+ return checkDescendants(node, segment.descendantChecks);
2261
+ case "variable":
2262
+ if (node.type !== "mustache_interpolation") return false;
2263
+ if (!matchesName(getInterpolationPath(node)?.toLowerCase() ?? null, segment)) return false;
2264
+ return checkDescendants(node, segment.descendantChecks);
2265
+ case "raw":
2266
+ if (node.type !== "mustache_triple") return false;
2267
+ if (!matchesName(getInterpolationPath(node)?.toLowerCase() ?? null, segment)) return false;
2268
+ return checkDescendants(node, segment.descendantChecks);
2269
+ case "comment":
2270
+ if (node.type !== "mustache_comment") return false;
2271
+ if (!matchesName(getCommentContent(node)?.toLowerCase() ?? null, segment)) return false;
2272
+ return checkDescendants(node, segment.descendantChecks);
2273
+ case "partial":
2274
+ if (node.type !== "mustache_partial") return false;
2275
+ if (!matchesName(getPartialName(node)?.toLowerCase() ?? null, segment)) return false;
2276
+ return checkDescendants(node, segment.descendantChecks);
2277
+ }
2278
+ }
1793
2279
  function checkAncestors(ancestors, segments, segIdx, childCombinator) {
1794
2280
  if (segIdx < 0) return true;
1795
2281
  const segment = segments[segIdx];
2282
+ const ancestorKind = ancestorKindForSegment(segment);
2283
+ if (ancestorKind === null) return false;
1796
2284
  if (childCombinator === "child") {
1797
- for (let a = ancestors.length - 1; a >= 0; a--) {
1798
- const entry = ancestors[a];
1799
- if (entry.kind !== segment.kind) continue;
1800
- if (segment.name !== null && entry.name !== segment.name) return false;
1801
- if (segment.kind === "html" && segment.attributes.length > 0) {
1802
- if (!checkAttributes(entry.node, segment.attributes)) return false;
2285
+ for (let a2 = ancestors.length - 1; a2 >= 0; a2--) {
2286
+ const entry = ancestors[a2];
2287
+ if (entry.kind !== ancestorKind) {
2288
+ if (ancestorKind === "root" && entry.kind === "html") return false;
2289
+ continue;
1803
2290
  }
1804
- return checkAncestors(ancestors.slice(0, a), segments, segIdx - 1, segment.combinator);
2291
+ if (!matchesName(entry.name, segment)) return false;
2292
+ if (segment.kind === "html" && !checkAttributes(entry.node, segment.attributes)) return false;
2293
+ if (!checkDescendants(entry.node, segment.descendantChecks)) return false;
2294
+ return checkAncestors(ancestors.slice(0, a2), segments, segIdx - 1, segment.combinator);
1805
2295
  }
1806
2296
  return false;
1807
2297
  }
1808
- for (let a = ancestors.length - 1; a >= 0; a--) {
1809
- const entry = ancestors[a];
1810
- if (entry.kind !== segment.kind) continue;
1811
- if (segment.name !== null && entry.name !== segment.name) continue;
1812
- if (segment.kind === "html" && segment.attributes.length > 0) {
1813
- if (!checkAttributes(entry.node, segment.attributes)) continue;
1814
- }
1815
- if (checkAncestors(ancestors.slice(0, a), segments, segIdx - 1, segment.combinator)) {
2298
+ for (let a2 = ancestors.length - 1; a2 >= 0; a2--) {
2299
+ const entry = ancestors[a2];
2300
+ if (entry.kind !== ancestorKind) continue;
2301
+ if (!matchesName(entry.name, segment)) continue;
2302
+ if (segment.kind === "html" && !checkAttributes(entry.node, segment.attributes)) continue;
2303
+ if (!checkDescendants(entry.node, segment.descendantChecks)) continue;
2304
+ if (checkAncestors(ancestors.slice(0, a2), segments, segIdx - 1, segment.combinator)) {
1816
2305
  return true;
1817
2306
  }
1818
2307
  }
1819
2308
  return false;
1820
2309
  }
1821
- function getReportNode(node) {
2310
+ function ancestorKindForSegment(segment) {
2311
+ if (segment.rootOnly) return "root";
2312
+ if (segment.kind === "html") return "html";
2313
+ if (segment.kind === "section") return "section";
2314
+ if (segment.kind === "inverted") return "inverted";
2315
+ return null;
2316
+ }
2317
+ function getReportNode(node, rootNode) {
1822
2318
  if (HTML_ELEMENT_TYPES.has(node.type)) {
1823
2319
  const startTag = node.children.find(
1824
- (c) => c.type === "html_start_tag" || c.type === "html_self_closing_tag"
2320
+ (c2) => c2.type === "html_start_tag" || c2.type === "html_self_closing_tag"
1825
2321
  );
1826
2322
  return startTag ?? node;
1827
2323
  }
1828
- if (MUSTACHE_SECTION_TYPES.has(node.type)) {
2324
+ if (node.type === "mustache_section" || node.type === "mustache_inverted_section") {
1829
2325
  const begin = node.children.find(
1830
- (c) => c.type === "mustache_section_begin" || c.type === "mustache_inverted_section_begin"
2326
+ (c2) => c2.type === "mustache_section_begin" || c2.type === "mustache_inverted_section_begin"
1831
2327
  );
1832
2328
  return begin ?? node;
1833
2329
  }
2330
+ if (rootNode && node === rootNode) {
2331
+ return {
2332
+ type: node.type,
2333
+ text: "",
2334
+ startPosition: node.startPosition,
2335
+ endPosition: { row: node.startPosition.row, column: node.startPosition.column + 1 },
2336
+ startIndex: node.startIndex,
2337
+ endIndex: Math.min(node.startIndex + 1, node.endIndex),
2338
+ children: []
2339
+ };
2340
+ }
1834
2341
  return node;
1835
2342
  }
1836
- function matchAlternative(rootNode, alt) {
2343
+ function matchAlternative(rootNode, segments) {
1837
2344
  const results = [];
1838
- const lastSegment = alt.segments[alt.segments.length - 1];
2345
+ const lastSegment = segments[segments.length - 1];
1839
2346
  function walk(node, ancestors) {
1840
- if (nodeMatchesSegment(node, lastSegment)) {
1841
- if (alt.segments.length === 1 || checkAncestors(ancestors, alt.segments, alt.segments.length - 2, lastSegment.combinator)) {
1842
- results.push(getReportNode(node));
2347
+ if (nodeMatchesSegment(node, lastSegment, rootNode)) {
2348
+ if (segments.length === 1 || checkAncestors(ancestors, segments, segments.length - 2, lastSegment.combinator)) {
2349
+ results.push(getReportNode(node, rootNode));
1843
2350
  }
1844
2351
  }
1845
2352
  let newAncestors = ancestors;
1846
- if (HTML_ELEMENT_TYPES.has(node.type)) {
1847
- const tagName = getTagName(node)?.toLowerCase();
1848
- if (tagName) {
1849
- newAncestors = [...ancestors, { kind: "html", name: tagName, node }];
1850
- }
1851
- } else if (MUSTACHE_SECTION_TYPES.has(node.type)) {
1852
- const sectionName = getSectionName(node)?.toLowerCase();
1853
- if (sectionName) {
1854
- newAncestors = [...ancestors, { kind: "mustache", name: sectionName, node }];
2353
+ const ancestorKind = ancestorKindForNode(node);
2354
+ if (ancestorKind !== null) {
2355
+ const name = ancestorKind === "html" ? getTagName(node)?.toLowerCase() : getSectionName(node)?.toLowerCase();
2356
+ if (name) {
2357
+ newAncestors = [...ancestors, { kind: ancestorKind, name, node }];
1855
2358
  }
1856
2359
  }
1857
- for (const child of node.children) {
1858
- walk(child, newAncestors);
1859
- }
2360
+ for (const child of node.children) walk(child, newAncestors);
1860
2361
  }
1861
- walk(rootNode, []);
2362
+ walk(rootNode, [{ kind: "root", name: "", node: rootNode }]);
1862
2363
  return results;
1863
2364
  }
1864
2365
  function matchSelector(rootNode, selector) {
1865
2366
  const allResults = [];
1866
2367
  const seen = /* @__PURE__ */ new Set();
1867
- for (const alt of selector.alternatives) {
2368
+ for (const alt of selector) {
1868
2369
  for (const node of matchAlternative(rootNode, alt)) {
1869
2370
  if (!seen.has(node)) {
1870
2371
  seen.add(node);
@@ -1883,7 +2384,7 @@ var ERROR_NODE_TYPES = /* @__PURE__ */ new Set([
1883
2384
  ]);
1884
2385
  function errorMessageForNode(nodeType, node) {
1885
2386
  if (nodeType === "mustache_erroneous_section_end" || nodeType === "mustache_erroneous_inverted_section_end") {
1886
- const tagNameNode = node.children.find((c) => c.type === "mustache_erroneous_tag_name");
2387
+ const tagNameNode = node.children.find((c2) => c2.type === "mustache_erroneous_tag_name");
1887
2388
  return `Mismatched mustache section: {{/${tagNameNode?.text || "?"}}}`;
1888
2389
  }
1889
2390
  if (nodeType === "ERROR") {
@@ -1891,8 +2392,17 @@ function errorMessageForNode(nodeType, node) {
1891
2392
  }
1892
2393
  return `Missing ${nodeType}`;
1893
2394
  }
1894
- function resolveRuleSeverity(rules, ruleName) {
1895
- return rules?.[ruleName] ?? RULE_DEFAULTS[ruleName] ?? "off";
2395
+ function resolveRuleConfig(rules, ruleName) {
2396
+ const entry = rules?.[ruleName];
2397
+ let severity;
2398
+ if (entry === void 0) {
2399
+ severity = RULE_DEFAULTS[ruleName] ?? "off";
2400
+ } else if (typeof entry === "string") {
2401
+ severity = entry;
2402
+ } else {
2403
+ severity = entry.severity;
2404
+ }
2405
+ return { severity, entry };
1896
2406
  }
1897
2407
  function parseDisableDirective(node, customRuleIds) {
1898
2408
  if (node.type !== "html_comment" && node.type !== "mustache_comment") return null;
@@ -1954,7 +2464,7 @@ function collectErrors(tree, rules, customTagNames, customRules) {
1954
2464
  for (const error of unclosedErrors) {
1955
2465
  errors.push({ node: error.node, message: error.message });
1956
2466
  }
1957
- const customRuleIds = customRules ? new Set(customRules.map((r) => r.id)) : void 0;
2467
+ const customRuleIds = customRules ? new Set(customRules.map((r2) => r2.id)) : void 0;
1958
2468
  const disabledRules = collectDisabledRules(tree.rootNode, customRuleIds);
1959
2469
  const effectiveRules = { ...rules };
1960
2470
  for (const rule of disabledRules) {
@@ -1969,12 +2479,19 @@ function collectErrors(tree, rules, customTagNames, customRules) {
1969
2479
  { rule: "duplicateAttributes", errors: () => checkDuplicateAttributes(tree.rootNode) },
1970
2480
  { rule: "unescapedEntities", errors: () => checkUnescapedEntities(tree.rootNode) },
1971
2481
  { rule: "preferMustacheComments", errors: () => checkHtmlComments(tree.rootNode) },
1972
- { rule: "unrecognizedHtmlTags", errors: () => checkUnrecognizedHtmlTags(tree.rootNode, customTagNames) }
2482
+ { rule: "unrecognizedHtmlTags", errors: () => checkUnrecognizedHtmlTags(tree.rootNode, customTagNames) },
2483
+ {
2484
+ rule: "elementContentTooLong",
2485
+ errors: (entry) => {
2486
+ const elements = (entry && typeof entry === "object" ? entry.elements : void 0) ?? [];
2487
+ return checkElementContentTooLong(tree.rootNode, elements);
2488
+ }
2489
+ }
1973
2490
  ];
1974
2491
  for (const { rule, errors: getErrors } of ruleChecks) {
1975
- const severity = resolveRuleSeverity(effectiveRules, rule);
2492
+ const { severity, entry } = resolveRuleConfig(effectiveRules, rule);
1976
2493
  if (severity === "off") continue;
1977
- for (const error of getErrors()) {
2494
+ for (const error of getErrors(entry)) {
1978
2495
  errors.push({
1979
2496
  node: error.node,
1980
2497
  message: error.message,
@@ -1999,7 +2516,7 @@ function collectErrors(tree, rules, customTagNames, customRules) {
1999
2516
  }
2000
2517
  }
2001
2518
  return errors.filter(
2002
- (e) => !(e.message.includes("HTML comment found") && parseDisableDirective(e.node, customRuleIds) !== null)
2519
+ (e2) => !(e2.message.includes("HTML comment found") && parseDisableDirective(e2.node, customRuleIds) !== null)
2003
2520
  );
2004
2521
  }
2005
2522
 
@@ -2029,12 +2546,12 @@ function formatError(error, source) {
2029
2546
  const contextStart = Math.max(0, errorLine - 2);
2030
2547
  const contextEnd = Math.min(lines.length - 1, error.endLine - 1);
2031
2548
  const gutterWidth = String(contextEnd + 1).length;
2032
- const pad = (n) => String(n).padStart(gutterWidth);
2549
+ const pad = (n2) => String(n2).padStart(gutterWidth);
2033
2550
  const outputLines = [header];
2034
2551
  outputLines.push(source_default.dim(" ".repeat(gutterWidth) + " |"));
2035
- for (let i = contextStart; i <= contextEnd; i++) {
2036
- const lineNum = i + 1;
2037
- outputLines.push(source_default.dim(`${pad(lineNum)} |`) + " " + lines[i]);
2552
+ for (let i2 = contextStart; i2 <= contextEnd; i2++) {
2553
+ const lineNum = i2 + 1;
2554
+ outputLines.push(source_default.dim(`${pad(lineNum)} |`) + " " + lines[i2]);
2038
2555
  }
2039
2556
  const lastErrorLineIdx = error.endLine - 1;
2040
2557
  const lastLine = lines[lastErrorLineIdx] || "";
@@ -2108,7 +2625,7 @@ function resolveFiles(cliPatterns) {
2108
2625
  return { files: [], config };
2109
2626
  }
2110
2627
  let files = expandGlobs(patterns);
2111
- files = files.filter((f) => !DEFAULT_EXCLUDE_SEGMENTS.some((seg) => f.includes(seg)));
2628
+ files = files.filter((f2) => !DEFAULT_EXCLUDE_SEGMENTS.some((seg) => f2.includes(seg)));
2112
2629
  if (config?.exclude && config.exclude.length > 0) {
2113
2630
  const cwd = process.cwd();
2114
2631
  const excludeSet = /* @__PURE__ */ new Set();
@@ -2121,7 +2638,7 @@ function resolveFiles(cliPatterns) {
2121
2638
  }
2122
2639
  }
2123
2640
  }
2124
- files = files.filter((f) => !excludeSet.has(f));
2641
+ files = files.filter((f2) => !excludeSet.has(f2));
2125
2642
  }
2126
2643
  return { files, config };
2127
2644
  }
@@ -2133,13 +2650,13 @@ function applyFixes(source, errors) {
2133
2650
  }
2134
2651
  }
2135
2652
  if (replacements.length === 0) return source;
2136
- replacements.sort((a, b) => b.startIndex - a.startIndex);
2653
+ replacements.sort((a2, b) => b.startIndex - a2.startIndex);
2137
2654
  let result = source;
2138
2655
  let minIndex = Infinity;
2139
- for (const r of replacements) {
2140
- if (r.endIndex > minIndex) continue;
2141
- result = result.slice(0, r.startIndex) + r.newText + result.slice(r.endIndex);
2142
- minIndex = r.startIndex;
2656
+ for (const r2 of replacements) {
2657
+ if (r2.endIndex > minIndex) continue;
2658
+ result = result.slice(0, r2.startIndex) + r2.newText + result.slice(r2.endIndex);
2659
+ minIndex = r2.startIndex;
2143
2660
  }
2144
2661
  return result;
2145
2662
  }
@@ -2168,7 +2685,7 @@ async function run(args) {
2168
2685
  return 0;
2169
2686
  }
2170
2687
  const fixMode = args.includes("--fix");
2171
- const patterns = args.filter((a) => a !== "--fix");
2688
+ const patterns = args.filter((a2) => a2 !== "--fix");
2172
2689
  const { files, config } = resolveFiles(patterns);
2173
2690
  if (files.length === 0) {
2174
2691
  if (patterns.length === 0 && (!config?.include || config.include.length === 0)) {
@@ -2177,8 +2694,8 @@ async function run(args) {
2177
2694
  }
2178
2695
  const displayPatterns = patterns.length > 0 ? patterns : config?.include ?? [];
2179
2696
  console.error(source_default.yellow("No files matched the given patterns:"));
2180
- for (const p of displayPatterns) {
2181
- console.error(source_default.yellow(` ${p}`));
2697
+ for (const p2 of displayPatterns) {
2698
+ console.error(source_default.yellow(` ${p2}`));
2182
2699
  }
2183
2700
  return 1;
2184
2701
  }
@@ -2189,7 +2706,7 @@ async function run(args) {
2189
2706
  const cwd = process.cwd();
2190
2707
  const errorOutput = [];
2191
2708
  const rules = config?.rules;
2192
- const customTagNames = config?.customTags?.map((t) => t.name);
2709
+ const customTagNames = config?.customTags?.map((t2) => t2.name);
2193
2710
  const customRules = config?.customRules;
2194
2711
  for (const file of files) {
2195
2712
  const displayPath = import_node_path.default.relative(cwd, file) || file;
@@ -2205,8 +2722,8 @@ async function run(args) {
2205
2722
  }
2206
2723
  const tree = parseDocument(source);
2207
2724
  const errors = collectErrors2(tree, displayPath, rules, customTagNames, customRules);
2208
- const fileErrors = errors.filter((e) => e.severity !== "warning");
2209
- const fileWarnings = errors.filter((e) => e.severity === "warning");
2725
+ const fileErrors = errors.filter((e2) => e2.severity !== "warning");
2726
+ const fileWarnings = errors.filter((e2) => e2.severity === "warning");
2210
2727
  if (errors.length > 0) {
2211
2728
  filesWithErrors++;
2212
2729
  totalErrors += fileErrors.length;
@@ -2271,8 +2788,8 @@ var FullTextDocument = class _FullTextDocument {
2271
2788
  let lineOffsets = this._lineOffsets;
2272
2789
  const addedLineOffsets = computeLineOffsets(change.text, false, startOffset);
2273
2790
  if (endLine - startLine === addedLineOffsets.length) {
2274
- for (let i = 0, len = addedLineOffsets.length; i < len; i++) {
2275
- lineOffsets[i + startLine + 1] = addedLineOffsets[i];
2791
+ for (let i2 = 0, len = addedLineOffsets.length; i2 < len; i2++) {
2792
+ lineOffsets[i2 + startLine + 1] = addedLineOffsets[i2];
2276
2793
  }
2277
2794
  } else {
2278
2795
  if (addedLineOffsets.length < 1e4) {
@@ -2283,8 +2800,8 @@ var FullTextDocument = class _FullTextDocument {
2283
2800
  }
2284
2801
  const diff = change.text.length - (endOffset - startOffset);
2285
2802
  if (diff !== 0) {
2286
- for (let i = startLine + 1 + addedLineOffsets.length, len = lineOffsets.length; i < len; i++) {
2287
- lineOffsets[i] = lineOffsets[i] + diff;
2803
+ for (let i2 = startLine + 1 + addedLineOffsets.length, len = lineOffsets.length; i2 < len; i2++) {
2804
+ lineOffsets[i2] = lineOffsets[i2] + diff;
2288
2805
  }
2289
2806
  }
2290
2807
  } else if (_FullTextDocument.isFull(change)) {
@@ -2371,26 +2888,26 @@ var TextDocument;
2371
2888
  TextDocument2.update = update;
2372
2889
  function applyEdits(document, edits) {
2373
2890
  const text2 = document.getText();
2374
- const sortedEdits = mergeSort(edits.map(getWellformedEdit), (a, b) => {
2375
- const diff = a.range.start.line - b.range.start.line;
2891
+ const sortedEdits = mergeSort(edits.map(getWellformedEdit), (a2, b) => {
2892
+ const diff = a2.range.start.line - b.range.start.line;
2376
2893
  if (diff === 0) {
2377
- return a.range.start.character - b.range.start.character;
2894
+ return a2.range.start.character - b.range.start.character;
2378
2895
  }
2379
2896
  return diff;
2380
2897
  });
2381
2898
  let lastModifiedOffset = 0;
2382
2899
  const spans = [];
2383
- for (const e of sortedEdits) {
2384
- const startOffset = document.offsetAt(e.range.start);
2900
+ for (const e2 of sortedEdits) {
2901
+ const startOffset = document.offsetAt(e2.range.start);
2385
2902
  if (startOffset < lastModifiedOffset) {
2386
2903
  throw new Error("Overlapping edit");
2387
2904
  } else if (startOffset > lastModifiedOffset) {
2388
2905
  spans.push(text2.substring(lastModifiedOffset, startOffset));
2389
2906
  }
2390
- if (e.newText.length) {
2391
- spans.push(e.newText);
2907
+ if (e2.newText.length) {
2908
+ spans.push(e2.newText);
2392
2909
  }
2393
- lastModifiedOffset = document.offsetAt(e.range.end);
2910
+ lastModifiedOffset = document.offsetAt(e2.range.end);
2394
2911
  }
2395
2912
  spans.push(text2.substr(lastModifiedOffset));
2396
2913
  return spans.join("");
@@ -2401,39 +2918,39 @@ function mergeSort(data, compare) {
2401
2918
  if (data.length <= 1) {
2402
2919
  return data;
2403
2920
  }
2404
- const p = data.length / 2 | 0;
2405
- const left = data.slice(0, p);
2406
- const right = data.slice(p);
2921
+ const p2 = data.length / 2 | 0;
2922
+ const left = data.slice(0, p2);
2923
+ const right = data.slice(p2);
2407
2924
  mergeSort(left, compare);
2408
2925
  mergeSort(right, compare);
2409
2926
  let leftIdx = 0;
2410
2927
  let rightIdx = 0;
2411
- let i = 0;
2928
+ let i2 = 0;
2412
2929
  while (leftIdx < left.length && rightIdx < right.length) {
2413
2930
  const ret = compare(left[leftIdx], right[rightIdx]);
2414
2931
  if (ret <= 0) {
2415
- data[i++] = left[leftIdx++];
2932
+ data[i2++] = left[leftIdx++];
2416
2933
  } else {
2417
- data[i++] = right[rightIdx++];
2934
+ data[i2++] = right[rightIdx++];
2418
2935
  }
2419
2936
  }
2420
2937
  while (leftIdx < left.length) {
2421
- data[i++] = left[leftIdx++];
2938
+ data[i2++] = left[leftIdx++];
2422
2939
  }
2423
2940
  while (rightIdx < right.length) {
2424
- data[i++] = right[rightIdx++];
2941
+ data[i2++] = right[rightIdx++];
2425
2942
  }
2426
2943
  return data;
2427
2944
  }
2428
2945
  function computeLineOffsets(text2, isAtLineStart, textOffset = 0) {
2429
2946
  const result = isAtLineStart ? [textOffset] : [];
2430
- for (let i = 0; i < text2.length; i++) {
2431
- const ch = text2.charCodeAt(i);
2947
+ for (let i2 = 0; i2 < text2.length; i2++) {
2948
+ const ch = text2.charCodeAt(i2);
2432
2949
  if (isEOL(ch)) {
2433
- if (ch === 13 && i + 1 < text2.length && text2.charCodeAt(i + 1) === 10) {
2434
- i++;
2950
+ if (ch === 13 && i2 + 1 < text2.length && text2.charCodeAt(i2 + 1) === 10) {
2951
+ i2++;
2435
2952
  }
2436
- result.push(textOffset + i + 1);
2953
+ result.push(textOffset + i2 + 1);
2437
2954
  }
2438
2955
  }
2439
2956
  return result;
@@ -2466,8 +2983,8 @@ function print(doc, options) {
2466
2983
  }
2467
2984
  function currentColumn(output) {
2468
2985
  let col = 0;
2469
- for (let i = output.length - 1; i >= 0; i--) {
2470
- const chunk = output[i];
2986
+ for (let i2 = output.length - 1; i2 >= 0; i2--) {
2987
+ const chunk = output[i2];
2471
2988
  const nlIndex = chunk.lastIndexOf("\n");
2472
2989
  if (nlIndex !== -1) {
2473
2990
  col += chunk.length - nlIndex - 1;
@@ -2577,12 +3094,12 @@ function printDoc(doc, state, output, options) {
2577
3094
  function printFill(parts, state, output, options) {
2578
3095
  if (parts.length === 0) return;
2579
3096
  const printWidth = options.printWidth ?? 80;
2580
- for (let i = 0; i < parts.length; i++) {
2581
- const content = parts[i];
2582
- const separator = i + 1 < parts.length ? parts[i + 1] : null;
3097
+ for (let i2 = 0; i2 < parts.length; i2++) {
3098
+ const content = parts[i2];
3099
+ const separator = i2 + 1 < parts.length ? parts[i2 + 1] : null;
2583
3100
  printDoc(content, state, output, options);
2584
3101
  if (separator === null) break;
2585
- const nextContent = i + 2 < parts.length ? parts[i + 2] : null;
3102
+ const nextContent = i2 + 2 < parts.length ? parts[i2 + 2] : null;
2586
3103
  if (nextContent !== null) {
2587
3104
  const testOutput = [];
2588
3105
  const flatState = { ...state, mode: "flat" };
@@ -2600,7 +3117,7 @@ function printFill(parts, state, output, options) {
2600
3117
  } else {
2601
3118
  printDoc(separator, state, output, options);
2602
3119
  }
2603
- i++;
3120
+ i2++;
2604
3121
  }
2605
3122
  }
2606
3123
  function makeIndent(level, options) {
@@ -2633,10 +3150,10 @@ function indent(contents) {
2633
3150
  if (contents === "") return "";
2634
3151
  return { type: "indent", contents };
2635
3152
  }
2636
- function indentN(contents, n) {
2637
- if (n <= 0 || contents === "") return contents;
3153
+ function indentN(contents, n2) {
3154
+ if (n2 <= 0 || contents === "") return contents;
2638
3155
  let result = contents;
2639
- for (let i = 0; i < n; i++) {
3156
+ for (let i2 = 0; i2 < n2; i2++) {
2640
3157
  result = indent(result);
2641
3158
  }
2642
3159
  return result;
@@ -2650,7 +3167,7 @@ function ifBreak(breakContents, flatContents, options) {
2650
3167
  return { type: "ifBreak", breakContents, flatContents, groupId: options?.groupId };
2651
3168
  }
2652
3169
  function fill(parts) {
2653
- const filtered = parts.filter((p) => p !== "");
3170
+ const filtered = parts.filter((p2) => p2 !== "");
2654
3171
  if (filtered.length === 0) return "";
2655
3172
  if (filtered.length === 1) return filtered[0];
2656
3173
  return { type: "fill", parts: filtered };
@@ -2661,12 +3178,12 @@ function isLine(doc) {
2661
3178
 
2662
3179
  // lsp/server/src/formatting/utils.ts
2663
3180
  function normalizeText(text2) {
2664
- return text2.split("\n").map((line2) => line2.replace(/[ \t]+/g, " ").trim()).filter((line2, i, arr) => line2 || i > 0 && i < arr.length - 1).join("\n");
3181
+ return text2.split("\n").map((line2) => line2.replace(/[ \t]+/g, " ").trim()).filter((line2, i2, arr) => line2 || i2 > 0 && i2 < arr.length - 1).join("\n");
2665
3182
  }
2666
3183
  function getVisibleChildren(node) {
2667
3184
  const children = [];
2668
- for (let i = 0; i < node.childCount; i++) {
2669
- const child = node.child(i);
3185
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3186
+ const child = node.child(i2);
2670
3187
  if (child && !child.type.startsWith("_")) {
2671
3188
  children.push(child);
2672
3189
  }
@@ -2697,8 +3214,8 @@ ${middle.join("\n")}
2697
3214
  ${last} }}`;
2698
3215
  }
2699
3216
  const trimmed = inner.trim();
2700
- const s = prefix === "!" ? " " : space;
2701
- return `{{${prefix}${s}${trimmed}${s}}}`;
3217
+ const s2 = prefix === "!" ? " " : space;
3218
+ return `{{${prefix}${s2}${trimmed}${s2}}}`;
2702
3219
  }
2703
3220
  const plainMatch = raw.match(/^\{\{([\s\S]*)\}\}$/);
2704
3221
  if (plainMatch) {
@@ -2740,8 +3257,8 @@ function isCodeTag(config) {
2740
3257
  return !!(config.languageAttribute || config.languageDefault);
2741
3258
  }
2742
3259
  function getAttributeValue(node, attrName) {
2743
- for (let i = 0; i < node.childCount; i++) {
2744
- const child = node.child(i);
3260
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3261
+ const child = node.child(i2);
2745
3262
  if (child?.type === "html_start_tag") {
2746
3263
  for (let j = 0; j < child.childCount; j++) {
2747
3264
  const attr = child.child(j);
@@ -2958,8 +3475,8 @@ function getContentNodes(sectionNode) {
2958
3475
  const beginType = isInverted ? "mustache_inverted_section_begin" : "mustache_section_begin";
2959
3476
  const endType = isInverted ? "mustache_inverted_section_end" : "mustache_section_end";
2960
3477
  const contentNodes = [];
2961
- for (let i = 0; i < sectionNode.childCount; i++) {
2962
- const child = sectionNode.child(i);
3478
+ for (let i2 = 0; i2 < sectionNode.childCount; i2++) {
3479
+ const child = sectionNode.child(i2);
2963
3480
  if (!child) continue;
2964
3481
  if (child.type !== beginType && child.type !== endType && child.type !== "mustache_erroneous_section_end" && child.type !== "mustache_erroneous_inverted_section_end" && !child.type.startsWith("_")) {
2965
3482
  contentNodes.push(child);
@@ -2980,8 +3497,8 @@ function hasImplicitEndTagsRecursive(node) {
2980
3497
  let hasStartTag = false;
2981
3498
  let hasEndTag = false;
2982
3499
  let hasContentChildren = false;
2983
- for (let i = 0; i < node.childCount; i++) {
2984
- const child = node.child(i);
3500
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3501
+ const child = node.child(i2);
2985
3502
  if (!child) continue;
2986
3503
  if (child.type === "html_start_tag") hasStartTag = true;
2987
3504
  else if (child.type === "html_end_tag") hasEndTag = true;
@@ -2990,8 +3507,8 @@ function hasImplicitEndTagsRecursive(node) {
2990
3507
  }
2991
3508
  if (hasStartTag && !hasEndTag && hasContentChildren) return true;
2992
3509
  }
2993
- for (let i = 0; i < node.childCount; i++) {
2994
- const child = node.child(i);
3510
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3511
+ const child = node.child(i2);
2995
3512
  if (child && hasImplicitEndTagsRecursive(child)) {
2996
3513
  return true;
2997
3514
  }
@@ -3018,16 +3535,16 @@ function isInTextFlow(node, index, nodes) {
3018
3535
  return false;
3019
3536
  }
3020
3537
  function hasAdjacentInlineContent(index, nodes) {
3021
- for (let i = index - 1; i >= 0; i--) {
3022
- const n = nodes[i];
3023
- if (n.type === "text" && n.text.trim().length === 0) continue;
3024
- if (isInlineContentNode(n)) return true;
3538
+ for (let i2 = index - 1; i2 >= 0; i2--) {
3539
+ const n2 = nodes[i2];
3540
+ if (n2.type === "text" && n2.text.trim().length === 0) continue;
3541
+ if (isInlineContentNode(n2)) return true;
3025
3542
  break;
3026
3543
  }
3027
- for (let i = index + 1; i < nodes.length; i++) {
3028
- const n = nodes[i];
3029
- if (n.type === "text" && n.text.trim().length === 0) continue;
3030
- if (isInlineContentNode(n)) return true;
3544
+ for (let i2 = index + 1; i2 < nodes.length; i2++) {
3545
+ const n2 = nodes[i2];
3546
+ if (n2.type === "text" && n2.text.trim().length === 0) continue;
3547
+ if (isInlineContentNode(n2)) return true;
3031
3548
  break;
3032
3549
  }
3033
3550
  return false;
@@ -3083,15 +3600,15 @@ function dedentContent(rawContent) {
3083
3600
  }
3084
3601
  if (lines.length === 0) return "";
3085
3602
  let minIndent = Infinity;
3086
- for (const l of lines) {
3087
- if (l.trim() === "") continue;
3088
- const match = l.match(/^(\s*)/);
3603
+ for (const l2 of lines) {
3604
+ if (l2.trim() === "") continue;
3605
+ const match = l2.match(/^(\s*)/);
3089
3606
  if (match && match[1].length < minIndent) {
3090
3607
  minIndent = match[1].length;
3091
3608
  }
3092
3609
  }
3093
3610
  if (minIndent === Infinity) minIndent = 0;
3094
- return lines.map((l) => l.trim() === "" ? "" : l.slice(minIndent)).join("\n");
3611
+ return lines.map((l2) => l2.trim() === "" ? "" : l2.slice(minIndent)).join("\n");
3095
3612
  }
3096
3613
  function resolveIndentMode(node, config) {
3097
3614
  const mode = config.indent ?? "never";
@@ -3102,8 +3619,8 @@ function resolveIndentMode(node, config) {
3102
3619
  return isAttributeTruthy(value);
3103
3620
  }
3104
3621
  function getTagNameFromStartTag(startTag) {
3105
- for (let i = 0; i < startTag.childCount; i++) {
3106
- const child = startTag.child(i);
3622
+ for (let i2 = 0; i2 < startTag.childCount; i2++) {
3623
+ const child = startTag.child(i2);
3107
3624
  if (child?.type === "html_tag_name") return child.text.toLowerCase();
3108
3625
  }
3109
3626
  return null;
@@ -3172,8 +3689,8 @@ function formatHtmlElement(node, context, forceInline = false) {
3172
3689
  let endTag = null;
3173
3690
  let hasRealEndTag = false;
3174
3691
  const contentNodes = [];
3175
- for (let i = 0; i < node.childCount; i++) {
3176
- const child = node.child(i);
3692
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3693
+ const child = node.child(i2);
3177
3694
  if (!child) continue;
3178
3695
  if (child.type === "html_start_tag") {
3179
3696
  startTag = child;
@@ -3273,8 +3790,8 @@ function formatHtmlElement(node, context, forceInline = false) {
3273
3790
  const formattedContent = formatBlockChildren(contentNodes, context);
3274
3791
  const hasContent = hasDocContent(formattedContent);
3275
3792
  if (hasContent) {
3276
- const hasBlockChildren = contentNodes.some((child, i) => {
3277
- if (!shouldTreatAsBlock(child, i, contentNodes, tags)) {
3793
+ const hasBlockChildren = contentNodes.some((child, i2) => {
3794
+ if (!shouldTreatAsBlock(child, i2, contentNodes, tags)) {
3278
3795
  return false;
3279
3796
  }
3280
3797
  const childDisplay = getCSSDisplay(child, tags);
@@ -3330,8 +3847,8 @@ function formatHtmlElement(node, context, forceInline = false) {
3330
3847
  }
3331
3848
  function formatScriptStyleElement(node, context) {
3332
3849
  const parts = [];
3333
- for (let i = 0; i < node.childCount; i++) {
3334
- const child = node.child(i);
3850
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3851
+ const child = node.child(i2);
3335
3852
  if (!child) continue;
3336
3853
  if (child.type === "html_start_tag") {
3337
3854
  parts.push(formatStartTag(child, context));
@@ -3415,8 +3932,8 @@ function formatMustacheSection(node, context) {
3415
3932
  let beginNode = null;
3416
3933
  let endNode = null;
3417
3934
  const contentNodes = [];
3418
- for (let i = 0; i < node.childCount; i++) {
3419
- const child = node.child(i);
3935
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3936
+ const child = node.child(i2);
3420
3937
  if (!child) continue;
3421
3938
  if (child.type === beginType) {
3422
3939
  beginNode = child;
@@ -3431,7 +3948,7 @@ function formatMustacheSection(node, context) {
3431
3948
  parts.push(text(mustacheText(beginNode.text, context)));
3432
3949
  }
3433
3950
  const hasImplicit = hasImplicitEndTags(contentNodes);
3434
- const erroneousCount = contentNodes.filter((n) => n.type === "html_erroneous_end_tag").length;
3951
+ const erroneousCount = contentNodes.filter((n2) => n2.type === "html_erroneous_end_tag").length;
3435
3952
  const hasStaircase = !hasImplicit && erroneousCount > 0;
3436
3953
  if (hasStaircase) {
3437
3954
  let virtualDepth = erroneousCount - 1;
@@ -3485,8 +4002,8 @@ function formatMustacheSection(node, context) {
3485
4002
  parts.push(formattedContent);
3486
4003
  parts.push(hardline);
3487
4004
  } else {
3488
- const hasBlockChildren = contentNodes.some((child, i) => {
3489
- if (!shouldTreatAsBlock(child, i, contentNodes, context.customTags)) {
4005
+ const hasBlockChildren = contentNodes.some((child, i2) => {
4006
+ if (!shouldTreatAsBlock(child, i2, contentNodes, context.customTags)) {
3490
4007
  return false;
3491
4008
  }
3492
4009
  const childDisplay = getCSSDisplay(child, context.customTags);
@@ -3508,8 +4025,8 @@ function formatMustacheSection(node, context) {
3508
4025
  return group(concat(parts));
3509
4026
  }
3510
4027
  function startTagHasAttributes(startTag) {
3511
- for (let i = 0; i < startTag.childCount; i++) {
3512
- const child = startTag.child(i);
4028
+ for (let i2 = 0; i2 < startTag.childCount; i2++) {
4029
+ const child = startTag.child(i2);
3513
4030
  if (!child) continue;
3514
4031
  if (child.type === "html_attribute" || child.type === "mustache_attribute" || child.type === "mustache_interpolation" || child.type === "mustache_triple") {
3515
4032
  return true;
@@ -3520,8 +4037,8 @@ function startTagHasAttributes(startTag) {
3520
4037
  function formatStartTag(node, context, bare = false) {
3521
4038
  let tagNameText = "";
3522
4039
  const attrs = [];
3523
- for (let i = 0; i < node.childCount; i++) {
3524
- const child = node.child(i);
4040
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4041
+ const child = node.child(i2);
3525
4042
  if (!child) continue;
3526
4043
  if (child.type === "html_tag_name") {
3527
4044
  tagNameText = child.text;
@@ -3543,11 +4060,11 @@ function formatStartTag(node, context, bare = false) {
3543
4060
  return text("<" + tagNameText + closingBracket);
3544
4061
  }
3545
4062
  const attrParts = [];
3546
- for (let i = 0; i < attrs.length; i++) {
3547
- if (i > 0) {
4063
+ for (let i2 = 0; i2 < attrs.length; i2++) {
4064
+ if (i2 > 0) {
3548
4065
  attrParts.push(line);
3549
4066
  }
3550
- attrParts.push(attrs[i]);
4067
+ attrParts.push(attrs[i2]);
3551
4068
  }
3552
4069
  const breakClosingBracket = isSelfClosing ? "/>" : ">";
3553
4070
  const inner = concat([
@@ -3559,8 +4076,8 @@ function formatStartTag(node, context, bare = false) {
3559
4076
  return bare ? inner : group(inner);
3560
4077
  }
3561
4078
  function formatEndTag(node) {
3562
- for (let i = 0; i < node.childCount; i++) {
3563
- const child = node.child(i);
4079
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4080
+ const child = node.child(i2);
3564
4081
  if (child && child.type === "html_tag_name") {
3565
4082
  return text("</" + child.text + ">");
3566
4083
  }
@@ -3569,8 +4086,8 @@ function formatEndTag(node) {
3569
4086
  }
3570
4087
  function formatAttribute(node, context) {
3571
4088
  const parts = [];
3572
- for (let i = 0; i < node.childCount; i++) {
3573
- const child = node.child(i);
4089
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4090
+ const child = node.child(i2);
3574
4091
  if (!child) continue;
3575
4092
  if (child.type === "html_attribute_name") {
3576
4093
  parts.push(text(child.text));
@@ -3595,21 +4112,21 @@ function textWords(str) {
3595
4112
  const words = str.split(/\s+/).filter((w) => w.length > 0);
3596
4113
  if (words.length === 0) return [];
3597
4114
  const parts = [words[0]];
3598
- for (let i = 1; i < words.length; i++) {
4115
+ for (let i2 = 1; i2 < words.length; i2++) {
3599
4116
  parts.push(line);
3600
- parts.push(words[i]);
4117
+ parts.push(words[i2]);
3601
4118
  }
3602
4119
  return parts;
3603
4120
  }
3604
4121
  function collapseDelimitedRegions(parts, delimiters) {
3605
4122
  if (delimiters.length === 0) return parts;
3606
4123
  const sorted = [...delimiters].sort(
3607
- (a, b) => Math.max(b.start.length, b.end.length) - Math.max(a.start.length, a.end.length)
4124
+ (a2, b) => Math.max(b.start.length, b.end.length) - Math.max(a2.start.length, a2.end.length)
3608
4125
  );
3609
4126
  const result = [...parts];
3610
4127
  let activeDelimiter = null;
3611
- for (let i = 0; i < result.length; i++) {
3612
- const part = result[i];
4128
+ for (let i2 = 0; i2 < result.length; i2++) {
4129
+ const part = result[i2];
3613
4130
  if (typeof part === "string") {
3614
4131
  if (activeDelimiter === null) {
3615
4132
  for (const delim of sorted) {
@@ -3630,7 +4147,7 @@ function collapseDelimitedRegions(parts, delimiters) {
3630
4147
  }
3631
4148
  }
3632
4149
  } else if (activeDelimiter !== null && isLine(part)) {
3633
- result[i] = " ";
4150
+ result[i2] = " ";
3634
4151
  }
3635
4152
  }
3636
4153
  return result;
@@ -3682,8 +4199,8 @@ function formatBlockChildren(nodes, context) {
3682
4199
  const parts2 = noBreakDelims ? collapseDelimitedRegions(currentLine, noBreakDelims) : currentLine;
3683
4200
  return inlineContentToFill(parts2);
3684
4201
  }
3685
- for (let i = 0; i < nodes.length; i++) {
3686
- const node = nodes[i];
4202
+ for (let i2 = 0; i2 < nodes.length; i2++) {
4203
+ const node = nodes[i2];
3687
4204
  if (lastNodeEnd >= 0 && node.startIndex > lastNodeEnd && !inIgnoreRegion) {
3688
4205
  const gap = context.document.getText().slice(lastNodeEnd, node.startIndex);
3689
4206
  const newlineCount = (gap.match(/\n/g) || []).length;
@@ -3756,10 +4273,10 @@ function formatBlockChildren(nodes, context) {
3756
4273
  lastNodeEnd = node.endIndex;
3757
4274
  continue;
3758
4275
  }
3759
- const treatAsBlock = shouldTreatAsBlock(node, i, nodes, context.customTags);
4276
+ const treatAsBlock = shouldTreatAsBlock(node, i2, nodes, context.customTags);
3760
4277
  if (lastNodeEnd >= 0 && node.startIndex > lastNodeEnd) {
3761
- const prevNode = nodes[i - 1];
3762
- const prevTreatAsBlock = shouldTreatAsBlock(prevNode, i - 1, nodes, context.customTags);
4278
+ const prevNode = nodes[i2 - 1];
4279
+ const prevTreatAsBlock = shouldTreatAsBlock(prevNode, i2 - 1, nodes, context.customTags);
3763
4280
  if (!prevTreatAsBlock && !treatAsBlock) {
3764
4281
  const gap = context.document.getText().slice(lastNodeEnd, node.startIndex);
3765
4282
  if (/\s/.test(gap)) {
@@ -3780,7 +4297,7 @@ function formatBlockChildren(nodes, context) {
3780
4297
  pendingBlankLine = false;
3781
4298
  } else if (node.type === "html_comment" || node.type === "mustache_comment") {
3782
4299
  const isMultiline = node.startPosition.row !== node.endPosition.row;
3783
- const isOnOwnLine = i > 0 && node.startPosition.row > nodes[i - 1].endPosition.row;
4300
+ const isOnOwnLine = i2 > 0 && node.startPosition.row > nodes[i2 - 1].endPosition.row;
3784
4301
  if (isMultiline || isOnOwnLine) {
3785
4302
  if (currentLine.length > 0) {
3786
4303
  const lineContent = trimDoc(flushCurrentLine());
@@ -3806,7 +4323,7 @@ function formatBlockChildren(nodes, context) {
3806
4323
  blankLineBeforeCurrentLine = pendingBlankLine;
3807
4324
  pendingBlankLine = false;
3808
4325
  }
3809
- const forceInline = isInTextFlow(node, i, nodes);
4326
+ const forceInline = isInTextFlow(node, i2, nodes);
3810
4327
  const formatted = formatNode(node, context, forceInline);
3811
4328
  if (typeof formatted === "string" && formatted.includes("\n")) {
3812
4329
  const contentLines = formatted.split("\n");
@@ -3915,18 +4432,18 @@ function formatBlockChildren(nodes, context) {
3915
4432
  return empty;
3916
4433
  }
3917
4434
  const parts = [];
3918
- for (let i = 0; i < lines.length; i++) {
3919
- if (i > 0) {
3920
- if (lines[i].blankLineBefore) {
4435
+ for (let i2 = 0; i2 < lines.length; i2++) {
4436
+ if (i2 > 0) {
4437
+ if (lines[i2].blankLineBefore) {
3921
4438
  parts.push("\n");
3922
4439
  }
3923
- if (lines[i].rawLine) {
4440
+ if (lines[i2].rawLine) {
3924
4441
  parts.push("\n");
3925
4442
  } else {
3926
4443
  parts.push(hardline);
3927
4444
  }
3928
4445
  }
3929
- parts.push(lines[i].doc);
4446
+ parts.push(lines[i2].doc);
3930
4447
  }
3931
4448
  return concat(parts);
3932
4449
  }
@@ -4035,8 +4552,8 @@ function getEmbeddedLanguageId(node) {
4035
4552
  if (node.type === "html_style_element") {
4036
4553
  return "css";
4037
4554
  }
4038
- for (let i = 0; i < node.childCount; i++) {
4039
- const child = node.child(i);
4555
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4556
+ const child = node.child(i2);
4040
4557
  if (child?.type === "html_start_tag") {
4041
4558
  for (let j = 0; j < child.childCount; j++) {
4042
4559
  const attr = child.child(j);
@@ -4062,8 +4579,8 @@ function collectEmbeddedRegions(rootNode) {
4062
4579
  const regions = [];
4063
4580
  const walk = (node) => {
4064
4581
  if (node.type === "html_script_element" || node.type === "html_style_element") {
4065
- for (let i = 0; i < node.childCount; i++) {
4066
- const child = node.child(i);
4582
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4583
+ const child = node.child(i2);
4067
4584
  if (child?.type === "html_raw_text") {
4068
4585
  regions.push({
4069
4586
  startIndex: child.startIndex,
@@ -4074,8 +4591,8 @@ function collectEmbeddedRegions(rootNode) {
4074
4591
  }
4075
4592
  return;
4076
4593
  }
4077
- for (let i = 0; i < node.childCount; i++) {
4078
- const child = node.child(i);
4594
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4595
+ const child = node.child(i2);
4079
4596
  if (child) walk(child);
4080
4597
  }
4081
4598
  };
@@ -4115,9 +4632,9 @@ function parseFlags(args) {
4115
4632
  mustacheSpaces: void 0,
4116
4633
  patterns: []
4117
4634
  };
4118
- let i = 0;
4119
- while (i < args.length) {
4120
- const arg = args[i];
4635
+ let i2 = 0;
4636
+ while (i2 < args.length) {
4637
+ const arg = args[i2];
4121
4638
  switch (arg) {
4122
4639
  case "--write":
4123
4640
  flags.write = true;
@@ -4129,16 +4646,16 @@ function parseFlags(args) {
4129
4646
  flags.stdin = true;
4130
4647
  break;
4131
4648
  case "--indent-size":
4132
- i++;
4133
- flags.indentSize = parseInt(args[i], 10);
4649
+ i2++;
4650
+ flags.indentSize = parseInt(args[i2], 10);
4134
4651
  if (isNaN(flags.indentSize)) {
4135
4652
  console.error(source_default.red("Error: --indent-size requires a number"));
4136
4653
  process.exit(1);
4137
4654
  }
4138
4655
  break;
4139
4656
  case "--print-width":
4140
- i++;
4141
- flags.printWidth = parseInt(args[i], 10);
4657
+ i2++;
4658
+ flags.printWidth = parseInt(args[i2], 10);
4142
4659
  if (isNaN(flags.printWidth)) {
4143
4660
  console.error(source_default.red("Error: --print-width requires a number"));
4144
4661
  process.exit(1);
@@ -4151,7 +4668,7 @@ function parseFlags(args) {
4151
4668
  flags.patterns.push(arg);
4152
4669
  break;
4153
4670
  }
4154
- i++;
4671
+ i2++;
4155
4672
  }
4156
4673
  return flags;
4157
4674
  }