@featurevisor/core 2.26.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/coverage/clover.xml +4991 -3130
  3. package/coverage/coverage-final.json +63 -39
  4. package/coverage/lcov-report/block-navigation.js +1 -1
  5. package/coverage/lcov-report/index.html +248 -98
  6. package/coverage/lcov-report/sorter.js +21 -7
  7. package/coverage/lcov-report/src/assess-distribution/index.html +116 -0
  8. package/coverage/lcov-report/src/assess-distribution/index.ts.html +754 -0
  9. package/coverage/lcov-report/{list → src/benchmark}/index.html +30 -30
  10. package/coverage/lcov-report/src/benchmark/index.ts.html +793 -0
  11. package/coverage/lcov-report/{builder → src/builder}/allocator.ts.html +38 -38
  12. package/coverage/lcov-report/{builder/buildScopedConditions.ts.html → src/builder/applyContextToConditions.ts.html} +80 -65
  13. package/coverage/lcov-report/{builder/buildScopedDatafile.ts.html → src/builder/applyContextToDatafile.ts.html} +92 -92
  14. package/coverage/lcov-report/{builder/buildScopedSegments.ts.html → src/builder/applyContextToSegments.ts.html} +103 -67
  15. package/coverage/lcov-report/{builder → src/builder}/buildDatafile.ts.html +336 -306
  16. package/coverage/lcov-report/src/builder/buildProject.ts.html +1117 -0
  17. package/coverage/lcov-report/src/builder/buildRuntimeDatafiles.ts.html +256 -0
  18. package/coverage/lcov-report/{builder → src/builder}/getFeatureRanges.ts.html +22 -22
  19. package/coverage/lcov-report/{builder → src/builder}/hashes.ts.html +50 -50
  20. package/coverage/lcov-report/{builder → src/builder}/index.html +114 -84
  21. package/coverage/lcov-report/{tester/cliFormat.ts.html → src/builder/index.ts.html} +17 -29
  22. package/coverage/lcov-report/{builder → src/builder}/mutateVariables.ts.html +55 -55
  23. package/coverage/lcov-report/{builder → src/builder}/mutator.ts.html +118 -118
  24. package/coverage/lcov-report/{builder → src/builder}/revision.ts.html +15 -15
  25. package/coverage/lcov-report/{builder → src/builder}/traffic.ts.html +86 -86
  26. package/coverage/lcov-report/src/cli/cli.ts.html +400 -0
  27. package/coverage/lcov-report/{tester → src/cli}/index.html +41 -41
  28. package/coverage/lcov-report/src/cli/plugins.ts.html +214 -0
  29. package/coverage/lcov-report/{config → src/config}/index.html +31 -31
  30. package/coverage/lcov-report/{config → src/config}/index.ts.html +12 -12
  31. package/coverage/lcov-report/{config → src/config}/projectConfig.ts.html +312 -96
  32. package/coverage/lcov-report/{datasource → src/datasource}/adapter.ts.html +28 -73
  33. package/coverage/lcov-report/{datasource → src/datasource}/datasource.ts.html +191 -104
  34. package/coverage/lcov-report/{datasource → src/datasource}/filesystemAdapter.ts.html +233 -635
  35. package/coverage/lcov-report/{datasource → src/datasource}/index.html +48 -48
  36. package/coverage/lcov-report/{datasource → src/datasource}/index.ts.html +14 -14
  37. package/coverage/lcov-report/src/evaluate/index.html +116 -0
  38. package/coverage/lcov-report/src/evaluate/index.ts.html +814 -0
  39. package/coverage/lcov-report/src/find-duplicate-segments/findDuplicateSegments.ts.html +313 -0
  40. package/coverage/lcov-report/src/find-duplicate-segments/index.html +131 -0
  41. package/coverage/lcov-report/src/find-duplicate-segments/index.ts.html +307 -0
  42. package/coverage/lcov-report/src/find-usage/index.html +116 -0
  43. package/coverage/lcov-report/src/find-usage/index.ts.html +1780 -0
  44. package/coverage/lcov-report/src/generate-code/index.html +131 -0
  45. package/coverage/lcov-report/src/generate-code/index.ts.html +403 -0
  46. package/coverage/lcov-report/{generate-code → src/generate-code}/typescript.ts.html +266 -1361
  47. package/coverage/lcov-report/{generate-code → src}/index.html +38 -23
  48. package/coverage/lcov-report/src/info/index.html +116 -0
  49. package/coverage/lcov-report/src/info/index.ts.html +472 -0
  50. package/coverage/lcov-report/src/init/index.html +116 -0
  51. package/coverage/lcov-report/src/init/index.ts.html +280 -0
  52. package/coverage/lcov-report/{linter → src/linter}/attributeSchema.ts.html +160 -157
  53. package/coverage/lcov-report/{linter → src/linter}/checkCircularDependency.ts.html +25 -25
  54. package/coverage/lcov-report/{linter → src/linter}/checkPercentageExceedingSlot.ts.html +42 -42
  55. package/coverage/lcov-report/{linter → src/linter}/conditionSchema.ts.html +207 -207
  56. package/coverage/lcov-report/{linter → src/linter}/featureSchema.ts.html +462 -471
  57. package/coverage/lcov-report/{linter → src/linter}/groupSchema.ts.html +25 -22
  58. package/coverage/lcov-report/{linter → src/linter}/index.html +129 -99
  59. package/coverage/lcov-report/src/linter/index.ts.html +88 -0
  60. package/coverage/lcov-report/{linter → src/linter}/lintProject.ts.html +740 -332
  61. package/coverage/lcov-report/{linter → src/linter}/mutationNotation.ts.html +130 -130
  62. package/coverage/lcov-report/{linter → src/linter}/printError.ts.html +27 -27
  63. package/coverage/lcov-report/{linter → src/linter}/schema.ts.html +153 -150
  64. package/coverage/lcov-report/{linter → src/linter}/segmentSchema.ts.html +18 -15
  65. package/coverage/lcov-report/src/linter/targetSchema.ts.html +223 -0
  66. package/coverage/lcov-report/{linter → src/linter}/testSchema.ts.html +54 -48
  67. package/coverage/lcov-report/{linter → src/linter}/zodHelpers.ts.html +17 -17
  68. package/coverage/lcov-report/src/list/index.html +131 -0
  69. package/coverage/lcov-report/src/list/index.ts.html +2065 -0
  70. package/coverage/lcov-report/{list → src/list}/matrix.ts.html +43 -58
  71. package/coverage/lcov-report/src/promoter/index.html +116 -0
  72. package/coverage/lcov-report/src/promoter/index.ts.html +3883 -0
  73. package/coverage/lcov-report/src/sets.ts.html +313 -0
  74. package/coverage/lcov-report/src/targeting.ts.html +403 -0
  75. package/coverage/lcov-report/src/tester/cliFormat.ts.html +133 -0
  76. package/coverage/lcov-report/{tester → src/tester}/helpers.ts.html +15 -15
  77. package/coverage/lcov-report/src/tester/index.html +206 -0
  78. package/coverage/lcov-report/src/tester/prettyDuration.ts.html +187 -0
  79. package/coverage/lcov-report/src/tester/printTestResult.ts.html +337 -0
  80. package/coverage/lcov-report/src/tester/testFeature.ts.html +1186 -0
  81. package/coverage/lcov-report/src/tester/testProject.ts.html +1018 -0
  82. package/coverage/lcov-report/src/tester/testSegment.ts.html +316 -0
  83. package/coverage/lcov-report/{utils → src/utils}/extractKeys.ts.html +68 -68
  84. package/coverage/lcov-report/{utils → src/utils}/git.ts.html +44 -68
  85. package/coverage/lcov-report/{utils → src/utils}/index.html +44 -44
  86. package/coverage/lcov-report/{utils → src/utils}/index.ts.html +14 -14
  87. package/coverage/lcov-report/{utils → src/utils}/pretty.ts.html +20 -20
  88. package/coverage/lcov.info +10121 -5723
  89. package/jest.config.js +13 -4
  90. package/lib/assess-distribution/index.d.ts +1 -1
  91. package/lib/assess-distribution/index.js +59 -40
  92. package/lib/assess-distribution/index.js.map +1 -1
  93. package/lib/benchmark/index.d.ts +8 -5
  94. package/lib/benchmark/index.js +82 -65
  95. package/lib/benchmark/index.js.map +1 -1
  96. package/lib/builder/applyContextToConditions.d.ts +5 -0
  97. package/lib/builder/{buildScopedConditions.js → applyContextToConditions.js} +19 -14
  98. package/lib/builder/applyContextToConditions.js.map +1 -0
  99. package/lib/builder/applyContextToDatafile.d.ts +2 -0
  100. package/lib/builder/{buildScopedDatafile.js → applyContextToDatafile.js} +26 -26
  101. package/lib/builder/applyContextToDatafile.js.map +1 -0
  102. package/lib/builder/applyContextToSegments.d.ts +5 -0
  103. package/lib/builder/{buildScopedSegments.js → applyContextToSegments.js} +19 -14
  104. package/lib/builder/applyContextToSegments.js.map +1 -0
  105. package/lib/builder/buildDatafile.d.ts +9 -6
  106. package/lib/builder/buildDatafile.js +86 -51
  107. package/lib/builder/buildDatafile.js.map +1 -1
  108. package/lib/builder/buildProject.d.ts +17 -3
  109. package/lib/builder/buildProject.js +151 -59
  110. package/lib/builder/buildProject.js.map +1 -1
  111. package/lib/builder/buildRuntimeDatafiles.d.ts +12 -0
  112. package/lib/builder/buildRuntimeDatafiles.js +35 -0
  113. package/lib/builder/buildRuntimeDatafiles.js.map +1 -0
  114. package/lib/builder/getFeatureRanges.js +34 -1
  115. package/lib/builder/getFeatureRanges.js.map +1 -1
  116. package/lib/builder/hashes.js +34 -1
  117. package/lib/builder/hashes.js.map +1 -1
  118. package/lib/builder/index.d.ts +0 -1
  119. package/lib/builder/index.js +0 -1
  120. package/lib/builder/index.js.map +1 -1
  121. package/lib/cli/cli.js +0 -4
  122. package/lib/cli/cli.js.map +1 -1
  123. package/lib/cli/plugins.js +7 -2
  124. package/lib/cli/plugins.js.map +1 -1
  125. package/lib/config/projectConfig.d.ts +17 -17
  126. package/lib/config/projectConfig.js +101 -15
  127. package/lib/config/projectConfig.js.map +1 -1
  128. package/lib/datasource/adapter.d.ts +7 -9
  129. package/lib/datasource/adapter.js +0 -7
  130. package/lib/datasource/adapter.js.map +1 -1
  131. package/lib/datasource/datasource.d.ts +15 -5
  132. package/lib/datasource/datasource.js +37 -9
  133. package/lib/datasource/datasource.js.map +1 -1
  134. package/lib/datasource/filesystemAdapter.d.ts +4 -10
  135. package/lib/datasource/filesystemAdapter.js +111 -149
  136. package/lib/datasource/filesystemAdapter.js.map +1 -1
  137. package/lib/evaluate/index.d.ts +1 -7
  138. package/lib/evaluate/index.js +81 -67
  139. package/lib/evaluate/index.js.map +1 -1
  140. package/lib/find-duplicate-segments/findDuplicateSegments.js +34 -1
  141. package/lib/find-duplicate-segments/findDuplicateSegments.js.map +1 -1
  142. package/lib/find-duplicate-segments/index.js +21 -13
  143. package/lib/find-duplicate-segments/index.js.map +1 -1
  144. package/lib/find-usage/index.js +57 -41
  145. package/lib/find-usage/index.js.map +1 -1
  146. package/lib/generate-code/index.d.ts +1 -1
  147. package/lib/generate-code/index.js +64 -21
  148. package/lib/generate-code/index.js.map +1 -1
  149. package/lib/generate-code/typescript.d.ts +1 -1
  150. package/lib/generate-code/typescript.js +59 -333
  151. package/lib/generate-code/typescript.js.map +1 -1
  152. package/lib/index.d.ts +2 -1
  153. package/lib/index.js +2 -1
  154. package/lib/index.js.map +1 -1
  155. package/lib/info/index.js +57 -16
  156. package/lib/info/index.js.map +1 -1
  157. package/lib/init/index.d.ts +2 -2
  158. package/lib/init/index.js +39 -3
  159. package/lib/init/index.js.map +1 -1
  160. package/lib/linter/attributeSchema.d.ts +1 -0
  161. package/lib/linter/attributeSchema.js +1 -0
  162. package/lib/linter/attributeSchema.js.map +1 -1
  163. package/lib/linter/conditionSchema.js +5 -5
  164. package/lib/linter/conditionSchema.js.map +1 -1
  165. package/lib/linter/featureSchema.d.ts +4 -1
  166. package/lib/linter/featureSchema.js +15 -13
  167. package/lib/linter/featureSchema.js.map +1 -1
  168. package/lib/linter/groupSchema.d.ts +1 -0
  169. package/lib/linter/groupSchema.js +1 -0
  170. package/lib/linter/groupSchema.js.map +1 -1
  171. package/lib/linter/lintProject.d.ts +1 -3
  172. package/lib/linter/lintProject.js +198 -68
  173. package/lib/linter/lintProject.js.map +1 -1
  174. package/lib/linter/schema.js +1 -0
  175. package/lib/linter/schema.js.map +1 -1
  176. package/lib/linter/segmentSchema.d.ts +1 -0
  177. package/lib/linter/segmentSchema.js +1 -0
  178. package/lib/linter/segmentSchema.js.map +1 -1
  179. package/lib/linter/targetSchema.d.ts +16 -0
  180. package/lib/linter/targetSchema.js +40 -0
  181. package/lib/linter/targetSchema.js.map +1 -0
  182. package/lib/linter/testSchema.d.ts +4 -3
  183. package/lib/linter/testSchema.js +9 -4
  184. package/lib/linter/testSchema.js.map +1 -1
  185. package/lib/list/index.d.ts +1 -0
  186. package/lib/list/index.js +131 -12
  187. package/lib/list/index.js.map +1 -1
  188. package/lib/list/matrix.js +3 -7
  189. package/lib/list/matrix.js.map +1 -1
  190. package/lib/promoter/index.d.ts +50 -0
  191. package/lib/promoter/index.js +880 -0
  192. package/lib/promoter/index.js.map +1 -0
  193. package/lib/sets.d.ts +11 -0
  194. package/lib/sets.js +81 -0
  195. package/lib/sets.js.map +1 -0
  196. package/lib/targeting.d.ts +14 -0
  197. package/lib/targeting.js +82 -0
  198. package/lib/targeting.js.map +1 -0
  199. package/lib/tester/cliFormat.d.ts +7 -1
  200. package/lib/tester/cliFormat.js +11 -2
  201. package/lib/tester/cliFormat.js.map +1 -1
  202. package/lib/tester/printTestResult.js +2 -2
  203. package/lib/tester/printTestResult.js.map +1 -1
  204. package/lib/tester/testFeature.d.ts +0 -1
  205. package/lib/tester/testFeature.js +8 -25
  206. package/lib/tester/testFeature.js.map +1 -1
  207. package/lib/tester/testProject.d.ts +2 -3
  208. package/lib/tester/testProject.js +93 -86
  209. package/lib/tester/testProject.js.map +1 -1
  210. package/lib/tester/testSegment.d.ts +1 -1
  211. package/lib/tester/testSegment.js +3 -21
  212. package/lib/tester/testSegment.js.map +1 -1
  213. package/lib/utils/git.js +45 -19
  214. package/lib/utils/git.js.map +1 -1
  215. package/package.json +12 -12
  216. package/src/assess-distribution/index.ts +72 -52
  217. package/src/benchmark/index.ts +124 -91
  218. package/src/builder/{buildScopedConditions.spec.ts → applyContextToConditions.spec.ts} +160 -142
  219. package/src/builder/{buildScopedConditions.ts → applyContextToConditions.ts} +19 -14
  220. package/src/builder/{buildScopedDatafile.spec.ts → applyContextToDatafile.spec.ts} +141 -81
  221. package/src/builder/{buildScopedDatafile.ts → applyContextToDatafile.ts} +33 -33
  222. package/src/builder/{buildScopedSegments.spec.ts → applyContextToSegments.spec.ts} +171 -151
  223. package/src/builder/{buildScopedSegments.ts → applyContextToSegments.ts} +26 -14
  224. package/src/builder/buildDatafile.spec.ts +192 -14
  225. package/src/builder/buildDatafile.ts +74 -64
  226. package/src/builder/buildProject.ts +171 -86
  227. package/src/builder/buildRuntimeDatafiles.ts +57 -0
  228. package/src/builder/index.ts +0 -1
  229. package/src/cli/cli.ts +0 -5
  230. package/src/cli/plugins.ts +7 -2
  231. package/src/config/projectConfig.spec.ts +171 -8
  232. package/src/config/projectConfig.ts +100 -28
  233. package/src/datasource/adapter.ts +8 -23
  234. package/src/datasource/datasource.ts +50 -21
  235. package/src/datasource/filesystemAdapter.spec.ts +133 -74
  236. package/src/datasource/filesystemAdapter.ts +93 -227
  237. package/src/evaluate/index.ts +109 -97
  238. package/src/find-duplicate-segments/index.ts +34 -16
  239. package/src/find-usage/index.ts +89 -44
  240. package/src/generate-code/index.ts +36 -24
  241. package/src/generate-code/typescript.spec.ts +106 -0
  242. package/src/generate-code/typescript.ts +33 -398
  243. package/src/index.ts +2 -1
  244. package/src/info/index.ts +72 -16
  245. package/src/init/index.ts +1 -1
  246. package/src/linter/attributeSchema.ts +1 -0
  247. package/src/linter/conditionSchema.spec.ts +23 -3
  248. package/src/linter/conditionSchema.ts +5 -5
  249. package/src/linter/featureSchema.spec.ts +107 -18
  250. package/src/linter/featureSchema.ts +25 -28
  251. package/src/linter/groupSchema.ts +1 -0
  252. package/src/linter/lintProject.spec.ts +131 -92
  253. package/src/linter/lintProject.ts +233 -97
  254. package/src/linter/schema.ts +1 -0
  255. package/src/linter/segmentSchema.spec.ts +5 -3
  256. package/src/linter/segmentSchema.ts +1 -0
  257. package/src/linter/targetSchema.spec.ts +159 -0
  258. package/src/linter/targetSchema.ts +46 -0
  259. package/src/linter/testSchema.spec.ts +70 -5
  260. package/src/linter/testSchema.ts +12 -10
  261. package/src/list/index.spec.ts +135 -0
  262. package/src/list/index.ts +188 -12
  263. package/src/list/matrix.ts +3 -8
  264. package/src/promoter/index.spec.ts +617 -0
  265. package/src/promoter/index.ts +1266 -0
  266. package/src/sets.ts +76 -0
  267. package/src/targeting.spec.ts +74 -0
  268. package/src/targeting.ts +106 -0
  269. package/src/tester/cliFormat.ts +11 -1
  270. package/src/tester/printTestResult.ts +12 -3
  271. package/src/tester/testFeature.ts +10 -36
  272. package/src/tester/testProject.spec.ts +50 -0
  273. package/src/tester/testProject.ts +89 -140
  274. package/src/tester/testSegment.ts +5 -22
  275. package/src/utils/git.ts +13 -21
  276. package/tsconfig.cjs.json +5 -1
  277. package/tsconfig.typecheck.json +9 -0
  278. package/coverage/lcov-report/builder/convertToV1.ts.html +0 -583
  279. package/lib/builder/allocator.spec.d.ts +0 -1
  280. package/lib/builder/allocator.spec.js +0 -85
  281. package/lib/builder/allocator.spec.js.map +0 -1
  282. package/lib/builder/buildDatafile.spec.d.ts +0 -1
  283. package/lib/builder/buildDatafile.spec.js +0 -233
  284. package/lib/builder/buildDatafile.spec.js.map +0 -1
  285. package/lib/builder/buildScopedConditions.d.ts +0 -5
  286. package/lib/builder/buildScopedConditions.js.map +0 -1
  287. package/lib/builder/buildScopedConditions.spec.d.ts +0 -1
  288. package/lib/builder/buildScopedConditions.spec.js +0 -2167
  289. package/lib/builder/buildScopedConditions.spec.js.map +0 -1
  290. package/lib/builder/buildScopedDatafile.d.ts +0 -2
  291. package/lib/builder/buildScopedDatafile.js.map +0 -1
  292. package/lib/builder/buildScopedDatafile.spec.d.ts +0 -1
  293. package/lib/builder/buildScopedDatafile.spec.js +0 -2277
  294. package/lib/builder/buildScopedDatafile.spec.js.map +0 -1
  295. package/lib/builder/buildScopedSegments.d.ts +0 -5
  296. package/lib/builder/buildScopedSegments.js.map +0 -1
  297. package/lib/builder/buildScopedSegments.spec.d.ts +0 -1
  298. package/lib/builder/buildScopedSegments.spec.js +0 -1062
  299. package/lib/builder/buildScopedSegments.spec.js.map +0 -1
  300. package/lib/builder/convertToV1.d.ts +0 -10
  301. package/lib/builder/convertToV1.js +0 -119
  302. package/lib/builder/convertToV1.js.map +0 -1
  303. package/lib/builder/mutateVariables.spec.d.ts +0 -1
  304. package/lib/builder/mutateVariables.spec.js +0 -1074
  305. package/lib/builder/mutateVariables.spec.js.map +0 -1
  306. package/lib/builder/mutator.spec.d.ts +0 -1
  307. package/lib/builder/mutator.spec.js +0 -368
  308. package/lib/builder/mutator.spec.js.map +0 -1
  309. package/lib/builder/revision.spec.d.ts +0 -1
  310. package/lib/builder/revision.spec.js +0 -21
  311. package/lib/builder/revision.spec.js.map +0 -1
  312. package/lib/builder/traffic.spec.d.ts +0 -1
  313. package/lib/builder/traffic.spec.js +0 -872
  314. package/lib/builder/traffic.spec.js.map +0 -1
  315. package/lib/config/projectConfig.spec.d.ts +0 -1
  316. package/lib/config/projectConfig.spec.js +0 -24
  317. package/lib/config/projectConfig.spec.js.map +0 -1
  318. package/lib/datasource/filesystemAdapter.spec.d.ts +0 -1
  319. package/lib/datasource/filesystemAdapter.spec.js +0 -88
  320. package/lib/datasource/filesystemAdapter.spec.js.map +0 -1
  321. package/lib/generate-code/typescript.spec.d.ts +0 -1
  322. package/lib/generate-code/typescript.spec.js +0 -78
  323. package/lib/generate-code/typescript.spec.js.map +0 -1
  324. package/lib/linter/attributeSchema.spec.d.ts +0 -1
  325. package/lib/linter/attributeSchema.spec.js +0 -266
  326. package/lib/linter/attributeSchema.spec.js.map +0 -1
  327. package/lib/linter/conditionSchema.spec.d.ts +0 -1
  328. package/lib/linter/conditionSchema.spec.js +0 -380
  329. package/lib/linter/conditionSchema.spec.js.map +0 -1
  330. package/lib/linter/featureSchema.spec.d.ts +0 -1
  331. package/lib/linter/featureSchema.spec.js +0 -1552
  332. package/lib/linter/featureSchema.spec.js.map +0 -1
  333. package/lib/linter/lintProject.spec.d.ts +0 -1
  334. package/lib/linter/lintProject.spec.js +0 -211
  335. package/lib/linter/lintProject.spec.js.map +0 -1
  336. package/lib/linter/mutationNotation.spec.d.ts +0 -1
  337. package/lib/linter/mutationNotation.spec.js +0 -598
  338. package/lib/linter/mutationNotation.spec.js.map +0 -1
  339. package/lib/linter/schema.spec.d.ts +0 -1
  340. package/lib/linter/schema.spec.js +0 -535
  341. package/lib/linter/schema.spec.js.map +0 -1
  342. package/lib/linter/segmentSchema.spec.d.ts +0 -1
  343. package/lib/linter/segmentSchema.spec.js +0 -303
  344. package/lib/linter/segmentSchema.spec.js.map +0 -1
  345. package/lib/linter/testSchema.spec.d.ts +0 -1
  346. package/lib/linter/testSchema.spec.js +0 -162
  347. package/lib/linter/testSchema.spec.js.map +0 -1
  348. package/lib/list/matrix.spec.d.ts +0 -1
  349. package/lib/list/matrix.spec.js +0 -42
  350. package/lib/list/matrix.spec.js.map +0 -1
  351. package/lib/site/exportSite.d.ts +0 -2
  352. package/lib/site/exportSite.js +0 -30
  353. package/lib/site/exportSite.js.map +0 -1
  354. package/lib/site/generateHistory.d.ts +0 -3
  355. package/lib/site/generateHistory.js +0 -31
  356. package/lib/site/generateHistory.js.map +0 -1
  357. package/lib/site/generateSiteSearchIndex.d.ts +0 -4
  358. package/lib/site/generateSiteSearchIndex.js +0 -195
  359. package/lib/site/generateSiteSearchIndex.js.map +0 -1
  360. package/lib/site/getLastModifiedFromHistory.d.ts +0 -2
  361. package/lib/site/getLastModifiedFromHistory.js +0 -18
  362. package/lib/site/getLastModifiedFromHistory.js.map +0 -1
  363. package/lib/site/getOwnerAndRepoFromUrl.d.ts +0 -4
  364. package/lib/site/getOwnerAndRepoFromUrl.js +0 -20
  365. package/lib/site/getOwnerAndRepoFromUrl.js.map +0 -1
  366. package/lib/site/getRelativePaths.d.ts +0 -6
  367. package/lib/site/getRelativePaths.js +0 -15
  368. package/lib/site/getRelativePaths.js.map +0 -1
  369. package/lib/site/getRepoDetails.d.ts +0 -8
  370. package/lib/site/getRepoDetails.js +0 -48
  371. package/lib/site/getRepoDetails.js.map +0 -1
  372. package/lib/site/index.d.ts +0 -2
  373. package/lib/site/index.js +0 -43
  374. package/lib/site/index.js.map +0 -1
  375. package/lib/site/serveSite.d.ts +0 -2
  376. package/lib/site/serveSite.js +0 -54
  377. package/lib/site/serveSite.js.map +0 -1
  378. package/lib/tester/helpers.spec.d.ts +0 -1
  379. package/lib/tester/helpers.spec.js +0 -115
  380. package/lib/tester/helpers.spec.js.map +0 -1
  381. package/src/builder/convertToV1.ts +0 -166
  382. package/src/site/exportSite.ts +0 -42
  383. package/src/site/generateHistory.ts +0 -40
  384. package/src/site/generateSiteSearchIndex.ts +0 -258
  385. package/src/site/getLastModifiedFromHistory.ts +0 -21
  386. package/src/site/getOwnerAndRepoFromUrl.ts +0 -17
  387. package/src/site/getRelativePaths.ts +0 -24
  388. package/src/site/getRepoDetails.ts +0 -62
  389. package/src/site/index.ts +0 -46
  390. package/src/site/serveSite.ts +0 -58
@@ -3,15 +3,15 @@
3
3
  <html lang="en">
4
4
 
5
5
  <head>
6
- <title>Code coverage report for linter/lintProject.ts</title>
6
+ <title>Code coverage report for src/linter/lintProject.ts</title>
7
7
  <meta charset="utf-8" />
8
- <link rel="stylesheet" href="../prettify.css" />
9
- <link rel="stylesheet" href="../base.css" />
10
- <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
8
+ <link rel="stylesheet" href="../../prettify.css" />
9
+ <link rel="stylesheet" href="../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
11
  <meta name="viewport" content="width=device-width, initial-scale=1" />
12
12
  <style type='text/css'>
13
13
  .coverage-summary .sorter {
14
- background-image: url(../sort-arrow-sprite.png);
14
+ background-image: url(../../sort-arrow-sprite.png);
15
15
  }
16
16
  </style>
17
17
  </head>
@@ -19,34 +19,34 @@
19
19
  <body>
20
20
  <div class='wrapper'>
21
21
  <div class='pad1'>
22
- <h1><a href="../index.html">All files</a> / <a href="index.html">linter</a> lintProject.ts</h1>
22
+ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/linter</a> lintProject.ts</h1>
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">74.7% </span>
26
+ <span class="strong">78.26% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>192/257</span>
28
+ <span class='fraction'>252/322</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">63.97% </span>
33
+ <span class="strong">70.92% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>103/161</span>
35
+ <span class='fraction'>161/227</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">57.14% </span>
40
+ <span class="strong">62.96% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>12/21</span>
42
+ <span class='fraction'>17/27</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">76.8% </span>
47
+ <span class="strong">80.19% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>192/250</span>
49
+ <span class='fraction'>251/313</span>
50
50
  </div>
51
51
 
52
52
 
@@ -57,11 +57,11 @@
57
57
  <template id="filterTemplate">
58
58
  <div class="quiet">
59
59
  Filter:
60
- <input oninput="onInput()" type="search" id="fileSearch">
60
+ <input type="search" id="fileSearch">
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line medium'></div>
64
+ <div class='status-line high'></div>
65
65
  <pre><table class="coverage">
66
66
  <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
67
  <a name='L2'></a><a href='#L2'>2</a>
@@ -800,26 +800,165 @@
800
800
  <a name='L735'></a><a href='#L735'>735</a>
801
801
  <a name='L736'></a><a href='#L736'>736</a>
802
802
  <a name='L737'></a><a href='#L737'>737</a>
803
- <a name='L738'></a><a href='#L738'>738</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
804
- <span class="cline-any cline-yes">1x</span>
803
+ <a name='L738'></a><a href='#L738'>738</a>
804
+ <a name='L739'></a><a href='#L739'>739</a>
805
+ <a name='L740'></a><a href='#L740'>740</a>
806
+ <a name='L741'></a><a href='#L741'>741</a>
807
+ <a name='L742'></a><a href='#L742'>742</a>
808
+ <a name='L743'></a><a href='#L743'>743</a>
809
+ <a name='L744'></a><a href='#L744'>744</a>
810
+ <a name='L745'></a><a href='#L745'>745</a>
811
+ <a name='L746'></a><a href='#L746'>746</a>
812
+ <a name='L747'></a><a href='#L747'>747</a>
813
+ <a name='L748'></a><a href='#L748'>748</a>
814
+ <a name='L749'></a><a href='#L749'>749</a>
815
+ <a name='L750'></a><a href='#L750'>750</a>
816
+ <a name='L751'></a><a href='#L751'>751</a>
817
+ <a name='L752'></a><a href='#L752'>752</a>
818
+ <a name='L753'></a><a href='#L753'>753</a>
819
+ <a name='L754'></a><a href='#L754'>754</a>
820
+ <a name='L755'></a><a href='#L755'>755</a>
821
+ <a name='L756'></a><a href='#L756'>756</a>
822
+ <a name='L757'></a><a href='#L757'>757</a>
823
+ <a name='L758'></a><a href='#L758'>758</a>
824
+ <a name='L759'></a><a href='#L759'>759</a>
825
+ <a name='L760'></a><a href='#L760'>760</a>
826
+ <a name='L761'></a><a href='#L761'>761</a>
827
+ <a name='L762'></a><a href='#L762'>762</a>
828
+ <a name='L763'></a><a href='#L763'>763</a>
829
+ <a name='L764'></a><a href='#L764'>764</a>
830
+ <a name='L765'></a><a href='#L765'>765</a>
831
+ <a name='L766'></a><a href='#L766'>766</a>
832
+ <a name='L767'></a><a href='#L767'>767</a>
833
+ <a name='L768'></a><a href='#L768'>768</a>
834
+ <a name='L769'></a><a href='#L769'>769</a>
835
+ <a name='L770'></a><a href='#L770'>770</a>
836
+ <a name='L771'></a><a href='#L771'>771</a>
837
+ <a name='L772'></a><a href='#L772'>772</a>
838
+ <a name='L773'></a><a href='#L773'>773</a>
839
+ <a name='L774'></a><a href='#L774'>774</a>
840
+ <a name='L775'></a><a href='#L775'>775</a>
841
+ <a name='L776'></a><a href='#L776'>776</a>
842
+ <a name='L777'></a><a href='#L777'>777</a>
843
+ <a name='L778'></a><a href='#L778'>778</a>
844
+ <a name='L779'></a><a href='#L779'>779</a>
845
+ <a name='L780'></a><a href='#L780'>780</a>
846
+ <a name='L781'></a><a href='#L781'>781</a>
847
+ <a name='L782'></a><a href='#L782'>782</a>
848
+ <a name='L783'></a><a href='#L783'>783</a>
849
+ <a name='L784'></a><a href='#L784'>784</a>
850
+ <a name='L785'></a><a href='#L785'>785</a>
851
+ <a name='L786'></a><a href='#L786'>786</a>
852
+ <a name='L787'></a><a href='#L787'>787</a>
853
+ <a name='L788'></a><a href='#L788'>788</a>
854
+ <a name='L789'></a><a href='#L789'>789</a>
855
+ <a name='L790'></a><a href='#L790'>790</a>
856
+ <a name='L791'></a><a href='#L791'>791</a>
857
+ <a name='L792'></a><a href='#L792'>792</a>
858
+ <a name='L793'></a><a href='#L793'>793</a>
859
+ <a name='L794'></a><a href='#L794'>794</a>
860
+ <a name='L795'></a><a href='#L795'>795</a>
861
+ <a name='L796'></a><a href='#L796'>796</a>
862
+ <a name='L797'></a><a href='#L797'>797</a>
863
+ <a name='L798'></a><a href='#L798'>798</a>
864
+ <a name='L799'></a><a href='#L799'>799</a>
865
+ <a name='L800'></a><a href='#L800'>800</a>
866
+ <a name='L801'></a><a href='#L801'>801</a>
867
+ <a name='L802'></a><a href='#L802'>802</a>
868
+ <a name='L803'></a><a href='#L803'>803</a>
869
+ <a name='L804'></a><a href='#L804'>804</a>
870
+ <a name='L805'></a><a href='#L805'>805</a>
871
+ <a name='L806'></a><a href='#L806'>806</a>
872
+ <a name='L807'></a><a href='#L807'>807</a>
873
+ <a name='L808'></a><a href='#L808'>808</a>
874
+ <a name='L809'></a><a href='#L809'>809</a>
875
+ <a name='L810'></a><a href='#L810'>810</a>
876
+ <a name='L811'></a><a href='#L811'>811</a>
877
+ <a name='L812'></a><a href='#L812'>812</a>
878
+ <a name='L813'></a><a href='#L813'>813</a>
879
+ <a name='L814'></a><a href='#L814'>814</a>
880
+ <a name='L815'></a><a href='#L815'>815</a>
881
+ <a name='L816'></a><a href='#L816'>816</a>
882
+ <a name='L817'></a><a href='#L817'>817</a>
883
+ <a name='L818'></a><a href='#L818'>818</a>
884
+ <a name='L819'></a><a href='#L819'>819</a>
885
+ <a name='L820'></a><a href='#L820'>820</a>
886
+ <a name='L821'></a><a href='#L821'>821</a>
887
+ <a name='L822'></a><a href='#L822'>822</a>
888
+ <a name='L823'></a><a href='#L823'>823</a>
889
+ <a name='L824'></a><a href='#L824'>824</a>
890
+ <a name='L825'></a><a href='#L825'>825</a>
891
+ <a name='L826'></a><a href='#L826'>826</a>
892
+ <a name='L827'></a><a href='#L827'>827</a>
893
+ <a name='L828'></a><a href='#L828'>828</a>
894
+ <a name='L829'></a><a href='#L829'>829</a>
895
+ <a name='L830'></a><a href='#L830'>830</a>
896
+ <a name='L831'></a><a href='#L831'>831</a>
897
+ <a name='L832'></a><a href='#L832'>832</a>
898
+ <a name='L833'></a><a href='#L833'>833</a>
899
+ <a name='L834'></a><a href='#L834'>834</a>
900
+ <a name='L835'></a><a href='#L835'>835</a>
901
+ <a name='L836'></a><a href='#L836'>836</a>
902
+ <a name='L837'></a><a href='#L837'>837</a>
903
+ <a name='L838'></a><a href='#L838'>838</a>
904
+ <a name='L839'></a><a href='#L839'>839</a>
905
+ <a name='L840'></a><a href='#L840'>840</a>
906
+ <a name='L841'></a><a href='#L841'>841</a>
907
+ <a name='L842'></a><a href='#L842'>842</a>
908
+ <a name='L843'></a><a href='#L843'>843</a>
909
+ <a name='L844'></a><a href='#L844'>844</a>
910
+ <a name='L845'></a><a href='#L845'>845</a>
911
+ <a name='L846'></a><a href='#L846'>846</a>
912
+ <a name='L847'></a><a href='#L847'>847</a>
913
+ <a name='L848'></a><a href='#L848'>848</a>
914
+ <a name='L849'></a><a href='#L849'>849</a>
915
+ <a name='L850'></a><a href='#L850'>850</a>
916
+ <a name='L851'></a><a href='#L851'>851</a>
917
+ <a name='L852'></a><a href='#L852'>852</a>
918
+ <a name='L853'></a><a href='#L853'>853</a>
919
+ <a name='L854'></a><a href='#L854'>854</a>
920
+ <a name='L855'></a><a href='#L855'>855</a>
921
+ <a name='L856'></a><a href='#L856'>856</a>
922
+ <a name='L857'></a><a href='#L857'>857</a>
923
+ <a name='L858'></a><a href='#L858'>858</a>
924
+ <a name='L859'></a><a href='#L859'>859</a>
925
+ <a name='L860'></a><a href='#L860'>860</a>
926
+ <a name='L861'></a><a href='#L861'>861</a>
927
+ <a name='L862'></a><a href='#L862'>862</a>
928
+ <a name='L863'></a><a href='#L863'>863</a>
929
+ <a name='L864'></a><a href='#L864'>864</a>
930
+ <a name='L865'></a><a href='#L865'>865</a>
931
+ <a name='L866'></a><a href='#L866'>866</a>
932
+ <a name='L867'></a><a href='#L867'>867</a>
933
+ <a name='L868'></a><a href='#L868'>868</a>
934
+ <a name='L869'></a><a href='#L869'>869</a>
935
+ <a name='L870'></a><a href='#L870'>870</a>
936
+ <a name='L871'></a><a href='#L871'>871</a>
937
+ <a name='L872'></a><a href='#L872'>872</a>
938
+ <a name='L873'></a><a href='#L873'>873</a>
939
+ <a name='L874'></a><a href='#L874'>874</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
940
+ <span class="cline-any cline-yes">2x</span>
941
+ <span class="cline-any cline-yes">2x</span>
805
942
  <span class="cline-any cline-neutral">&nbsp;</span>
806
943
  <span class="cline-any cline-neutral">&nbsp;</span>
807
944
  <span class="cline-any cline-neutral">&nbsp;</span>
808
945
  <span class="cline-any cline-neutral">&nbsp;</span>
809
- <span class="cline-any cline-yes">1x</span>
810
- <span class="cline-any cline-yes">1x</span>
811
- <span class="cline-any cline-yes">1x</span>
812
- <span class="cline-any cline-yes">1x</span>
813
- <span class="cline-any cline-yes">1x</span>
814
- <span class="cline-any cline-yes">1x</span>
815
- <span class="cline-any cline-yes">1x</span>
946
+ <span class="cline-any cline-yes">2x</span>
947
+ <span class="cline-any cline-yes">2x</span>
948
+ <span class="cline-any cline-yes">2x</span>
949
+ <span class="cline-any cline-yes">2x</span>
950
+ <span class="cline-any cline-yes">2x</span>
951
+ <span class="cline-any cline-yes">2x</span>
952
+ <span class="cline-any cline-yes">2x</span>
953
+ <span class="cline-any cline-yes">2x</span>
816
954
  <span class="cline-any cline-neutral">&nbsp;</span>
817
- <span class="cline-any cline-yes">1x</span>
818
- <span class="cline-any cline-yes">1x</span>
819
- <span class="cline-any cline-yes">1x</span>
955
+ <span class="cline-any cline-yes">2x</span>
956
+ <span class="cline-any cline-yes">2x</span>
957
+ <span class="cline-any cline-yes">2x</span>
820
958
  <span class="cline-any cline-neutral">&nbsp;</span>
821
- <span class="cline-any cline-yes">1x</span>
959
+ <span class="cline-any cline-yes">2x</span>
822
960
  <span class="cline-any cline-neutral">&nbsp;</span>
961
+ <span class="cline-any cline-yes">2x</span>
823
962
  <span class="cline-any cline-neutral">&nbsp;</span>
824
963
  <span class="cline-any cline-neutral">&nbsp;</span>
825
964
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -848,11 +987,71 @@
848
987
  <span class="cline-any cline-neutral">&nbsp;</span>
849
988
  <span class="cline-any cline-neutral">&nbsp;</span>
850
989
  <span class="cline-any cline-neutral">&nbsp;</span>
851
- <span class="cline-any cline-yes">1x</span>
852
- <span class="cline-any cline-yes">1x</span>
853
990
  <span class="cline-any cline-neutral">&nbsp;</span>
854
- <span class="cline-any cline-yes">1x</span>
855
- <span class="cline-any cline-yes">1x</span>
991
+ <span class="cline-any cline-neutral">&nbsp;</span>
992
+ <span class="cline-any cline-neutral">&nbsp;</span>
993
+ <span class="cline-any cline-neutral">&nbsp;</span>
994
+ <span class="cline-any cline-neutral">&nbsp;</span>
995
+ <span class="cline-any cline-yes">2x</span>
996
+ <span class="cline-any cline-neutral">&nbsp;</span>
997
+ <span class="cline-any cline-yes">2x</span>
998
+ <span class="cline-any cline-neutral">&nbsp;</span>
999
+ <span class="cline-any cline-neutral">&nbsp;</span>
1000
+ <span class="cline-any cline-yes">2x</span>
1001
+ <span class="cline-any cline-neutral">&nbsp;</span>
1002
+ <span class="cline-any cline-neutral">&nbsp;</span>
1003
+ <span class="cline-any cline-yes">1204x</span>
1004
+ <span class="cline-any cline-neutral">&nbsp;</span>
1005
+ <span class="cline-any cline-neutral">&nbsp;</span>
1006
+ <span class="cline-any cline-neutral">&nbsp;</span>
1007
+ <span class="cline-any cline-yes">1204x</span>
1008
+ <span class="cline-any cline-neutral">&nbsp;</span>
1009
+ <span class="cline-any cline-neutral">&nbsp;</span>
1010
+ <span class="cline-any cline-neutral">&nbsp;</span>
1011
+ <span class="cline-any cline-neutral">&nbsp;</span>
1012
+ <span class="cline-any cline-yes">1204x</span>
1013
+ <span class="cline-any cline-neutral">&nbsp;</span>
1014
+ <span class="cline-any cline-neutral">&nbsp;</span>
1015
+ <span class="cline-any cline-neutral">&nbsp;</span>
1016
+ <span class="cline-any cline-neutral">&nbsp;</span>
1017
+ <span class="cline-any cline-neutral">&nbsp;</span>
1018
+ <span class="cline-any cline-neutral">&nbsp;</span>
1019
+ <span class="cline-any cline-neutral">&nbsp;</span>
1020
+ <span class="cline-any cline-yes">1204x</span>
1021
+ <span class="cline-any cline-neutral">&nbsp;</span>
1022
+ <span class="cline-any cline-yes">1204x</span>
1023
+ <span class="cline-any cline-neutral">&nbsp;</span>
1024
+ <span class="cline-any cline-neutral">&nbsp;</span>
1025
+ <span class="cline-any cline-neutral">&nbsp;</span>
1026
+ <span class="cline-any cline-neutral">&nbsp;</span>
1027
+ <span class="cline-any cline-yes">350x</span>
1028
+ <span class="cline-any cline-yes">350x</span>
1029
+ <span class="cline-any cline-yes">350x</span>
1030
+ <span class="cline-any cline-neutral">&nbsp;</span>
1031
+ <span class="cline-any cline-neutral">&nbsp;</span>
1032
+ <span class="cline-any cline-yes">1204x</span>
1033
+ <span class="cline-any cline-neutral">&nbsp;</span>
1034
+ <span class="cline-any cline-neutral">&nbsp;</span>
1035
+ <span class="cline-any cline-neutral">&nbsp;</span>
1036
+ <span class="cline-any cline-neutral">&nbsp;</span>
1037
+ <span class="cline-any cline-neutral">&nbsp;</span>
1038
+ <span class="cline-any cline-neutral">&nbsp;</span>
1039
+ <span class="cline-any cline-neutral">&nbsp;</span>
1040
+ <span class="cline-any cline-neutral">&nbsp;</span>
1041
+ <span class="cline-any cline-neutral">&nbsp;</span>
1042
+ <span class="cline-any cline-yes">1326x</span>
1043
+ <span class="cline-any cline-neutral">&nbsp;</span>
1044
+ <span class="cline-any cline-yes">1326x</span>
1045
+ <span class="cline-any cline-yes">350x</span>
1046
+ <span class="cline-any cline-yes">350x</span>
1047
+ <span class="cline-any cline-yes">350x</span>
1048
+ <span class="cline-any cline-yes">350x</span>
1049
+ <span class="cline-any cline-neutral">&nbsp;</span>
1050
+ <span class="cline-any cline-neutral">&nbsp;</span>
1051
+ <span class="cline-any cline-neutral">&nbsp;</span>
1052
+ <span class="cline-any cline-neutral">&nbsp;</span>
1053
+ <span class="cline-any cline-yes">1326x</span>
1054
+ <span class="cline-any cline-neutral">&nbsp;</span>
856
1055
  <span class="cline-any cline-neutral">&nbsp;</span>
857
1056
  <span class="cline-any cline-neutral">&nbsp;</span>
858
1057
  <span class="cline-any cline-no">&nbsp;</span>
@@ -866,97 +1065,115 @@
866
1065
  <span class="cline-any cline-neutral">&nbsp;</span>
867
1066
  <span class="cline-any cline-neutral">&nbsp;</span>
868
1067
  <span class="cline-any cline-neutral">&nbsp;</span>
869
- <span class="cline-any cline-yes">86x</span>
1068
+ <span class="cline-any cline-yes">222x</span>
870
1069
  <span class="cline-any cline-neutral">&nbsp;</span>
871
1070
  <span class="cline-any cline-neutral">&nbsp;</span>
872
- <span class="cline-any cline-yes">106x</span>
873
- <span class="cline-any cline-yes">96x</span>
1071
+ <span class="cline-any cline-yes">258x</span>
1072
+ <span class="cline-any cline-yes">240x</span>
874
1073
  <span class="cline-any cline-neutral">&nbsp;</span>
875
1074
  <span class="cline-any cline-neutral">&nbsp;</span>
876
- <span class="cline-any cline-yes">10x</span>
877
- <span class="cline-any cline-yes">20x</span>
878
- <span class="cline-any cline-yes">20x</span>
879
- <span class="cline-any cline-yes">20x</span>
1075
+ <span class="cline-any cline-yes">18x</span>
1076
+ <span class="cline-any cline-yes">36x</span>
1077
+ <span class="cline-any cline-yes">36x</span>
1078
+ <span class="cline-any cline-yes">36x</span>
880
1079
  <span class="cline-any cline-neutral">&nbsp;</span>
881
1080
  <span class="cline-any cline-neutral">&nbsp;</span>
882
1081
  <span class="cline-any cline-neutral">&nbsp;</span>
883
- <span class="cline-any cline-yes">86x</span>
1082
+ <span class="cline-any cline-yes">222x</span>
884
1083
  <span class="cline-any cline-neutral">&nbsp;</span>
885
1084
  <span class="cline-any cline-neutral">&nbsp;</span>
886
- <span class="cline-any cline-yes">1x</span>
1085
+ <span class="cline-any cline-yes">44x</span>
887
1086
  <span class="cline-any cline-neutral">&nbsp;</span>
888
1087
  <span class="cline-any cline-neutral">&nbsp;</span>
889
1088
  <span class="cline-any cline-neutral">&nbsp;</span>
890
- <span class="cline-any cline-yes">7x</span>
1089
+ <span class="cline-any cline-yes">45x</span>
891
1090
  <span class="cline-any cline-neutral">&nbsp;</span>
892
- <span class="cline-any cline-yes">7x</span>
893
- <span class="cline-any cline-yes">7x</span>
1091
+ <span class="cline-any cline-yes">45x</span>
1092
+ <span class="cline-any cline-yes">45x</span>
894
1093
  <span class="cline-any cline-neutral">&nbsp;</span>
895
1094
  <span class="cline-any cline-neutral">&nbsp;</span>
896
- <span class="cline-any cline-yes">22x</span>
1095
+ <span class="cline-any cline-yes">225x</span>
897
1096
  <span class="cline-any cline-no">&nbsp;</span>
898
1097
  <span class="cline-any cline-neutral">&nbsp;</span>
899
1098
  <span class="cline-any cline-neutral">&nbsp;</span>
900
1099
  <span class="cline-any cline-neutral">&nbsp;</span>
901
1100
  <span class="cline-any cline-neutral">&nbsp;</span>
902
- <span class="cline-any cline-yes">428x</span>
903
- <span class="cline-any cline-yes">428x</span>
1101
+ <span class="cline-any cline-yes">1204x</span>
904
1102
  <span class="cline-any cline-neutral">&nbsp;</span>
905
- <span class="cline-any cline-yes">428x</span>
906
- <span class="cline-any cline-yes">69x</span>
907
- <span class="cline-any cline-yes">359x</span>
908
- <span class="cline-any cline-yes">66x</span>
909
- <span class="cline-any cline-yes">293x</span>
910
- <span class="cline-any cline-yes">89x</span>
911
- <span class="cline-any cline-yes">204x</span>
912
- <span class="cline-any cline-yes">3x</span>
913
- <span class="cline-any cline-yes">201x</span>
914
- <span class="cline-any cline-yes">60x</span>
915
1103
  <span class="cline-any cline-neutral">&nbsp;</span>
916
- <span class="cline-any cline-yes">141x</span>
1104
+ <span class="cline-any cline-yes">1204x</span>
917
1105
  <span class="cline-any cline-neutral">&nbsp;</span>
1106
+ <span class="cline-any cline-yes">1204x</span>
1107
+ <span class="cline-any cline-yes">205x</span>
1108
+ <span class="cline-any cline-yes">999x</span>
1109
+ <span class="cline-any cline-yes">189x</span>
1110
+ <span class="cline-any cline-yes">810x</span>
1111
+ <span class="cline-any cline-yes">263x</span>
1112
+ <span class="cline-any cline-yes">547x</span>
1113
+ <span class="cline-any cline-yes">8x</span>
1114
+ <span class="cline-any cline-yes">539x</span>
1115
+ <span class="cline-any cline-yes">174x</span>
1116
+ <span class="cline-any cline-yes">365x</span>
1117
+ <span class="cline-any cline-yes">15x</span>
918
1118
  <span class="cline-any cline-neutral">&nbsp;</span>
919
- <span class="cline-any cline-yes">428x</span>
920
- <span class="cline-any cline-no">&nbsp;</span>
1119
+ <span class="cline-any cline-yes">350x</span>
921
1120
  <span class="cline-any cline-neutral">&nbsp;</span>
922
1121
  <span class="cline-any cline-neutral">&nbsp;</span>
923
- <span class="cline-any cline-yes">428x</span>
1122
+ <span class="cline-any cline-yes">1204x</span>
1123
+ <span class="cline-any cline-no">&nbsp;</span>
924
1124
  <span class="cline-any cline-neutral">&nbsp;</span>
925
1125
  <span class="cline-any cline-neutral">&nbsp;</span>
1126
+ <span class="cline-any cline-yes">1204x</span>
926
1127
  <span class="cline-any cline-neutral">&nbsp;</span>
927
1128
  <span class="cline-any cline-neutral">&nbsp;</span>
928
1129
  <span class="cline-any cline-neutral">&nbsp;</span>
1130
+ <span class="cline-any cline-yes">298x</span>
1131
+ <span class="cline-any cline-yes">43x</span>
929
1132
  <span class="cline-any cline-neutral">&nbsp;</span>
930
- <span class="cline-any cline-yes">4x</span>
1133
+ <span class="cline-any cline-yes">255x</span>
1134
+ <span class="cline-any cline-yes">43x</span>
931
1135
  <span class="cline-any cline-neutral">&nbsp;</span>
932
- <span class="cline-any cline-yes">4x</span>
933
- <span class="cline-any cline-yes">1x</span>
1136
+ <span class="cline-any cline-yes">212x</span>
1137
+ <span class="cline-any cline-yes">42x</span>
934
1138
  <span class="cline-any cline-neutral">&nbsp;</span>
1139
+ <span class="cline-any cline-yes">170x</span>
1140
+ <span class="cline-any cline-yes">42x</span>
935
1141
  <span class="cline-any cline-neutral">&nbsp;</span>
936
- <span class="cline-any cline-yes">3x</span>
937
- <span class="cline-any cline-no">&nbsp;</span>
1142
+ <span class="cline-any cline-yes">128x</span>
1143
+ <span class="cline-any cline-yes">42x</span>
938
1144
  <span class="cline-any cline-neutral">&nbsp;</span>
1145
+ <span class="cline-any cline-yes">86x</span>
1146
+ <span class="cline-any cline-yes">42x</span>
939
1147
  <span class="cline-any cline-neutral">&nbsp;</span>
940
- <span class="cline-any cline-yes">3x</span>
941
- <span class="cline-any cline-yes">3x</span>
942
1148
  <span class="cline-any cline-neutral">&nbsp;</span>
1149
+ <span class="cline-any cline-yes">44x</span>
943
1150
  <span class="cline-any cline-neutral">&nbsp;</span>
944
1151
  <span class="cline-any cline-neutral">&nbsp;</span>
945
- <span class="cline-any cline-yes">1x</span>
946
1152
  <span class="cline-any cline-neutral">&nbsp;</span>
947
1153
  <span class="cline-any cline-neutral">&nbsp;</span>
948
1154
  <span class="cline-any cline-neutral">&nbsp;</span>
949
1155
  <span class="cline-any cline-neutral">&nbsp;</span>
1156
+ <span class="cline-any cline-yes">419x</span>
1157
+ <span class="cline-any cline-yes">72x</span>
950
1158
  <span class="cline-any cline-neutral">&nbsp;</span>
951
- <span class="cline-any cline-yes">1x</span>
952
- <span class="cline-any cline-yes">1x</span>
953
1159
  <span class="cline-any cline-neutral">&nbsp;</span>
1160
+ <span class="cline-any cline-yes">347x</span>
1161
+ <span class="cline-any cline-yes">347x</span>
1162
+ <span class="cline-any cline-yes">347x</span>
954
1163
  <span class="cline-any cline-neutral">&nbsp;</span>
1164
+ <span class="cline-any cline-yes">347x</span>
1165
+ <span class="cline-any cline-yes">1326x</span>
1166
+ <span class="cline-any cline-yes">1326x</span>
1167
+ <span class="cline-any cline-yes">1326x</span>
955
1168
  <span class="cline-any cline-neutral">&nbsp;</span>
956
- <span class="cline-any cline-yes">2x</span>
1169
+ <span class="cline-any cline-yes">1326x</span>
1170
+ <span class="cline-any cline-no">&nbsp;</span>
957
1171
  <span class="cline-any cline-neutral">&nbsp;</span>
958
1172
  <span class="cline-any cline-neutral">&nbsp;</span>
1173
+ <span class="cline-any cline-yes">1326x</span>
959
1174
  <span class="cline-any cline-neutral">&nbsp;</span>
1175
+ <span class="cline-any cline-yes">1326x</span>
1176
+ <span class="cline-any cline-yes">1x</span>
960
1177
  <span class="cline-any cline-neutral">&nbsp;</span>
961
1178
  <span class="cline-any cline-neutral">&nbsp;</span>
962
1179
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -966,17 +1183,14 @@
966
1183
  <span class="cline-any cline-neutral">&nbsp;</span>
967
1184
  <span class="cline-any cline-neutral">&nbsp;</span>
968
1185
  <span class="cline-any cline-neutral">&nbsp;</span>
969
- <span class="cline-any cline-yes">4x</span>
970
- <span class="cline-any cline-yes">3x</span>
1186
+ <span class="cline-any cline-yes">1326x</span>
1187
+ <span class="cline-any cline-yes">122x</span>
971
1188
  <span class="cline-any cline-neutral">&nbsp;</span>
972
- <span class="cline-any cline-yes">1x</span>
973
- <span class="cline-any cline-yes">1x</span>
974
1189
  <span class="cline-any cline-neutral">&nbsp;</span>
975
1190
  <span class="cline-any cline-neutral">&nbsp;</span>
976
1191
  <span class="cline-any cline-neutral">&nbsp;</span>
977
- <span class="cline-any cline-yes">1x</span>
978
1192
  <span class="cline-any cline-neutral">&nbsp;</span>
979
- <span class="cline-any cline-no">&nbsp;</span>
1193
+ <span class="cline-any cline-yes">297x</span>
980
1194
  <span class="cline-any cline-neutral">&nbsp;</span>
981
1195
  <span class="cline-any cline-neutral">&nbsp;</span>
982
1196
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -993,7 +1207,7 @@
993
1207
  <span class="cline-any cline-neutral">&nbsp;</span>
994
1208
  <span class="cline-any cline-neutral">&nbsp;</span>
995
1209
  <span class="cline-any cline-neutral">&nbsp;</span>
996
- <span class="cline-any cline-yes">9x</span>
1210
+ <span class="cline-any cline-yes">10x</span>
997
1211
  <span class="cline-any cline-neutral">&nbsp;</span>
998
1212
  <span class="cline-any cline-neutral">&nbsp;</span>
999
1213
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1015,7 +1229,7 @@
1015
1229
  <span class="cline-any cline-neutral">&nbsp;</span>
1016
1230
  <span class="cline-any cline-neutral">&nbsp;</span>
1017
1231
  <span class="cline-any cline-neutral">&nbsp;</span>
1018
- <span class="cline-any cline-yes">1x</span>
1232
+ <span class="cline-any cline-yes">2x</span>
1019
1233
  <span class="cline-any cline-neutral">&nbsp;</span>
1020
1234
  <span class="cline-any cline-neutral">&nbsp;</span>
1021
1235
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1025,7 +1239,7 @@
1025
1239
  <span class="cline-any cline-neutral">&nbsp;</span>
1026
1240
  <span class="cline-any cline-neutral">&nbsp;</span>
1027
1241
  <span class="cline-any cline-neutral">&nbsp;</span>
1028
- <span class="cline-any cline-yes">1x</span>
1242
+ <span class="cline-any cline-yes">2x</span>
1029
1243
  <span class="cline-any cline-no">&nbsp;</span>
1030
1244
  <span class="cline-any cline-no">&nbsp;</span>
1031
1245
  <span class="cline-any cline-no">&nbsp;</span>
@@ -1073,28 +1287,15 @@
1073
1287
  <span class="cline-any cline-neutral">&nbsp;</span>
1074
1288
  <span class="cline-any cline-neutral">&nbsp;</span>
1075
1289
  <span class="cline-any cline-neutral">&nbsp;</span>
1076
- <span class="cline-any cline-yes">5x</span>
1077
- <span class="cline-any cline-neutral">&nbsp;</span>
1078
- <span class="cline-any cline-yes">5x</span>
1079
- <span class="cline-any cline-neutral">&nbsp;</span>
1290
+ <span class="cline-any cline-yes">7x</span>
1080
1291
  <span class="cline-any cline-neutral">&nbsp;</span>
1081
1292
  <span class="cline-any cline-neutral">&nbsp;</span>
1082
1293
  <span class="cline-any cline-neutral">&nbsp;</span>
1083
1294
  <span class="cline-any cline-neutral">&nbsp;</span>
1084
- <span class="cline-any cline-yes">5x</span>
1085
- <span class="cline-any cline-yes">5x</span>
1086
1295
  <span class="cline-any cline-neutral">&nbsp;</span>
1087
1296
  <span class="cline-any cline-yes">7x</span>
1088
- <span class="cline-any cline-neutral">&nbsp;</span>
1089
1297
  <span class="cline-any cline-yes">7x</span>
1090
- <span class="cline-any cline-neutral">&nbsp;</span>
1091
- <span class="cline-any cline-neutral">&nbsp;</span>
1092
- <span class="cline-any cline-neutral">&nbsp;</span>
1093
1298
  <span class="cline-any cline-yes">7x</span>
1094
- <span class="cline-any cline-neutral">&nbsp;</span>
1095
- <span class="cline-any cline-neutral">&nbsp;</span>
1096
- <span class="cline-any cline-neutral">&nbsp;</span>
1097
- <span class="cline-any cline-neutral">&nbsp;</span>
1098
1299
  <span class="cline-any cline-yes">7x</span>
1099
1300
  <span class="cline-any cline-yes">7x</span>
1100
1301
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1109,8 +1310,7 @@
1109
1310
  <span class="cline-any cline-neutral">&nbsp;</span>
1110
1311
  <span class="cline-any cline-neutral">&nbsp;</span>
1111
1312
  <span class="cline-any cline-neutral">&nbsp;</span>
1112
- <span class="cline-any cline-neutral">&nbsp;</span>
1113
- <span class="cline-any cline-yes">5x</span>
1313
+ <span class="cline-any cline-yes">7x</span>
1114
1314
  <span class="cline-any cline-no">&nbsp;</span>
1115
1315
  <span class="cline-any cline-no">&nbsp;</span>
1116
1316
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1142,51 +1342,53 @@
1142
1342
  <span class="cline-any cline-neutral">&nbsp;</span>
1143
1343
  <span class="cline-any cline-neutral">&nbsp;</span>
1144
1344
  <span class="cline-any cline-neutral">&nbsp;</span>
1145
- <span class="cline-any cline-yes">7x</span>
1345
+ <span class="cline-any cline-yes">45x</span>
1146
1346
  <span class="cline-any cline-neutral">&nbsp;</span>
1147
- <span class="cline-any cline-yes">7x</span>
1347
+ <span class="cline-any cline-yes">45x</span>
1148
1348
  <span class="cline-any cline-no">&nbsp;</span>
1149
1349
  <span class="cline-any cline-no">&nbsp;</span>
1150
1350
  <span class="cline-any cline-no">&nbsp;</span>
1151
1351
  <span class="cline-any cline-neutral">&nbsp;</span>
1152
1352
  <span class="cline-any cline-neutral">&nbsp;</span>
1153
1353
  <span class="cline-any cline-neutral">&nbsp;</span>
1154
- <span class="cline-any cline-yes">7x</span>
1155
- <span class="cline-any cline-yes">7x</span>
1156
- <span class="cline-any cline-yes">7x</span>
1157
- <span class="cline-any cline-yes">100x</span>
1158
- <span class="cline-any cline-yes">100x</span>
1354
+ <span class="cline-any cline-yes">45x</span>
1355
+ <span class="cline-any cline-yes">45x</span>
1356
+ <span class="cline-any cline-yes">45x</span>
1357
+ <span class="cline-any cline-yes">214x</span>
1358
+ <span class="cline-any cline-yes">214x</span>
1159
1359
  <span class="cline-any cline-neutral">&nbsp;</span>
1160
1360
  <span class="cline-any cline-neutral">&nbsp;</span>
1161
1361
  <span class="cline-any cline-neutral">&nbsp;</span>
1162
1362
  <span class="cline-any cline-neutral">&nbsp;</span>
1163
1363
  <span class="cline-any cline-neutral">&nbsp;</span>
1164
1364
  <span class="cline-any cline-neutral">&nbsp;</span>
1165
- <span class="cline-any cline-yes">7x</span>
1166
- <span class="cline-any cline-yes">7x</span>
1167
- <span class="cline-any cline-yes">7x</span>
1365
+ <span class="cline-any cline-yes">45x</span>
1366
+ <span class="cline-any cline-yes">45x</span>
1367
+ <span class="cline-any cline-yes">45x</span>
1168
1368
  <span class="cline-any cline-neutral">&nbsp;</span>
1169
- <span class="cline-any cline-yes">7x</span>
1170
- <span class="cline-any cline-yes">86x</span>
1171
- <span class="cline-any cline-yes">86x</span>
1369
+ <span class="cline-any cline-yes">45x</span>
1370
+ <span class="cline-any cline-yes">222x</span>
1371
+ <span class="cline-any cline-yes">222x</span>
1172
1372
  <span class="cline-any cline-neutral">&nbsp;</span>
1173
1373
  <span class="cline-any cline-neutral">&nbsp;</span>
1174
1374
  <span class="cline-any cline-neutral">&nbsp;</span>
1175
1375
  <span class="cline-any cline-neutral">&nbsp;</span>
1176
1376
  <span class="cline-any cline-neutral">&nbsp;</span>
1177
- <span class="cline-any cline-yes">7x</span>
1178
- <span class="cline-any cline-yes">4x</span>
1377
+ <span class="cline-any cline-yes">45x</span>
1378
+ <span class="cline-any cline-yes">43x</span>
1379
+ <span class="cline-any cline-neutral">&nbsp;</span>
1380
+ <span class="cline-any cline-yes">43x</span>
1179
1381
  <span class="cline-any cline-neutral">&nbsp;</span>
1180
1382
  <span class="cline-any cline-no">&nbsp;</span>
1181
1383
  <span class="cline-any cline-neutral">&nbsp;</span>
1182
- <span class="cline-any cline-yes">4x</span>
1183
- <span class="cline-any cline-yes">4x</span>
1384
+ <span class="cline-any cline-yes">43x</span>
1385
+ <span class="cline-any cline-yes">42x</span>
1184
1386
  <span class="cline-any cline-neutral">&nbsp;</span>
1185
1387
  <span class="cline-any cline-neutral">&nbsp;</span>
1186
- <span class="cline-any cline-yes">4x</span>
1187
- <span class="cline-any cline-yes">69x</span>
1388
+ <span class="cline-any cline-yes">43x</span>
1389
+ <span class="cline-any cline-yes">205x</span>
1188
1390
  <span class="cline-any cline-neutral">&nbsp;</span>
1189
- <span class="cline-any cline-yes">69x</span>
1391
+ <span class="cline-any cline-yes">205x</span>
1190
1392
  <span class="cline-any cline-yes">1x</span>
1191
1393
  <span class="cline-any cline-neutral">&nbsp;</span>
1192
1394
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1197,12 +1399,12 @@
1197
1399
  <span class="cline-any cline-neutral">&nbsp;</span>
1198
1400
  <span class="cline-any cline-neutral">&nbsp;</span>
1199
1401
  <span class="cline-any cline-neutral">&nbsp;</span>
1200
- <span class="cline-any cline-yes">69x</span>
1201
- <span class="cline-any cline-yes">69x</span>
1202
- <span class="cline-any cline-yes">69x</span>
1402
+ <span class="cline-any cline-yes">205x</span>
1403
+ <span class="cline-any cline-yes">205x</span>
1404
+ <span class="cline-any cline-yes">205x</span>
1203
1405
  <span class="cline-any cline-neutral">&nbsp;</span>
1204
- <span class="cline-any cline-yes">69x</span>
1205
- <span class="cline-any cline-no">&nbsp;</span>
1406
+ <span class="cline-any cline-yes">205x</span>
1407
+ <span class="cline-any cline-yes">1x</span>
1206
1408
  <span class="cline-any cline-neutral">&nbsp;</span>
1207
1409
  <span class="cline-any cline-neutral">&nbsp;</span>
1208
1410
  <span class="cline-any cline-no">&nbsp;</span>
@@ -1210,33 +1412,35 @@
1210
1412
  <span class="cline-any cline-neutral">&nbsp;</span>
1211
1413
  <span class="cline-any cline-neutral">&nbsp;</span>
1212
1414
  <span class="cline-any cline-neutral">&nbsp;</span>
1213
- <span class="cline-any cline-yes">7x</span>
1214
- <span class="cline-any cline-yes">7x</span>
1215
- <span class="cline-any cline-yes">86x</span>
1216
- <span class="cline-any cline-yes">86x</span>
1415
+ <span class="cline-any cline-yes">45x</span>
1416
+ <span class="cline-any cline-yes">45x</span>
1417
+ <span class="cline-any cline-yes">222x</span>
1418
+ <span class="cline-any cline-yes">222x</span>
1217
1419
  <span class="cline-any cline-no">&nbsp;</span>
1218
1420
  <span class="cline-any cline-neutral">&nbsp;</span>
1219
1421
  <span class="cline-any cline-neutral">&nbsp;</span>
1220
- <span class="cline-any cline-yes">86x</span>
1422
+ <span class="cline-any cline-yes">222x</span>
1221
1423
  <span class="cline-any cline-neutral">&nbsp;</span>
1222
- <span class="cline-any cline-yes">7x</span>
1424
+ <span class="cline-any cline-yes">45x</span>
1223
1425
  <span class="cline-any cline-neutral">&nbsp;</span>
1224
1426
  <span class="cline-any cline-neutral">&nbsp;</span>
1225
- <span class="cline-any cline-yes">7x</span>
1226
- <span class="cline-any cline-yes">7x</span>
1227
- <span class="cline-any cline-yes">7x</span>
1427
+ <span class="cline-any cline-yes">45x</span>
1428
+ <span class="cline-any cline-yes">45x</span>
1429
+ <span class="cline-any cline-yes">45x</span>
1228
1430
  <span class="cline-any cline-neutral">&nbsp;</span>
1229
- <span class="cline-any cline-yes">7x</span>
1230
- <span class="cline-any cline-yes">3x</span>
1431
+ <span class="cline-any cline-yes">45x</span>
1432
+ <span class="cline-any cline-yes">42x</span>
1231
1433
  <span class="cline-any cline-neutral">&nbsp;</span>
1232
- <span class="cline-any cline-yes">3x</span>
1233
- <span class="cline-any cline-yes">3x</span>
1434
+ <span class="cline-any cline-yes">42x</span>
1234
1435
  <span class="cline-any cline-neutral">&nbsp;</span>
1436
+ <span class="cline-any cline-yes">42x</span>
1437
+ <span class="cline-any cline-yes">42x</span>
1235
1438
  <span class="cline-any cline-neutral">&nbsp;</span>
1236
- <span class="cline-any cline-yes">3x</span>
1237
- <span class="cline-any cline-yes">66x</span>
1238
1439
  <span class="cline-any cline-neutral">&nbsp;</span>
1239
- <span class="cline-any cline-yes">66x</span>
1440
+ <span class="cline-any cline-yes">42x</span>
1441
+ <span class="cline-any cline-yes">189x</span>
1442
+ <span class="cline-any cline-neutral">&nbsp;</span>
1443
+ <span class="cline-any cline-yes">189x</span>
1240
1444
  <span class="cline-any cline-no">&nbsp;</span>
1241
1445
  <span class="cline-any cline-neutral">&nbsp;</span>
1242
1446
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1247,22 +1451,22 @@
1247
1451
  <span class="cline-any cline-neutral">&nbsp;</span>
1248
1452
  <span class="cline-any cline-neutral">&nbsp;</span>
1249
1453
  <span class="cline-any cline-neutral">&nbsp;</span>
1250
- <span class="cline-any cline-yes">66x</span>
1251
- <span class="cline-any cline-yes">66x</span>
1252
- <span class="cline-any cline-yes">66x</span>
1454
+ <span class="cline-any cline-yes">189x</span>
1455
+ <span class="cline-any cline-yes">189x</span>
1456
+ <span class="cline-any cline-yes">188x</span>
1253
1457
  <span class="cline-any cline-neutral">&nbsp;</span>
1254
- <span class="cline-any cline-yes">66x</span>
1458
+ <span class="cline-any cline-yes">188x</span>
1255
1459
  <span class="cline-any cline-yes">1x</span>
1256
1460
  <span class="cline-any cline-neutral">&nbsp;</span>
1257
1461
  <span class="cline-any cline-neutral">&nbsp;</span>
1258
- <span class="cline-any cline-no">&nbsp;</span>
1462
+ <span class="cline-any cline-yes">1x</span>
1259
1463
  <span class="cline-any cline-neutral">&nbsp;</span>
1260
1464
  <span class="cline-any cline-neutral">&nbsp;</span>
1261
1465
  <span class="cline-any cline-neutral">&nbsp;</span>
1262
1466
  <span class="cline-any cline-neutral">&nbsp;</span>
1263
1467
  <span class="cline-any cline-neutral">&nbsp;</span>
1264
- <span class="cline-any cline-yes">7x</span>
1265
- <span class="cline-any cline-yes">7x</span>
1468
+ <span class="cline-any cline-yes">45x</span>
1469
+ <span class="cline-any cline-yes">45x</span>
1266
1470
  <span class="cline-any cline-neutral">&nbsp;</span>
1267
1471
  <span class="cline-any cline-neutral">&nbsp;</span>
1268
1472
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1272,17 +1476,19 @@
1272
1476
  <span class="cline-any cline-neutral">&nbsp;</span>
1273
1477
  <span class="cline-any cline-neutral">&nbsp;</span>
1274
1478
  <span class="cline-any cline-neutral">&nbsp;</span>
1275
- <span class="cline-any cline-yes">7x</span>
1276
- <span class="cline-any cline-yes">5x</span>
1479
+ <span class="cline-any cline-yes">45x</span>
1480
+ <span class="cline-any cline-yes">42x</span>
1277
1481
  <span class="cline-any cline-neutral">&nbsp;</span>
1278
- <span class="cline-any cline-yes">5x</span>
1279
- <span class="cline-any cline-yes">5x</span>
1482
+ <span class="cline-any cline-yes">42x</span>
1280
1483
  <span class="cline-any cline-neutral">&nbsp;</span>
1484
+ <span class="cline-any cline-yes">42x</span>
1485
+ <span class="cline-any cline-yes">41x</span>
1281
1486
  <span class="cline-any cline-neutral">&nbsp;</span>
1282
- <span class="cline-any cline-yes">5x</span>
1283
- <span class="cline-any cline-yes">83x</span>
1284
1487
  <span class="cline-any cline-neutral">&nbsp;</span>
1285
- <span class="cline-any cline-yes">83x</span>
1488
+ <span class="cline-any cline-yes">42x</span>
1489
+ <span class="cline-any cline-yes">263x</span>
1490
+ <span class="cline-any cline-neutral">&nbsp;</span>
1491
+ <span class="cline-any cline-yes">263x</span>
1286
1492
  <span class="cline-any cline-no">&nbsp;</span>
1287
1493
  <span class="cline-any cline-neutral">&nbsp;</span>
1288
1494
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1295,21 +1501,21 @@
1295
1501
  <span class="cline-any cline-neutral">&nbsp;</span>
1296
1502
  <span class="cline-any cline-neutral">&nbsp;</span>
1297
1503
  <span class="cline-any cline-neutral">&nbsp;</span>
1298
- <span class="cline-any cline-yes">83x</span>
1299
- <span class="cline-any cline-yes">83x</span>
1504
+ <span class="cline-any cline-yes">263x</span>
1505
+ <span class="cline-any cline-yes">263x</span>
1300
1506
  <span class="cline-any cline-neutral">&nbsp;</span>
1301
- <span class="cline-any cline-yes">82x</span>
1507
+ <span class="cline-any cline-yes">263x</span>
1302
1508
  <span class="cline-any cline-neutral">&nbsp;</span>
1303
- <span class="cline-any cline-yes">82x</span>
1509
+ <span class="cline-any cline-yes">263x</span>
1304
1510
  <span class="cline-any cline-yes">2x</span>
1305
1511
  <span class="cline-any cline-neutral">&nbsp;</span>
1306
1512
  <span class="cline-any cline-neutral">&nbsp;</span>
1307
- <span class="cline-any cline-yes">1x</span>
1513
+ <span class="cline-any cline-no">&nbsp;</span>
1308
1514
  <span class="cline-any cline-neutral">&nbsp;</span>
1309
1515
  <span class="cline-any cline-neutral">&nbsp;</span>
1310
- <span class="cline-any cline-yes">83x</span>
1311
- <span class="cline-any cline-yes">3x</span>
1312
- <span class="cline-any cline-yes">3x</span>
1516
+ <span class="cline-any cline-yes">263x</span>
1517
+ <span class="cline-any cline-yes">7x</span>
1518
+ <span class="cline-any cline-yes">7x</span>
1313
1519
  <span class="cline-any cline-neutral">&nbsp;</span>
1314
1520
  <span class="cline-any cline-no">&nbsp;</span>
1315
1521
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1324,20 +1530,22 @@
1324
1530
  <span class="cline-any cline-neutral">&nbsp;</span>
1325
1531
  <span class="cline-any cline-neutral">&nbsp;</span>
1326
1532
  <span class="cline-any cline-neutral">&nbsp;</span>
1327
- <span class="cline-any cline-yes">7x</span>
1328
- <span class="cline-any cline-yes">7x</span>
1533
+ <span class="cline-any cline-yes">45x</span>
1534
+ <span class="cline-any cline-yes">45x</span>
1329
1535
  <span class="cline-any cline-neutral">&nbsp;</span>
1330
- <span class="cline-any cline-yes">7x</span>
1331
- <span class="cline-any cline-yes">3x</span>
1536
+ <span class="cline-any cline-yes">45x</span>
1537
+ <span class="cline-any cline-yes">42x</span>
1332
1538
  <span class="cline-any cline-neutral">&nbsp;</span>
1333
- <span class="cline-any cline-yes">3x</span>
1334
- <span class="cline-any cline-yes">3x</span>
1539
+ <span class="cline-any cline-yes">42x</span>
1335
1540
  <span class="cline-any cline-neutral">&nbsp;</span>
1541
+ <span class="cline-any cline-yes">42x</span>
1542
+ <span class="cline-any cline-yes">8x</span>
1336
1543
  <span class="cline-any cline-neutral">&nbsp;</span>
1337
- <span class="cline-any cline-yes">3x</span>
1338
- <span class="cline-any cline-yes">3x</span>
1339
1544
  <span class="cline-any cline-neutral">&nbsp;</span>
1340
- <span class="cline-any cline-yes">3x</span>
1545
+ <span class="cline-any cline-yes">42x</span>
1546
+ <span class="cline-any cline-yes">8x</span>
1547
+ <span class="cline-any cline-neutral">&nbsp;</span>
1548
+ <span class="cline-any cline-yes">8x</span>
1341
1549
  <span class="cline-any cline-no">&nbsp;</span>
1342
1550
  <span class="cline-any cline-neutral">&nbsp;</span>
1343
1551
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1350,21 +1558,21 @@
1350
1558
  <span class="cline-any cline-neutral">&nbsp;</span>
1351
1559
  <span class="cline-any cline-neutral">&nbsp;</span>
1352
1560
  <span class="cline-any cline-neutral">&nbsp;</span>
1353
- <span class="cline-any cline-yes">3x</span>
1354
- <span class="cline-any cline-yes">3x</span>
1561
+ <span class="cline-any cline-yes">8x</span>
1562
+ <span class="cline-any cline-yes">8x</span>
1355
1563
  <span class="cline-any cline-neutral">&nbsp;</span>
1356
- <span class="cline-any cline-yes">3x</span>
1564
+ <span class="cline-any cline-yes">8x</span>
1357
1565
  <span class="cline-any cline-neutral">&nbsp;</span>
1358
- <span class="cline-any cline-yes">3x</span>
1566
+ <span class="cline-any cline-yes">8x</span>
1359
1567
  <span class="cline-any cline-no">&nbsp;</span>
1360
1568
  <span class="cline-any cline-neutral">&nbsp;</span>
1361
1569
  <span class="cline-any cline-neutral">&nbsp;</span>
1362
1570
  <span class="cline-any cline-no">&nbsp;</span>
1363
1571
  <span class="cline-any cline-neutral">&nbsp;</span>
1364
1572
  <span class="cline-any cline-neutral">&nbsp;</span>
1365
- <span class="cline-any cline-yes">3x</span>
1366
- <span class="cline-any cline-yes">3x</span>
1367
- <span class="cline-any cline-yes">3x</span>
1573
+ <span class="cline-any cline-yes">8x</span>
1574
+ <span class="cline-any cline-yes">8x</span>
1575
+ <span class="cline-any cline-yes">8x</span>
1368
1576
  <span class="cline-any cline-neutral">&nbsp;</span>
1369
1577
  <span class="cline-any cline-no">&nbsp;</span>
1370
1578
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1381,19 +1589,21 @@
1381
1589
  <span class="cline-any cline-neutral">&nbsp;</span>
1382
1590
  <span class="cline-any cline-neutral">&nbsp;</span>
1383
1591
  <span class="cline-any cline-neutral">&nbsp;</span>
1384
- <span class="cline-any cline-yes">7x</span>
1592
+ <span class="cline-any cline-yes">45x</span>
1385
1593
  <span class="cline-any cline-neutral">&nbsp;</span>
1386
- <span class="cline-any cline-yes">7x</span>
1387
- <span class="cline-any cline-yes">3x</span>
1594
+ <span class="cline-any cline-yes">45x</span>
1595
+ <span class="cline-any cline-yes">42x</span>
1388
1596
  <span class="cline-any cline-neutral">&nbsp;</span>
1389
- <span class="cline-any cline-yes">3x</span>
1390
- <span class="cline-any cline-yes">3x</span>
1597
+ <span class="cline-any cline-yes">42x</span>
1391
1598
  <span class="cline-any cline-neutral">&nbsp;</span>
1599
+ <span class="cline-any cline-yes">42x</span>
1600
+ <span class="cline-any cline-yes">41x</span>
1392
1601
  <span class="cline-any cline-neutral">&nbsp;</span>
1393
- <span class="cline-any cline-yes">3x</span>
1394
- <span class="cline-any cline-yes">60x</span>
1395
1602
  <span class="cline-any cline-neutral">&nbsp;</span>
1396
- <span class="cline-any cline-yes">60x</span>
1603
+ <span class="cline-any cline-yes">42x</span>
1604
+ <span class="cline-any cline-yes">174x</span>
1605
+ <span class="cline-any cline-neutral">&nbsp;</span>
1606
+ <span class="cline-any cline-yes">174x</span>
1397
1607
  <span class="cline-any cline-no">&nbsp;</span>
1398
1608
  <span class="cline-any cline-neutral">&nbsp;</span>
1399
1609
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1404,12 +1614,12 @@
1404
1614
  <span class="cline-any cline-neutral">&nbsp;</span>
1405
1615
  <span class="cline-any cline-neutral">&nbsp;</span>
1406
1616
  <span class="cline-any cline-neutral">&nbsp;</span>
1407
- <span class="cline-any cline-yes">60x</span>
1408
- <span class="cline-any cline-yes">60x</span>
1617
+ <span class="cline-any cline-yes">174x</span>
1618
+ <span class="cline-any cline-yes">174x</span>
1409
1619
  <span class="cline-any cline-neutral">&nbsp;</span>
1410
- <span class="cline-any cline-yes">60x</span>
1620
+ <span class="cline-any cline-yes">174x</span>
1411
1621
  <span class="cline-any cline-neutral">&nbsp;</span>
1412
- <span class="cline-any cline-yes">60x</span>
1622
+ <span class="cline-any cline-yes">174x</span>
1413
1623
  <span class="cline-any cline-no">&nbsp;</span>
1414
1624
  <span class="cline-any cline-neutral">&nbsp;</span>
1415
1625
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1419,59 +1629,111 @@
1419
1629
  <span class="cline-any cline-neutral">&nbsp;</span>
1420
1630
  <span class="cline-any cline-neutral">&nbsp;</span>
1421
1631
  <span class="cline-any cline-neutral">&nbsp;</span>
1422
- <span class="cline-any cline-yes">7x</span>
1632
+ <span class="cline-any cline-yes">45x</span>
1633
+ <span class="cline-any cline-yes">45x</span>
1423
1634
  <span class="cline-any cline-neutral">&nbsp;</span>
1424
- <span class="cline-any cline-yes">7x</span>
1635
+ <span class="cline-any cline-yes">45x</span>
1636
+ <span class="cline-any cline-yes">42x</span>
1425
1637
  <span class="cline-any cline-neutral">&nbsp;</span>
1638
+ <span class="cline-any cline-yes">42x</span>
1426
1639
  <span class="cline-any cline-neutral">&nbsp;</span>
1640
+ <span class="cline-any cline-yes">42x</span>
1641
+ <span class="cline-any cline-yes">8x</span>
1427
1642
  <span class="cline-any cline-neutral">&nbsp;</span>
1428
1643
  <span class="cline-any cline-neutral">&nbsp;</span>
1644
+ <span class="cline-any cline-yes">42x</span>
1645
+ <span class="cline-any cline-yes">15x</span>
1646
+ <span class="cline-any cline-neutral">&nbsp;</span>
1647
+ <span class="cline-any cline-yes">15x</span>
1648
+ <span class="cline-any cline-no">&nbsp;</span>
1429
1649
  <span class="cline-any cline-neutral">&nbsp;</span>
1430
- <span class="cline-any cline-yes">7x</span>
1431
- <span class="cline-any cline-yes">4x</span>
1432
1650
  <span class="cline-any cline-neutral">&nbsp;</span>
1433
- <span class="cline-any cline-yes">4x</span>
1434
- <span class="cline-any cline-yes">4x</span>
1435
1651
  <span class="cline-any cline-neutral">&nbsp;</span>
1436
1652
  <span class="cline-any cline-neutral">&nbsp;</span>
1437
- <span class="cline-any cline-yes">4x</span>
1438
- <span class="cline-any cline-yes">141x</span>
1439
1653
  <span class="cline-any cline-neutral">&nbsp;</span>
1440
- <span class="cline-any cline-yes">141x</span>
1654
+ <span class="cline-any cline-neutral">&nbsp;</span>
1655
+ <span class="cline-any cline-neutral">&nbsp;</span>
1656
+ <span class="cline-any cline-neutral">&nbsp;</span>
1657
+ <span class="cline-any cline-neutral">&nbsp;</span>
1658
+ <span class="cline-any cline-yes">15x</span>
1659
+ <span class="cline-any cline-yes">15x</span>
1660
+ <span class="cline-any cline-neutral">&nbsp;</span>
1661
+ <span class="cline-any cline-yes">15x</span>
1662
+ <span class="cline-any cline-neutral">&nbsp;</span>
1663
+ <span class="cline-any cline-yes">15x</span>
1441
1664
  <span class="cline-any cline-no">&nbsp;</span>
1442
1665
  <span class="cline-any cline-neutral">&nbsp;</span>
1443
1666
  <span class="cline-any cline-neutral">&nbsp;</span>
1667
+ <span class="cline-any cline-no">&nbsp;</span>
1444
1668
  <span class="cline-any cline-neutral">&nbsp;</span>
1445
1669
  <span class="cline-any cline-neutral">&nbsp;</span>
1446
1670
  <span class="cline-any cline-neutral">&nbsp;</span>
1447
1671
  <span class="cline-any cline-neutral">&nbsp;</span>
1448
1672
  <span class="cline-any cline-neutral">&nbsp;</span>
1673
+ <span class="cline-any cline-yes">45x</span>
1674
+ <span class="cline-any cline-neutral">&nbsp;</span>
1675
+ <span class="cline-any cline-yes">45x</span>
1676
+ <span class="cline-any cline-neutral">&nbsp;</span>
1449
1677
  <span class="cline-any cline-neutral">&nbsp;</span>
1450
1678
  <span class="cline-any cline-neutral">&nbsp;</span>
1451
- <span class="cline-any cline-yes">141x</span>
1452
- <span class="cline-any cline-yes">141x</span>
1453
1679
  <span class="cline-any cline-neutral">&nbsp;</span>
1454
- <span class="cline-any cline-yes">141x</span>
1455
1680
  <span class="cline-any cline-neutral">&nbsp;</span>
1456
- <span class="cline-any cline-yes">141x</span>
1457
- <span class="cline-any cline-yes">2x</span>
1458
1681
  <span class="cline-any cline-neutral">&nbsp;</span>
1682
+ <span class="cline-any cline-yes">45x</span>
1683
+ <span class="cline-any cline-yes">44x</span>
1459
1684
  <span class="cline-any cline-neutral">&nbsp;</span>
1685
+ <span class="cline-any cline-yes">44x</span>
1686
+ <span class="cline-any cline-neutral">&nbsp;</span>
1687
+ <span class="cline-any cline-yes">44x</span>
1688
+ <span class="cline-any cline-yes">43x</span>
1689
+ <span class="cline-any cline-neutral">&nbsp;</span>
1690
+ <span class="cline-any cline-neutral">&nbsp;</span>
1691
+ <span class="cline-any cline-yes">44x</span>
1692
+ <span class="cline-any cline-yes">350x</span>
1693
+ <span class="cline-any cline-neutral">&nbsp;</span>
1694
+ <span class="cline-any cline-yes">350x</span>
1460
1695
  <span class="cline-any cline-no">&nbsp;</span>
1461
1696
  <span class="cline-any cline-neutral">&nbsp;</span>
1462
1697
  <span class="cline-any cline-neutral">&nbsp;</span>
1463
1698
  <span class="cline-any cline-neutral">&nbsp;</span>
1464
1699
  <span class="cline-any cline-neutral">&nbsp;</span>
1465
- <span class="cline-any cline-yes">7x</span>
1466
1700
  <span class="cline-any cline-neutral">&nbsp;</span>
1467
1701
  <span class="cline-any cline-neutral">&nbsp;</span>
1468
1702
  <span class="cline-any cline-neutral">&nbsp;</span>
1469
1703
  <span class="cline-any cline-neutral">&nbsp;</span>
1470
1704
  <span class="cline-any cline-neutral">&nbsp;</span>
1705
+ <span class="cline-any cline-yes">350x</span>
1706
+ <span class="cline-any cline-yes">350x</span>
1707
+ <span class="cline-any cline-neutral">&nbsp;</span>
1708
+ <span class="cline-any cline-yes">350x</span>
1709
+ <span class="cline-any cline-neutral">&nbsp;</span>
1710
+ <span class="cline-any cline-yes">350x</span>
1711
+ <span class="cline-any cline-yes">3x</span>
1712
+ <span class="cline-any cline-neutral">&nbsp;</span>
1713
+ <span class="cline-any cline-neutral">&nbsp;</span>
1714
+ <span class="cline-any cline-no">&nbsp;</span>
1715
+ <span class="cline-any cline-neutral">&nbsp;</span>
1716
+ <span class="cline-any cline-neutral">&nbsp;</span>
1717
+ <span class="cline-any cline-neutral">&nbsp;</span>
1718
+ <span class="cline-any cline-neutral">&nbsp;</span>
1719
+ <span class="cline-any cline-yes">45x</span>
1720
+ <span class="cline-any cline-neutral">&nbsp;</span>
1721
+ <span class="cline-any cline-neutral">&nbsp;</span>
1722
+ <span class="cline-any cline-neutral">&nbsp;</span>
1723
+ <span class="cline-any cline-neutral">&nbsp;</span>
1724
+ <span class="cline-any cline-neutral">&nbsp;</span>
1725
+ <span class="cline-any cline-yes">2x</span>
1726
+ <span class="cline-any cline-neutral">&nbsp;</span>
1727
+ <span class="cline-any cline-neutral">&nbsp;</span>
1471
1728
  <span class="cline-any cline-yes">1x</span>
1472
1729
  <span class="cline-any cline-neutral">&nbsp;</span>
1730
+ <span class="cline-any cline-yes">1x</span>
1731
+ <span class="cline-any cline-neutral">&nbsp;</span>
1732
+ <span class="cline-any cline-yes">1x</span>
1733
+ <span class="cline-any cline-yes">1x</span>
1473
1734
  <span class="cline-any cline-neutral">&nbsp;</span>
1474
1735
  <span class="cline-any cline-yes">1x</span>
1736
+ <span class="cline-any cline-yes">1x</span>
1475
1737
  <span class="cline-any cline-neutral">&nbsp;</span>
1476
1738
  <span class="cline-any cline-yes">1x</span>
1477
1739
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1499,6 +1761,16 @@
1499
1761
  <span class="cline-any cline-neutral">&nbsp;</span>
1500
1762
  <span class="cline-any cline-neutral">&nbsp;</span>
1501
1763
  <span class="cline-any cline-neutral">&nbsp;</span>
1764
+ <span class="cline-any cline-yes">1x</span>
1765
+ <span class="cline-any cline-no">&nbsp;</span>
1766
+ <span class="cline-any cline-neutral">&nbsp;</span>
1767
+ <span class="cline-any cline-neutral">&nbsp;</span>
1768
+ <span class="cline-any cline-yes">1x</span>
1769
+ <span class="cline-any cline-no">&nbsp;</span>
1770
+ <span class="cline-any cline-no">&nbsp;</span>
1771
+ <span class="cline-any cline-neutral">&nbsp;</span>
1772
+ <span class="cline-any cline-neutral">&nbsp;</span>
1773
+ <span class="cline-any cline-neutral">&nbsp;</span>
1502
1774
  <span class="cline-any cline-neutral">&nbsp;</span>
1503
1775
  <span class="cline-any cline-neutral">&nbsp;</span>
1504
1776
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1538,6 +1810,7 @@
1538
1810
  <span class="cline-any cline-neutral">&nbsp;</span>
1539
1811
  <span class="cline-any cline-neutral">&nbsp;</span>
1540
1812
  <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">// for use in node only
1813
+ import * as fs from "fs";
1541
1814
  import * as path from "path";
1542
1815
  &nbsp;
1543
1816
  import type { Attribute, Schema } from "@featurevisor/types";
@@ -1550,15 +1823,24 @@ import { getGroupZodSchema } from "./groupSchema";
1550
1823
  import { getFeatureZodSchema } from "./featureSchema";
1551
1824
  import { getSchemaZodSchema } from "./schema";
1552
1825
  import { getTestsZodSchema } from "./testSchema";
1826
+ import { getTargetZodSchema } from "./targetSchema";
1553
1827
  &nbsp;
1554
1828
  import { checkForCircularDependencyInRequired } from "./checkCircularDependency";
1555
1829
  import { checkForFeatureExceedingGroupSlotPercentage } from "./checkPercentageExceedingSlot";
1556
1830
  import { getLintIssuesFromZodError, printZodError } from "./printError";
1557
1831
  import { Dependencies } from "../dependencies";
1558
- import { CLI_FORMAT_RED, CLI_FORMAT_BOLD_UNDERLINE } from "../tester/cliFormat";
1832
+ import { CLI_FORMAT_BOLD_UNDERLINE, CLI_FORMAT_GREEN, CLI_FORMAT_RED } from "../tester/cliFormat";
1559
1833
  import { Plugin } from "../cli";
1834
+ import { assertProjectSetJsonSelection, getProjectSetExecutions, printSetHeader } from "../sets";
1560
1835
  &nbsp;
1561
- export type LintEntityType = "attribute" | "segment" | "feature" | "group" | "schema" | "test";
1836
+ export type LintEntityType =
1837
+ | "attribute"
1838
+ | "segment"
1839
+ | "feature"
1840
+ | "group"
1841
+ | "schema"
1842
+ | "target"
1843
+ | "test";
1562
1844
  &nbsp;
1563
1845
  export interface LintProjectOptions {
1564
1846
  keyPattern?: string;
@@ -1576,8 +1858,6 @@ export interface LintErrorItem {
1576
1858
  path: (string | number)[];
1577
1859
  code?: string;
1578
1860
  value?: unknown;
1579
- /** Present only when splitByEnvironment is true and the error is from an environment-specific file (rules/force/expose). */
1580
- environment?: string;
1581
1861
  }
1582
1862
  &nbsp;
1583
1863
  export interface LintResult {
@@ -1586,12 +1866,67 @@ export interface LintResult {
1586
1866
  }
1587
1867
  &nbsp;
1588
1868
  const ENTITY_NAME_REGEX = /^[a-zA-Z0-9_\-./]+$/;
1589
- const ENTITY_NAME_REGEX_ERROR = "Names must be alphanumeric and can contain _, -, and .";
1869
+ const ENTITY_NAME_REGEX_ERROR =
1870
+ "Names must be alphanumeric and can contain _, -, /, ., and the configured namespace character";
1590
1871
  &nbsp;
1591
- const ATTRIBUTE_NAME_REGEX = /^[a-zA-Z0-9_\-/]+$/;
1592
- const ATTRIBUTE_NAME_REGEX_ERROR = "Names must be alphanumeric and can contain _, and -";
1872
+ const ATTRIBUTE_NAME_REGEX_ERROR =
1873
+ "Names must be alphanumeric and can contain _, -, /, ., and the configured namespace character";
1593
1874
  &nbsp;
1594
- async function <span class="fstat-no" title="function not covered" >getAuthorsOfEntity(</span>datasource, entityType, entityKey): Promise&lt;string[]&gt; {
1875
+ function escapeRegExp(value: string): string {
1876
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&amp;");
1877
+ }
1878
+ &nbsp;
1879
+ function isValidEntityKey(key: string, namespaceCharacter: string): boolean {
1880
+ const keyWithoutNamespaceCharacter = key.replace(
1881
+ new RegExp(escapeRegExp(namespaceCharacter), "g"),
1882
+ "",
1883
+ );
1884
+ &nbsp;
1885
+ return ENTITY_NAME_REGEX.test(keyWithoutNamespaceCharacter);
1886
+ }
1887
+ &nbsp;
1888
+ function getPathSegmentsFromKey(
1889
+ key: string,
1890
+ namespaceCharacter: string,
1891
+ entityType?: LintEntityType,
1892
+ ): string[] {
1893
+ const pathSegments = key.split(namespaceCharacter);
1894
+ &nbsp;
1895
+ if (
1896
+ entityType === "test" &amp;&amp;
1897
+ pathSegments.length &gt; 1 &amp;&amp;
1898
+ ["spec", "feature", "segment"].includes(pathSegments[pathSegments.length - 1])
1899
+ ) {
1900
+ const suffix = pathSegments[pathSegments.length - 1];
1901
+ pathSegments[pathSegments.length - 2] = `${pathSegments[pathSegments.length - 2]}.${suffix}`;
1902
+ pathSegments.pop();
1903
+ }
1904
+ &nbsp;
1905
+ return pathSegments;
1906
+ }
1907
+ &nbsp;
1908
+ function getReservedNameCheckValue(
1909
+ entityType: LintEntityType,
1910
+ name: string,
1911
+ isFile: boolean,
1912
+ extension: string,
1913
+ ): string {
1914
+ let value =
1915
+ isFile &amp;&amp; name.endsWith(`.${extension}`) ? name.slice(0, -extension.length - 1) : name;
1916
+ &nbsp;
1917
+ if (entityType === "test" &amp;&amp; isFile) {
1918
+ for (const suffix of [".spec", ".feature", ".segment"]) {
1919
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (value.endsWith(suffix)) {
1920
+ value = value.slice(0, -suffix.length);
1921
+ break;
1922
+ }
1923
+ }
1924
+ }
1925
+ &nbsp;
1926
+ return value;
1927
+ }
1928
+ &nbsp;
1929
+ async function <span class="fstat-no" title="function not covered" >getAuthorsOfEntity(d</span>atasource, entityType, entityKey): Promise&lt;string[]&gt; {
1595
1930
  const entries = <span class="cstat-no" title="statement not covered" >await datasource.listHistoryEntries(entityType, entityKey);</span>
1596
1931
  const authors: string[] = <span class="cstat-no" title="statement not covered" >Array.from(new Set(entries.map(<span class="fstat-no" title="function not covered" >(e</span>ntry) =&gt; <span class="cstat-no" title="statement not covered" >entry.author)</span>));</span>
1597
1932
  &nbsp;
@@ -1636,7 +1971,9 @@ export async function lintProject(
1636
1971
  }
1637
1972
  &nbsp;
1638
1973
  function getFullPathFromKey(type: LintEntityType, key: string, relative = false) {
1639
- const fileName = `${key}.${datasource.getExtension()}`;
1974
+ const fileName = `${getPathSegmentsFromKey(key, projectConfig.namespaceCharacter, type).join(
1975
+ path.sep,
1976
+ )}.${datasource.getExtension()}`;
1640
1977
  let fullPath = "";
1641
1978
  &nbsp;
1642
1979
  if (type === "attribute") {
@@ -1649,6 +1986,8 @@ export async function lintProject(
1649
1986
  fullPath = path.join(projectConfig.groupsDirectoryPath, fileName);
1650
1987
  } else if (type === "schema") {
1651
1988
  fullPath = path.join(projectConfig.schemasDirectoryPath, fileName);
1989
+ } else if (type === "target") {
1990
+ fullPath = path.join(projectConfig.targetsDirectoryPath, fileName);
1652
1991
  } else {
1653
1992
  fullPath = path.join(projectConfig.testsDirectoryPath, fileName);
1654
1993
  }
@@ -1660,70 +1999,81 @@ export async function lintProject(
1660
1999
  return fullPath;
1661
2000
  }
1662
2001
  &nbsp;
1663
- async function getFeaturePathFromIssuePath(
1664
- featureKey: string,
1665
- issuePath: (string | number)[] = <span class="branch-0 cbranch-no" title="branch not covered" >[],</span>
1666
- ): Promise&lt;string&gt; {
1667
- const defaultPath = getFullPathFromKey("feature", featureKey);
1668
- &nbsp;
1669
- if (!projectConfig.splitByEnvironment) {
1670
- return defaultPath;
2002
+ function getEntityDirectoryPath(type: LintEntityType): string {
2003
+ if (type === "attribute") {
2004
+ return projectConfig.attributesDirectoryPath;
2005
+ }
2006
+ if (type === "segment") {
2007
+ return projectConfig.segmentsDirectoryPath;
2008
+ }
2009
+ if (type === "feature") {
2010
+ return projectConfig.featuresDirectoryPath;
2011
+ }
2012
+ if (type === "group") {
2013
+ return projectConfig.groupsDirectoryPath;
2014
+ }
2015
+ if (type === "schema") {
2016
+ return projectConfig.schemasDirectoryPath;
2017
+ }
2018
+ if (type === "target") {
2019
+ return projectConfig.targetsDirectoryPath;
1671
2020
  }
1672
2021
  &nbsp;
1673
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!Array.isArray(projectConfig.environments)) {
1674
- <span class="cstat-no" title="statement not covered" > return defaultPath;</span>
2022
+ return projectConfig.testsDirectoryPath;
2023
+ }
2024
+ &nbsp;
2025
+ async function lintReservedNamespaceCharacterInPathNames(
2026
+ entityType: LintEntityType,
2027
+ directoryPath: string,
2028
+ ) {
2029
+ if (!fs.existsSync(directoryPath)) {
2030
+ return;
1675
2031
  }
1676
2032
  &nbsp;
1677
- const [topLevelKey, environment] = issuePath;
1678
- if (
1679
- (topLevelKey === "rules" || topLevelKey === "force" || topLevelKey === "expose") &amp;&amp;
1680
- typeof environment === "string"
1681
- ) {
1682
- const sourcePath = await datasource.getFeaturePropertySourcePath(
1683
- featureKey,
1684
- topLevelKey,
1685
- environment,
1686
- );
2033
+ const extension = datasource.getExtension();
2034
+ const namespaceCharacter = projectConfig.namespaceCharacter;
2035
+ const entries = fs.readdirSync(directoryPath, { withFileTypes: true });
2036
+ &nbsp;
2037
+ for (const entry of entries) {
2038
+ const entryPath = path.join(directoryPath, entry.name);
2039
+ const isFile = entry.isFile();
2040
+ const isDirectory = entry.isDirectory();
1687
2041
  &nbsp;
1688
- if (sourcePath) {
1689
- return sourcePath;
2042
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!isDirectory &amp;&amp; !(isFile &amp;&amp; entry.name.endsWith(`.${extension}`))) {
2043
+ <span class="cstat-no" title="statement not covered" > continue;</span>
1690
2044
  }
1691
- }
1692
2045
  &nbsp;
1693
- return defaultPath;
1694
- }
2046
+ const nameToCheck = getReservedNameCheckValue(entityType, entry.name, isFile, extension);
1695
2047
  &nbsp;
1696
- /**
1697
- * When the error is from an environment-specific file (splitByEnvironment), the Zod path
1698
- * is against the merged feature (e.g. rules.production.1.variables.foo). Return the path
1699
- * as it appears in that file (e.g. rules.1.variables.foo) by stripping the environment segment.
1700
- */
1701
- function getPathRelativeToFeatureFile(
1702
- issuePath: (string | number)[],
1703
- targetPath: string,
1704
- defaultFeaturePath: string,
1705
- ): (string | number)[] {
1706
- if (targetPath === defaultFeaturePath || issuePath.length &lt; 2) {
1707
- return issuePath;
1708
- }
1709
- const [topLevelKey, second] = issuePath;
1710
- if (
1711
- (topLevelKey === "rules" || <span class="branch-1 cbranch-no" title="branch not covered" >topLevelKey === "force" </span>|| <span class="branch-2 cbranch-no" title="branch not covered" >topLevelKey === "expose")</span> &amp;&amp;
1712
- typeof second === "string"
1713
- ) {
1714
- return [topLevelKey, ...issuePath.slice(2)];
2048
+ if (nameToCheck.includes(namespaceCharacter)) {
2049
+ await reportSimpleError({
2050
+ entityType,
2051
+ key: path.relative(getEntityDirectoryPath(entityType), entryPath),
2052
+ fullPath: entryPath,
2053
+ message: `Invalid file or directory name: "${entry.name}"`,
2054
+ detail: `Namespace character "${namespaceCharacter}" is not allowed in entity file or directory names.`,
2055
+ code: "invalid_name",
2056
+ });
2057
+ }
2058
+ &nbsp;
2059
+ if (isDirectory) {
2060
+ await lintReservedNamespaceCharacterInPathNames(entityType, entryPath);
2061
+ }
1715
2062
  }
1716
- <span class="cstat-no" title="statement not covered" > return issuePath;</span>
1717
2063
  }
1718
2064
  &nbsp;
1719
- async function <span class="fstat-no" title="function not covered" >printEntityHeader(</span>entityType: LintEntityType, key: string, fullPath: string) {
1720
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (isJsonMode) {</span>
2065
+ async function lintReservedNamespaceCharacterInEntityPaths(entityType: LintEntityType) {
2066
+ await lintReservedNamespaceCharacterInPathNames(entityType, getEntityDirectoryPath(entityType));
2067
+ }
2068
+ &nbsp;
2069
+ async function <span class="fstat-no" title="function not covered" >printEntityHeader(e</span>ntityType: LintEntityType, key: string, fullPath: string) {
2070
+ <span class="cstat-no" title="statement not covered" > if (isJsonMode) {</span>
1721
2071
  <span class="cstat-no" title="statement not covered" > return;</span>
1722
2072
  }
1723
2073
  &nbsp;
1724
2074
  <span class="cstat-no" title="statement not covered" > console.log(CLI_FORMAT_BOLD_UNDERLINE, fullPath);</span>
1725
2075
  &nbsp;
1726
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (options.authors) {</span>
2076
+ <span class="cstat-no" title="statement not covered" > if (options.authors) {</span>
1727
2077
  const authors = <span class="cstat-no" title="statement not covered" >await getAuthorsOfEntity(datasource, entityType, key);</span>
1728
2078
  <span class="cstat-no" title="statement not covered" > console.log(` Authors: ${authors.join(", ")}\n`);</span>
1729
2079
  }
@@ -1765,7 +2115,7 @@ export async function lintProject(
1765
2115
  <span class="missing-if-branch" title="if path not taken" >I</span>if (!isJsonMode) {
1766
2116
  <span class="cstat-no" title="statement not covered" > await printEntityHeader(entityType, key, fullPath);</span>
1767
2117
  <span class="cstat-no" title="statement not covered" > console.log(CLI_FORMAT_RED, ` =&gt; Error: ${message}`);</span>
1768
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (detail) {</span>
2118
+ <span class="cstat-no" title="statement not covered" > if (detail) {</span>
1769
2119
  <span class="cstat-no" title="statement not covered" > console.log(CLI_FORMAT_RED, ` ${detail}`);</span>
1770
2120
  }
1771
2121
  <span class="cstat-no" title="statement not covered" > console.log("");</span>
@@ -1782,11 +2132,11 @@ export async function lintProject(
1782
2132
  error &amp;&amp;
1783
2133
  typeof error === "object" &amp;&amp;
1784
2134
  "featurevisorFilePath" in error &amp;&amp;
1785
- typeof error.featurevisorFilePath === "string"
1786
- ? error.featurevisorFilePath
1787
- : <span class="branch-1 cbranch-no" title="branch not covered" >undefined;</span>
1788
- const targetPath = pathFromError || <span class="branch-1 cbranch-no" title="branch not covered" >fullPath;</span>
1789
- const message = error instanceof Error ? error.message : <span class="branch-1 cbranch-no" title="branch not covered" >String(error);</span>
2135
+ <span class="branch-3 cbranch-no" title="branch not covered" > typeof error.featurevisorFilePath === "string"</span>
2136
+ ? <span class="branch-0 cbranch-no" title="branch not covered" >error.featurevisorFilePath</span>
2137
+ : undefined;
2138
+ const targetPath = pathFromError || fullPath;
2139
+ const message = error instanceof Error ? <span class="branch-0 cbranch-no" title="branch not covered" >error.message </span>: String(error);
1790
2140
  &nbsp;
1791
2141
  recordError({
1792
2142
  filePath: path.relative(process.cwd(), targetPath),
@@ -1794,7 +2144,7 @@ export async function lintProject(
1794
2144
  key,
1795
2145
  message,
1796
2146
  path: [],
1797
- code: error instanceof Error ? error.name : <span class="branch-1 cbranch-no" title="branch not covered" >undefined,</span>
2147
+ code: error instanceof Error ? <span class="branch-0 cbranch-no" title="branch not covered" >error.name </span>: undefined,
1798
2148
  });
1799
2149
  &nbsp;
1800
2150
  <span class="missing-if-branch" title="if path not taken" >I</span>if (!isJsonMode) {
@@ -1811,8 +2161,6 @@ export async function lintProject(
1811
2161
  error: ZodError,
1812
2162
  ) {
1813
2163
  const issues = getLintIssuesFromZodError(error);
1814
- const defaultFeaturePath =
1815
- entityType === "feature" ? getFullPathFromKey("feature", key) : fullPath;
1816
2164
  &nbsp;
1817
2165
  const issuesWithTargetPath: {
1818
2166
  issue: (typeof issues)[0];
@@ -1820,19 +2168,8 @@ export async function lintProject(
1820
2168
  pathRelativeToFile: (string | number)[];
1821
2169
  }[] = [];
1822
2170
  for (const issue of issues) {
1823
- const targetPath =
1824
- entityType === "feature" ? await getFeaturePathFromIssuePath(key, issue.path) : fullPath;
1825
- const pathRelativeToFile =
1826
- entityType === "feature"
1827
- ? getPathRelativeToFeatureFile(issue.path, targetPath, defaultFeaturePath)
1828
- : issue.path;
1829
- const isFromEnvFile =
1830
- entityType === "feature" &amp;&amp;
1831
- targetPath !== defaultFeaturePath &amp;&amp;
1832
- issue.path.length &gt;= 2 &amp;&amp;
1833
- (issue.path[0] === "rules" || <span class="branch-4 cbranch-no" title="branch not covered" >issue.path[0] === "force" </span>|| <span class="branch-5 cbranch-no" title="branch not covered" >issue.path[0] === "expose")</span> &amp;&amp;
1834
- typeof issue.path[1] === "string";
1835
- const environment = isFromEnvFile ? (issue.path[1] as string) : undefined;
2171
+ const targetPath = fullPath;
2172
+ const pathRelativeToFile = issue.path;
1836
2173
  issuesWithTargetPath.push({ issue, targetPath, pathRelativeToFile });
1837
2174
  &nbsp;
1838
2175
  recordError({
@@ -1843,7 +2180,6 @@ export async function lintProject(
1843
2180
  path: pathRelativeToFile,
1844
2181
  code: issue.code,
1845
2182
  value: issue.value,
1846
- ...(environment !== undefined &amp;&amp; { environment }),
1847
2183
  });
1848
2184
  }
1849
2185
  &nbsp;
@@ -1858,7 +2194,7 @@ export async function lintProject(
1858
2194
  &gt;();
1859
2195
  <span class="cstat-no" title="statement not covered" > for (const { issue, targetPath, pathRelativeToFile } of issuesWithTargetPath) {</span>
1860
2196
  const pathKey = <span class="cstat-no" title="statement not covered" >targetPath;</span>
1861
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!byPath.has(pathKey)) <span class="cstat-no" title="statement not covered" >byPath.set(pathKey, []);</span></span>
2197
+ <span class="cstat-no" title="statement not covered" > if (!byPath.has(pathKey)) <span class="cstat-no" title="statement not covered" >byPath.set(pathKey, []);</span></span>
1862
2198
  <span class="cstat-no" title="statement not covered" > byPath.get(pathKey)!.push({ issue, pathRelativeToFile });</span>
1863
2199
  }
1864
2200
  <span class="cstat-no" title="statement not covered" > for (const [targetPathKey, groupItems] of byPath) {</span>
@@ -1866,7 +2202,7 @@ export async function lintProject(
1866
2202
  <span class="cstat-no" title="statement not covered" > for (const { issue, pathRelativeToFile } of groupItems) {</span>
1867
2203
  <span class="cstat-no" title="statement not covered" > console.log(CLI_FORMAT_RED, ` =&gt; Error: ${issue.message}`);</span>
1868
2204
  <span class="cstat-no" title="statement not covered" > console.log(" Path:", pathRelativeToFile.join("."));</span>
1869
- <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof issue.value !== "undefined" &amp;&amp; issue.value !== "undefined") {</span>
2205
+ <span class="cstat-no" title="statement not covered" > if (typeof issue.value !== "undefined" &amp;&amp; issue.value !== "undefined") {</span>
1870
2206
  <span class="cstat-no" title="statement not covered" > console.log(" Value:", issue.value);</span>
1871
2207
  }
1872
2208
  <span class="cstat-no" title="statement not covered" > console.log("");</span>
@@ -1879,7 +2215,7 @@ export async function lintProject(
1879
2215
  }
1880
2216
  }
1881
2217
  &nbsp;
1882
- const keyPattern = options.keyPattern ? <span class="branch-0 cbranch-no" title="branch not covered" >new RegExp(options.keyPattern) </span>: null;
2218
+ const keyPattern = options.keyPattern ? <span class="branch-0 cbranch-no" title="branch not covered" >new RegExp(options.keyPattern) : n</span>ull;
1883
2219
  &nbsp;
1884
2220
  <span class="missing-if-branch" title="if path not taken" >I</span>if (keyPattern) {
1885
2221
  <span class="cstat-no" title="statement not covered" > log("");</span>
@@ -1912,9 +2248,11 @@ export async function lintProject(
1912
2248
  }
1913
2249
  &nbsp;
1914
2250
  if (!options.entityType || options.entityType === "attribute") {
2251
+ await lintReservedNamespaceCharacterInEntityPaths("attribute");
2252
+ &nbsp;
1915
2253
  const filteredKeys = !keyPattern
1916
2254
  ? attributes
1917
- : <span class="branch-1 cbranch-no" title="branch not covered" >attributes.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key))</span>;</span>
2255
+ : <span class="branch-1 cbranch-no" title="branch not covered" >attributes.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key));</span></span>
1918
2256
  &nbsp;
1919
2257
  if (filteredKeys.length &gt; 0) {
1920
2258
  log(`Linting ${filteredKeys.length} attributes...\n`);
@@ -1923,7 +2261,7 @@ export async function lintProject(
1923
2261
  for (const key of filteredKeys) {
1924
2262
  const fullPath = getFullPathFromKey("attribute", key);
1925
2263
  &nbsp;
1926
- if (!ATTRIBUTE_NAME_REGEX.test(key)) {
2264
+ if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
1927
2265
  await reportSimpleError({
1928
2266
  entityType: "attribute",
1929
2267
  key,
@@ -1935,11 +2273,11 @@ export async function lintProject(
1935
2273
  }
1936
2274
  &nbsp;
1937
2275
  try {
1938
- const parsed = attributesByKey[key] ?? (<span class="branch-1 cbranch-no" title="branch not covered" >await datasource.readAttribute(key))</span>;
2276
+ const parsed = attributesByKey[key] ?? (<span class="branch-1 cbranch-no" title="branch not covered" >await datasource.readAttribute(key));</span>
1939
2277
  const result = attributeZodSchema.safeParse(parsed);
1940
2278
  &nbsp;
1941
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!result.success &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >"error" in result)</span> {
1942
- <span class="cstat-no" title="statement not covered" > await reportZodValidationError("attribute", key, fullPath, result.error);</span>
2279
+ if (!result.success &amp;&amp; "error" in result) {
2280
+ await reportZodValidationError("attribute", key, fullPath, result.error);
1943
2281
  }
1944
2282
  } catch (error) {
1945
2283
  <span class="cstat-no" title="statement not covered" > await reportThrownError("attribute", key, fullPath, error);</span>
@@ -1964,16 +2302,18 @@ export async function lintProject(
1964
2302
  const segmentZodSchema = getSegmentZodSchema(projectConfig, conditionsZodSchema);
1965
2303
  &nbsp;
1966
2304
  if (!options.entityType || options.entityType === "segment") {
1967
- const filteredKeys = !keyPattern ? segments : <span class="branch-1 cbranch-no" title="branch not covered" >segments.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key))</span>;</span>
2305
+ await lintReservedNamespaceCharacterInEntityPaths("segment");
1968
2306
  &nbsp;
1969
- if (filteredKeys.length &gt; 0) {
2307
+ const filteredKeys = !keyPattern ? segments : <span class="branch-1 cbranch-no" title="branch not covered" >segments.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key));</span></span>
2308
+ &nbsp;
2309
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (filteredKeys.length &gt; 0) {
1970
2310
  log(`Linting ${filteredKeys.length} segments...\n`);
1971
2311
  }
1972
2312
  &nbsp;
1973
2313
  for (const key of filteredKeys) {
1974
2314
  const fullPath = getFullPathFromKey("segment", key);
1975
2315
  &nbsp;
1976
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!ENTITY_NAME_REGEX.test(key)) {
2316
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
1977
2317
  <span class="cstat-no" title="statement not covered" > await reportSimpleError({</span>
1978
2318
  entityType: "segment",
1979
2319
  key,
@@ -1992,7 +2332,7 @@ export async function lintProject(
1992
2332
  await reportZodValidationError("segment", key, fullPath, result.error);
1993
2333
  }
1994
2334
  } catch (error) {
1995
- <span class="cstat-no" title="statement not covered" > await reportThrownError("segment", key, fullPath, error);</span>
2335
+ await reportThrownError("segment", key, fullPath, error);
1996
2336
  }
1997
2337
  }
1998
2338
  }
@@ -2010,7 +2350,9 @@ export async function lintProject(
2010
2350
  );
2011
2351
  &nbsp;
2012
2352
  if (!options.entityType || options.entityType === "feature") {
2013
- const filteredKeys = !keyPattern ? features : <span class="branch-1 cbranch-no" title="branch not covered" >features.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key))</span>;</span>
2353
+ await lintReservedNamespaceCharacterInEntityPaths("feature");
2354
+ &nbsp;
2355
+ const filteredKeys = !keyPattern ? features : <span class="branch-1 cbranch-no" title="branch not covered" >features.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key));</span></span>
2014
2356
  &nbsp;
2015
2357
  if (filteredKeys.length &gt; 0) {
2016
2358
  log(`Linting ${filteredKeys.length} features...\n`);
@@ -2019,7 +2361,7 @@ export async function lintProject(
2019
2361
  for (const key of filteredKeys) {
2020
2362
  const fullPath = getFullPathFromKey("feature", key);
2021
2363
  &nbsp;
2022
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!ENTITY_NAME_REGEX.test(key)) {
2364
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
2023
2365
  <span class="cstat-no" title="statement not covered" > await reportSimpleError({</span>
2024
2366
  entityType: "feature",
2025
2367
  key,
@@ -2041,7 +2383,7 @@ export async function lintProject(
2041
2383
  await reportZodValidationError("feature", key, fullPath, result.error);
2042
2384
  }
2043
2385
  } catch (error) {
2044
- await reportThrownError("feature", key, fullPath, error);
2386
+ <span class="cstat-no" title="statement not covered" > await reportThrownError("feature", key, fullPath, error);</span>
2045
2387
  }
2046
2388
  &nbsp;
2047
2389
  if (parsed &amp;&amp; parsed.required) {
@@ -2065,7 +2407,9 @@ export async function lintProject(
2065
2407
  const groupZodSchema = getGroupZodSchema(projectConfig, datasource, features);
2066
2408
  &nbsp;
2067
2409
  if (!options.entityType || options.entityType === "group") {
2068
- const filteredKeys = !keyPattern ? groups : <span class="branch-1 cbranch-no" title="branch not covered" >groups.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key))</span>;</span>
2410
+ await lintReservedNamespaceCharacterInEntityPaths("group");
2411
+ &nbsp;
2412
+ const filteredKeys = !keyPattern ? groups : <span class="branch-1 cbranch-no" title="branch not covered" >groups.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key));</span></span>
2069
2413
  &nbsp;
2070
2414
  if (filteredKeys.length &gt; 0) {
2071
2415
  log(`Linting ${filteredKeys.length} groups...\n`);
@@ -2074,7 +2418,7 @@ export async function lintProject(
2074
2418
  for (const key of filteredKeys) {
2075
2419
  const fullPath = getFullPathFromKey("group", key);
2076
2420
  &nbsp;
2077
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!ENTITY_NAME_REGEX.test(key)) {
2421
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
2078
2422
  <span class="cstat-no" title="statement not covered" > await reportSimpleError({</span>
2079
2423
  entityType: "group",
2080
2424
  key,
@@ -2092,14 +2436,14 @@ export async function lintProject(
2092
2436
  &nbsp;
2093
2437
  const result = groupZodSchema.safeParse(parsed);
2094
2438
  &nbsp;
2095
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!result.success &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >"error" in result)</span> {
2439
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!result.success &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >"error" in result) {</span>
2096
2440
  <span class="cstat-no" title="statement not covered" > await reportZodValidationError("group", key, fullPath, result.error);</span>
2097
2441
  }
2098
2442
  } catch (error) {
2099
2443
  <span class="cstat-no" title="statement not covered" > await reportThrownError("group", key, fullPath, error);</span>
2100
2444
  }
2101
2445
  &nbsp;
2102
- if (parsed) {
2446
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (parsed) {
2103
2447
  try {
2104
2448
  await checkForFeatureExceedingGroupSlotPercentage(datasource, parsed, features);
2105
2449
  } catch (error) {
@@ -2121,7 +2465,9 @@ export async function lintProject(
2121
2465
  const schemaZodSchema = getSchemaZodSchema(schemas);
2122
2466
  &nbsp;
2123
2467
  if (!options.entityType || options.entityType === "schema") {
2124
- const filteredKeys = !keyPattern ? schemas : <span class="branch-1 cbranch-no" title="branch not covered" >schemas.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key))</span>;</span>
2468
+ await lintReservedNamespaceCharacterInEntityPaths("schema");
2469
+ &nbsp;
2470
+ const filteredKeys = !keyPattern ? schemas : <span class="branch-1 cbranch-no" title="branch not covered" >schemas.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key));</span></span>
2125
2471
  &nbsp;
2126
2472
  if (filteredKeys.length &gt; 0) {
2127
2473
  log(`Linting ${filteredKeys.length} schemas...\n`);
@@ -2130,7 +2476,7 @@ export async function lintProject(
2130
2476
  for (const key of filteredKeys) {
2131
2477
  const fullPath = getFullPathFromKey("schema", key);
2132
2478
  &nbsp;
2133
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!ENTITY_NAME_REGEX.test(key)) {
2479
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
2134
2480
  <span class="cstat-no" title="statement not covered" > await reportSimpleError({</span>
2135
2481
  entityType: "schema",
2136
2482
  key,
@@ -2146,7 +2492,7 @@ export async function lintProject(
2146
2492
  &nbsp;
2147
2493
  const result = schemaZodSchema.safeParse(parsed);
2148
2494
  &nbsp;
2149
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!result.success &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >"error" in result)</span> {
2495
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!result.success &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >"error" in result) {</span>
2150
2496
  <span class="cstat-no" title="statement not covered" > await reportZodValidationError("schema", key, fullPath, result.error);</span>
2151
2497
  }
2152
2498
  } catch (error) {
@@ -2154,6 +2500,47 @@ export async function lintProject(
2154
2500
  }
2155
2501
  }
2156
2502
  }
2503
+ &nbsp;
2504
+ // lint targets
2505
+ const targets = await datasource.listTargets();
2506
+ const targetZodSchema = getTargetZodSchema(projectConfig);
2507
+ &nbsp;
2508
+ if (!options.entityType || options.entityType === "target") {
2509
+ await lintReservedNamespaceCharacterInEntityPaths("target");
2510
+ &nbsp;
2511
+ const filteredKeys = !keyPattern ? targets : <span class="branch-1 cbranch-no" title="branch not covered" >targets.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key));</span></span>
2512
+ &nbsp;
2513
+ if (filteredKeys.length &gt; 0) {
2514
+ log(`Linting ${filteredKeys.length} targets...\n`);
2515
+ }
2516
+ &nbsp;
2517
+ for (const key of filteredKeys) {
2518
+ const fullPath = getFullPathFromKey("target", key);
2519
+ &nbsp;
2520
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
2521
+ <span class="cstat-no" title="statement not covered" > await reportSimpleError({</span>
2522
+ entityType: "target",
2523
+ key,
2524
+ fullPath,
2525
+ message: `Invalid name: "${key}"`,
2526
+ detail: ENTITY_NAME_REGEX_ERROR,
2527
+ code: "invalid_name",
2528
+ });
2529
+ }
2530
+ &nbsp;
2531
+ try {
2532
+ const parsed = await datasource.readTarget(key);
2533
+ &nbsp;
2534
+ const result = targetZodSchema.safeParse(parsed);
2535
+ &nbsp;
2536
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!result.success &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >"error" in result) {</span>
2537
+ <span class="cstat-no" title="statement not covered" > await reportZodValidationError("target", key, fullPath, result.error);</span>
2538
+ }
2539
+ } catch (error) {
2540
+ <span class="cstat-no" title="statement not covered" > await reportThrownError("target", key, fullPath, error);</span>
2541
+ }
2542
+ }
2543
+ }
2157
2544
  &nbsp;
2158
2545
  // lint tests
2159
2546
  const tests = await datasource.listTests();
@@ -2162,10 +2549,13 @@ export async function lintProject(
2162
2549
  projectConfig,
2163
2550
  features as [string, ...string[]],
2164
2551
  segments as [string, ...string[]],
2552
+ targets as [string, ...string[]],
2165
2553
  );
2166
2554
  &nbsp;
2167
2555
  if (!options.entityType || options.entityType === "test") {
2168
- const filteredKeys = !keyPattern ? tests : <span class="branch-1 cbranch-no" title="branch not covered" >tests.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key))</span>;</span>
2556
+ await lintReservedNamespaceCharacterInEntityPaths("test");
2557
+ &nbsp;
2558
+ const filteredKeys = !keyPattern ? tests : <span class="branch-1 cbranch-no" title="branch not covered" >tests.filter(<span class="fstat-no" title="function not covered" >(k</span>ey) =&gt; <span class="cstat-no" title="statement not covered" >keyPattern.test(key));</span></span>
2169
2559
  &nbsp;
2170
2560
  if (filteredKeys.length &gt; 0) {
2171
2561
  log(`Linting ${filteredKeys.length} tests...\n`);
@@ -2174,7 +2564,7 @@ export async function lintProject(
2174
2564
  for (const key of filteredKeys) {
2175
2565
  const fullPath = getFullPathFromKey("test", key);
2176
2566
  &nbsp;
2177
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!ENTITY_NAME_REGEX.test(key)) {
2567
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
2178
2568
  <span class="cstat-no" title="statement not covered" > await reportSimpleError({</span>
2179
2569
  entityType: "test",
2180
2570
  key,
@@ -2210,30 +2600,48 @@ export const lintPlugin: Plugin = {
2210
2600
  handler: async function (options) {
2211
2601
  const { rootDirectoryPath, projectConfig, datasource, parsed } = options;
2212
2602
  &nbsp;
2213
- const result = await lintProject(
2214
- {
2215
- rootDirectoryPath,
2216
- projectConfig,
2217
- datasource,
2218
- options: parsed,
2219
- },
2220
- {
2221
- keyPattern: parsed.keyPattern,
2222
- entityType: parsed.entityType,
2223
- authors: parsed.authors,
2224
- json: parsed.json,
2225
- pretty: parsed.pretty,
2226
- },
2227
- );
2228
- &nbsp;
2229
- if (parsed.json) {
2230
- const payload = { errors: result.errors };
2231
- console.log(parsed.pretty ? JSON.stringify(payload, null, 2) : <span class="branch-1 cbranch-no" title="branch not covered" >JSON.stringify(payload))</span>;
2603
+ assertProjectSetJsonSelection(projectConfig, parsed.set, parsed.json);
2604
+ &nbsp;
2605
+ const executions = await getProjectSetExecutions(projectConfig, datasource, parsed.set);
2606
+ let hasError = false;
2607
+ &nbsp;
2608
+ for (const execution of executions) {
2609
+ printSetHeader(projectConfig, execution.set, parsed.json);
2610
+ &nbsp;
2611
+ const result = await lintProject(
2612
+ {
2613
+ rootDirectoryPath,
2614
+ projectConfig: execution.projectConfig,
2615
+ datasource: execution.datasource,
2616
+ options: parsed,
2617
+ },
2618
+ {
2619
+ keyPattern: parsed.keyPattern,
2620
+ entityType: parsed.entityType,
2621
+ authors: parsed.authors,
2622
+ json: parsed.json,
2623
+ pretty: parsed.pretty,
2624
+ },
2625
+ );
2626
+ &nbsp;
2627
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (parsed.json) {
2628
+ const payload = { errors: result.errors };
2629
+ console.log(parsed.pretty ? JSON.stringify(payload, null, 2) : <span class="branch-1 cbranch-no" title="branch not covered" >JSON.stringify(payload));</span>
2630
+ }
2631
+ &nbsp;
2632
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (result.hasError) {
2633
+ <span class="cstat-no" title="statement not covered" > hasError = true;</span>
2634
+ }
2232
2635
  }
2233
2636
  &nbsp;
2234
- <span class="missing-if-branch" title="if path not taken" >I</span>if (result.hasError) {
2637
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (hasError) {
2235
2638
  <span class="cstat-no" title="statement not covered" > return false;</span>
2236
2639
  }
2640
+ &nbsp;
2641
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!parsed.json) {
2642
+ <span class="cstat-no" title="statement not covered" > console.log("");</span>
2643
+ <span class="cstat-no" title="statement not covered" > console.log(CLI_FORMAT_GREEN, "✔ No lint errors found");</span>
2644
+ }
2237
2645
  },
2238
2646
  examples: [
2239
2647
  {
@@ -2281,16 +2689,16 @@ export const lintPlugin: Plugin = {
2281
2689
  <div class='footer quiet pad2 space-top1 center small'>
2282
2690
  Code coverage generated by
2283
2691
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
2284
- at 2026-04-26T16:47:51.164Z
2692
+ at 2026-07-12T20:35:50.655Z
2285
2693
  </div>
2286
- <script src="../prettify.js"></script>
2694
+ <script src="../../prettify.js"></script>
2287
2695
  <script>
2288
2696
  window.onload = function () {
2289
2697
  prettyPrint();
2290
2698
  };
2291
2699
  </script>
2292
- <script src="../sorter.js"></script>
2293
- <script src="../block-navigation.js"></script>
2700
+ <script src="../../sorter.js"></script>
2701
+ <script src="../../block-navigation.js"></script>
2294
2702
  </body>
2295
2703
  </html>
2296
2704