@reteps/tree-sitter-htmlmustache 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +52 -22
  2. package/cli/out/main.js +915 -426
  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,264 +1651,685 @@ 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
+ const attributes = [];
1967
+ const descendantChecks = [];
1968
+ const forbidChange = (requested) => {
1969
+ if (kind === void 0) return false;
1970
+ if (kind === requested) return false;
1971
+ return true;
1972
+ };
1973
+ for (const token of tokens) {
1974
+ switch (token.type) {
1975
+ case "type":
1976
+ if (forbidChange("html")) return null;
1977
+ kind = "html";
1978
+ name = token.name.toLowerCase();
1979
+ break;
1980
+ case "universal":
1981
+ if (forbidChange("html")) return null;
1982
+ kind = "html";
1983
+ name = null;
1984
+ break;
1985
+ case "class":
1986
+ if (forbidChange("html")) return null;
1987
+ kind = "html";
1988
+ attributes.push(classConstraint(token, false));
1989
+ break;
1990
+ case "id":
1991
+ if (forbidChange("html")) return null;
1992
+ kind = "html";
1993
+ attributes.push(idConstraint(token, false));
1994
+ break;
1995
+ case "attribute": {
1996
+ if (forbidChange("html")) return null;
1997
+ if (kind === void 0) kind = "html";
1998
+ const c2 = attributeConstraint(token, false);
1999
+ if (!c2) return null;
2000
+ attributes.push(c2);
2001
+ break;
2002
+ }
2003
+ case "pseudo-class": {
2004
+ if (MUSTACHE_KIND_PSEUDO.has(token.name)) {
2005
+ const mustacheKind = mustacheKindFromMarker(token.name);
2006
+ if (mustacheKind === null) return null;
2007
+ if (forbidChange(mustacheKind)) return null;
2008
+ kind = mustacheKind;
2009
+ const glob = parseGlob(token.argument ?? "");
2010
+ name = glob.name;
2011
+ pathRegex = glob.pathRegex;
2012
+ break;
2013
+ }
2014
+ if (token.name === "has") {
2015
+ const sel = subtreeToSelector(token.subtree);
2016
+ if (!sel) return null;
2017
+ descendantChecks.push({ selector: sel, negated: false });
2018
+ break;
2019
+ }
2020
+ if (token.name === "not") {
2021
+ if (!applyNegatedSubtree(token.subtree, attributes, descendantChecks)) return null;
2022
+ break;
2023
+ }
2024
+ return null;
2025
+ }
2026
+ default:
2027
+ return null;
2028
+ }
1719
2029
  }
1720
- if (raw[pos.i] === "[" || raw[pos.i] === ":") {
2030
+ if (kind === void 0) {
1721
2031
  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) {
2032
+ }
2033
+ const isHtml = kind === "html";
2034
+ const finalAttrs = isHtml ? attributes : [];
2035
+ return { kind, name, pathRegex, attributes: finalAttrs, descendantChecks, combinator: "descendant" };
2036
+ }
2037
+ function mustacheKindFromMarker(name) {
2038
+ switch (name) {
2039
+ case "m-section":
2040
+ return "section";
2041
+ case "m-inverted":
2042
+ return "inverted";
2043
+ case "m-variable":
2044
+ return "variable";
2045
+ case "m-raw":
2046
+ return "raw";
2047
+ case "m-comment":
2048
+ return "comment";
2049
+ case "m-partial":
2050
+ return "partial";
2051
+ default:
2052
+ return null;
2053
+ }
2054
+ }
2055
+ function parseGlob(arg) {
2056
+ const trimmed = arg.trim();
2057
+ if (trimmed === "" || trimmed === "*") {
2058
+ return { name: null };
2059
+ }
2060
+ if (!trimmed.includes("*")) {
2061
+ return { name: trimmed.toLowerCase() };
2062
+ }
2063
+ const escaped = trimmed.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
2064
+ const pathRegex = new RegExp(`^${escaped}$`, "i");
2065
+ return { name: trimmed.toLowerCase(), pathRegex };
2066
+ }
2067
+ function attributeConstraint(token, negated) {
2068
+ const name = token.name.toLowerCase();
2069
+ if (token.operator === void 0) {
2070
+ return { name, op: "=", value: void 0, negated };
2071
+ }
2072
+ let op;
2073
+ switch (token.operator) {
2074
+ case "=":
2075
+ op = "=";
2076
+ break;
2077
+ case "^=":
2078
+ op = "^=";
2079
+ break;
2080
+ case "*=":
2081
+ op = "*=";
2082
+ break;
2083
+ case "$=":
2084
+ op = "$=";
2085
+ break;
2086
+ case "~=":
2087
+ op = "~=";
2088
+ break;
2089
+ default:
2090
+ return null;
2091
+ }
2092
+ return { name, op, value: stripQuotes(token.value ?? ""), negated };
2093
+ }
2094
+ function classConstraint(token, negated) {
2095
+ return { name: "class", op: "~=", value: token.name, negated };
2096
+ }
2097
+ function idConstraint(token, negated) {
2098
+ return { name: "id", op: "=", value: token.name, negated };
2099
+ }
2100
+ function applyNegatedSubtree(subtree, attributes, descendantChecks) {
2101
+ if (!subtree) return false;
2102
+ if (subtree.type === "attribute") {
2103
+ const c2 = attributeConstraint(subtree, true);
2104
+ if (!c2) return false;
2105
+ attributes.push(c2);
2106
+ return true;
2107
+ }
2108
+ if (subtree.type === "class") {
2109
+ attributes.push(classConstraint(subtree, true));
2110
+ return true;
2111
+ }
2112
+ if (subtree.type === "id") {
2113
+ attributes.push(idConstraint(subtree, true));
2114
+ return true;
2115
+ }
2116
+ if (subtree.type === "pseudo-class" && subtree.name === "has") {
2117
+ const sel = subtreeToSelector(subtree.subtree);
2118
+ if (!sel) return false;
2119
+ descendantChecks.push({ selector: sel, negated: true });
2120
+ return true;
2121
+ }
2122
+ return false;
2123
+ }
2124
+ function subtreeToSelector(subtree) {
2125
+ if (!subtree) return null;
2126
+ const tops = subtree.type === "list" ? subtree.list : [subtree];
2127
+ const alts = [];
2128
+ for (const top of tops) {
2129
+ const segments = [];
2130
+ if (!collectSegments(top, "descendant", segments)) return null;
2131
+ if (segments.length === 0) return null;
2132
+ alts.push(segments);
2133
+ }
2134
+ return alts.length > 0 ? alts : null;
2135
+ }
2136
+ function stripQuotes(raw) {
2137
+ if (raw.length < 2) return raw;
2138
+ const first = raw[0];
2139
+ const last = raw[raw.length - 1];
2140
+ if ((first === '"' || first === "'") && first === last) {
2141
+ return raw.slice(1, -1);
2142
+ }
2143
+ return raw;
2144
+ }
2145
+ function ancestorKindForNode(node) {
2146
+ if (HTML_ELEMENT_TYPES.has(node.type)) return "html";
2147
+ if (node.type === "mustache_section") return "section";
2148
+ if (node.type === "mustache_inverted_section") return "inverted";
2149
+ return null;
2150
+ }
2151
+ function getHtmlAttributes(node) {
1739
2152
  const startTag = node.children.find(
1740
- (c) => c.type === "html_start_tag" || c.type === "html_self_closing_tag"
2153
+ (c2) => c2.type === "html_start_tag" || c2.type === "html_self_closing_tag"
1741
2154
  );
1742
2155
  if (!startTag) return [];
1743
2156
  const attrs = [];
1744
2157
  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
- }
2158
+ if (child.type !== "html_attribute") continue;
2159
+ let attrName = "";
2160
+ let attrValue;
2161
+ for (const part of child.children) {
2162
+ if (part.type === "html_attribute_name") {
2163
+ attrName = part.text.toLowerCase();
2164
+ } else if (part.type === "html_quoted_attribute_value") {
2165
+ attrValue = part.text.replace(/^["']|["']$/g, "");
2166
+ } else if (part.type === "html_attribute_value") {
2167
+ attrValue = part.text;
1756
2168
  }
1757
- if (attrName) attrs.push({ name: attrName, value: attrValue });
1758
2169
  }
2170
+ if (attrName) attrs.push({ name: attrName, value: attrValue });
1759
2171
  }
1760
2172
  return attrs;
1761
2173
  }
2174
+ function matchesAttributeValue(has, c2) {
2175
+ if (has === void 0 || c2.value === void 0) return false;
2176
+ const v = c2.value;
2177
+ if (v === "") return false;
2178
+ switch (c2.op) {
2179
+ case "=":
2180
+ return has === v;
2181
+ case "^=":
2182
+ return has.startsWith(v);
2183
+ case "*=":
2184
+ return has.includes(v);
2185
+ case "$=":
2186
+ return has.endsWith(v);
2187
+ case "~=":
2188
+ return has.split(/\s+/).includes(v);
2189
+ }
2190
+ }
1762
2191
  function checkAttributes(node, constraints) {
1763
2192
  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 {
2193
+ const nodeAttrs = getHtmlAttributes(node);
2194
+ for (const c2 of constraints) {
2195
+ const found = nodeAttrs.find((a2) => a2.name === c2.name);
2196
+ if (c2.negated) {
2197
+ if (!found) continue;
2198
+ if (c2.value === void 0) return false;
2199
+ if (matchesAttributeValue(found.value, c2)) return false;
2200
+ continue;
2201
+ }
2202
+ if (c2.value === void 0) {
1772
2203
  if (!found) return false;
2204
+ continue;
1773
2205
  }
2206
+ if (!found || !matchesAttributeValue(found.value, c2)) return false;
1774
2207
  }
1775
2208
  return true;
1776
2209
  }
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;
2210
+ function checkDescendants(node, checks) {
2211
+ if (checks.length === 0) return true;
2212
+ for (const check of checks) {
2213
+ const present = hasDescendantMatch(node, check.selector);
2214
+ if (check.negated ? present : !present) return false;
1790
2215
  }
1791
2216
  return true;
1792
2217
  }
2218
+ function hasDescendantMatch(node, selector) {
2219
+ for (const child of node.children) {
2220
+ if (matchSelector(child, selector).length > 0) return true;
2221
+ }
2222
+ return false;
2223
+ }
2224
+ function matchesName(actual, segment) {
2225
+ if (segment.name === null) return true;
2226
+ if (actual === null) return false;
2227
+ if (segment.pathRegex) return segment.pathRegex.test(actual);
2228
+ return actual === segment.name;
2229
+ }
2230
+ function nodeMatchesSegment(node, segment) {
2231
+ switch (segment.kind) {
2232
+ case "html": {
2233
+ if (!HTML_ELEMENT_TYPES.has(node.type)) return false;
2234
+ if (segment.name !== null) {
2235
+ const tagName = getTagName(node)?.toLowerCase();
2236
+ if (tagName !== segment.name) return false;
2237
+ }
2238
+ return checkAttributes(node, segment.attributes) && checkDescendants(node, segment.descendantChecks);
2239
+ }
2240
+ case "section":
2241
+ if (node.type !== "mustache_section") return false;
2242
+ if (!matchesName(getSectionName(node)?.toLowerCase() ?? null, segment)) return false;
2243
+ return checkDescendants(node, segment.descendantChecks);
2244
+ case "inverted":
2245
+ if (node.type !== "mustache_inverted_section") return false;
2246
+ if (!matchesName(getSectionName(node)?.toLowerCase() ?? null, segment)) return false;
2247
+ return checkDescendants(node, segment.descendantChecks);
2248
+ case "variable":
2249
+ if (node.type !== "mustache_interpolation") return false;
2250
+ if (!matchesName(getInterpolationPath(node)?.toLowerCase() ?? null, segment)) return false;
2251
+ return checkDescendants(node, segment.descendantChecks);
2252
+ case "raw":
2253
+ if (node.type !== "mustache_triple") return false;
2254
+ if (!matchesName(getInterpolationPath(node)?.toLowerCase() ?? null, segment)) return false;
2255
+ return checkDescendants(node, segment.descendantChecks);
2256
+ case "comment":
2257
+ if (node.type !== "mustache_comment") return false;
2258
+ if (!matchesName(getCommentContent(node)?.toLowerCase() ?? null, segment)) return false;
2259
+ return checkDescendants(node, segment.descendantChecks);
2260
+ case "partial":
2261
+ if (node.type !== "mustache_partial") return false;
2262
+ if (!matchesName(getPartialName(node)?.toLowerCase() ?? null, segment)) return false;
2263
+ return checkDescendants(node, segment.descendantChecks);
2264
+ }
2265
+ }
1793
2266
  function checkAncestors(ancestors, segments, segIdx, childCombinator) {
1794
2267
  if (segIdx < 0) return true;
1795
2268
  const segment = segments[segIdx];
2269
+ const ancestorKind = ancestorKindForSegment(segment);
2270
+ if (ancestorKind === null) return false;
1796
2271
  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;
1803
- }
1804
- return checkAncestors(ancestors.slice(0, a), segments, segIdx - 1, segment.combinator);
2272
+ for (let a2 = ancestors.length - 1; a2 >= 0; a2--) {
2273
+ const entry = ancestors[a2];
2274
+ if (entry.kind !== ancestorKind) continue;
2275
+ if (!matchesName(entry.name, segment)) return false;
2276
+ if (segment.kind === "html" && !checkAttributes(entry.node, segment.attributes)) return false;
2277
+ if (!checkDescendants(entry.node, segment.descendantChecks)) return false;
2278
+ return checkAncestors(ancestors.slice(0, a2), segments, segIdx - 1, segment.combinator);
1805
2279
  }
1806
2280
  return false;
1807
2281
  }
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)) {
2282
+ for (let a2 = ancestors.length - 1; a2 >= 0; a2--) {
2283
+ const entry = ancestors[a2];
2284
+ if (entry.kind !== ancestorKind) continue;
2285
+ if (!matchesName(entry.name, segment)) continue;
2286
+ if (segment.kind === "html" && !checkAttributes(entry.node, segment.attributes)) continue;
2287
+ if (!checkDescendants(entry.node, segment.descendantChecks)) continue;
2288
+ if (checkAncestors(ancestors.slice(0, a2), segments, segIdx - 1, segment.combinator)) {
1816
2289
  return true;
1817
2290
  }
1818
2291
  }
1819
2292
  return false;
1820
2293
  }
2294
+ function ancestorKindForSegment(segment) {
2295
+ if (segment.kind === "html") return "html";
2296
+ if (segment.kind === "section") return "section";
2297
+ if (segment.kind === "inverted") return "inverted";
2298
+ return null;
2299
+ }
1821
2300
  function getReportNode(node) {
1822
2301
  if (HTML_ELEMENT_TYPES.has(node.type)) {
1823
2302
  const startTag = node.children.find(
1824
- (c) => c.type === "html_start_tag" || c.type === "html_self_closing_tag"
2303
+ (c2) => c2.type === "html_start_tag" || c2.type === "html_self_closing_tag"
1825
2304
  );
1826
2305
  return startTag ?? node;
1827
2306
  }
1828
- if (MUSTACHE_SECTION_TYPES.has(node.type)) {
2307
+ if (node.type === "mustache_section" || node.type === "mustache_inverted_section") {
1829
2308
  const begin = node.children.find(
1830
- (c) => c.type === "mustache_section_begin" || c.type === "mustache_inverted_section_begin"
2309
+ (c2) => c2.type === "mustache_section_begin" || c2.type === "mustache_inverted_section_begin"
1831
2310
  );
1832
2311
  return begin ?? node;
1833
2312
  }
1834
2313
  return node;
1835
2314
  }
1836
- function matchAlternative(rootNode, alt) {
2315
+ function matchAlternative(rootNode, segments) {
1837
2316
  const results = [];
1838
- const lastSegment = alt.segments[alt.segments.length - 1];
2317
+ const lastSegment = segments[segments.length - 1];
1839
2318
  function walk(node, ancestors) {
1840
2319
  if (nodeMatchesSegment(node, lastSegment)) {
1841
- if (alt.segments.length === 1 || checkAncestors(ancestors, alt.segments, alt.segments.length - 2, lastSegment.combinator)) {
2320
+ if (segments.length === 1 || checkAncestors(ancestors, segments, segments.length - 2, lastSegment.combinator)) {
1842
2321
  results.push(getReportNode(node));
1843
2322
  }
1844
2323
  }
1845
2324
  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 }];
2325
+ const ancestorKind = ancestorKindForNode(node);
2326
+ if (ancestorKind !== null) {
2327
+ const name = ancestorKind === "html" ? getTagName(node)?.toLowerCase() : getSectionName(node)?.toLowerCase();
2328
+ if (name) {
2329
+ newAncestors = [...ancestors, { kind: ancestorKind, name, node }];
1855
2330
  }
1856
2331
  }
1857
- for (const child of node.children) {
1858
- walk(child, newAncestors);
1859
- }
2332
+ for (const child of node.children) walk(child, newAncestors);
1860
2333
  }
1861
2334
  walk(rootNode, []);
1862
2335
  return results;
@@ -1864,7 +2337,7 @@ function matchAlternative(rootNode, alt) {
1864
2337
  function matchSelector(rootNode, selector) {
1865
2338
  const allResults = [];
1866
2339
  const seen = /* @__PURE__ */ new Set();
1867
- for (const alt of selector.alternatives) {
2340
+ for (const alt of selector) {
1868
2341
  for (const node of matchAlternative(rootNode, alt)) {
1869
2342
  if (!seen.has(node)) {
1870
2343
  seen.add(node);
@@ -1883,7 +2356,7 @@ var ERROR_NODE_TYPES = /* @__PURE__ */ new Set([
1883
2356
  ]);
1884
2357
  function errorMessageForNode(nodeType, node) {
1885
2358
  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");
2359
+ const tagNameNode = node.children.find((c2) => c2.type === "mustache_erroneous_tag_name");
1887
2360
  return `Mismatched mustache section: {{/${tagNameNode?.text || "?"}}}`;
1888
2361
  }
1889
2362
  if (nodeType === "ERROR") {
@@ -1891,8 +2364,17 @@ function errorMessageForNode(nodeType, node) {
1891
2364
  }
1892
2365
  return `Missing ${nodeType}`;
1893
2366
  }
1894
- function resolveRuleSeverity(rules, ruleName) {
1895
- return rules?.[ruleName] ?? RULE_DEFAULTS[ruleName] ?? "off";
2367
+ function resolveRuleConfig(rules, ruleName) {
2368
+ const entry = rules?.[ruleName];
2369
+ let severity;
2370
+ if (entry === void 0) {
2371
+ severity = RULE_DEFAULTS[ruleName] ?? "off";
2372
+ } else if (typeof entry === "string") {
2373
+ severity = entry;
2374
+ } else {
2375
+ severity = entry.severity;
2376
+ }
2377
+ return { severity, entry };
1896
2378
  }
1897
2379
  function parseDisableDirective(node, customRuleIds) {
1898
2380
  if (node.type !== "html_comment" && node.type !== "mustache_comment") return null;
@@ -1954,7 +2436,7 @@ function collectErrors(tree, rules, customTagNames, customRules) {
1954
2436
  for (const error of unclosedErrors) {
1955
2437
  errors.push({ node: error.node, message: error.message });
1956
2438
  }
1957
- const customRuleIds = customRules ? new Set(customRules.map((r) => r.id)) : void 0;
2439
+ const customRuleIds = customRules ? new Set(customRules.map((r2) => r2.id)) : void 0;
1958
2440
  const disabledRules = collectDisabledRules(tree.rootNode, customRuleIds);
1959
2441
  const effectiveRules = { ...rules };
1960
2442
  for (const rule of disabledRules) {
@@ -1969,12 +2451,19 @@ function collectErrors(tree, rules, customTagNames, customRules) {
1969
2451
  { rule: "duplicateAttributes", errors: () => checkDuplicateAttributes(tree.rootNode) },
1970
2452
  { rule: "unescapedEntities", errors: () => checkUnescapedEntities(tree.rootNode) },
1971
2453
  { rule: "preferMustacheComments", errors: () => checkHtmlComments(tree.rootNode) },
1972
- { rule: "unrecognizedHtmlTags", errors: () => checkUnrecognizedHtmlTags(tree.rootNode, customTagNames) }
2454
+ { rule: "unrecognizedHtmlTags", errors: () => checkUnrecognizedHtmlTags(tree.rootNode, customTagNames) },
2455
+ {
2456
+ rule: "elementContentTooLong",
2457
+ errors: (entry) => {
2458
+ const elements = (entry && typeof entry === "object" ? entry.elements : void 0) ?? [];
2459
+ return checkElementContentTooLong(tree.rootNode, elements);
2460
+ }
2461
+ }
1973
2462
  ];
1974
2463
  for (const { rule, errors: getErrors } of ruleChecks) {
1975
- const severity = resolveRuleSeverity(effectiveRules, rule);
2464
+ const { severity, entry } = resolveRuleConfig(effectiveRules, rule);
1976
2465
  if (severity === "off") continue;
1977
- for (const error of getErrors()) {
2466
+ for (const error of getErrors(entry)) {
1978
2467
  errors.push({
1979
2468
  node: error.node,
1980
2469
  message: error.message,
@@ -1999,7 +2488,7 @@ function collectErrors(tree, rules, customTagNames, customRules) {
1999
2488
  }
2000
2489
  }
2001
2490
  return errors.filter(
2002
- (e) => !(e.message.includes("HTML comment found") && parseDisableDirective(e.node, customRuleIds) !== null)
2491
+ (e2) => !(e2.message.includes("HTML comment found") && parseDisableDirective(e2.node, customRuleIds) !== null)
2003
2492
  );
2004
2493
  }
2005
2494
 
@@ -2029,12 +2518,12 @@ function formatError(error, source) {
2029
2518
  const contextStart = Math.max(0, errorLine - 2);
2030
2519
  const contextEnd = Math.min(lines.length - 1, error.endLine - 1);
2031
2520
  const gutterWidth = String(contextEnd + 1).length;
2032
- const pad = (n) => String(n).padStart(gutterWidth);
2521
+ const pad = (n2) => String(n2).padStart(gutterWidth);
2033
2522
  const outputLines = [header];
2034
2523
  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]);
2524
+ for (let i2 = contextStart; i2 <= contextEnd; i2++) {
2525
+ const lineNum = i2 + 1;
2526
+ outputLines.push(source_default.dim(`${pad(lineNum)} |`) + " " + lines[i2]);
2038
2527
  }
2039
2528
  const lastErrorLineIdx = error.endLine - 1;
2040
2529
  const lastLine = lines[lastErrorLineIdx] || "";
@@ -2108,7 +2597,7 @@ function resolveFiles(cliPatterns) {
2108
2597
  return { files: [], config };
2109
2598
  }
2110
2599
  let files = expandGlobs(patterns);
2111
- files = files.filter((f) => !DEFAULT_EXCLUDE_SEGMENTS.some((seg) => f.includes(seg)));
2600
+ files = files.filter((f2) => !DEFAULT_EXCLUDE_SEGMENTS.some((seg) => f2.includes(seg)));
2112
2601
  if (config?.exclude && config.exclude.length > 0) {
2113
2602
  const cwd = process.cwd();
2114
2603
  const excludeSet = /* @__PURE__ */ new Set();
@@ -2121,7 +2610,7 @@ function resolveFiles(cliPatterns) {
2121
2610
  }
2122
2611
  }
2123
2612
  }
2124
- files = files.filter((f) => !excludeSet.has(f));
2613
+ files = files.filter((f2) => !excludeSet.has(f2));
2125
2614
  }
2126
2615
  return { files, config };
2127
2616
  }
@@ -2133,13 +2622,13 @@ function applyFixes(source, errors) {
2133
2622
  }
2134
2623
  }
2135
2624
  if (replacements.length === 0) return source;
2136
- replacements.sort((a, b) => b.startIndex - a.startIndex);
2625
+ replacements.sort((a2, b) => b.startIndex - a2.startIndex);
2137
2626
  let result = source;
2138
2627
  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;
2628
+ for (const r2 of replacements) {
2629
+ if (r2.endIndex > minIndex) continue;
2630
+ result = result.slice(0, r2.startIndex) + r2.newText + result.slice(r2.endIndex);
2631
+ minIndex = r2.startIndex;
2143
2632
  }
2144
2633
  return result;
2145
2634
  }
@@ -2168,7 +2657,7 @@ async function run(args) {
2168
2657
  return 0;
2169
2658
  }
2170
2659
  const fixMode = args.includes("--fix");
2171
- const patterns = args.filter((a) => a !== "--fix");
2660
+ const patterns = args.filter((a2) => a2 !== "--fix");
2172
2661
  const { files, config } = resolveFiles(patterns);
2173
2662
  if (files.length === 0) {
2174
2663
  if (patterns.length === 0 && (!config?.include || config.include.length === 0)) {
@@ -2177,8 +2666,8 @@ async function run(args) {
2177
2666
  }
2178
2667
  const displayPatterns = patterns.length > 0 ? patterns : config?.include ?? [];
2179
2668
  console.error(source_default.yellow("No files matched the given patterns:"));
2180
- for (const p of displayPatterns) {
2181
- console.error(source_default.yellow(` ${p}`));
2669
+ for (const p2 of displayPatterns) {
2670
+ console.error(source_default.yellow(` ${p2}`));
2182
2671
  }
2183
2672
  return 1;
2184
2673
  }
@@ -2189,7 +2678,7 @@ async function run(args) {
2189
2678
  const cwd = process.cwd();
2190
2679
  const errorOutput = [];
2191
2680
  const rules = config?.rules;
2192
- const customTagNames = config?.customTags?.map((t) => t.name);
2681
+ const customTagNames = config?.customTags?.map((t2) => t2.name);
2193
2682
  const customRules = config?.customRules;
2194
2683
  for (const file of files) {
2195
2684
  const displayPath = import_node_path.default.relative(cwd, file) || file;
@@ -2205,8 +2694,8 @@ async function run(args) {
2205
2694
  }
2206
2695
  const tree = parseDocument(source);
2207
2696
  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");
2697
+ const fileErrors = errors.filter((e2) => e2.severity !== "warning");
2698
+ const fileWarnings = errors.filter((e2) => e2.severity === "warning");
2210
2699
  if (errors.length > 0) {
2211
2700
  filesWithErrors++;
2212
2701
  totalErrors += fileErrors.length;
@@ -2271,8 +2760,8 @@ var FullTextDocument = class _FullTextDocument {
2271
2760
  let lineOffsets = this._lineOffsets;
2272
2761
  const addedLineOffsets = computeLineOffsets(change.text, false, startOffset);
2273
2762
  if (endLine - startLine === addedLineOffsets.length) {
2274
- for (let i = 0, len = addedLineOffsets.length; i < len; i++) {
2275
- lineOffsets[i + startLine + 1] = addedLineOffsets[i];
2763
+ for (let i2 = 0, len = addedLineOffsets.length; i2 < len; i2++) {
2764
+ lineOffsets[i2 + startLine + 1] = addedLineOffsets[i2];
2276
2765
  }
2277
2766
  } else {
2278
2767
  if (addedLineOffsets.length < 1e4) {
@@ -2283,8 +2772,8 @@ var FullTextDocument = class _FullTextDocument {
2283
2772
  }
2284
2773
  const diff = change.text.length - (endOffset - startOffset);
2285
2774
  if (diff !== 0) {
2286
- for (let i = startLine + 1 + addedLineOffsets.length, len = lineOffsets.length; i < len; i++) {
2287
- lineOffsets[i] = lineOffsets[i] + diff;
2775
+ for (let i2 = startLine + 1 + addedLineOffsets.length, len = lineOffsets.length; i2 < len; i2++) {
2776
+ lineOffsets[i2] = lineOffsets[i2] + diff;
2288
2777
  }
2289
2778
  }
2290
2779
  } else if (_FullTextDocument.isFull(change)) {
@@ -2371,26 +2860,26 @@ var TextDocument;
2371
2860
  TextDocument2.update = update;
2372
2861
  function applyEdits(document, edits) {
2373
2862
  const text2 = document.getText();
2374
- const sortedEdits = mergeSort(edits.map(getWellformedEdit), (a, b) => {
2375
- const diff = a.range.start.line - b.range.start.line;
2863
+ const sortedEdits = mergeSort(edits.map(getWellformedEdit), (a2, b) => {
2864
+ const diff = a2.range.start.line - b.range.start.line;
2376
2865
  if (diff === 0) {
2377
- return a.range.start.character - b.range.start.character;
2866
+ return a2.range.start.character - b.range.start.character;
2378
2867
  }
2379
2868
  return diff;
2380
2869
  });
2381
2870
  let lastModifiedOffset = 0;
2382
2871
  const spans = [];
2383
- for (const e of sortedEdits) {
2384
- const startOffset = document.offsetAt(e.range.start);
2872
+ for (const e2 of sortedEdits) {
2873
+ const startOffset = document.offsetAt(e2.range.start);
2385
2874
  if (startOffset < lastModifiedOffset) {
2386
2875
  throw new Error("Overlapping edit");
2387
2876
  } else if (startOffset > lastModifiedOffset) {
2388
2877
  spans.push(text2.substring(lastModifiedOffset, startOffset));
2389
2878
  }
2390
- if (e.newText.length) {
2391
- spans.push(e.newText);
2879
+ if (e2.newText.length) {
2880
+ spans.push(e2.newText);
2392
2881
  }
2393
- lastModifiedOffset = document.offsetAt(e.range.end);
2882
+ lastModifiedOffset = document.offsetAt(e2.range.end);
2394
2883
  }
2395
2884
  spans.push(text2.substr(lastModifiedOffset));
2396
2885
  return spans.join("");
@@ -2401,39 +2890,39 @@ function mergeSort(data, compare) {
2401
2890
  if (data.length <= 1) {
2402
2891
  return data;
2403
2892
  }
2404
- const p = data.length / 2 | 0;
2405
- const left = data.slice(0, p);
2406
- const right = data.slice(p);
2893
+ const p2 = data.length / 2 | 0;
2894
+ const left = data.slice(0, p2);
2895
+ const right = data.slice(p2);
2407
2896
  mergeSort(left, compare);
2408
2897
  mergeSort(right, compare);
2409
2898
  let leftIdx = 0;
2410
2899
  let rightIdx = 0;
2411
- let i = 0;
2900
+ let i2 = 0;
2412
2901
  while (leftIdx < left.length && rightIdx < right.length) {
2413
2902
  const ret = compare(left[leftIdx], right[rightIdx]);
2414
2903
  if (ret <= 0) {
2415
- data[i++] = left[leftIdx++];
2904
+ data[i2++] = left[leftIdx++];
2416
2905
  } else {
2417
- data[i++] = right[rightIdx++];
2906
+ data[i2++] = right[rightIdx++];
2418
2907
  }
2419
2908
  }
2420
2909
  while (leftIdx < left.length) {
2421
- data[i++] = left[leftIdx++];
2910
+ data[i2++] = left[leftIdx++];
2422
2911
  }
2423
2912
  while (rightIdx < right.length) {
2424
- data[i++] = right[rightIdx++];
2913
+ data[i2++] = right[rightIdx++];
2425
2914
  }
2426
2915
  return data;
2427
2916
  }
2428
2917
  function computeLineOffsets(text2, isAtLineStart, textOffset = 0) {
2429
2918
  const result = isAtLineStart ? [textOffset] : [];
2430
- for (let i = 0; i < text2.length; i++) {
2431
- const ch = text2.charCodeAt(i);
2919
+ for (let i2 = 0; i2 < text2.length; i2++) {
2920
+ const ch = text2.charCodeAt(i2);
2432
2921
  if (isEOL(ch)) {
2433
- if (ch === 13 && i + 1 < text2.length && text2.charCodeAt(i + 1) === 10) {
2434
- i++;
2922
+ if (ch === 13 && i2 + 1 < text2.length && text2.charCodeAt(i2 + 1) === 10) {
2923
+ i2++;
2435
2924
  }
2436
- result.push(textOffset + i + 1);
2925
+ result.push(textOffset + i2 + 1);
2437
2926
  }
2438
2927
  }
2439
2928
  return result;
@@ -2466,8 +2955,8 @@ function print(doc, options) {
2466
2955
  }
2467
2956
  function currentColumn(output) {
2468
2957
  let col = 0;
2469
- for (let i = output.length - 1; i >= 0; i--) {
2470
- const chunk = output[i];
2958
+ for (let i2 = output.length - 1; i2 >= 0; i2--) {
2959
+ const chunk = output[i2];
2471
2960
  const nlIndex = chunk.lastIndexOf("\n");
2472
2961
  if (nlIndex !== -1) {
2473
2962
  col += chunk.length - nlIndex - 1;
@@ -2577,12 +3066,12 @@ function printDoc(doc, state, output, options) {
2577
3066
  function printFill(parts, state, output, options) {
2578
3067
  if (parts.length === 0) return;
2579
3068
  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;
3069
+ for (let i2 = 0; i2 < parts.length; i2++) {
3070
+ const content = parts[i2];
3071
+ const separator = i2 + 1 < parts.length ? parts[i2 + 1] : null;
2583
3072
  printDoc(content, state, output, options);
2584
3073
  if (separator === null) break;
2585
- const nextContent = i + 2 < parts.length ? parts[i + 2] : null;
3074
+ const nextContent = i2 + 2 < parts.length ? parts[i2 + 2] : null;
2586
3075
  if (nextContent !== null) {
2587
3076
  const testOutput = [];
2588
3077
  const flatState = { ...state, mode: "flat" };
@@ -2600,7 +3089,7 @@ function printFill(parts, state, output, options) {
2600
3089
  } else {
2601
3090
  printDoc(separator, state, output, options);
2602
3091
  }
2603
- i++;
3092
+ i2++;
2604
3093
  }
2605
3094
  }
2606
3095
  function makeIndent(level, options) {
@@ -2633,10 +3122,10 @@ function indent(contents) {
2633
3122
  if (contents === "") return "";
2634
3123
  return { type: "indent", contents };
2635
3124
  }
2636
- function indentN(contents, n) {
2637
- if (n <= 0 || contents === "") return contents;
3125
+ function indentN(contents, n2) {
3126
+ if (n2 <= 0 || contents === "") return contents;
2638
3127
  let result = contents;
2639
- for (let i = 0; i < n; i++) {
3128
+ for (let i2 = 0; i2 < n2; i2++) {
2640
3129
  result = indent(result);
2641
3130
  }
2642
3131
  return result;
@@ -2650,7 +3139,7 @@ function ifBreak(breakContents, flatContents, options) {
2650
3139
  return { type: "ifBreak", breakContents, flatContents, groupId: options?.groupId };
2651
3140
  }
2652
3141
  function fill(parts) {
2653
- const filtered = parts.filter((p) => p !== "");
3142
+ const filtered = parts.filter((p2) => p2 !== "");
2654
3143
  if (filtered.length === 0) return "";
2655
3144
  if (filtered.length === 1) return filtered[0];
2656
3145
  return { type: "fill", parts: filtered };
@@ -2661,12 +3150,12 @@ function isLine(doc) {
2661
3150
 
2662
3151
  // lsp/server/src/formatting/utils.ts
2663
3152
  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");
3153
+ 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
3154
  }
2666
3155
  function getVisibleChildren(node) {
2667
3156
  const children = [];
2668
- for (let i = 0; i < node.childCount; i++) {
2669
- const child = node.child(i);
3157
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3158
+ const child = node.child(i2);
2670
3159
  if (child && !child.type.startsWith("_")) {
2671
3160
  children.push(child);
2672
3161
  }
@@ -2697,8 +3186,8 @@ ${middle.join("\n")}
2697
3186
  ${last} }}`;
2698
3187
  }
2699
3188
  const trimmed = inner.trim();
2700
- const s = prefix === "!" ? " " : space;
2701
- return `{{${prefix}${s}${trimmed}${s}}}`;
3189
+ const s2 = prefix === "!" ? " " : space;
3190
+ return `{{${prefix}${s2}${trimmed}${s2}}}`;
2702
3191
  }
2703
3192
  const plainMatch = raw.match(/^\{\{([\s\S]*)\}\}$/);
2704
3193
  if (plainMatch) {
@@ -2740,8 +3229,8 @@ function isCodeTag(config) {
2740
3229
  return !!(config.languageAttribute || config.languageDefault);
2741
3230
  }
2742
3231
  function getAttributeValue(node, attrName) {
2743
- for (let i = 0; i < node.childCount; i++) {
2744
- const child = node.child(i);
3232
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3233
+ const child = node.child(i2);
2745
3234
  if (child?.type === "html_start_tag") {
2746
3235
  for (let j = 0; j < child.childCount; j++) {
2747
3236
  const attr = child.child(j);
@@ -2958,8 +3447,8 @@ function getContentNodes(sectionNode) {
2958
3447
  const beginType = isInverted ? "mustache_inverted_section_begin" : "mustache_section_begin";
2959
3448
  const endType = isInverted ? "mustache_inverted_section_end" : "mustache_section_end";
2960
3449
  const contentNodes = [];
2961
- for (let i = 0; i < sectionNode.childCount; i++) {
2962
- const child = sectionNode.child(i);
3450
+ for (let i2 = 0; i2 < sectionNode.childCount; i2++) {
3451
+ const child = sectionNode.child(i2);
2963
3452
  if (!child) continue;
2964
3453
  if (child.type !== beginType && child.type !== endType && child.type !== "mustache_erroneous_section_end" && child.type !== "mustache_erroneous_inverted_section_end" && !child.type.startsWith("_")) {
2965
3454
  contentNodes.push(child);
@@ -2980,8 +3469,8 @@ function hasImplicitEndTagsRecursive(node) {
2980
3469
  let hasStartTag = false;
2981
3470
  let hasEndTag = false;
2982
3471
  let hasContentChildren = false;
2983
- for (let i = 0; i < node.childCount; i++) {
2984
- const child = node.child(i);
3472
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3473
+ const child = node.child(i2);
2985
3474
  if (!child) continue;
2986
3475
  if (child.type === "html_start_tag") hasStartTag = true;
2987
3476
  else if (child.type === "html_end_tag") hasEndTag = true;
@@ -2990,8 +3479,8 @@ function hasImplicitEndTagsRecursive(node) {
2990
3479
  }
2991
3480
  if (hasStartTag && !hasEndTag && hasContentChildren) return true;
2992
3481
  }
2993
- for (let i = 0; i < node.childCount; i++) {
2994
- const child = node.child(i);
3482
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3483
+ const child = node.child(i2);
2995
3484
  if (child && hasImplicitEndTagsRecursive(child)) {
2996
3485
  return true;
2997
3486
  }
@@ -3018,16 +3507,16 @@ function isInTextFlow(node, index, nodes) {
3018
3507
  return false;
3019
3508
  }
3020
3509
  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;
3510
+ for (let i2 = index - 1; i2 >= 0; i2--) {
3511
+ const n2 = nodes[i2];
3512
+ if (n2.type === "text" && n2.text.trim().length === 0) continue;
3513
+ if (isInlineContentNode(n2)) return true;
3025
3514
  break;
3026
3515
  }
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;
3516
+ for (let i2 = index + 1; i2 < nodes.length; i2++) {
3517
+ const n2 = nodes[i2];
3518
+ if (n2.type === "text" && n2.text.trim().length === 0) continue;
3519
+ if (isInlineContentNode(n2)) return true;
3031
3520
  break;
3032
3521
  }
3033
3522
  return false;
@@ -3083,15 +3572,15 @@ function dedentContent(rawContent) {
3083
3572
  }
3084
3573
  if (lines.length === 0) return "";
3085
3574
  let minIndent = Infinity;
3086
- for (const l of lines) {
3087
- if (l.trim() === "") continue;
3088
- const match = l.match(/^(\s*)/);
3575
+ for (const l2 of lines) {
3576
+ if (l2.trim() === "") continue;
3577
+ const match = l2.match(/^(\s*)/);
3089
3578
  if (match && match[1].length < minIndent) {
3090
3579
  minIndent = match[1].length;
3091
3580
  }
3092
3581
  }
3093
3582
  if (minIndent === Infinity) minIndent = 0;
3094
- return lines.map((l) => l.trim() === "" ? "" : l.slice(minIndent)).join("\n");
3583
+ return lines.map((l2) => l2.trim() === "" ? "" : l2.slice(minIndent)).join("\n");
3095
3584
  }
3096
3585
  function resolveIndentMode(node, config) {
3097
3586
  const mode = config.indent ?? "never";
@@ -3102,8 +3591,8 @@ function resolveIndentMode(node, config) {
3102
3591
  return isAttributeTruthy(value);
3103
3592
  }
3104
3593
  function getTagNameFromStartTag(startTag) {
3105
- for (let i = 0; i < startTag.childCount; i++) {
3106
- const child = startTag.child(i);
3594
+ for (let i2 = 0; i2 < startTag.childCount; i2++) {
3595
+ const child = startTag.child(i2);
3107
3596
  if (child?.type === "html_tag_name") return child.text.toLowerCase();
3108
3597
  }
3109
3598
  return null;
@@ -3172,8 +3661,8 @@ function formatHtmlElement(node, context, forceInline = false) {
3172
3661
  let endTag = null;
3173
3662
  let hasRealEndTag = false;
3174
3663
  const contentNodes = [];
3175
- for (let i = 0; i < node.childCount; i++) {
3176
- const child = node.child(i);
3664
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3665
+ const child = node.child(i2);
3177
3666
  if (!child) continue;
3178
3667
  if (child.type === "html_start_tag") {
3179
3668
  startTag = child;
@@ -3273,8 +3762,8 @@ function formatHtmlElement(node, context, forceInline = false) {
3273
3762
  const formattedContent = formatBlockChildren(contentNodes, context);
3274
3763
  const hasContent = hasDocContent(formattedContent);
3275
3764
  if (hasContent) {
3276
- const hasBlockChildren = contentNodes.some((child, i) => {
3277
- if (!shouldTreatAsBlock(child, i, contentNodes, tags)) {
3765
+ const hasBlockChildren = contentNodes.some((child, i2) => {
3766
+ if (!shouldTreatAsBlock(child, i2, contentNodes, tags)) {
3278
3767
  return false;
3279
3768
  }
3280
3769
  const childDisplay = getCSSDisplay(child, tags);
@@ -3330,8 +3819,8 @@ function formatHtmlElement(node, context, forceInline = false) {
3330
3819
  }
3331
3820
  function formatScriptStyleElement(node, context) {
3332
3821
  const parts = [];
3333
- for (let i = 0; i < node.childCount; i++) {
3334
- const child = node.child(i);
3822
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3823
+ const child = node.child(i2);
3335
3824
  if (!child) continue;
3336
3825
  if (child.type === "html_start_tag") {
3337
3826
  parts.push(formatStartTag(child, context));
@@ -3415,8 +3904,8 @@ function formatMustacheSection(node, context) {
3415
3904
  let beginNode = null;
3416
3905
  let endNode = null;
3417
3906
  const contentNodes = [];
3418
- for (let i = 0; i < node.childCount; i++) {
3419
- const child = node.child(i);
3907
+ for (let i2 = 0; i2 < node.childCount; i2++) {
3908
+ const child = node.child(i2);
3420
3909
  if (!child) continue;
3421
3910
  if (child.type === beginType) {
3422
3911
  beginNode = child;
@@ -3431,7 +3920,7 @@ function formatMustacheSection(node, context) {
3431
3920
  parts.push(text(mustacheText(beginNode.text, context)));
3432
3921
  }
3433
3922
  const hasImplicit = hasImplicitEndTags(contentNodes);
3434
- const erroneousCount = contentNodes.filter((n) => n.type === "html_erroneous_end_tag").length;
3923
+ const erroneousCount = contentNodes.filter((n2) => n2.type === "html_erroneous_end_tag").length;
3435
3924
  const hasStaircase = !hasImplicit && erroneousCount > 0;
3436
3925
  if (hasStaircase) {
3437
3926
  let virtualDepth = erroneousCount - 1;
@@ -3485,8 +3974,8 @@ function formatMustacheSection(node, context) {
3485
3974
  parts.push(formattedContent);
3486
3975
  parts.push(hardline);
3487
3976
  } else {
3488
- const hasBlockChildren = contentNodes.some((child, i) => {
3489
- if (!shouldTreatAsBlock(child, i, contentNodes, context.customTags)) {
3977
+ const hasBlockChildren = contentNodes.some((child, i2) => {
3978
+ if (!shouldTreatAsBlock(child, i2, contentNodes, context.customTags)) {
3490
3979
  return false;
3491
3980
  }
3492
3981
  const childDisplay = getCSSDisplay(child, context.customTags);
@@ -3508,8 +3997,8 @@ function formatMustacheSection(node, context) {
3508
3997
  return group(concat(parts));
3509
3998
  }
3510
3999
  function startTagHasAttributes(startTag) {
3511
- for (let i = 0; i < startTag.childCount; i++) {
3512
- const child = startTag.child(i);
4000
+ for (let i2 = 0; i2 < startTag.childCount; i2++) {
4001
+ const child = startTag.child(i2);
3513
4002
  if (!child) continue;
3514
4003
  if (child.type === "html_attribute" || child.type === "mustache_attribute" || child.type === "mustache_interpolation" || child.type === "mustache_triple") {
3515
4004
  return true;
@@ -3520,8 +4009,8 @@ function startTagHasAttributes(startTag) {
3520
4009
  function formatStartTag(node, context, bare = false) {
3521
4010
  let tagNameText = "";
3522
4011
  const attrs = [];
3523
- for (let i = 0; i < node.childCount; i++) {
3524
- const child = node.child(i);
4012
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4013
+ const child = node.child(i2);
3525
4014
  if (!child) continue;
3526
4015
  if (child.type === "html_tag_name") {
3527
4016
  tagNameText = child.text;
@@ -3543,11 +4032,11 @@ function formatStartTag(node, context, bare = false) {
3543
4032
  return text("<" + tagNameText + closingBracket);
3544
4033
  }
3545
4034
  const attrParts = [];
3546
- for (let i = 0; i < attrs.length; i++) {
3547
- if (i > 0) {
4035
+ for (let i2 = 0; i2 < attrs.length; i2++) {
4036
+ if (i2 > 0) {
3548
4037
  attrParts.push(line);
3549
4038
  }
3550
- attrParts.push(attrs[i]);
4039
+ attrParts.push(attrs[i2]);
3551
4040
  }
3552
4041
  const breakClosingBracket = isSelfClosing ? "/>" : ">";
3553
4042
  const inner = concat([
@@ -3559,8 +4048,8 @@ function formatStartTag(node, context, bare = false) {
3559
4048
  return bare ? inner : group(inner);
3560
4049
  }
3561
4050
  function formatEndTag(node) {
3562
- for (let i = 0; i < node.childCount; i++) {
3563
- const child = node.child(i);
4051
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4052
+ const child = node.child(i2);
3564
4053
  if (child && child.type === "html_tag_name") {
3565
4054
  return text("</" + child.text + ">");
3566
4055
  }
@@ -3569,8 +4058,8 @@ function formatEndTag(node) {
3569
4058
  }
3570
4059
  function formatAttribute(node, context) {
3571
4060
  const parts = [];
3572
- for (let i = 0; i < node.childCount; i++) {
3573
- const child = node.child(i);
4061
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4062
+ const child = node.child(i2);
3574
4063
  if (!child) continue;
3575
4064
  if (child.type === "html_attribute_name") {
3576
4065
  parts.push(text(child.text));
@@ -3595,21 +4084,21 @@ function textWords(str) {
3595
4084
  const words = str.split(/\s+/).filter((w) => w.length > 0);
3596
4085
  if (words.length === 0) return [];
3597
4086
  const parts = [words[0]];
3598
- for (let i = 1; i < words.length; i++) {
4087
+ for (let i2 = 1; i2 < words.length; i2++) {
3599
4088
  parts.push(line);
3600
- parts.push(words[i]);
4089
+ parts.push(words[i2]);
3601
4090
  }
3602
4091
  return parts;
3603
4092
  }
3604
4093
  function collapseDelimitedRegions(parts, delimiters) {
3605
4094
  if (delimiters.length === 0) return parts;
3606
4095
  const sorted = [...delimiters].sort(
3607
- (a, b) => Math.max(b.start.length, b.end.length) - Math.max(a.start.length, a.end.length)
4096
+ (a2, b) => Math.max(b.start.length, b.end.length) - Math.max(a2.start.length, a2.end.length)
3608
4097
  );
3609
4098
  const result = [...parts];
3610
4099
  let activeDelimiter = null;
3611
- for (let i = 0; i < result.length; i++) {
3612
- const part = result[i];
4100
+ for (let i2 = 0; i2 < result.length; i2++) {
4101
+ const part = result[i2];
3613
4102
  if (typeof part === "string") {
3614
4103
  if (activeDelimiter === null) {
3615
4104
  for (const delim of sorted) {
@@ -3630,7 +4119,7 @@ function collapseDelimitedRegions(parts, delimiters) {
3630
4119
  }
3631
4120
  }
3632
4121
  } else if (activeDelimiter !== null && isLine(part)) {
3633
- result[i] = " ";
4122
+ result[i2] = " ";
3634
4123
  }
3635
4124
  }
3636
4125
  return result;
@@ -3682,8 +4171,8 @@ function formatBlockChildren(nodes, context) {
3682
4171
  const parts2 = noBreakDelims ? collapseDelimitedRegions(currentLine, noBreakDelims) : currentLine;
3683
4172
  return inlineContentToFill(parts2);
3684
4173
  }
3685
- for (let i = 0; i < nodes.length; i++) {
3686
- const node = nodes[i];
4174
+ for (let i2 = 0; i2 < nodes.length; i2++) {
4175
+ const node = nodes[i2];
3687
4176
  if (lastNodeEnd >= 0 && node.startIndex > lastNodeEnd && !inIgnoreRegion) {
3688
4177
  const gap = context.document.getText().slice(lastNodeEnd, node.startIndex);
3689
4178
  const newlineCount = (gap.match(/\n/g) || []).length;
@@ -3756,10 +4245,10 @@ function formatBlockChildren(nodes, context) {
3756
4245
  lastNodeEnd = node.endIndex;
3757
4246
  continue;
3758
4247
  }
3759
- const treatAsBlock = shouldTreatAsBlock(node, i, nodes, context.customTags);
4248
+ const treatAsBlock = shouldTreatAsBlock(node, i2, nodes, context.customTags);
3760
4249
  if (lastNodeEnd >= 0 && node.startIndex > lastNodeEnd) {
3761
- const prevNode = nodes[i - 1];
3762
- const prevTreatAsBlock = shouldTreatAsBlock(prevNode, i - 1, nodes, context.customTags);
4250
+ const prevNode = nodes[i2 - 1];
4251
+ const prevTreatAsBlock = shouldTreatAsBlock(prevNode, i2 - 1, nodes, context.customTags);
3763
4252
  if (!prevTreatAsBlock && !treatAsBlock) {
3764
4253
  const gap = context.document.getText().slice(lastNodeEnd, node.startIndex);
3765
4254
  if (/\s/.test(gap)) {
@@ -3780,7 +4269,7 @@ function formatBlockChildren(nodes, context) {
3780
4269
  pendingBlankLine = false;
3781
4270
  } else if (node.type === "html_comment" || node.type === "mustache_comment") {
3782
4271
  const isMultiline = node.startPosition.row !== node.endPosition.row;
3783
- const isOnOwnLine = i > 0 && node.startPosition.row > nodes[i - 1].endPosition.row;
4272
+ const isOnOwnLine = i2 > 0 && node.startPosition.row > nodes[i2 - 1].endPosition.row;
3784
4273
  if (isMultiline || isOnOwnLine) {
3785
4274
  if (currentLine.length > 0) {
3786
4275
  const lineContent = trimDoc(flushCurrentLine());
@@ -3806,7 +4295,7 @@ function formatBlockChildren(nodes, context) {
3806
4295
  blankLineBeforeCurrentLine = pendingBlankLine;
3807
4296
  pendingBlankLine = false;
3808
4297
  }
3809
- const forceInline = isInTextFlow(node, i, nodes);
4298
+ const forceInline = isInTextFlow(node, i2, nodes);
3810
4299
  const formatted = formatNode(node, context, forceInline);
3811
4300
  if (typeof formatted === "string" && formatted.includes("\n")) {
3812
4301
  const contentLines = formatted.split("\n");
@@ -3915,18 +4404,18 @@ function formatBlockChildren(nodes, context) {
3915
4404
  return empty;
3916
4405
  }
3917
4406
  const parts = [];
3918
- for (let i = 0; i < lines.length; i++) {
3919
- if (i > 0) {
3920
- if (lines[i].blankLineBefore) {
4407
+ for (let i2 = 0; i2 < lines.length; i2++) {
4408
+ if (i2 > 0) {
4409
+ if (lines[i2].blankLineBefore) {
3921
4410
  parts.push("\n");
3922
4411
  }
3923
- if (lines[i].rawLine) {
4412
+ if (lines[i2].rawLine) {
3924
4413
  parts.push("\n");
3925
4414
  } else {
3926
4415
  parts.push(hardline);
3927
4416
  }
3928
4417
  }
3929
- parts.push(lines[i].doc);
4418
+ parts.push(lines[i2].doc);
3930
4419
  }
3931
4420
  return concat(parts);
3932
4421
  }
@@ -4035,8 +4524,8 @@ function getEmbeddedLanguageId(node) {
4035
4524
  if (node.type === "html_style_element") {
4036
4525
  return "css";
4037
4526
  }
4038
- for (let i = 0; i < node.childCount; i++) {
4039
- const child = node.child(i);
4527
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4528
+ const child = node.child(i2);
4040
4529
  if (child?.type === "html_start_tag") {
4041
4530
  for (let j = 0; j < child.childCount; j++) {
4042
4531
  const attr = child.child(j);
@@ -4062,8 +4551,8 @@ function collectEmbeddedRegions(rootNode) {
4062
4551
  const regions = [];
4063
4552
  const walk = (node) => {
4064
4553
  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);
4554
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4555
+ const child = node.child(i2);
4067
4556
  if (child?.type === "html_raw_text") {
4068
4557
  regions.push({
4069
4558
  startIndex: child.startIndex,
@@ -4074,8 +4563,8 @@ function collectEmbeddedRegions(rootNode) {
4074
4563
  }
4075
4564
  return;
4076
4565
  }
4077
- for (let i = 0; i < node.childCount; i++) {
4078
- const child = node.child(i);
4566
+ for (let i2 = 0; i2 < node.childCount; i2++) {
4567
+ const child = node.child(i2);
4079
4568
  if (child) walk(child);
4080
4569
  }
4081
4570
  };
@@ -4115,9 +4604,9 @@ function parseFlags(args) {
4115
4604
  mustacheSpaces: void 0,
4116
4605
  patterns: []
4117
4606
  };
4118
- let i = 0;
4119
- while (i < args.length) {
4120
- const arg = args[i];
4607
+ let i2 = 0;
4608
+ while (i2 < args.length) {
4609
+ const arg = args[i2];
4121
4610
  switch (arg) {
4122
4611
  case "--write":
4123
4612
  flags.write = true;
@@ -4129,16 +4618,16 @@ function parseFlags(args) {
4129
4618
  flags.stdin = true;
4130
4619
  break;
4131
4620
  case "--indent-size":
4132
- i++;
4133
- flags.indentSize = parseInt(args[i], 10);
4621
+ i2++;
4622
+ flags.indentSize = parseInt(args[i2], 10);
4134
4623
  if (isNaN(flags.indentSize)) {
4135
4624
  console.error(source_default.red("Error: --indent-size requires a number"));
4136
4625
  process.exit(1);
4137
4626
  }
4138
4627
  break;
4139
4628
  case "--print-width":
4140
- i++;
4141
- flags.printWidth = parseInt(args[i], 10);
4629
+ i2++;
4630
+ flags.printWidth = parseInt(args[i2], 10);
4142
4631
  if (isNaN(flags.printWidth)) {
4143
4632
  console.error(source_default.red("Error: --print-width requires a number"));
4144
4633
  process.exit(1);
@@ -4151,7 +4640,7 @@ function parseFlags(args) {
4151
4640
  flags.patterns.push(arg);
4152
4641
  break;
4153
4642
  }
4154
- i++;
4643
+ i2++;
4155
4644
  }
4156
4645
  return flags;
4157
4646
  }