@intlayer/engine 9.5.9 → 9.5.11

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 (303) hide show
  1. package/dist/cjs/cli.cjs +7 -0
  2. package/dist/cjs/docReview/alignBlocks.cjs +53 -36
  3. package/dist/cjs/docReview/alignBlocks.cjs.map +1 -1
  4. package/dist/cjs/docReview/rebuildDocument.cjs +3 -1
  5. package/dist/cjs/docReview/rebuildDocument.cjs.map +1 -1
  6. package/dist/cjs/docReview/reviewReport.cjs.map +1 -1
  7. package/dist/cjs/docReview/segmentDocument.cjs +8 -5
  8. package/dist/cjs/docReview/segmentDocument.cjs.map +1 -1
  9. package/dist/cjs/init/cms.cjs +35 -0
  10. package/dist/cjs/init/cms.cjs.map +1 -1
  11. package/dist/cjs/init/documentationRouter.cjs +141 -0
  12. package/dist/cjs/init/documentationRouter.cjs.map +1 -0
  13. package/dist/cjs/init/frameworkSetup/backend/index.cjs +138 -0
  14. package/dist/cjs/init/frameworkSetup/backend/index.cjs.map +1 -0
  15. package/dist/cjs/init/frameworkSetup/backend/transforms.cjs +223 -0
  16. package/dist/cjs/init/frameworkSetup/backend/transforms.cjs.map +1 -0
  17. package/dist/cjs/init/frameworkSetup/index.cjs +9 -3
  18. package/dist/cjs/init/frameworkSetup/index.cjs.map +1 -1
  19. package/dist/cjs/init/frameworkSetup/localeRouting.cjs +13 -0
  20. package/dist/cjs/init/frameworkSetup/localeRouting.cjs.map +1 -0
  21. package/dist/cjs/init/frameworkSetup/nextAppRouter/index.cjs +34 -7
  22. package/dist/cjs/init/frameworkSetup/nextAppRouter/index.cjs.map +1 -1
  23. package/dist/cjs/init/frameworkSetup/nextAppRouter/templates.cjs +56 -0
  24. package/dist/cjs/init/frameworkSetup/nextAppRouter/templates.cjs.map +1 -1
  25. package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs +6 -3
  26. package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs.map +1 -1
  27. package/dist/cjs/init/frameworkSetup/tanstackStart/index.cjs +32 -3
  28. package/dist/cjs/init/frameworkSetup/tanstackStart/index.cjs.map +1 -1
  29. package/dist/cjs/init/frameworkSetup/tanstackStart/templates.cjs +58 -0
  30. package/dist/cjs/init/frameworkSetup/tanstackStart/templates.cjs.map +1 -1
  31. package/dist/cjs/init/frameworkSetup/tanstackStart/transforms.cjs +94 -14
  32. package/dist/cjs/init/frameworkSetup/tanstackStart/transforms.cjs.map +1 -1
  33. package/dist/cjs/init/index.cjs +46 -159
  34. package/dist/cjs/init/index.cjs.map +1 -1
  35. package/dist/cjs/init/utils/configManipulation.cjs +39 -0
  36. package/dist/cjs/init/utils/configManipulation.cjs.map +1 -1
  37. package/dist/cjs/init/utils/index.cjs +10 -0
  38. package/dist/cjs/init/utils/lintConfig.cjs +52 -0
  39. package/dist/cjs/init/utils/lintConfig.cjs.map +1 -0
  40. package/dist/cjs/init/utils/packageManager.cjs +62 -13
  41. package/dist/cjs/init/utils/packageManager.cjs.map +1 -1
  42. package/dist/cjs/init/utils/urlRoutingFramework.cjs +41 -0
  43. package/dist/cjs/init/utils/urlRoutingFramework.cjs.map +1 -0
  44. package/dist/cjs/initConfig/index.cjs +4 -1
  45. package/dist/cjs/initConfig/index.cjs.map +1 -1
  46. package/dist/cjs/installMCP/installMCP.cjs +1 -1
  47. package/dist/cjs/installMCP/installMCP.cjs.map +1 -1
  48. package/dist/cjs/loadDictionaries/loadLocalDictionaries.cjs +3 -1
  49. package/dist/cjs/loadDictionaries/loadLocalDictionaries.cjs.map +1 -1
  50. package/dist/cjs/loadDictionaries/loadRemoteDictionaries.cjs +1 -1
  51. package/dist/cjs/loadDictionaries/loadRemoteDictionaries.cjs.map +1 -1
  52. package/dist/cjs/loadDictionaries/log.cjs +1 -1
  53. package/dist/cjs/loadDictionaries/log.cjs.map +1 -1
  54. package/dist/cjs/loadDictionaries/logTypeScriptErrors.cjs +111 -43
  55. package/dist/cjs/loadDictionaries/logTypeScriptErrors.cjs.map +1 -1
  56. package/dist/cjs/scan/analyzeBundleContent.cjs +26 -12
  57. package/dist/cjs/scan/analyzeBundleContent.cjs.map +1 -1
  58. package/dist/cjs/scan/calculateScore.cjs +4 -1
  59. package/dist/cjs/scan/calculateScore.cjs.map +1 -1
  60. package/dist/cjs/scan/checks.cjs +394 -221
  61. package/dist/cjs/scan/checks.cjs.map +1 -1
  62. package/dist/cjs/scan/detection/checkDetails.cjs +56 -0
  63. package/dist/cjs/scan/detection/checkDetails.cjs.map +1 -0
  64. package/dist/cjs/scan/detection/classifyInternalLinks.cjs +47 -0
  65. package/dist/cjs/scan/detection/classifyInternalLinks.cjs.map +1 -0
  66. package/dist/cjs/scan/detection/detectRoutingStrategy.cjs +143 -0
  67. package/dist/cjs/scan/detection/detectRoutingStrategy.cjs.map +1 -0
  68. package/dist/cjs/scan/detection/detectTechnologies.cjs +89 -0
  69. package/dist/cjs/scan/detection/detectTechnologies.cjs.map +1 -0
  70. package/dist/cjs/scan/detection/index.cjs +36 -0
  71. package/dist/cjs/scan/detection/localeCode.cjs +118 -0
  72. package/dist/cjs/scan/detection/localeCode.cjs.map +1 -0
  73. package/dist/cjs/scan/detection/localizedPages.cjs +48 -0
  74. package/dist/cjs/scan/detection/localizedPages.cjs.map +1 -0
  75. package/dist/cjs/scan/detection/technologySignatures.cjs +564 -0
  76. package/dist/cjs/scan/detection/technologySignatures.cjs.map +1 -0
  77. package/dist/cjs/scan/detection/url.cjs +53 -0
  78. package/dist/cjs/scan/detection/url.cjs.map +1 -0
  79. package/dist/cjs/scan/fetchText.cjs +56 -0
  80. package/dist/cjs/scan/fetchText.cjs.map +1 -0
  81. package/dist/cjs/scan/index.cjs +59 -3
  82. package/dist/cjs/scan/parseHtml.cjs +55 -10
  83. package/dist/cjs/scan/parseHtml.cjs.map +1 -1
  84. package/dist/cjs/scan/robots.cjs +65 -0
  85. package/dist/cjs/scan/robots.cjs.map +1 -0
  86. package/dist/cjs/scan/runScanChecks.cjs +89 -0
  87. package/dist/cjs/scan/runScanChecks.cjs.map +1 -0
  88. package/dist/cjs/scan/scanWebsite.cjs +58 -52
  89. package/dist/cjs/scan/scanWebsite.cjs.map +1 -1
  90. package/dist/cjs/scan/sitemap.cjs +109 -0
  91. package/dist/cjs/scan/sitemap.cjs.map +1 -0
  92. package/dist/cjs/utils/chunkJSON.cjs +24 -9
  93. package/dist/cjs/utils/chunkJSON.cjs.map +1 -1
  94. package/dist/cjs/utils/getChunk.cjs +2 -2
  95. package/dist/cjs/utils/getChunk.cjs.map +1 -1
  96. package/dist/cjs/utils/runParallel/index.cjs +1 -1
  97. package/dist/cjs/utils/runParallel/index.cjs.map +1 -1
  98. package/dist/cjs/utils/runParallel/pidTree.cjs +23 -11
  99. package/dist/cjs/utils/runParallel/pidTree.cjs.map +1 -1
  100. package/dist/cjs/utils/runParallel/ps.cjs +8 -3
  101. package/dist/cjs/utils/runParallel/ps.cjs.map +1 -1
  102. package/dist/cjs/utils/runParallel/runTask.cjs +2 -1
  103. package/dist/cjs/utils/runParallel/runTask.cjs.map +1 -1
  104. package/dist/cjs/utils/runParallel/wmic.cjs +8 -3
  105. package/dist/cjs/utils/runParallel/wmic.cjs.map +1 -1
  106. package/dist/cjs/writeContentDeclaration/detectExportedComponentName.cjs +7 -4
  107. package/dist/cjs/writeContentDeclaration/detectExportedComponentName.cjs.map +1 -1
  108. package/dist/cjs/writeContentDeclaration/writeMarkdownFile.cjs +2 -2
  109. package/dist/cjs/writeContentDeclaration/writeMarkdownFile.cjs.map +1 -1
  110. package/dist/esm/cli.mjs +5 -3
  111. package/dist/esm/docReview/alignBlocks.mjs +53 -36
  112. package/dist/esm/docReview/alignBlocks.mjs.map +1 -1
  113. package/dist/esm/docReview/rebuildDocument.mjs +3 -1
  114. package/dist/esm/docReview/rebuildDocument.mjs.map +1 -1
  115. package/dist/esm/docReview/reviewReport.mjs.map +1 -1
  116. package/dist/esm/docReview/segmentDocument.mjs +8 -5
  117. package/dist/esm/docReview/segmentDocument.mjs.map +1 -1
  118. package/dist/esm/init/cms.mjs +35 -2
  119. package/dist/esm/init/cms.mjs.map +1 -1
  120. package/dist/esm/init/documentationRouter.mjs +139 -0
  121. package/dist/esm/init/documentationRouter.mjs.map +1 -0
  122. package/dist/esm/init/frameworkSetup/backend/index.mjs +130 -0
  123. package/dist/esm/init/frameworkSetup/backend/index.mjs.map +1 -0
  124. package/dist/esm/init/frameworkSetup/backend/transforms.mjs +216 -0
  125. package/dist/esm/init/frameworkSetup/backend/transforms.mjs.map +1 -0
  126. package/dist/esm/init/frameworkSetup/index.mjs +9 -3
  127. package/dist/esm/init/frameworkSetup/index.mjs.map +1 -1
  128. package/dist/esm/init/frameworkSetup/localeRouting.mjs +12 -0
  129. package/dist/esm/init/frameworkSetup/localeRouting.mjs.map +1 -0
  130. package/dist/esm/init/frameworkSetup/nextAppRouter/index.mjs +36 -9
  131. package/dist/esm/init/frameworkSetup/nextAppRouter/index.mjs.map +1 -1
  132. package/dist/esm/init/frameworkSetup/nextAppRouter/templates.mjs +54 -1
  133. package/dist/esm/init/frameworkSetup/nextAppRouter/templates.mjs.map +1 -1
  134. package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs +6 -3
  135. package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs.map +1 -1
  136. package/dist/esm/init/frameworkSetup/tanstackStart/index.mjs +35 -6
  137. package/dist/esm/init/frameworkSetup/tanstackStart/index.mjs.map +1 -1
  138. package/dist/esm/init/frameworkSetup/tanstackStart/templates.mjs +56 -1
  139. package/dist/esm/init/frameworkSetup/tanstackStart/templates.mjs.map +1 -1
  140. package/dist/esm/init/frameworkSetup/tanstackStart/transforms.mjs +94 -15
  141. package/dist/esm/init/frameworkSetup/tanstackStart/transforms.mjs.map +1 -1
  142. package/dist/esm/init/index.mjs +42 -158
  143. package/dist/esm/init/index.mjs.map +1 -1
  144. package/dist/esm/init/utils/configManipulation.mjs +38 -1
  145. package/dist/esm/init/utils/configManipulation.mjs.map +1 -1
  146. package/dist/esm/init/utils/index.mjs +5 -3
  147. package/dist/esm/init/utils/lintConfig.mjs +50 -0
  148. package/dist/esm/init/utils/lintConfig.mjs.map +1 -0
  149. package/dist/esm/init/utils/packageManager.mjs +60 -14
  150. package/dist/esm/init/utils/packageManager.mjs.map +1 -1
  151. package/dist/esm/init/utils/urlRoutingFramework.mjs +40 -0
  152. package/dist/esm/init/utils/urlRoutingFramework.mjs.map +1 -0
  153. package/dist/esm/initConfig/index.mjs +4 -1
  154. package/dist/esm/initConfig/index.mjs.map +1 -1
  155. package/dist/esm/installMCP/installMCP.mjs +1 -1
  156. package/dist/esm/installMCP/installMCP.mjs.map +1 -1
  157. package/dist/esm/loadDictionaries/loadLocalDictionaries.mjs +3 -1
  158. package/dist/esm/loadDictionaries/loadLocalDictionaries.mjs.map +1 -1
  159. package/dist/esm/loadDictionaries/loadRemoteDictionaries.mjs +1 -1
  160. package/dist/esm/loadDictionaries/loadRemoteDictionaries.mjs.map +1 -1
  161. package/dist/esm/loadDictionaries/log.mjs +1 -1
  162. package/dist/esm/loadDictionaries/log.mjs.map +1 -1
  163. package/dist/esm/loadDictionaries/logTypeScriptErrors.mjs +112 -44
  164. package/dist/esm/loadDictionaries/logTypeScriptErrors.mjs.map +1 -1
  165. package/dist/esm/scan/analyzeBundleContent.mjs +26 -12
  166. package/dist/esm/scan/analyzeBundleContent.mjs.map +1 -1
  167. package/dist/esm/scan/calculateScore.mjs +4 -1
  168. package/dist/esm/scan/calculateScore.mjs.map +1 -1
  169. package/dist/esm/scan/checks.mjs +387 -220
  170. package/dist/esm/scan/checks.mjs.map +1 -1
  171. package/dist/esm/scan/detection/checkDetails.mjs +54 -0
  172. package/dist/esm/scan/detection/checkDetails.mjs.map +1 -0
  173. package/dist/esm/scan/detection/classifyInternalLinks.mjs +46 -0
  174. package/dist/esm/scan/detection/classifyInternalLinks.mjs.map +1 -0
  175. package/dist/esm/scan/detection/detectRoutingStrategy.mjs +141 -0
  176. package/dist/esm/scan/detection/detectRoutingStrategy.mjs.map +1 -0
  177. package/dist/esm/scan/detection/detectTechnologies.mjs +87 -0
  178. package/dist/esm/scan/detection/detectTechnologies.mjs.map +1 -0
  179. package/dist/esm/scan/detection/index.mjs +10 -0
  180. package/dist/esm/scan/detection/localeCode.mjs +108 -0
  181. package/dist/esm/scan/detection/localeCode.mjs.map +1 -0
  182. package/dist/esm/scan/detection/localizedPages.mjs +46 -0
  183. package/dist/esm/scan/detection/localizedPages.mjs.map +1 -0
  184. package/dist/esm/scan/detection/technologySignatures.mjs +563 -0
  185. package/dist/esm/scan/detection/technologySignatures.mjs.map +1 -0
  186. package/dist/esm/scan/detection/url.mjs +47 -0
  187. package/dist/esm/scan/detection/url.mjs.map +1 -0
  188. package/dist/esm/scan/fetchText.mjs +55 -0
  189. package/dist/esm/scan/fetchText.mjs.map +1 -0
  190. package/dist/esm/scan/index.mjs +15 -3
  191. package/dist/esm/scan/parseHtml.mjs +52 -11
  192. package/dist/esm/scan/parseHtml.mjs.map +1 -1
  193. package/dist/esm/scan/robots.mjs +63 -0
  194. package/dist/esm/scan/robots.mjs.map +1 -0
  195. package/dist/esm/scan/runScanChecks.mjs +88 -0
  196. package/dist/esm/scan/runScanChecks.mjs.map +1 -0
  197. package/dist/esm/scan/scanWebsite.mjs +59 -53
  198. package/dist/esm/scan/scanWebsite.mjs.map +1 -1
  199. package/dist/esm/scan/sitemap.mjs +105 -0
  200. package/dist/esm/scan/sitemap.mjs.map +1 -0
  201. package/dist/esm/utils/chunkJSON.mjs +24 -9
  202. package/dist/esm/utils/chunkJSON.mjs.map +1 -1
  203. package/dist/esm/utils/getChunk.mjs +2 -2
  204. package/dist/esm/utils/getChunk.mjs.map +1 -1
  205. package/dist/esm/utils/runParallel/index.mjs +1 -1
  206. package/dist/esm/utils/runParallel/index.mjs.map +1 -1
  207. package/dist/esm/utils/runParallel/pidTree.mjs +23 -11
  208. package/dist/esm/utils/runParallel/pidTree.mjs.map +1 -1
  209. package/dist/esm/utils/runParallel/ps.mjs +8 -3
  210. package/dist/esm/utils/runParallel/ps.mjs.map +1 -1
  211. package/dist/esm/utils/runParallel/runTask.mjs +2 -1
  212. package/dist/esm/utils/runParallel/runTask.mjs.map +1 -1
  213. package/dist/esm/utils/runParallel/wmic.mjs +8 -3
  214. package/dist/esm/utils/runParallel/wmic.mjs.map +1 -1
  215. package/dist/esm/writeContentDeclaration/detectExportedComponentName.mjs +7 -4
  216. package/dist/esm/writeContentDeclaration/detectExportedComponentName.mjs.map +1 -1
  217. package/dist/esm/writeContentDeclaration/writeMarkdownFile.mjs +2 -2
  218. package/dist/esm/writeContentDeclaration/writeMarkdownFile.mjs.map +1 -1
  219. package/dist/types/cli.d.ts +5 -3
  220. package/dist/types/docReview/rebuildDocument.d.ts.map +1 -1
  221. package/dist/types/docReview/reviewReport.d.ts.map +1 -1
  222. package/dist/types/docReview/segmentDocument.d.ts.map +1 -1
  223. package/dist/types/formatDictionary.d.ts +2 -2
  224. package/dist/types/init/cms.d.ts +11 -0
  225. package/dist/types/init/cms.d.ts.map +1 -1
  226. package/dist/types/init/documentationRouter.d.ts +64 -0
  227. package/dist/types/init/documentationRouter.d.ts.map +1 -0
  228. package/dist/types/init/frameworkSetup/backend/index.d.ts +16 -0
  229. package/dist/types/init/frameworkSetup/backend/index.d.ts.map +1 -0
  230. package/dist/types/init/frameworkSetup/backend/transforms.d.ts +37 -0
  231. package/dist/types/init/frameworkSetup/backend/transforms.d.ts.map +1 -0
  232. package/dist/types/init/frameworkSetup/index.d.ts.map +1 -1
  233. package/dist/types/init/frameworkSetup/localeRouting.d.ts +11 -0
  234. package/dist/types/init/frameworkSetup/localeRouting.d.ts.map +1 -0
  235. package/dist/types/init/frameworkSetup/nextAppRouter/index.d.ts +5 -5
  236. package/dist/types/init/frameworkSetup/nextAppRouter/index.d.ts.map +1 -1
  237. package/dist/types/init/frameworkSetup/nextAppRouter/templates.d.ts +12 -0
  238. package/dist/types/init/frameworkSetup/nextAppRouter/templates.d.ts.map +1 -1
  239. package/dist/types/init/frameworkSetup/nextAppRouter/transforms.d.ts +10 -1
  240. package/dist/types/init/frameworkSetup/nextAppRouter/transforms.d.ts.map +1 -1
  241. package/dist/types/init/frameworkSetup/tanstackStart/index.d.ts +3 -2
  242. package/dist/types/init/frameworkSetup/tanstackStart/index.d.ts.map +1 -1
  243. package/dist/types/init/frameworkSetup/tanstackStart/templates.d.ts +10 -0
  244. package/dist/types/init/frameworkSetup/tanstackStart/templates.d.ts.map +1 -1
  245. package/dist/types/init/frameworkSetup/tanstackStart/transforms.d.ts +12 -0
  246. package/dist/types/init/frameworkSetup/tanstackStart/transforms.d.ts.map +1 -1
  247. package/dist/types/init/frameworkSetup/types.d.ts +6 -0
  248. package/dist/types/init/frameworkSetup/types.d.ts.map +1 -1
  249. package/dist/types/init/index.d.ts +15 -1
  250. package/dist/types/init/index.d.ts.map +1 -1
  251. package/dist/types/init/utils/configManipulation.d.ts +14 -0
  252. package/dist/types/init/utils/configManipulation.d.ts.map +1 -1
  253. package/dist/types/init/utils/index.d.ts +5 -3
  254. package/dist/types/init/utils/lintConfig.d.ts +28 -0
  255. package/dist/types/init/utils/lintConfig.d.ts.map +1 -0
  256. package/dist/types/init/utils/packageManager.d.ts +29 -6
  257. package/dist/types/init/utils/packageManager.d.ts.map +1 -1
  258. package/dist/types/init/utils/urlRoutingFramework.d.ts +9 -0
  259. package/dist/types/init/utils/urlRoutingFramework.d.ts.map +1 -0
  260. package/dist/types/initConfig/index.d.ts +3 -1
  261. package/dist/types/initConfig/index.d.ts.map +1 -1
  262. package/dist/types/loadDictionaries/logTypeScriptErrors.d.ts +4 -0
  263. package/dist/types/loadDictionaries/logTypeScriptErrors.d.ts.map +1 -1
  264. package/dist/types/scan/analyzeBundleContent.d.ts.map +1 -1
  265. package/dist/types/scan/calculateScore.d.ts +4 -1
  266. package/dist/types/scan/calculateScore.d.ts.map +1 -1
  267. package/dist/types/scan/checks.d.ts +114 -21
  268. package/dist/types/scan/checks.d.ts.map +1 -1
  269. package/dist/types/scan/detection/checkDetails.d.ts +29 -0
  270. package/dist/types/scan/detection/checkDetails.d.ts.map +1 -0
  271. package/dist/types/scan/detection/classifyInternalLinks.d.ts +44 -0
  272. package/dist/types/scan/detection/classifyInternalLinks.d.ts.map +1 -0
  273. package/dist/types/scan/detection/detectRoutingStrategy.d.ts +60 -0
  274. package/dist/types/scan/detection/detectRoutingStrategy.d.ts.map +1 -0
  275. package/dist/types/scan/detection/detectTechnologies.d.ts +60 -0
  276. package/dist/types/scan/detection/detectTechnologies.d.ts.map +1 -0
  277. package/dist/types/scan/detection/index.d.ts +9 -0
  278. package/dist/types/scan/detection/localeCode.d.ts +49 -0
  279. package/dist/types/scan/detection/localeCode.d.ts.map +1 -0
  280. package/dist/types/scan/detection/localizedPages.d.ts +40 -0
  281. package/dist/types/scan/detection/localizedPages.d.ts.map +1 -0
  282. package/dist/types/scan/detection/technologySignatures.d.ts +48 -0
  283. package/dist/types/scan/detection/technologySignatures.d.ts.map +1 -0
  284. package/dist/types/scan/detection/url.d.ts +27 -0
  285. package/dist/types/scan/detection/url.d.ts.map +1 -0
  286. package/dist/types/scan/fetchText.d.ts +30 -0
  287. package/dist/types/scan/fetchText.d.ts.map +1 -0
  288. package/dist/types/scan/index.d.ts +16 -4
  289. package/dist/types/scan/parseHtml.d.ts +17 -0
  290. package/dist/types/scan/parseHtml.d.ts.map +1 -1
  291. package/dist/types/scan/robots.d.ts +23 -0
  292. package/dist/types/scan/robots.d.ts.map +1 -0
  293. package/dist/types/scan/runScanChecks.d.ts +43 -0
  294. package/dist/types/scan/runScanChecks.d.ts.map +1 -0
  295. package/dist/types/scan/scanWebsite.d.ts.map +1 -1
  296. package/dist/types/scan/sitemap.d.ts +49 -0
  297. package/dist/types/scan/sitemap.d.ts.map +1 -0
  298. package/dist/types/scan/types.d.ts +15 -0
  299. package/dist/types/scan/types.d.ts.map +1 -1
  300. package/dist/types/utils/chunkJSON.d.ts.map +1 -1
  301. package/dist/types/utils/runParallel/pidTree.d.ts.map +1 -1
  302. package/dist/types/writeContentDeclaration/writeMarkdownFile.d.ts.map +1 -1
  303. package/package.json +16 -8
@@ -0,0 +1,108 @@
1
+ //#region src/scan/detection/localeCode.ts
2
+ /**
3
+ * Locale-code helpers shared by the scan checks and the routing detection.
4
+ *
5
+ * Dependency-free and browser-safe: consumed by the CLI, the backend audit and
6
+ * the Chrome extension popup.
7
+ */
8
+ /** Syntactic shape of a locale code: `en`, `en-US`, `pt_BR`, `zh-Hant-TW`… */
9
+ const LOCALE_CODE_PATTERN = /^[a-z]{2,3}([_-][a-z]{4})?([_-]([a-z]{2}|[0-9]{3}))?$/i;
10
+ /** Languages written right-to-left. */
11
+ const RIGHT_TO_LEFT_LANGUAGES = /* @__PURE__ */ new Set([
12
+ "ar",
13
+ "arc",
14
+ "ckb",
15
+ "dv",
16
+ "fa",
17
+ "he",
18
+ "iw",
19
+ "ku",
20
+ "ps",
21
+ "sd",
22
+ "syr",
23
+ "ug",
24
+ "ur",
25
+ "yi"
26
+ ]);
27
+ /** Lower-case a locale code and use `-` as separator (`pt_BR` → `pt-br`). */
28
+ const normalizeLocaleCode = (localeCode) => localeCode.trim().replace(/_/g, "-").toLowerCase();
29
+ /** Primary language subtag of a locale code (`en-US` → `en`). */
30
+ const getLanguageCode = (localeCode) => normalizeLocaleCode(localeCode).split("-")[0] ?? "";
31
+ /** Whether two locale codes designate the same locale, ignoring case/separator. */
32
+ const isSameLocale = (firstLocale, secondLocale) => Boolean(firstLocale) && Boolean(secondLocale) && normalizeLocaleCode(firstLocale) === normalizeLocaleCode(secondLocale);
33
+ /** Whether two locale codes share the same language (`fr` vs `fr-CA`). */
34
+ const isSameLanguage = (firstLocale, secondLocale) => Boolean(firstLocale && secondLocale) && getLanguageCode(firstLocale) === getLanguageCode(secondLocale);
35
+ /** Whether a string looks like a locale code (used on URL segments). */
36
+ const looksLikeLocaleCode = (value) => LOCALE_CODE_PATTERN.test(value);
37
+ /**
38
+ * Whether a locale code is a valid BCP 47 tag (`en_US` and `english` are not).
39
+ * `x-default` is accepted since it is a valid hreflang value.
40
+ */
41
+ const isValidLocaleCode = (localeCode) => {
42
+ if (localeCode.toLowerCase() === "x-default") return true;
43
+ if (!LOCALE_CODE_PATTERN.test(localeCode) || localeCode.includes("_")) return false;
44
+ try {
45
+ return Intl.getCanonicalLocales(localeCode).length === 1;
46
+ } catch {
47
+ return false;
48
+ }
49
+ };
50
+ /** Whether the locale is written right-to-left (`ar`, `he-IL`, `fa`…). */
51
+ const isRightToLeftLocale = (localeCode) => RIGHT_TO_LEFT_LANGUAGES.has(getLanguageCode(localeCode));
52
+ /**
53
+ * Find, among `candidateLocales`, the one matching `value` (a URL segment, a
54
+ * subdomain label or a query-string value). Falls back to a language-only match
55
+ * when no exact match exists (`/fr/` for hreflang `fr-FR`).
56
+ */
57
+ const findMatchingLocale = (value, candidateLocales) => {
58
+ if (!value) return void 0;
59
+ const normalizedValue = normalizeLocaleCode(value);
60
+ const exactMatch = candidateLocales.find((locale) => normalizeLocaleCode(locale) === normalizedValue);
61
+ if (exactMatch) return exactMatch;
62
+ const languageMatches = candidateLocales.filter((locale) => getLanguageCode(locale) === normalizedValue);
63
+ return languageMatches.length === 1 ? languageMatches[0] : void 0;
64
+ };
65
+ /** Open Graph locale shape: `language_TERRITORY` (`en_GB`, `pt_BR`). */
66
+ const OPEN_GRAPH_LOCALE_PATTERN = /^[a-z]{2,3}_[A-Z]{2}$/;
67
+ /**
68
+ * Whether a value is a valid `og:locale` (`en_GB`). Open Graph does not accept
69
+ * a bare language (`en`) nor BCP 47 separators (`en-GB`): crawlers then fall
70
+ * back to `en_US`.
71
+ */
72
+ const isValidOpenGraphLocale = (localeCode) => OPEN_GRAPH_LOCALE_PATTERN.test(localeCode.trim());
73
+ /** Region subtag of a locale code, if any (`en-GB` → `GB`, `zh-Hant-TW` → `TW`). */
74
+ const getRegionCode = (localeCode) => {
75
+ try {
76
+ return new Intl.Locale(normalizeLocaleCode(localeCode)).region;
77
+ } catch {
78
+ return;
79
+ }
80
+ };
81
+ /** Most likely region of a language (`en` → `US`, `fr` → `FR`, `ja` → `JP`). */
82
+ const getLikelyRegionCode = (languageCode) => {
83
+ try {
84
+ return new Intl.Locale(languageCode).maximize().region;
85
+ } catch {
86
+ return;
87
+ }
88
+ };
89
+ /**
90
+ * Suggest the `og:locale` value for a locale code. The region comes from the
91
+ * locale itself, then from `regionHint` (typically `<html lang>`) when it
92
+ * shares the language, then from the language's most likely region.
93
+ *
94
+ * @example
95
+ * toOpenGraphLocale('en', 'en-GB'); // 'en_GB'
96
+ * toOpenGraphLocale('pt-br'); // 'pt_BR'
97
+ * toOpenGraphLocale('fr'); // 'fr_FR'
98
+ */
99
+ const toOpenGraphLocale = (localeCode, regionHint) => {
100
+ const languageCode = getLanguageCode(localeCode);
101
+ if (!/^[a-z]{2,3}$/.test(languageCode)) return void 0;
102
+ const regionCode = getRegionCode(localeCode) ?? (regionHint && isSameLanguage(localeCode, regionHint) ? getRegionCode(regionHint) : void 0) ?? getLikelyRegionCode(languageCode);
103
+ return regionCode && /^[A-Z]{2}$/.test(regionCode) ? `${languageCode}_${regionCode}` : void 0;
104
+ };
105
+
106
+ //#endregion
107
+ export { findMatchingLocale, getLanguageCode, isRightToLeftLocale, isSameLanguage, isSameLocale, isValidLocaleCode, isValidOpenGraphLocale, looksLikeLocaleCode, normalizeLocaleCode, toOpenGraphLocale };
108
+ //# sourceMappingURL=localeCode.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localeCode.mjs","names":[],"sources":["../../../../src/scan/detection/localeCode.ts"],"sourcesContent":["/**\n * Locale-code helpers shared by the scan checks and the routing detection.\n *\n * Dependency-free and browser-safe: consumed by the CLI, the backend audit and\n * the Chrome extension popup.\n */\n\n/** Syntactic shape of a locale code: `en`, `en-US`, `pt_BR`, `zh-Hant-TW`… */\nconst LOCALE_CODE_PATTERN =\n /^[a-z]{2,3}([_-][a-z]{4})?([_-]([a-z]{2}|[0-9]{3}))?$/i;\n\n/** Languages written right-to-left. */\nconst RIGHT_TO_LEFT_LANGUAGES = new Set([\n 'ar',\n 'arc',\n 'ckb',\n 'dv',\n 'fa',\n 'he',\n 'iw',\n 'ku',\n 'ps',\n 'sd',\n 'syr',\n 'ug',\n 'ur',\n 'yi',\n]);\n\n/** Lower-case a locale code and use `-` as separator (`pt_BR` → `pt-br`). */\nexport const normalizeLocaleCode = (localeCode: string): string =>\n localeCode.trim().replace(/_/g, '-').toLowerCase();\n\n/** Primary language subtag of a locale code (`en-US` → `en`). */\nexport const getLanguageCode = (localeCode: string): string =>\n normalizeLocaleCode(localeCode).split('-')[0] ?? '';\n\n/** Whether two locale codes designate the same locale, ignoring case/separator. */\nexport const isSameLocale = (\n firstLocale: string | undefined,\n secondLocale: string | undefined\n): boolean =>\n Boolean(firstLocale) &&\n Boolean(secondLocale) &&\n normalizeLocaleCode(firstLocale as string) ===\n normalizeLocaleCode(secondLocale as string);\n\n/** Whether two locale codes share the same language (`fr` vs `fr-CA`). */\nexport const isSameLanguage = (\n firstLocale: string | undefined,\n secondLocale: string | undefined\n): boolean =>\n Boolean(firstLocale && secondLocale) &&\n getLanguageCode(firstLocale as string) ===\n getLanguageCode(secondLocale as string);\n\n/** Whether a string looks like a locale code (used on URL segments). */\nexport const looksLikeLocaleCode = (value: string): boolean =>\n LOCALE_CODE_PATTERN.test(value);\n\n/**\n * Whether a locale code is a valid BCP 47 tag (`en_US` and `english` are not).\n * `x-default` is accepted since it is a valid hreflang value.\n */\nexport const isValidLocaleCode = (localeCode: string): boolean => {\n if (localeCode.toLowerCase() === 'x-default') return true;\n if (!LOCALE_CODE_PATTERN.test(localeCode) || localeCode.includes('_')) {\n return false;\n }\n try {\n return Intl.getCanonicalLocales(localeCode).length === 1;\n } catch {\n return false;\n }\n};\n\n/** Whether the locale is written right-to-left (`ar`, `he-IL`, `fa`…). */\nexport const isRightToLeftLocale = (localeCode: string): boolean =>\n RIGHT_TO_LEFT_LANGUAGES.has(getLanguageCode(localeCode));\n\n/**\n * Find, among `candidateLocales`, the one matching `value` (a URL segment, a\n * subdomain label or a query-string value). Falls back to a language-only match\n * when no exact match exists (`/fr/` for hreflang `fr-FR`).\n */\nexport const findMatchingLocale = (\n value: string | undefined | null,\n candidateLocales: readonly string[]\n): string | undefined => {\n if (!value) return undefined;\n const normalizedValue = normalizeLocaleCode(value);\n\n const exactMatch = candidateLocales.find(\n (locale) => normalizeLocaleCode(locale) === normalizedValue\n );\n if (exactMatch) return exactMatch;\n\n const languageMatches = candidateLocales.filter(\n (locale) => getLanguageCode(locale) === normalizedValue\n );\n return languageMatches.length === 1 ? languageMatches[0] : undefined;\n};\n\n/** Open Graph locale shape: `language_TERRITORY` (`en_GB`, `pt_BR`). */\nconst OPEN_GRAPH_LOCALE_PATTERN = /^[a-z]{2,3}_[A-Z]{2}$/;\n\n/**\n * Whether a value is a valid `og:locale` (`en_GB`). Open Graph does not accept\n * a bare language (`en`) nor BCP 47 separators (`en-GB`): crawlers then fall\n * back to `en_US`.\n */\nexport const isValidOpenGraphLocale = (localeCode: string): boolean =>\n OPEN_GRAPH_LOCALE_PATTERN.test(localeCode.trim());\n\n/** Region subtag of a locale code, if any (`en-GB` → `GB`, `zh-Hant-TW` → `TW`). */\nconst getRegionCode = (localeCode: string): string | undefined => {\n try {\n return new Intl.Locale(normalizeLocaleCode(localeCode)).region;\n } catch {\n return undefined;\n }\n};\n\n/** Most likely region of a language (`en` → `US`, `fr` → `FR`, `ja` → `JP`). */\nconst getLikelyRegionCode = (languageCode: string): string | undefined => {\n try {\n return new Intl.Locale(languageCode).maximize().region;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Suggest the `og:locale` value for a locale code. The region comes from the\n * locale itself, then from `regionHint` (typically `<html lang>`) when it\n * shares the language, then from the language's most likely region.\n *\n * @example\n * toOpenGraphLocale('en', 'en-GB'); // 'en_GB'\n * toOpenGraphLocale('pt-br'); // 'pt_BR'\n * toOpenGraphLocale('fr'); // 'fr_FR'\n */\nexport const toOpenGraphLocale = (\n localeCode: string,\n regionHint?: string\n): string | undefined => {\n const languageCode = getLanguageCode(localeCode);\n if (!/^[a-z]{2,3}$/.test(languageCode)) return undefined;\n\n const regionCode =\n getRegionCode(localeCode) ??\n (regionHint && isSameLanguage(localeCode, regionHint)\n ? getRegionCode(regionHint)\n : undefined) ??\n getLikelyRegionCode(languageCode);\n\n return regionCode && /^[A-Z]{2}$/.test(regionCode)\n ? `${languageCode}_${regionCode}`\n : undefined;\n};\n"],"mappings":";;;;;;;;AAQA,MAAM,sBACJ;;AAGF,MAAM,0CAA0B,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;AAGD,MAAa,uBAAuB,eAClC,WAAW,KAAK,CAAC,CAAC,QAAQ,MAAM,GAAG,CAAC,CAAC,YAAY;;AAGnD,MAAa,mBAAmB,eAC9B,oBAAoB,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;;AAGnD,MAAa,gBACX,aACA,iBAEA,QAAQ,WAAW,KACnB,QAAQ,YAAY,KACpB,oBAAoB,WAAqB,MACvC,oBAAoB,YAAsB;;AAG9C,MAAa,kBACX,aACA,iBAEA,QAAQ,eAAe,YAAY,KACnC,gBAAgB,WAAqB,MACnC,gBAAgB,YAAsB;;AAG1C,MAAa,uBAAuB,UAClC,oBAAoB,KAAK,KAAK;;;;;AAMhC,MAAa,qBAAqB,eAAgC;CAChE,IAAI,WAAW,YAAY,MAAM,aAAa,OAAO;CACrD,IAAI,CAAC,oBAAoB,KAAK,UAAU,KAAK,WAAW,SAAS,GAAG,GAClE,OAAO;CAET,IAAI;EACF,OAAO,KAAK,oBAAoB,UAAU,CAAC,CAAC,WAAW;CACzD,QAAQ;EACN,OAAO;CACT;AACF;;AAGA,MAAa,uBAAuB,eAClC,wBAAwB,IAAI,gBAAgB,UAAU,CAAC;;;;;;AAOzD,MAAa,sBACX,OACA,qBACuB;CACvB,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,kBAAkB,oBAAoB,KAAK;CAEjD,MAAM,aAAa,iBAAiB,MACjC,WAAW,oBAAoB,MAAM,MAAM,eAC9C;CACA,IAAI,YAAY,OAAO;CAEvB,MAAM,kBAAkB,iBAAiB,QACtC,WAAW,gBAAgB,MAAM,MAAM,eAC1C;CACA,OAAO,gBAAgB,WAAW,IAAI,gBAAgB,KAAK;AAC7D;;AAGA,MAAM,4BAA4B;;;;;;AAOlC,MAAa,0BAA0B,eACrC,0BAA0B,KAAK,WAAW,KAAK,CAAC;;AAGlD,MAAM,iBAAiB,eAA2C;CAChE,IAAI;EACF,OAAO,IAAI,KAAK,OAAO,oBAAoB,UAAU,CAAC,CAAC,CAAC;CAC1D,QAAQ;EACN;CACF;AACF;;AAGA,MAAM,uBAAuB,iBAA6C;CACxE,IAAI;EACF,OAAO,IAAI,KAAK,OAAO,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC;CAClD,QAAQ;EACN;CACF;AACF;;;;;;;;;;;AAYA,MAAa,qBACX,YACA,eACuB;CACvB,MAAM,eAAe,gBAAgB,UAAU;CAC/C,IAAI,CAAC,eAAe,KAAK,YAAY,GAAG,OAAO;CAE/C,MAAM,aACJ,cAAc,UAAU,MACvB,cAAc,eAAe,YAAY,UAAU,IAChD,cAAc,UAAU,IACxB,WACJ,oBAAoB,YAAY;CAElC,OAAO,cAAc,aAAa,KAAK,UAAU,IAC7C,GAAG,aAAa,GAAG,eACnB;AACN"}
@@ -0,0 +1,46 @@
1
+ import { normalizeUrl, parseUrl } from "./url.mjs";
2
+ import { isSameLocale } from "./localeCode.mjs";
3
+
4
+ //#region src/scan/detection/localizedPages.ts
5
+ const X_DEFAULT = "x-default";
6
+ /**
7
+ * Turns the hreflang alternates of a page into a navigable list: absolute,
8
+ * deduped by URL (a real locale wins over `x-default`), flagging the current
9
+ * page, `x-default` last.
10
+ *
11
+ * @param hreflangs - `<link rel="alternate" hreflang>` entries of the page.
12
+ * @param currentUrl - Absolute URL of the page, used to resolve relative hrefs.
13
+ */
14
+ const getLocalizedPages = (hreflangs, currentUrl) => {
15
+ const normalizedCurrentUrl = normalizeUrl(currentUrl);
16
+ const pagesByUrl = /* @__PURE__ */ new Map();
17
+ for (const { hreflang, href } of hreflangs) {
18
+ const url = hreflang ? parseUrl(href, currentUrl)?.href : void 0;
19
+ if (!url) continue;
20
+ const existingPage = pagesByUrl.get(url);
21
+ if (existingPage && existingPage.hreflang !== X_DEFAULT) continue;
22
+ pagesByUrl.set(url, {
23
+ hreflang,
24
+ url,
25
+ isCurrent: normalizeUrl(url) === normalizedCurrentUrl
26
+ });
27
+ }
28
+ return Array.from(pagesByUrl.values()).sort((firstPage, secondPage) => Number(firstPage.hreflang === X_DEFAULT) - Number(secondPage.hreflang === X_DEFAULT));
29
+ };
30
+ /**
31
+ * Whether the page is the base (unlocalized / default-locale entry) version of
32
+ * a multilingual page: the `x-default` target, the root of a `prefix-all`
33
+ * site, or the unmarked default-locale URL. i18n issues tend to hide on the
34
+ * localized versions rather than on this one.
35
+ */
36
+ const isBaseLocalePage = ({ pageUrl, hreflangs, routing }) => {
37
+ if (routing.locales.length < 2) return false;
38
+ const xDefaultHref = hreflangs.find(({ hreflang }) => hreflang.toLowerCase() === X_DEFAULT)?.href;
39
+ if (xDefaultHref && normalizeUrl(xDefaultHref, pageUrl) === normalizeUrl(pageUrl)) return true;
40
+ if (routing.strategy === "prefix-all") return !routing.urlLocale;
41
+ return (routing.strategy === "prefix-no-default" || routing.strategy === "search-params" || routing.strategy === "subdomain") && isSameLocale(routing.urlLocale, routing.defaultLocale);
42
+ };
43
+
44
+ //#endregion
45
+ export { getLocalizedPages, isBaseLocalePage };
46
+ //# sourceMappingURL=localizedPages.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localizedPages.mjs","names":[],"sources":["../../../../src/scan/detection/localizedPages.ts"],"sourcesContent":["import type { RoutingDetection } from './detectRoutingStrategy';\nimport { isSameLocale } from './localeCode';\nimport { normalizeUrl, parseUrl } from './url';\n\n/** A localized version of a page, read from its hreflang tags. */\nexport type LocalizedPage = {\n hreflang: string;\n /** Absolute URL of the localized version. */\n url: string;\n /** True when this alternate points to the page currently inspected. */\n isCurrent: boolean;\n};\n\nconst X_DEFAULT = 'x-default';\n\n/**\n * Turns the hreflang alternates of a page into a navigable list: absolute,\n * deduped by URL (a real locale wins over `x-default`), flagging the current\n * page, `x-default` last.\n *\n * @param hreflangs - `<link rel=\"alternate\" hreflang>` entries of the page.\n * @param currentUrl - Absolute URL of the page, used to resolve relative hrefs.\n */\nexport const getLocalizedPages = (\n hreflangs: { hreflang: string; href: string }[],\n currentUrl: string\n): LocalizedPage[] => {\n const normalizedCurrentUrl = normalizeUrl(currentUrl);\n const pagesByUrl = new Map<string, LocalizedPage>();\n\n for (const { hreflang, href } of hreflangs) {\n const url = hreflang ? parseUrl(href, currentUrl)?.href : undefined;\n if (!url) continue;\n\n const existingPage = pagesByUrl.get(url);\n\n // Keep a real locale over `x-default` when both point to the same URL.\n if (existingPage && existingPage.hreflang !== X_DEFAULT) continue;\n\n pagesByUrl.set(url, {\n hreflang,\n url,\n isCurrent: normalizeUrl(url) === normalizedCurrentUrl,\n });\n }\n\n return Array.from(pagesByUrl.values()).sort(\n (firstPage, secondPage) =>\n Number(firstPage.hreflang === X_DEFAULT) -\n Number(secondPage.hreflang === X_DEFAULT)\n );\n};\n\n/** Input of {@link isBaseLocalePage}. */\nexport type BaseLocalePageInput = {\n pageUrl: string;\n hreflangs: { hreflang: string; href: string }[];\n routing: Pick<\n RoutingDetection,\n 'strategy' | 'locales' | 'urlLocale' | 'defaultLocale'\n >;\n};\n\n/**\n * Whether the page is the base (unlocalized / default-locale entry) version of\n * a multilingual page: the `x-default` target, the root of a `prefix-all`\n * site, or the unmarked default-locale URL. i18n issues tend to hide on the\n * localized versions rather than on this one.\n */\nexport const isBaseLocalePage = ({\n pageUrl,\n hreflangs,\n routing,\n}: BaseLocalePageInput): boolean => {\n if (routing.locales.length < 2) return false;\n\n const xDefaultHref = hreflangs.find(\n ({ hreflang }) => hreflang.toLowerCase() === X_DEFAULT\n )?.href;\n if (\n xDefaultHref &&\n normalizeUrl(xDefaultHref, pageUrl) === normalizeUrl(pageUrl)\n ) {\n return true;\n }\n\n if (routing.strategy === 'prefix-all') return !routing.urlLocale;\n\n const hasUnmarkedDefaultLocale =\n routing.strategy === 'prefix-no-default' ||\n routing.strategy === 'search-params' ||\n routing.strategy === 'subdomain';\n\n return (\n hasUnmarkedDefaultLocale &&\n isSameLocale(routing.urlLocale, routing.defaultLocale)\n );\n};\n"],"mappings":";;;;AAaA,MAAM,YAAY;;;;;;;;;AAUlB,MAAa,qBACX,WACA,eACoB;CACpB,MAAM,uBAAuB,aAAa,UAAU;CACpD,MAAM,6BAAa,IAAI,IAA2B;CAElD,KAAK,MAAM,EAAE,UAAU,UAAU,WAAW;EAC1C,MAAM,MAAM,WAAW,SAAS,MAAM,UAAU,CAAC,EAAE,OAAO;EAC1D,IAAI,CAAC,KAAK;EAEV,MAAM,eAAe,WAAW,IAAI,GAAG;EAGvC,IAAI,gBAAgB,aAAa,aAAa,WAAW;EAEzD,WAAW,IAAI,KAAK;GAClB;GACA;GACA,WAAW,aAAa,GAAG,MAAM;EACnC,CAAC;CACH;CAEA,OAAO,MAAM,KAAK,WAAW,OAAO,CAAC,CAAC,CAAC,MACpC,WAAW,eACV,OAAO,UAAU,aAAa,SAAS,IACvC,OAAO,WAAW,aAAa,SAAS,CAC5C;AACF;;;;;;;AAkBA,MAAa,oBAAoB,EAC/B,SACA,WACA,cACkC;CAClC,IAAI,QAAQ,QAAQ,SAAS,GAAG,OAAO;CAEvC,MAAM,eAAe,UAAU,MAC5B,EAAE,eAAe,SAAS,YAAY,MAAM,SAC/C,CAAC,EAAE;CACH,IACE,gBACA,aAAa,cAAc,OAAO,MAAM,aAAa,OAAO,GAE5D,OAAO;CAGT,IAAI,QAAQ,aAAa,cAAc,OAAO,CAAC,QAAQ;CAOvD,QAJE,QAAQ,aAAa,uBACrB,QAAQ,aAAa,mBACrB,QAAQ,aAAa,gBAIrB,aAAa,QAAQ,WAAW,QAAQ,aAAa;AAEzD"}