chaffjs 0.28.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (895) hide show
  1. package/dist/ai-score/of-document.d.ts.map +1 -1
  2. package/dist/ai-score/of-document.js +23 -14
  3. package/dist/ai-score/of-document.js.map +1 -1
  4. package/dist/ai-score/render.d.ts.map +1 -1
  5. package/dist/ai-score/render.js +13 -4
  6. package/dist/ai-score/render.js.map +1 -1
  7. package/dist/ai-score/score.d.ts +16 -1
  8. package/dist/ai-score/score.d.ts.map +1 -1
  9. package/dist/ai-score/score.js +15 -3
  10. package/dist/ai-score/score.js.map +1 -1
  11. package/dist/ai-score/signals.d.ts +2 -4
  12. package/dist/ai-score/signals.d.ts.map +1 -1
  13. package/dist/ai-score/signals.js +11 -2
  14. package/dist/ai-score/signals.js.map +1 -1
  15. package/dist/ai-score/text.d.ts +2 -0
  16. package/dist/ai-score/text.d.ts.map +1 -1
  17. package/dist/ai-score/text.js +4 -2
  18. package/dist/ai-score/text.js.map +1 -1
  19. package/dist/announced-count.d.ts +2 -0
  20. package/dist/announced-count.d.ts.map +1 -1
  21. package/dist/announced-count.js +14 -7
  22. package/dist/announced-count.js.map +1 -1
  23. package/dist/check-source.d.ts +3 -1
  24. package/dist/check-source.d.ts.map +1 -1
  25. package/dist/check-source.js +3 -1
  26. package/dist/check-source.js.map +1 -1
  27. package/dist/cli-text.d.ts.map +1 -1
  28. package/dist/cli-text.js +38 -16
  29. package/dist/cli-text.js.map +1 -1
  30. package/dist/cli.d.ts.map +1 -1
  31. package/dist/cli.js +2 -1
  32. package/dist/cli.js.map +1 -1
  33. package/dist/commands/cite-claims.d.ts +36 -0
  34. package/dist/commands/cite-claims.d.ts.map +1 -0
  35. package/dist/commands/cite-claims.js +81 -0
  36. package/dist/commands/cite-claims.js.map +1 -0
  37. package/dist/commands/cite-page.d.ts +14 -0
  38. package/dist/commands/cite-page.d.ts.map +1 -0
  39. package/dist/commands/cite-page.js +47 -0
  40. package/dist/commands/cite-page.js.map +1 -0
  41. package/dist/commands/cite-scaffold.d.ts +16 -0
  42. package/dist/commands/cite-scaffold.d.ts.map +1 -0
  43. package/dist/commands/cite-scaffold.js +21 -0
  44. package/dist/commands/cite-scaffold.js.map +1 -0
  45. package/dist/commands/cite.d.ts +3 -12
  46. package/dist/commands/cite.d.ts.map +1 -1
  47. package/dist/commands/cite.js +110 -51
  48. package/dist/commands/cite.js.map +1 -1
  49. package/dist/company-names.d.ts +34 -0
  50. package/dist/company-names.d.ts.map +1 -0
  51. package/dist/company-names.js +158 -0
  52. package/dist/company-names.js.map +1 -0
  53. package/dist/default-values.d.ts +17 -0
  54. package/dist/default-values.d.ts.map +1 -0
  55. package/dist/default-values.js +134 -0
  56. package/dist/default-values.js.map +1 -0
  57. package/dist/deprecated-use.d.ts +17 -0
  58. package/dist/deprecated-use.d.ts.map +1 -0
  59. package/dist/deprecated-use.js +95 -0
  60. package/dist/deprecated-use.js.map +1 -0
  61. package/dist/derived/stays.d.ts +43 -0
  62. package/dist/derived/stays.d.ts.map +1 -0
  63. package/dist/derived/stays.js +105 -0
  64. package/dist/derived/stays.js.map +1 -0
  65. package/dist/detectors/acronym-context.d.ts +2 -2
  66. package/dist/detectors/acronym-context.d.ts.map +1 -1
  67. package/dist/detectors/acronym-context.js +6 -0
  68. package/dist/detectors/acronym-context.js.map +1 -1
  69. package/dist/detectors/address-word.d.ts +3 -0
  70. package/dist/detectors/address-word.d.ts.map +1 -0
  71. package/dist/detectors/address-word.js +7 -0
  72. package/dist/detectors/address-word.js.map +1 -0
  73. package/dist/detectors/agreement-slip.d.ts.map +1 -1
  74. package/dist/detectors/agreement-slip.js +4 -1
  75. package/dist/detectors/agreement-slip.js.map +1 -1
  76. package/dist/detectors/ai-phrasing.d.ts +0 -4
  77. package/dist/detectors/ai-phrasing.d.ts.map +1 -1
  78. package/dist/detectors/ai-phrasing.js +5 -1
  79. package/dist/detectors/ai-phrasing.js.map +1 -1
  80. package/dist/detectors/amount-range.d.ts +3 -0
  81. package/dist/detectors/amount-range.d.ts.map +1 -0
  82. package/dist/detectors/amount-range.js +38 -0
  83. package/dist/detectors/amount-range.js.map +1 -0
  84. package/dist/detectors/amount-scale.d.ts +6 -1
  85. package/dist/detectors/amount-scale.d.ts.map +1 -1
  86. package/dist/detectors/amount-scale.js +33 -9
  87. package/dist/detectors/amount-scale.js.map +1 -1
  88. package/dist/detectors/announced-count.d.ts +1 -1
  89. package/dist/detectors/announced-count.d.ts.map +1 -1
  90. package/dist/detectors/announced-count.js +18 -3
  91. package/dist/detectors/announced-count.js.map +1 -1
  92. package/dist/detectors/bare-comparative.d.ts.map +1 -1
  93. package/dist/detectors/bare-comparative.js +4 -1
  94. package/dist/detectors/bare-comparative.js.map +1 -1
  95. package/dist/detectors/block-quotation.d.ts +13 -0
  96. package/dist/detectors/block-quotation.d.ts.map +1 -0
  97. package/dist/detectors/block-quotation.js +86 -0
  98. package/dist/detectors/block-quotation.js.map +1 -0
  99. package/dist/detectors/bracket-label.d.ts +10 -0
  100. package/dist/detectors/bracket-label.d.ts.map +1 -0
  101. package/dist/detectors/bracket-label.js +51 -0
  102. package/dist/detectors/bracket-label.js.map +1 -0
  103. package/dist/detectors/citation-entry.d.ts +5 -0
  104. package/dist/detectors/citation-entry.d.ts.map +1 -1
  105. package/dist/detectors/citation-entry.js +19 -5
  106. package/dist/detectors/citation-entry.js.map +1 -1
  107. package/dist/detectors/code-before.d.ts +6 -0
  108. package/dist/detectors/code-before.d.ts.map +1 -0
  109. package/dist/detectors/code-before.js +15 -0
  110. package/dist/detectors/code-before.js.map +1 -0
  111. package/dist/detectors/connective-hierarchy.d.ts +11 -1
  112. package/dist/detectors/connective-hierarchy.d.ts.map +1 -1
  113. package/dist/detectors/connective-hierarchy.js +26 -6
  114. package/dist/detectors/connective-hierarchy.js.map +1 -1
  115. package/dist/detectors/currency-notation.d.ts.map +1 -1
  116. package/dist/detectors/currency-notation.js +2 -1
  117. package/dist/detectors/currency-notation.js.map +1 -1
  118. package/dist/detectors/date-outside-period.d.ts +4 -0
  119. package/dist/detectors/date-outside-period.d.ts.map +1 -0
  120. package/dist/detectors/date-outside-period.js +34 -0
  121. package/dist/detectors/date-outside-period.js.map +1 -0
  122. package/dist/detectors/default-values.d.ts +3 -0
  123. package/dist/detectors/default-values.d.ts.map +1 -0
  124. package/dist/detectors/default-values.js +14 -0
  125. package/dist/detectors/default-values.js.map +1 -0
  126. package/dist/detectors/defined-term-form.d.ts +6 -2
  127. package/dist/detectors/defined-term-form.d.ts.map +1 -1
  128. package/dist/detectors/defined-term-form.js +72 -12
  129. package/dist/detectors/defined-term-form.js.map +1 -1
  130. package/dist/detectors/definition-use.d.ts.map +1 -1
  131. package/dist/detectors/definition-use.js +8 -1
  132. package/dist/detectors/definition-use.js.map +1 -1
  133. package/dist/detectors/deprecated-use.d.ts +3 -0
  134. package/dist/detectors/deprecated-use.d.ts.map +1 -0
  135. package/dist/detectors/deprecated-use.js +14 -0
  136. package/dist/detectors/deprecated-use.js.map +1 -0
  137. package/dist/detectors/derived-numbers.d.ts +1 -1
  138. package/dist/detectors/derived-numbers.d.ts.map +1 -1
  139. package/dist/detectors/derived-numbers.js +70 -15
  140. package/dist/detectors/derived-numbers.js.map +1 -1
  141. package/dist/detectors/document-shape.d.ts +1 -0
  142. package/dist/detectors/document-shape.d.ts.map +1 -1
  143. package/dist/detectors/document-shape.js +4 -1
  144. package/dist/detectors/document-shape.js.map +1 -1
  145. package/dist/detectors/due-date.d.ts +3 -0
  146. package/dist/detectors/due-date.d.ts.map +1 -0
  147. package/dist/detectors/due-date.js +38 -0
  148. package/dist/detectors/due-date.js.map +1 -0
  149. package/dist/detectors/en-shape.d.ts.map +1 -1
  150. package/dist/detectors/en-shape.js +17 -9
  151. package/dist/detectors/en-shape.js.map +1 -1
  152. package/dist/detectors/fact-consistency.d.ts.map +1 -1
  153. package/dist/detectors/fact-consistency.js +76 -2
  154. package/dist/detectors/fact-consistency.js.map +1 -1
  155. package/dist/detectors/heading-echo.d.ts.map +1 -1
  156. package/dist/detectors/heading-echo.js +10 -1
  157. package/dist/detectors/heading-echo.js.map +1 -1
  158. package/dist/detectors/kana-function-word.d.ts +12 -0
  159. package/dist/detectors/kana-function-word.d.ts.map +1 -0
  160. package/dist/detectors/kana-function-word.js +59 -0
  161. package/dist/detectors/kana-function-word.js.map +1 -0
  162. package/dist/detectors/line-amount.d.ts +3 -0
  163. package/dist/detectors/line-amount.d.ts.map +1 -0
  164. package/dist/detectors/line-amount.js +22 -0
  165. package/dist/detectors/line-amount.js.map +1 -0
  166. package/dist/detectors/location-pointer.d.ts +6 -0
  167. package/dist/detectors/location-pointer.d.ts.map +1 -0
  168. package/dist/detectors/location-pointer.js +22 -0
  169. package/dist/detectors/location-pointer.js.map +1 -0
  170. package/dist/detectors/mark-shape.d.ts.map +1 -1
  171. package/dist/detectors/mark-shape.js +13 -1
  172. package/dist/detectors/mark-shape.js.map +1 -1
  173. package/dist/detectors/nado-closed-list.d.ts +3 -0
  174. package/dist/detectors/nado-closed-list.d.ts.map +1 -0
  175. package/dist/detectors/nado-closed-list.js +21 -0
  176. package/dist/detectors/nado-closed-list.js.map +1 -0
  177. package/dist/detectors/name-variant.d.ts.map +1 -1
  178. package/dist/detectors/name-variant.js +82 -8
  179. package/dist/detectors/name-variant.js.map +1 -1
  180. package/dist/detectors/next-word.d.ts.map +1 -1
  181. package/dist/detectors/next-word.js +41 -8
  182. package/dist/detectors/next-word.js.map +1 -1
  183. package/dist/detectors/number-word-figure.d.ts +5 -0
  184. package/dist/detectors/number-word-figure.d.ts.map +1 -0
  185. package/dist/detectors/number-word-figure.js +32 -0
  186. package/dist/detectors/number-word-figure.js.map +1 -0
  187. package/dist/detectors/obligation-without-deadline.d.ts +39 -0
  188. package/dist/detectors/obligation-without-deadline.d.ts.map +1 -0
  189. package/dist/detectors/obligation-without-deadline.js +148 -0
  190. package/dist/detectors/obligation-without-deadline.js.map +1 -0
  191. package/dist/detectors/open-end-names.d.ts +23 -0
  192. package/dist/detectors/open-end-names.d.ts.map +1 -0
  193. package/dist/detectors/open-end-names.js +95 -0
  194. package/dist/detectors/open-end-names.js.map +1 -0
  195. package/dist/detectors/ordinal-run-gaps.d.ts +8 -0
  196. package/dist/detectors/ordinal-run-gaps.d.ts.map +1 -0
  197. package/dist/detectors/ordinal-run-gaps.js +80 -0
  198. package/dist/detectors/ordinal-run-gaps.js.map +1 -0
  199. package/dist/detectors/orthographic-variant.d.ts.map +1 -1
  200. package/dist/detectors/orthographic-variant.js +26 -9
  201. package/dist/detectors/orthographic-variant.js.map +1 -1
  202. package/dist/detectors/orthography.d.ts.map +1 -1
  203. package/dist/detectors/orthography.js +5 -0
  204. package/dist/detectors/orthography.js.map +1 -1
  205. package/dist/detectors/parameter-table.d.ts +3 -0
  206. package/dist/detectors/parameter-table.d.ts.map +1 -0
  207. package/dist/detectors/parameter-table.js +16 -0
  208. package/dist/detectors/parameter-table.js.map +1 -0
  209. package/dist/detectors/phone-number-variant.d.ts +3 -0
  210. package/dist/detectors/phone-number-variant.d.ts.map +1 -0
  211. package/dist/detectors/phone-number-variant.js +18 -0
  212. package/dist/detectors/phone-number-variant.js.map +1 -0
  213. package/dist/detectors/prerequisite-order.d.ts +3 -0
  214. package/dist/detectors/prerequisite-order.d.ts.map +1 -0
  215. package/dist/detectors/prerequisite-order.js +30 -0
  216. package/dist/detectors/prerequisite-order.js.map +1 -0
  217. package/dist/detectors/quote-unnamed-speaker.d.ts +3 -0
  218. package/dist/detectors/quote-unnamed-speaker.d.ts.map +1 -0
  219. package/dist/detectors/quote-unnamed-speaker.js +18 -0
  220. package/dist/detectors/quote-unnamed-speaker.js.map +1 -0
  221. package/dist/detectors/quote-without-source.d.ts +12 -2
  222. package/dist/detectors/quote-without-source.d.ts.map +1 -1
  223. package/dist/detectors/quote-without-source.js +45 -11
  224. package/dist/detectors/quote-without-source.js.map +1 -1
  225. package/dist/detectors/registry/amount-range.d.ts +3 -0
  226. package/dist/detectors/registry/amount-range.d.ts.map +1 -0
  227. package/dist/detectors/registry/amount-range.js +3 -0
  228. package/dist/detectors/registry/amount-range.js.map +1 -0
  229. package/dist/detectors/registry/arrival-before-departure.d.ts +3 -0
  230. package/dist/detectors/registry/arrival-before-departure.d.ts.map +1 -0
  231. package/dist/detectors/registry/arrival-before-departure.js +3 -0
  232. package/dist/detectors/registry/arrival-before-departure.js.map +1 -0
  233. package/dist/detectors/registry/date-outside-period.d.ts +3 -0
  234. package/dist/detectors/registry/date-outside-period.d.ts.map +1 -0
  235. package/dist/detectors/registry/date-outside-period.js +3 -0
  236. package/dist/detectors/registry/date-outside-period.js.map +1 -0
  237. package/dist/detectors/registry/default-values.d.ts +3 -0
  238. package/dist/detectors/registry/default-values.d.ts.map +1 -0
  239. package/dist/detectors/registry/default-values.js +3 -0
  240. package/dist/detectors/registry/default-values.js.map +1 -0
  241. package/dist/detectors/registry/deprecated-use.d.ts +3 -0
  242. package/dist/detectors/registry/deprecated-use.d.ts.map +1 -0
  243. package/dist/detectors/registry/deprecated-use.js +3 -0
  244. package/dist/detectors/registry/deprecated-use.js.map +1 -0
  245. package/dist/detectors/registry/due-date.d.ts +3 -0
  246. package/dist/detectors/registry/due-date.d.ts.map +1 -0
  247. package/dist/detectors/registry/due-date.js +3 -0
  248. package/dist/detectors/registry/due-date.js.map +1 -0
  249. package/dist/detectors/registry/kana-function-word.d.ts +3 -0
  250. package/dist/detectors/registry/kana-function-word.d.ts.map +1 -0
  251. package/dist/detectors/registry/kana-function-word.js +3 -0
  252. package/dist/detectors/registry/kana-function-word.js.map +1 -0
  253. package/dist/detectors/registry/line-amount.d.ts +3 -0
  254. package/dist/detectors/registry/line-amount.d.ts.map +1 -0
  255. package/dist/detectors/registry/line-amount.js +3 -0
  256. package/dist/detectors/registry/line-amount.js.map +1 -0
  257. package/dist/detectors/registry/nado-closed-list.d.ts +3 -0
  258. package/dist/detectors/registry/nado-closed-list.d.ts.map +1 -0
  259. package/dist/detectors/registry/nado-closed-list.js +3 -0
  260. package/dist/detectors/registry/nado-closed-list.js.map +1 -0
  261. package/dist/detectors/registry/number-word-figure.d.ts +3 -0
  262. package/dist/detectors/registry/number-word-figure.d.ts.map +1 -0
  263. package/dist/detectors/registry/number-word-figure.js +3 -0
  264. package/dist/detectors/registry/number-word-figure.js.map +1 -0
  265. package/dist/detectors/registry/obligation-without-deadline.d.ts +3 -0
  266. package/dist/detectors/registry/obligation-without-deadline.d.ts.map +1 -0
  267. package/dist/detectors/registry/obligation-without-deadline.js +3 -0
  268. package/dist/detectors/registry/obligation-without-deadline.js.map +1 -0
  269. package/dist/detectors/registry/parameter-table.d.ts +3 -0
  270. package/dist/detectors/registry/parameter-table.d.ts.map +1 -0
  271. package/dist/detectors/registry/parameter-table.js +3 -0
  272. package/dist/detectors/registry/parameter-table.js.map +1 -0
  273. package/dist/detectors/registry/phone-number-variant.d.ts +3 -0
  274. package/dist/detectors/registry/phone-number-variant.d.ts.map +1 -0
  275. package/dist/detectors/registry/phone-number-variant.js +3 -0
  276. package/dist/detectors/registry/phone-number-variant.js.map +1 -0
  277. package/dist/detectors/registry/prerequisite-order.d.ts +3 -0
  278. package/dist/detectors/registry/prerequisite-order.d.ts.map +1 -0
  279. package/dist/detectors/registry/prerequisite-order.js +3 -0
  280. package/dist/detectors/registry/prerequisite-order.js.map +1 -0
  281. package/dist/detectors/registry/quote-unnamed-speaker.d.ts +3 -0
  282. package/dist/detectors/registry/quote-unnamed-speaker.d.ts.map +1 -0
  283. package/dist/detectors/registry/quote-unnamed-speaker.js +3 -0
  284. package/dist/detectors/registry/quote-unnamed-speaker.js.map +1 -0
  285. package/dist/detectors/registry/tax-amount.d.ts +3 -0
  286. package/dist/detectors/registry/tax-amount.d.ts.map +1 -0
  287. package/dist/detectors/registry/tax-amount.js +3 -0
  288. package/dist/detectors/registry/tax-amount.js.map +1 -0
  289. package/dist/detectors/registry/time-order.d.ts +3 -0
  290. package/dist/detectors/registry/time-order.d.ts.map +1 -0
  291. package/dist/detectors/registry/time-order.js +3 -0
  292. package/dist/detectors/registry/time-order.js.map +1 -0
  293. package/dist/detectors/registry/ui-label.d.ts +3 -0
  294. package/dist/detectors/registry/ui-label.d.ts.map +1 -0
  295. package/dist/detectors/registry/ui-label.js +3 -0
  296. package/dist/detectors/registry/ui-label.js.map +1 -0
  297. package/dist/detectors/registry/undefined-call.d.ts +3 -0
  298. package/dist/detectors/registry/undefined-call.d.ts.map +1 -0
  299. package/dist/detectors/registry/undefined-call.js +3 -0
  300. package/dist/detectors/registry/undefined-call.js.map +1 -0
  301. package/dist/detectors/registry/undefined-term.d.ts +3 -0
  302. package/dist/detectors/registry/undefined-term.d.ts.map +1 -0
  303. package/dist/detectors/registry/undefined-term.js +3 -0
  304. package/dist/detectors/registry/undefined-term.js.map +1 -0
  305. package/dist/detectors/registry/version-order.d.ts +3 -0
  306. package/dist/detectors/registry/version-order.d.ts.map +1 -0
  307. package/dist/detectors/registry/version-order.js +3 -0
  308. package/dist/detectors/registry/version-order.js.map +1 -0
  309. package/dist/detectors/registry/warning-action.d.ts +3 -0
  310. package/dist/detectors/registry/warning-action.d.ts.map +1 -0
  311. package/dist/detectors/registry/warning-action.js +3 -0
  312. package/dist/detectors/registry/warning-action.js.map +1 -0
  313. package/dist/detectors/requirement-smell.d.ts.map +1 -1
  314. package/dist/detectors/requirement-smell.js +25 -8
  315. package/dist/detectors/requirement-smell.js.map +1 -1
  316. package/dist/detectors/structure-tree.d.ts +12 -4
  317. package/dist/detectors/structure-tree.d.ts.map +1 -1
  318. package/dist/detectors/structure-tree.js +31 -14
  319. package/dist/detectors/structure-tree.js.map +1 -1
  320. package/dist/detectors/superlative-scope.d.ts.map +1 -1
  321. package/dist/detectors/superlative-scope.js +11 -1
  322. package/dist/detectors/superlative-scope.js.map +1 -1
  323. package/dist/detectors/tax-amount.d.ts +3 -0
  324. package/dist/detectors/tax-amount.d.ts.map +1 -0
  325. package/dist/detectors/tax-amount.js +19 -0
  326. package/dist/detectors/tax-amount.js.map +1 -0
  327. package/dist/detectors/technical-docs.d.ts.map +1 -1
  328. package/dist/detectors/technical-docs.js +5 -1
  329. package/dist/detectors/technical-docs.js.map +1 -1
  330. package/dist/detectors/term-extension.d.ts +14 -0
  331. package/dist/detectors/term-extension.d.ts.map +1 -0
  332. package/dist/detectors/term-extension.js +67 -0
  333. package/dist/detectors/term-extension.js.map +1 -0
  334. package/dist/detectors/time-order.d.ts +4 -0
  335. package/dist/detectors/time-order.d.ts.map +1 -0
  336. package/dist/detectors/time-order.js +32 -0
  337. package/dist/detectors/time-order.js.map +1 -0
  338. package/dist/detectors/ui-label.d.ts +3 -0
  339. package/dist/detectors/ui-label.d.ts.map +1 -0
  340. package/dist/detectors/ui-label.js +16 -0
  341. package/dist/detectors/ui-label.js.map +1 -0
  342. package/dist/detectors/unbalanced-bracket.d.ts.map +1 -1
  343. package/dist/detectors/unbalanced-bracket.js +8 -13
  344. package/dist/detectors/unbalanced-bracket.js.map +1 -1
  345. package/dist/detectors/undefined-call.d.ts +3 -0
  346. package/dist/detectors/undefined-call.d.ts.map +1 -0
  347. package/dist/detectors/undefined-call.js +18 -0
  348. package/dist/detectors/undefined-call.js.map +1 -0
  349. package/dist/detectors/undefined-term.d.ts +22 -0
  350. package/dist/detectors/undefined-term.d.ts.map +1 -0
  351. package/dist/detectors/undefined-term.js +85 -0
  352. package/dist/detectors/undefined-term.js.map +1 -0
  353. package/dist/detectors/unknown-word.d.ts +1 -1
  354. package/dist/detectors/unknown-word.js +3 -3
  355. package/dist/detectors/unknown-word.js.map +1 -1
  356. package/dist/detectors/vague-deadline.d.ts +4 -0
  357. package/dist/detectors/vague-deadline.d.ts.map +1 -1
  358. package/dist/detectors/vague-deadline.js +3 -3
  359. package/dist/detectors/vague-deadline.js.map +1 -1
  360. package/dist/detectors/version-mismatch.d.ts.map +1 -1
  361. package/dist/detectors/version-mismatch.js +18 -1
  362. package/dist/detectors/version-mismatch.js.map +1 -1
  363. package/dist/detectors/version-order.d.ts +3 -0
  364. package/dist/detectors/version-order.d.ts.map +1 -0
  365. package/dist/detectors/version-order.js +43 -0
  366. package/dist/detectors/version-order.js.map +1 -0
  367. package/dist/detectors/warning-action.d.ts +3 -0
  368. package/dist/detectors/warning-action.d.ts.map +1 -0
  369. package/dist/detectors/warning-action.js +48 -0
  370. package/dist/detectors/warning-action.js.map +1 -0
  371. package/dist/facts/condition-pairs.d.ts +51 -0
  372. package/dist/facts/condition-pairs.d.ts.map +1 -0
  373. package/dist/facts/condition-pairs.js +203 -0
  374. package/dist/facts/condition-pairs.js.map +1 -0
  375. package/dist/facts/event-dates.d.ts +26 -0
  376. package/dist/facts/event-dates.d.ts.map +1 -0
  377. package/dist/facts/event-dates.js +38 -0
  378. package/dist/facts/event-dates.js.map +1 -0
  379. package/dist/facts/fact-scope.d.ts +2 -0
  380. package/dist/facts/fact-scope.d.ts.map +1 -1
  381. package/dist/facts/fact-scope.js +5 -0
  382. package/dist/facts/fact-scope.js.map +1 -1
  383. package/dist/facts/labelled-facts.d.ts +2 -0
  384. package/dist/facts/labelled-facts.d.ts.map +1 -1
  385. package/dist/facts/labelled-facts.js +9 -1
  386. package/dist/facts/labelled-facts.js.map +1 -1
  387. package/dist/facts/table-facts.d.ts +16 -0
  388. package/dist/facts/table-facts.d.ts.map +1 -1
  389. package/dist/facts/table-facts.js +2 -2
  390. package/dist/facts/table-facts.js.map +1 -1
  391. package/dist/grade/ai-score.d.ts +1 -1
  392. package/dist/grade/ai-score.d.ts.map +1 -1
  393. package/dist/grade/text.js +2 -2
  394. package/dist/grade/text.js.map +1 -1
  395. package/dist/heading-numbering.js +2 -2
  396. package/dist/heading-numbering.js.map +1 -1
  397. package/dist/html/fetch-page.d.ts +20 -0
  398. package/dist/html/fetch-page.d.ts.map +1 -0
  399. package/dist/html/fetch-page.js +51 -0
  400. package/dist/html/fetch-page.js.map +1 -0
  401. package/dist/html/fetched-text.d.ts +5 -0
  402. package/dist/html/fetched-text.d.ts.map +1 -0
  403. package/dist/html/fetched-text.js +25 -0
  404. package/dist/html/fetched-text.js.map +1 -0
  405. package/dist/html/html-content-block.d.ts +6 -0
  406. package/dist/html/html-content-block.d.ts.map +1 -0
  407. package/dist/html/html-content-block.js +86 -0
  408. package/dist/html/html-content-block.js.map +1 -0
  409. package/dist/html/html-elements.d.ts +41 -0
  410. package/dist/html/html-elements.d.ts.map +1 -0
  411. package/dist/html/html-elements.js +91 -0
  412. package/dist/html/html-elements.js.map +1 -0
  413. package/dist/html/html-footnote-marks.d.ts +2 -0
  414. package/dist/html/html-footnote-marks.d.ts.map +1 -0
  415. package/dist/html/html-footnote-marks.js +15 -0
  416. package/dist/html/html-footnote-marks.js.map +1 -0
  417. package/dist/html/html-heading-links.d.ts +6 -0
  418. package/dist/html/html-heading-links.d.ts.map +1 -0
  419. package/dist/html/html-heading-links.js +71 -0
  420. package/dist/html/html-heading-links.js.map +1 -0
  421. package/dist/html/html-lost-tags.d.ts +3 -0
  422. package/dist/html/html-lost-tags.d.ts.map +1 -0
  423. package/dist/html/html-lost-tags.js +11 -0
  424. package/dist/html/html-lost-tags.js.map +1 -0
  425. package/dist/html/html-markdown.d.ts +2 -0
  426. package/dist/html/html-markdown.d.ts.map +1 -0
  427. package/dist/html/html-markdown.js +347 -0
  428. package/dist/html/html-markdown.js.map +1 -0
  429. package/dist/html/html-preformatted.d.ts +17 -0
  430. package/dist/html/html-preformatted.d.ts.map +1 -0
  431. package/dist/html/html-preformatted.js +82 -0
  432. package/dist/html/html-preformatted.js.map +1 -0
  433. package/dist/html/html-reader-only.d.ts +6 -0
  434. package/dist/html/html-reader-only.d.ts.map +1 -0
  435. package/dist/html/html-reader-only.js +63 -0
  436. package/dist/html/html-reader-only.js.map +1 -0
  437. package/dist/html/html-run-in-headings.d.ts +2 -0
  438. package/dist/html/html-run-in-headings.d.ts.map +1 -0
  439. package/dist/html/html-run-in-headings.js +36 -0
  440. package/dist/html/html-run-in-headings.js.map +1 -0
  441. package/dist/html/html-tables.d.ts +3 -0
  442. package/dist/html/html-tables.d.ts.map +1 -0
  443. package/dist/html/html-tables.js +58 -0
  444. package/dist/html/html-tables.js.map +1 -0
  445. package/dist/html/html-widgets.d.ts +3 -0
  446. package/dist/html/html-widgets.d.ts.map +1 -0
  447. package/dist/html/html-widgets.js +71 -0
  448. package/dist/html/html-widgets.js.map +1 -0
  449. package/dist/html/markup-text.d.ts +5 -0
  450. package/dist/html/markup-text.d.ts.map +1 -0
  451. package/dist/html/markup-text.js +32 -0
  452. package/dist/html/markup-text.js.map +1 -0
  453. package/dist/html/page-document.d.ts +9 -0
  454. package/dist/html/page-document.d.ts.map +1 -0
  455. package/dist/html/page-document.js +19 -0
  456. package/dist/html/page-document.js.map +1 -0
  457. package/dist/inline-count.d.ts +19 -0
  458. package/dist/inline-count.d.ts.map +1 -0
  459. package/dist/inline-count.js +109 -0
  460. package/dist/inline-count.js.map +1 -0
  461. package/dist/kana-spelling.d.ts +5 -0
  462. package/dist/kana-spelling.d.ts.map +1 -1
  463. package/dist/kana-spelling.js +5 -0
  464. package/dist/kana-spelling.js.map +1 -1
  465. package/dist/location-part.d.ts +13 -0
  466. package/dist/location-part.d.ts.map +1 -0
  467. package/dist/location-part.js +24 -0
  468. package/dist/location-part.js.map +1 -0
  469. package/dist/nado-closed-list.d.ts +20 -0
  470. package/dist/nado-closed-list.d.ts.map +1 -0
  471. package/dist/nado-closed-list.js +72 -0
  472. package/dist/nado-closed-list.js.map +1 -0
  473. package/dist/name-cue.d.ts +17 -0
  474. package/dist/name-cue.d.ts.map +1 -0
  475. package/dist/name-cue.js +29 -0
  476. package/dist/name-cue.js.map +1 -0
  477. package/dist/name-variants.d.ts +23 -1
  478. package/dist/name-variants.d.ts.map +1 -1
  479. package/dist/name-variants.js +39 -8
  480. package/dist/name-variants.js.map +1 -1
  481. package/dist/paragraph-runs.d.ts +6 -1
  482. package/dist/paragraph-runs.d.ts.map +1 -1
  483. package/dist/paragraph-runs.js +9 -2
  484. package/dist/paragraph-runs.js.map +1 -1
  485. package/dist/parameter-table.d.ts +19 -0
  486. package/dist/parameter-table.d.ts.map +1 -0
  487. package/dist/parameter-table.js +191 -0
  488. package/dist/parameter-table.js.map +1 -0
  489. package/dist/phone-numbers.d.ts +23 -0
  490. package/dist/phone-numbers.d.ts.map +1 -0
  491. package/dist/phone-numbers.js +83 -0
  492. package/dist/phone-numbers.js.map +1 -0
  493. package/dist/place-names.d.ts +55 -0
  494. package/dist/place-names.d.ts.map +1 -0
  495. package/dist/place-names.js +196 -0
  496. package/dist/place-names.js.map +1 -0
  497. package/dist/plugin.d.ts +4 -0
  498. package/dist/plugin.d.ts.map +1 -1
  499. package/dist/prerequisite-order.d.ts +16 -0
  500. package/dist/prerequisite-order.d.ts.map +1 -0
  501. package/dist/prerequisite-order.js +29 -0
  502. package/dist/prerequisite-order.js.map +1 -0
  503. package/dist/profile/parse.d.ts.map +1 -1
  504. package/dist/profile/parse.js +10 -1
  505. package/dist/profile/parse.js.map +1 -1
  506. package/dist/reasons.d.ts +2 -0
  507. package/dist/reasons.d.ts.map +1 -1
  508. package/dist/reasons.js +2 -0
  509. package/dist/reasons.js.map +1 -1
  510. package/dist/render/rules-json.d.ts.map +1 -1
  511. package/dist/render/rules-json.js +4 -0
  512. package/dist/render/rules-json.js.map +1 -1
  513. package/dist/render/rules-table.d.ts.map +1 -1
  514. package/dist/render/rules-table.js +6 -2
  515. package/dist/render/rules-table.js.map +1 -1
  516. package/dist/rule-genres.d.ts +5 -2
  517. package/dist/rule-genres.d.ts.map +1 -1
  518. package/dist/rule-genres.js +2 -0
  519. package/dist/rule-genres.js.map +1 -1
  520. package/dist/rule-load.d.ts.map +1 -1
  521. package/dist/rule-load.js +2 -1
  522. package/dist/rule-load.js.map +1 -1
  523. package/dist/run.d.ts.map +1 -1
  524. package/dist/run.js +5 -1
  525. package/dist/run.js.map +1 -1
  526. package/dist/spelling.d.ts +2 -0
  527. package/dist/spelling.d.ts.map +1 -1
  528. package/dist/spelling.js +6 -0
  529. package/dist/spelling.js.map +1 -1
  530. package/dist/structure/action-due.d.ts +21 -0
  531. package/dist/structure/action-due.d.ts.map +1 -0
  532. package/dist/structure/action-due.js +126 -0
  533. package/dist/structure/action-due.js.map +1 -0
  534. package/dist/structure/amount-range.d.ts +30 -0
  535. package/dist/structure/amount-range.d.ts.map +1 -0
  536. package/dist/structure/amount-range.js +153 -0
  537. package/dist/structure/amount-range.js.map +1 -0
  538. package/dist/structure/amount-scale.d.ts +6 -0
  539. package/dist/structure/amount-scale.d.ts.map +1 -1
  540. package/dist/structure/amount-scale.js +13 -0
  541. package/dist/structure/amount-scale.js.map +1 -1
  542. package/dist/structure/cite.d.ts +5 -2
  543. package/dist/structure/cite.d.ts.map +1 -1
  544. package/dist/structure/cite.js +20 -1
  545. package/dist/structure/cite.js.map +1 -1
  546. package/dist/structure/counted-amounts.d.ts +12 -0
  547. package/dist/structure/counted-amounts.d.ts.map +1 -0
  548. package/dist/structure/counted-amounts.js +30 -0
  549. package/dist/structure/counted-amounts.js.map +1 -0
  550. package/dist/structure/date-order.d.ts +24 -3
  551. package/dist/structure/date-order.d.ts.map +1 -1
  552. package/dist/structure/date-order.js +49 -17
  553. package/dist/structure/date-order.js.map +1 -1
  554. package/dist/structure/date-outside-period.d.ts +27 -0
  555. package/dist/structure/date-outside-period.d.ts.map +1 -0
  556. package/dist/structure/date-outside-period.js +86 -0
  557. package/dist/structure/date-outside-period.js.map +1 -0
  558. package/dist/structure/definition-use.d.ts +5 -2
  559. package/dist/structure/definition-use.d.ts.map +1 -1
  560. package/dist/structure/definition-use.js +11 -3
  561. package/dist/structure/definition-use.js.map +1 -1
  562. package/dist/structure/due-date.d.ts +19 -0
  563. package/dist/structure/due-date.d.ts.map +1 -0
  564. package/dist/structure/due-date.js +30 -0
  565. package/dist/structure/due-date.js.map +1 -0
  566. package/dist/structure/heading-runs.d.ts +9 -0
  567. package/dist/structure/heading-runs.d.ts.map +1 -0
  568. package/dist/structure/heading-runs.js +23 -0
  569. package/dist/structure/heading-runs.js.map +1 -0
  570. package/dist/structure/install-pin.d.ts +46 -0
  571. package/dist/structure/install-pin.d.ts.map +1 -0
  572. package/dist/structure/install-pin.js +85 -0
  573. package/dist/structure/install-pin.js.map +1 -0
  574. package/dist/structure/leg-times.d.ts +34 -0
  575. package/dist/structure/leg-times.d.ts.map +1 -0
  576. package/dist/structure/leg-times.js +135 -0
  577. package/dist/structure/leg-times.js.map +1 -0
  578. package/dist/structure/line-amount-unit.d.ts +24 -0
  579. package/dist/structure/line-amount-unit.d.ts.map +1 -0
  580. package/dist/structure/line-amount-unit.js +24 -0
  581. package/dist/structure/line-amount-unit.js.map +1 -0
  582. package/dist/structure/line-amount.d.ts +40 -0
  583. package/dist/structure/line-amount.d.ts.map +1 -0
  584. package/dist/structure/line-amount.js +118 -0
  585. package/dist/structure/line-amount.js.map +1 -0
  586. package/dist/structure/number-word-figure.d.ts +37 -0
  587. package/dist/structure/number-word-figure.d.ts.map +1 -0
  588. package/dist/structure/number-word-figure.js +151 -0
  589. package/dist/structure/number-word-figure.js.map +1 -0
  590. package/dist/structure/numbering.d.ts +1 -0
  591. package/dist/structure/numbering.d.ts.map +1 -1
  592. package/dist/structure/numbering.js +3 -0
  593. package/dist/structure/numbering.js.map +1 -1
  594. package/dist/structure/ordinal-runs.d.ts +45 -0
  595. package/dist/structure/ordinal-runs.d.ts.map +1 -0
  596. package/dist/structure/ordinal-runs.js +78 -0
  597. package/dist/structure/ordinal-runs.js.map +1 -0
  598. package/dist/structure/percent-sum-prose.d.ts +1 -1
  599. package/dist/structure/percent-sum-prose.d.ts.map +1 -1
  600. package/dist/structure/percent-sum-prose.js +45 -3
  601. package/dist/structure/percent-sum-prose.js.map +1 -1
  602. package/dist/structure/percent-sum.d.ts +8 -0
  603. package/dist/structure/percent-sum.d.ts.map +1 -1
  604. package/dist/structure/percent-sum.js +8 -1
  605. package/dist/structure/percent-sum.js.map +1 -1
  606. package/dist/structure/release-list.d.ts +9 -0
  607. package/dist/structure/release-list.d.ts.map +1 -0
  608. package/dist/structure/release-list.js +46 -0
  609. package/dist/structure/release-list.js.map +1 -0
  610. package/dist/structure/share-column.d.ts +7 -0
  611. package/dist/structure/share-column.d.ts.map +1 -0
  612. package/dist/structure/share-column.js +22 -0
  613. package/dist/structure/share-column.js.map +1 -0
  614. package/dist/structure/stated-period.d.ts +31 -0
  615. package/dist/structure/stated-period.d.ts.map +1 -0
  616. package/dist/structure/stated-period.js +127 -0
  617. package/dist/structure/stated-period.js.map +1 -0
  618. package/dist/structure/tax.d.ts +25 -0
  619. package/dist/structure/tax.d.ts.map +1 -0
  620. package/dist/structure/tax.js +86 -0
  621. package/dist/structure/tax.js.map +1 -0
  622. package/dist/structure/time-marks.d.ts +58 -0
  623. package/dist/structure/time-marks.d.ts.map +1 -0
  624. package/dist/structure/time-marks.js +74 -0
  625. package/dist/structure/time-marks.js.map +1 -0
  626. package/dist/structure/time-order.d.ts +21 -0
  627. package/dist/structure/time-order.d.ts.map +1 -0
  628. package/dist/structure/time-order.js +108 -0
  629. package/dist/structure/time-order.js.map +1 -0
  630. package/dist/structure/title-lines.d.ts +8 -0
  631. package/dist/structure/title-lines.d.ts.map +1 -0
  632. package/dist/structure/title-lines.js +27 -0
  633. package/dist/structure/title-lines.js.map +1 -0
  634. package/dist/structure/total.d.ts.map +1 -1
  635. package/dist/structure/total.js +3 -1
  636. package/dist/structure/total.js.map +1 -1
  637. package/dist/structure/version-mismatch.d.ts +1 -5
  638. package/dist/structure/version-mismatch.d.ts.map +1 -1
  639. package/dist/structure/version-mismatch.js +65 -12
  640. package/dist/structure/version-mismatch.js.map +1 -1
  641. package/dist/structure/version-order.d.ts +23 -0
  642. package/dist/structure/version-order.d.ts.map +1 -0
  643. package/dist/structure/version-order.js +67 -0
  644. package/dist/structure/version-order.js.map +1 -0
  645. package/dist/table-text.d.ts +9 -0
  646. package/dist/table-text.d.ts.map +1 -0
  647. package/dist/table-text.js +36 -0
  648. package/dist/table-text.js.map +1 -0
  649. package/dist/ui-labels.d.ts +16 -0
  650. package/dist/ui-labels.d.ts.map +1 -0
  651. package/dist/ui-labels.js +42 -0
  652. package/dist/ui-labels.js.map +1 -0
  653. package/dist/undefined-call.d.ts +13 -0
  654. package/dist/undefined-call.d.ts.map +1 -0
  655. package/dist/undefined-call.js +55 -0
  656. package/dist/undefined-call.js.map +1 -0
  657. package/dist/unnamed-speaker.d.ts +23 -0
  658. package/dist/unnamed-speaker.d.ts.map +1 -0
  659. package/dist/unnamed-speaker.js +176 -0
  660. package/dist/unnamed-speaker.js.map +1 -0
  661. package/dist/warning-action.d.ts +22 -0
  662. package/dist/warning-action.d.ts.map +1 -0
  663. package/dist/warning-action.js +58 -0
  664. package/dist/warning-action.js.map +1 -0
  665. package/genres.yaml +2 -0
  666. package/package.json +4 -3
  667. package/profiles/statute.yaml +8 -0
  668. package/rules/agreement-slip.yaml +2 -2
  669. package/rules/amount-range-reversed.yaml +52 -0
  670. package/rules/amount-scale-consistency.yaml +4 -4
  671. package/rules/announced-count-mismatch.yaml +9 -4
  672. package/rules/arrival-before-departure.yaml +48 -0
  673. package/rules/connective-hierarchy.yaml +3 -3
  674. package/rules/currency-notation-consistency.yaml +2 -2
  675. package/rules/date-order.yaml +9 -4
  676. package/rules/date-outside-period.yaml +64 -0
  677. package/rules/default-value-mismatch.yaml +79 -0
  678. package/rules/defined-term-form.yaml +9 -7
  679. package/rules/deprecated-option-used.yaml +78 -0
  680. package/rules/doubled-nado.yaml +28 -12
  681. package/rules/due-before-issue.yaml +68 -0
  682. package/rules/duplicate-definition.yaml +2 -2
  683. package/rules/duration-mismatch.yaml +12 -4
  684. package/rules/heading-echo.yaml +2 -2
  685. package/rules/hyphen-as-dash.yaml +2 -2
  686. package/rules/kana-function-word.yaml +58 -0
  687. package/rules/latin-spacing.yaml +6 -5
  688. package/rules/line-amount-mismatch.yaml +58 -0
  689. package/rules/nado-closed-list.yaml +77 -0
  690. package/rules/name-variant.yaml +14 -2
  691. package/rules/number-word-figure-mismatch.yaml +76 -0
  692. package/rules/numbering-gap.yaml +2 -2
  693. package/rules/obligation-without-deadline.yaml +95 -0
  694. package/rules/one-sentence-paragraph-run.yaml +2 -3
  695. package/rules/parameter-table-mismatch.yaml +90 -0
  696. package/rules/percent-sum-mismatch.yaml +2 -2
  697. package/rules/phone-number-variant.yaml +68 -0
  698. package/rules/prerequisite-after-step.yaml +78 -0
  699. package/rules/quote-unnamed-speaker.yaml +67 -0
  700. package/rules/quote-without-source.yaml +6 -6
  701. package/rules/requirement-smell.yaml +3 -3
  702. package/rules/sentence-initial-conjunction-run.yaml +13 -7
  703. package/rules/summary-fact-mismatch.yaml +4 -4
  704. package/rules/tax-mismatch.yaml +71 -0
  705. package/rules/time-order.yaml +65 -0
  706. package/rules/title-length.yaml +2 -2
  707. package/rules/ui-label-variant.yaml +70 -0
  708. package/rules/unbalanced-bracket.yaml +4 -4
  709. package/rules/uncomparable-graded.yaml +29 -10
  710. package/rules/undefined-function-call.yaml +77 -0
  711. package/rules/undefined-term.yaml +72 -0
  712. package/rules/unknown-word.yaml +2 -2
  713. package/rules/unqualified-superlative.yaml +2 -2
  714. package/rules/use-before-definition.yaml +2 -2
  715. package/rules/version-mismatch.yaml +12 -4
  716. package/rules/version-order.yaml +85 -0
  717. package/rules/very-adjective.yaml +31 -13
  718. package/rules/warning-without-action.yaml +64 -0
  719. package/rules/wordy-phrase.yaml +27 -9
  720. package/src/ai-score/of-document.ts +19 -9
  721. package/src/ai-score/render.ts +24 -4
  722. package/src/ai-score/score.ts +24 -3
  723. package/src/ai-score/signals.ts +12 -2
  724. package/src/ai-score/text.ts +7 -2
  725. package/src/announced-count.ts +19 -12
  726. package/src/check-source.ts +11 -2
  727. package/src/cli-text.ts +38 -16
  728. package/src/cli.ts +2 -1
  729. package/src/commands/cite-claims.ts +103 -0
  730. package/src/commands/cite-page.ts +61 -0
  731. package/src/commands/cite-scaffold.ts +27 -0
  732. package/src/commands/cite.ts +127 -58
  733. package/src/company-names.ts +202 -0
  734. package/src/default-values.ts +158 -0
  735. package/src/deprecated-use.ts +122 -0
  736. package/src/derived/stays.ts +145 -0
  737. package/src/detectors/acronym-context.ts +10 -2
  738. package/src/detectors/address-word.ts +9 -0
  739. package/src/detectors/agreement-slip.ts +7 -1
  740. package/src/detectors/ai-phrasing.ts +6 -1
  741. package/src/detectors/amount-range.ts +54 -0
  742. package/src/detectors/amount-scale.ts +50 -17
  743. package/src/detectors/announced-count.ts +29 -11
  744. package/src/detectors/bare-comparative.ts +7 -2
  745. package/src/detectors/block-quotation.ts +95 -0
  746. package/src/detectors/bracket-label.ts +58 -0
  747. package/src/detectors/citation-entry.ts +20 -5
  748. package/src/detectors/code-before.ts +14 -0
  749. package/src/detectors/connective-hierarchy.ts +39 -11
  750. package/src/detectors/currency-notation.ts +2 -1
  751. package/src/detectors/date-outside-period.ts +38 -0
  752. package/src/detectors/default-values.ts +17 -0
  753. package/src/detectors/defined-term-form.ts +84 -15
  754. package/src/detectors/definition-use.ts +10 -2
  755. package/src/detectors/deprecated-use.ts +17 -0
  756. package/src/detectors/derived-numbers.ts +106 -15
  757. package/src/detectors/document-shape.ts +6 -1
  758. package/src/detectors/due-date.ts +47 -0
  759. package/src/detectors/en-shape.ts +27 -11
  760. package/src/detectors/fact-consistency.ts +95 -3
  761. package/src/detectors/heading-echo.ts +11 -1
  762. package/src/detectors/kana-function-word.ts +71 -0
  763. package/src/detectors/line-amount.ts +33 -0
  764. package/src/detectors/location-pointer.ts +30 -0
  765. package/src/detectors/mark-shape.ts +18 -1
  766. package/src/detectors/nado-closed-list.ts +25 -0
  767. package/src/detectors/name-variant.ts +106 -13
  768. package/src/detectors/next-word.ts +56 -9
  769. package/src/detectors/number-word-figure.ts +43 -0
  770. package/src/detectors/obligation-without-deadline.ts +192 -0
  771. package/src/detectors/open-end-names.ts +140 -0
  772. package/src/detectors/ordinal-run-gaps.ts +101 -0
  773. package/src/detectors/orthographic-variant.ts +39 -14
  774. package/src/detectors/orthography.ts +6 -1
  775. package/src/detectors/parameter-table.ts +17 -0
  776. package/src/detectors/phone-number-variant.ts +18 -0
  777. package/src/detectors/prerequisite-order.ts +35 -0
  778. package/src/detectors/quote-unnamed-speaker.ts +19 -0
  779. package/src/detectors/quote-without-source.ts +57 -10
  780. package/src/detectors/registry/amount-range.ts +4 -0
  781. package/src/detectors/registry/arrival-before-departure.ts +4 -0
  782. package/src/detectors/registry/date-outside-period.ts +4 -0
  783. package/src/detectors/registry/default-values.ts +4 -0
  784. package/src/detectors/registry/deprecated-use.ts +4 -0
  785. package/src/detectors/registry/due-date.ts +4 -0
  786. package/src/detectors/registry/kana-function-word.ts +4 -0
  787. package/src/detectors/registry/line-amount.ts +4 -0
  788. package/src/detectors/registry/nado-closed-list.ts +4 -0
  789. package/src/detectors/registry/number-word-figure.ts +4 -0
  790. package/src/detectors/registry/obligation-without-deadline.ts +4 -0
  791. package/src/detectors/registry/parameter-table.ts +4 -0
  792. package/src/detectors/registry/phone-number-variant.ts +4 -0
  793. package/src/detectors/registry/prerequisite-order.ts +4 -0
  794. package/src/detectors/registry/quote-unnamed-speaker.ts +4 -0
  795. package/src/detectors/registry/tax-amount.ts +4 -0
  796. package/src/detectors/registry/time-order.ts +4 -0
  797. package/src/detectors/registry/ui-label.ts +4 -0
  798. package/src/detectors/registry/undefined-call.ts +4 -0
  799. package/src/detectors/registry/undefined-term.ts +4 -0
  800. package/src/detectors/registry/version-order.ts +4 -0
  801. package/src/detectors/registry/warning-action.ts +4 -0
  802. package/src/detectors/requirement-smell.ts +29 -9
  803. package/src/detectors/structure-tree.ts +43 -21
  804. package/src/detectors/superlative-scope.ts +13 -1
  805. package/src/detectors/tax-amount.ts +25 -0
  806. package/src/detectors/technical-docs.ts +7 -1
  807. package/src/detectors/term-extension.ts +67 -0
  808. package/src/detectors/time-order.ts +49 -0
  809. package/src/detectors/ui-label.ts +17 -0
  810. package/src/detectors/unbalanced-bracket.ts +7 -14
  811. package/src/detectors/undefined-call.ts +19 -0
  812. package/src/detectors/undefined-term.ts +103 -0
  813. package/src/detectors/unknown-word.ts +3 -3
  814. package/src/detectors/vague-deadline.ts +3 -3
  815. package/src/detectors/version-mismatch.ts +26 -5
  816. package/src/detectors/version-order.ts +50 -0
  817. package/src/detectors/warning-action.ts +49 -0
  818. package/src/facts/condition-pairs.ts +289 -0
  819. package/src/facts/event-dates.ts +63 -0
  820. package/src/facts/fact-scope.ts +6 -0
  821. package/src/facts/labelled-facts.ts +13 -1
  822. package/src/facts/table-facts.ts +3 -3
  823. package/src/grade/ai-score.ts +1 -1
  824. package/src/grade/text.ts +2 -2
  825. package/src/heading-numbering.ts +2 -2
  826. package/src/html/fetch-page.ts +64 -0
  827. package/src/html/fetched-text.ts +32 -0
  828. package/src/html/html-content-block.ts +107 -0
  829. package/src/html/html-elements.ts +127 -0
  830. package/src/html/html-footnote-marks.ts +20 -0
  831. package/src/html/html-heading-links.ts +93 -0
  832. package/src/html/html-lost-tags.ts +14 -0
  833. package/src/html/html-markdown.ts +481 -0
  834. package/src/html/html-preformatted.ts +110 -0
  835. package/src/html/html-reader-only.ts +82 -0
  836. package/src/html/html-run-in-headings.ts +43 -0
  837. package/src/html/html-tables.ts +76 -0
  838. package/src/html/html-widgets.ts +114 -0
  839. package/src/html/markup-text.ts +35 -0
  840. package/src/html/page-document.ts +22 -0
  841. package/src/inline-count.ts +146 -0
  842. package/src/kana-spelling.ts +7 -0
  843. package/src/location-part.ts +30 -0
  844. package/src/nado-closed-list.ts +106 -0
  845. package/src/name-cue.ts +35 -0
  846. package/src/name-variants.ts +57 -11
  847. package/src/paragraph-runs.ts +12 -2
  848. package/src/parameter-table.ts +208 -0
  849. package/src/phone-numbers.ts +98 -0
  850. package/src/place-names.ts +248 -0
  851. package/src/plugin.ts +4 -0
  852. package/src/prerequisite-order.ts +39 -0
  853. package/src/profile/parse.ts +10 -1
  854. package/src/reasons.ts +4 -0
  855. package/src/render/rules-json.ts +4 -0
  856. package/src/render/rules-table.ts +6 -3
  857. package/src/rule-genres.ts +5 -2
  858. package/src/rule-load.ts +3 -2
  859. package/src/run.ts +3 -1
  860. package/src/spelling.ts +8 -0
  861. package/src/structure/action-due.ts +179 -0
  862. package/src/structure/amount-range.ts +219 -0
  863. package/src/structure/amount-scale.ts +18 -0
  864. package/src/structure/cite.ts +21 -2
  865. package/src/structure/counted-amounts.ts +42 -0
  866. package/src/structure/date-order.ts +72 -22
  867. package/src/structure/date-outside-period.ts +127 -0
  868. package/src/structure/definition-use.ts +24 -3
  869. package/src/structure/due-date.ts +46 -0
  870. package/src/structure/heading-runs.ts +24 -0
  871. package/src/structure/install-pin.ts +115 -0
  872. package/src/structure/leg-times.ts +198 -0
  873. package/src/structure/line-amount-unit.ts +35 -0
  874. package/src/structure/line-amount.ts +162 -0
  875. package/src/structure/number-word-figure.ts +199 -0
  876. package/src/structure/numbering.ts +3 -0
  877. package/src/structure/ordinal-runs.ts +107 -0
  878. package/src/structure/percent-sum-prose.ts +46 -3
  879. package/src/structure/percent-sum.ts +16 -2
  880. package/src/structure/release-list.ts +69 -0
  881. package/src/structure/share-column.ts +25 -0
  882. package/src/structure/stated-period.ts +161 -0
  883. package/src/structure/tax.ts +114 -0
  884. package/src/structure/time-marks.ts +127 -0
  885. package/src/structure/time-order.ts +140 -0
  886. package/src/structure/title-lines.ts +33 -0
  887. package/src/structure/total.ts +5 -1
  888. package/src/structure/version-mismatch.ts +67 -13
  889. package/src/structure/version-order.ts +84 -0
  890. package/src/table-text.ts +39 -0
  891. package/src/ui-labels.ts +55 -0
  892. package/src/undefined-call.ts +65 -0
  893. package/src/unnamed-speaker.ts +224 -0
  894. package/src/warning-action.ts +73 -0
  895. package/styles/koyobun.yaml +7 -4
@@ -0,0 +1,103 @@
1
+ // A term written as a defined term but defined nowhere: 本成果物 in a contract that defines 本業務 and 本契約 but no
2
+ // 本成果物. The document's own prefix for its defined terms (本, 本件: the language package's defined-term-prefix list)
3
+ // marks a word as one of its terms; a term with that prefix and no definition leaves the reader asking what it is.
4
+ // Only the document's own references (本条, 本契約: self-reference-noun and document-kind) are left. Pure; the parts of
5
+ // speech decide where a prefix is a prefix (本 in 本成果物) and not part of a word (本人, 本日).
6
+ import { definedTerms } from "../structure/definition-use.ts";
7
+ import { prefixGroupsOf, prefixVariants } from "../structure/term-prefix.ts";
8
+ import { quoteAt } from "./structure-tree.ts";
9
+ import type { Detector, Finding, ProseDocument, Token } from "../plugin.ts";
10
+
11
+ export type UndefinedTerm = { readonly offset: number; readonly term: string };
12
+
13
+ const NOUNS = new Set(["NOUN", "PROPN"]);
14
+ const QUOTE_PAIRS = [
15
+ ["「", "」"],
16
+ ["『", "』"],
17
+ ['"', '"'],
18
+ ["“", "”"],
19
+ ] as const;
20
+
21
+ const isNoun = (token: Token | undefined): token is Token => token !== undefined && NOUNS.has(token.pos);
22
+
23
+ /** A defined term whose rest after the prefix is shorter than this (本人, 本日) is a word, not the document's way of naming terms. */
24
+ const MIN_REST = 2;
25
+
26
+ /** A prefix written right after a noun is inside a longer word, not a prefix. */
27
+ const continuesWord = (before: Token | undefined, token: Token): boolean => isNoun(before) && before.span.end === token.span.start;
28
+
29
+ /** The term a prefix token starts: the prefix and the nouns written right after it (本 成果 物). */
30
+ const termAt = (source: string, tokens: readonly Token[], index: number): { readonly offset: number; readonly term: string } | undefined => {
31
+ const prefix = tokens[index];
32
+ if (prefix === undefined) return undefined;
33
+ const run = tokens.slice(index + 1);
34
+ const length = run.findIndex((token, at) => !isNoun(token) || token.span.start !== (run[at - 1] ?? prefix).span.end);
35
+ const last = run[(length === -1 ? run.length : length) - 1];
36
+ return last === undefined ? undefined : { offset: prefix.span.start, term: source.slice(prefix.span.start, last.span.end) };
37
+ };
38
+
39
+ /** What the decision needs from the document and its word lists. */
40
+ export type TermWords = {
41
+ readonly prefixes: readonly string[];
42
+ readonly prefixGroups: readonly (readonly string[])[];
43
+ /** What the document calls itself and its parts after a prefix (本条, 本契約, 本利用規約); never one of its terms. */
44
+ readonly selfNouns: readonly string[];
45
+ /** The term is set in quotes somewhere (「本情報」): defined in a form the structure did not read, or named on purpose. */
46
+ readonly isQuoted: (term: string) => boolean;
47
+ };
48
+
49
+ /** The defined terms and their other-prefix forms (本件業務 for 本業務), which defined-term-form reads. */
50
+ const knownForms = (defined: readonly string[], groups: TermWords["prefixGroups"]): string[] => [
51
+ ...defined,
52
+ ...defined.flatMap((term) => prefixVariants(term, groups)),
53
+ ];
54
+
55
+ /**
56
+ * The first use of each term written with the document's prefix and defined nowhere, when the document defines at
57
+ * least one term with that prefix (else the prefix is not its way of naming terms). A use that starts with a known
58
+ * form (本サービス上 where 本サービス is defined) is that term.
59
+ */
60
+ export const undefinedTerms = (source: string, sentences: readonly (readonly Token[])[], defined: readonly string[], words: TermWords): UndefinedTerm[] => {
61
+ const prefixes = words.prefixes.filter((prefix) => prefix !== "");
62
+ const prefixed = defined.filter((term) => prefixes.some((prefix) => term.startsWith(prefix) && Array.from(term.slice(prefix.length)).length >= MIN_REST));
63
+ if (prefixed.length === 0) return [];
64
+ const known = knownForms(defined, words.prefixGroups);
65
+ const isSelf = (term: string, prefix: string): boolean => {
66
+ const rest = term.slice(prefix.length);
67
+ return words.selfNouns.some((noun) => noun !== "" && (rest.startsWith(noun) || rest.endsWith(noun)));
68
+ };
69
+ const uses = sentences.flatMap((tokens) =>
70
+ tokens.flatMap((token, index) => {
71
+ if (!prefixes.includes(token.surface) || !isNoun(tokens[index + 1]) || continuesWord(tokens[index - 1], token)) return [];
72
+ const use = termAt(source, tokens, index);
73
+ if (use === undefined || isSelf(use.term, token.surface) || words.isQuoted(use.term)) return [];
74
+ if (known.some((form) => use.term.startsWith(form) || form.startsWith(use.term))) return [];
75
+ return [use];
76
+ }),
77
+ );
78
+ return uses.filter((use, index) => uses.findIndex((other) => other.term === use.term) === index);
79
+ };
80
+
81
+ const patternsOf = (doc: ProseDocument, lexicon: string): string[] => (doc.lexicons[lexicon] ?? []).map((entry) => entry.pattern);
82
+
83
+ const findingOf = (doc: ProseDocument, use: UndefinedTerm): Finding => ({
84
+ rule: "undefined-term",
85
+ severity: "info",
86
+ line: 0,
87
+ column: 0,
88
+ quote: quoteAt(doc.source, use.offset),
89
+ values: { term: use.term, offset: use.offset },
90
+ });
91
+
92
+ export const undefinedTerm: Detector = (doc): Finding[] => {
93
+ if (doc.structure === undefined) return [];
94
+ const prefixEntries = doc.lexicons["defined-term-prefix"] ?? [];
95
+ const sentences = doc.sentences.map((sentence) => sentence.tokens ?? []);
96
+ const defined = definedTerms(doc.structure).map((term) => term.term);
97
+ return undefinedTerms(doc.source, sentences, defined, {
98
+ prefixes: prefixEntries.map((entry) => entry.pattern),
99
+ prefixGroups: prefixGroupsOf(prefixEntries),
100
+ selfNouns: [...patternsOf(doc, "self-reference-noun"), ...patternsOf(doc, "document-kind")],
101
+ isQuoted: (term) => QUOTE_PAIRS.some(([open, close]) => doc.source.includes(`${open}${term}${close}`)),
102
+ }).map((use) => findingOf(doc, use));
103
+ };
@@ -1,5 +1,5 @@
1
1
  import type { Detector, Finding, ProseDocument } from "../plugin.ts";
2
- import { isKnownWord, suggestionFor, wordsToCheck, type CheckedWord, type Speller } from "../spelling.ts";
2
+ import { isKnownWord, isSplitWord, suggestionFor, wordsToCheck, type CheckedWord, type Speller } from "../spelling.ts";
3
3
  import { quoteAt } from "./structure-tree.ts";
4
4
 
5
5
  /** これより短い語は見ない。短い語は一字違いの語が多すぎて言い直しが決まらず(tost は test か toast か)、略した語(impl)も多い。 */
@@ -26,13 +26,13 @@ const usedOnce = (words: readonly CheckedWord[]): CheckedWord[] => {
26
26
 
27
27
  /**
28
28
  * 辞書に無い英語の語で、一字違いの辞書の語があるもの(recieve → receive)。辞書は adapter が持ち、無い言語では動かない。
29
- * 大文字を含む語(固有名詞・略語)、コード・URL の中、二度以上使う語、言い直しの無い語は言わない。
29
+ * 大文字を含む語(固有名詞・略語)、コード・URL の中、頭の字を分けた語の残り、二度以上使う語、言い直しの無い語は言わない。
30
30
  */
31
31
  export const unknownWord: Detector = (doc): Finding[] => {
32
32
  if (doc.dictionary === undefined) return [];
33
33
  const speller = spellerOf(doc, doc.dictionary());
34
34
  const known = new Set(patternsOf(doc, "known-misspelling"));
35
- const words = wordsToCheck(doc.prose ?? doc.source, MIN_LENGTH, MAX_LENGTH);
35
+ const words = wordsToCheck(doc.prose ?? doc.source, MIN_LENGTH, MAX_LENGTH).filter(({ offset }) => !isSplitWord(doc.source, offset));
36
36
  const used = new Set(words.map(({ word }) => word).filter((word) => isKnownWord(word, speller)));
37
37
  return usedOnce(words).flatMap(({ offset, word }) => {
38
38
  if (known.has(word) || isKnownWord(word, speller)) return [];
@@ -68,12 +68,12 @@ const concreteIn = (lower: string, entry: string): boolean => {
68
68
  );
69
69
  };
70
70
 
71
- const statesConcrete = (text: Text, concrete: readonly string[]): boolean => {
71
+ export const statesConcrete = (text: Text, concrete: readonly string[]): boolean => {
72
72
  const lower = text.text.toLowerCase();
73
73
  return concrete.some((entry) => concreteIn(lower, entry));
74
74
  };
75
75
 
76
- const grantsRight = (text: Text, permissions: readonly LexiconEntry[]): boolean => {
76
+ export const grantsRight = (text: Text, permissions: readonly LexiconEntry[]): boolean => {
77
77
  const lower = text.text.toLowerCase();
78
78
  const ending = withoutEnding(lower);
79
79
  return permissions
@@ -86,7 +86,7 @@ const isInsideLonger = (hit: Hit, hits: readonly Hit[]): boolean =>
86
86
  hits.some((other) => other.word.length > hit.word.length && other.at <= hit.at && hit.at + hit.word.length <= other.at + other.word.length);
87
87
 
88
88
  /** The vague limits in one sentence, in order. Matching ignores case. */
89
- const vagueIn = (text: Text, vague: readonly string[]): VagueDeadline[] => {
89
+ export const vagueIn = (text: Text, vague: readonly string[]): VagueDeadline[] => {
90
90
  const lower = text.text.toLowerCase();
91
91
  const hits = vague
92
92
  .filter((word) => word !== "")
@@ -1,12 +1,16 @@
1
- // version-mismatch: the version a code block's lead-in names against the one the block shows (structure/version-mismatch.ts).
2
- // The words that make a version a bound (「から」「以上」, "from", "or later") are the lexicon version-range; the words that
3
- // lead to the version installed (version, install) are version-lead.
4
- import type { Detector, Finding } from "../plugin.ts";
1
+ // version-mismatch: the version a code block's lead-in names against the one the block shows (structure/version-mismatch.ts),
2
+ // and an install command that pins the document's own package to a version its release list does not say is current
3
+ // (structure/install-pin.ts). The words that make a version a bound (「から」「以上」, "from", "or later") are the lexicon
4
+ // version-range; the words that lead to the version installed (version, install) are version-lead; the install commands
5
+ // are install-command.
6
+ import type { Detector, Finding, ProseDocument } from "../plugin.ts";
5
7
  import { versionMismatches, type RangeWord, type VersionWords } from "../structure/version-mismatch.ts";
8
+ import { installPinMismatches, ownTextOf, pinsIn } from "../structure/install-pin.ts";
9
+ import { releasesOf } from "../structure/release-list.ts";
6
10
  import { codeFences } from "./code-fences.ts";
7
11
  import { quoteAt } from "./structure-tree.ts";
8
12
 
9
- export const versionMismatch: Detector = (doc): Finding[] => {
13
+ const leadInFindings = (doc: ProseDocument): Finding[] => {
10
14
  const words: VersionWords = {
11
15
  ranges: (doc.lexicons["version-range"] ?? []).map((entry): RangeWord => ({ word: entry.pattern, position: entry.position ?? "before" })),
12
16
  versionWords: (doc.lexicons["version-lead"] ?? []).map((entry) => entry.pattern),
@@ -21,3 +25,20 @@ export const versionMismatch: Detector = (doc): Finding[] => {
21
25
  values: { ...issue.values, offset: issue.offset },
22
26
  }));
23
27
  };
28
+
29
+ const installPinFindings = (doc: ProseDocument): Finding[] => {
30
+ const shapes = (doc.lexicons["install-command"] ?? []).map((entry) => entry.pattern);
31
+ const headings = doc.markup?.headings ?? [];
32
+ const releases = releasesOf(doc.source, headings, codeFences(doc.source));
33
+ return installPinMismatches(pinsIn(doc.source, shapes), releases, ownTextOf(doc.source, headings)).map((issue) => ({
34
+ rule: "version-mismatch",
35
+ severity: "warning",
36
+ line: 0,
37
+ column: 0,
38
+ quote: quoteAt(doc.source, issue.offset),
39
+ variant: issue.variant,
40
+ values: { ...issue.values, offset: issue.offset },
41
+ }));
42
+ };
43
+
44
+ export const versionMismatch: Detector = (doc): Finding[] => [...leadInFindings(doc), ...installPinFindings(doc)];
@@ -0,0 +1,50 @@
1
+ // version-order: a changelog's version headings, or a list or table of releases, with one version out of order
2
+ // (structure/version-order.ts).
3
+ import { quoteAt } from "./structure-tree.ts";
4
+ import { codeFences } from "./code-fences.ts";
5
+ import { siblingHeadingRunsOf } from "../structure/heading-runs.ts";
6
+ import { runsOf, type Line } from "../structure/runs.ts";
7
+ import { isVersionHistory, leadingVersion, versionOrderBreaks, type VersionPoint } from "../structure/version-order.ts";
8
+ import type { Detector, Finding, MarkupHeading, ProseDocument } from "../plugin.ts";
9
+
10
+ const headingPoint = (source: string, heading: MarkupHeading): VersionPoint | undefined => {
11
+ const label = leadingVersion(heading.text);
12
+ if (label === undefined) return undefined;
13
+ const at = source.indexOf(label, heading.start);
14
+ return { offset: at === -1 ? heading.start : at, label };
15
+ };
16
+
17
+ /** The marker of a list item or the first pipe of a table row, before the item's text. */
18
+ const ITEM_MARKER = /^[ \t]*(?:[-*+]|\d{1,3}[.)]|\|)[ \t]*/u;
19
+
20
+ const itemVersions = (source: string, run: readonly Line[]): VersionPoint[] =>
21
+ run.flatMap((line) => {
22
+ const text = source.slice(line.start, line.end);
23
+ const marker = ITEM_MARKER.exec(text)?.[0] ?? "";
24
+ const label = leadingVersion(text.slice(marker.length));
25
+ return label === undefined ? [] : [{ offset: line.start + marker.length, label }];
26
+ });
27
+
28
+ /** A list in a code fence (an example changelog) is not the document's. */
29
+ const outsideFences = (source: string, run: readonly Line[]): Line[] => {
30
+ const fences = codeFences(source);
31
+ return run.filter((line) => !fences.some((fence) => line.start >= fence.start && line.start < fence.end));
32
+ };
33
+
34
+ const pointRuns = (doc: ProseDocument): VersionPoint[][] => [
35
+ ...siblingHeadingRunsOf(doc.markup?.headings ?? [], (heading) => headingPoint(doc.source, heading)),
36
+ ...runsOf(doc.source).map((run) => itemVersions(doc.source, outsideFences(doc.source, run))),
37
+ ];
38
+
39
+ export const versionOrder: Detector = (doc): Finding[] =>
40
+ pointRuns(doc)
41
+ .filter((run) => isVersionHistory(run.map((point) => point.label)))
42
+ .flatMap(versionOrderBreaks)
43
+ .map((issue) => ({
44
+ rule: "version-order",
45
+ severity: "warning",
46
+ line: 0,
47
+ column: 0,
48
+ quote: quoteAt(doc.source, issue.offset),
49
+ values: { ...issue.values, offset: issue.offset },
50
+ }));
@@ -0,0 +1,49 @@
1
+ // warning-without-action: a warning paragraph (Warning:, 注意:, > [!WARNING]) none of whose sentences tells the reader what
2
+ // to do (warning-action.ts). In English a sentence that opens with its verb (Export today's orders first) is an action too.
3
+ // A GitHub alert (> [!WARNING]) is read to the end of its block quote.
4
+ import { isInstruction, isStatement } from "./technical-docs.ts";
5
+ import { quoteAt } from "./structure-tree.ts";
6
+ import { namesAction, quoteBlockEnd, warningTextStart, type WarningWords } from "../warning-action.ts";
7
+ import type { Detector, Finding, Paragraph, ProseDocument, Sentence } from "../plugin.ts";
8
+
9
+ const wordsOf = (doc: ProseDocument): WarningWords => ({
10
+ labels: (doc.lexicons["warning-label"] ?? []).map((entry) => entry.pattern),
11
+ actions: (doc.lexicons["warning-action"] ?? []).map((entry) => entry.pattern),
12
+ });
13
+
14
+ /** An English sentence that opens with its verb, read from the parts of speech past the label: an instruction. */
15
+ const opensWithVerb = (doc: ProseDocument, sentence: Sentence, from: number): boolean => {
16
+ const tokens = (sentence.tokens ?? []).filter((token) => token.span.start >= from);
17
+ return doc.language === "en" && tokens.length > 0 && isInstruction(tokens) && !isStatement(tokens);
18
+ };
19
+
20
+ const isAction = (doc: ProseDocument, sentence: Sentence, from: number, words: WarningWords): boolean => {
21
+ const start = Math.max(sentence.span.start, from);
22
+ if (start >= sentence.span.end) return false;
23
+ return namesAction(doc.source.slice(start, sentence.span.end), words.actions) || opensWithVerb(doc, sentence, start);
24
+ };
25
+
26
+ const warningWithoutAction = (doc: ProseDocument, paragraph: Paragraph, words: WarningWords): Finding[] => {
27
+ const textStart = warningTextStart(doc.source.slice(paragraph.span.start, paragraph.span.end), words.labels);
28
+ if (textStart === undefined) return [];
29
+ const from = paragraph.span.start + textStart;
30
+ const end = quoteBlockEnd(doc.source, paragraph.span.start) ?? paragraph.span.end;
31
+ const said = doc.sentences.filter((sentence) => sentence.span.end > from && sentence.span.start < end);
32
+ if (said.length === 0 || said.some((sentence) => isAction(doc, sentence, from, words))) return [];
33
+ return [
34
+ {
35
+ rule: "warning-without-action",
36
+ severity: "info",
37
+ line: 0,
38
+ column: 0,
39
+ quote: quoteAt(doc.source, paragraph.span.start),
40
+ values: { offset: paragraph.span.start },
41
+ },
42
+ ];
43
+ };
44
+
45
+ export const warningAction: Detector = (doc): Finding[] => {
46
+ const words = wordsOf(doc);
47
+ if (words.labels.length === 0) return [];
48
+ return doc.paragraphs.flatMap((paragraph) => warningWithoutAction(doc, paragraph, words));
49
+ };
@@ -0,0 +1,289 @@
1
+ import type { Span, Token } from "../plugin.ts";
2
+ import { escapeRegExp } from "../orthography.ts";
3
+ import { comparable, sameValue, type FactValue } from "./fact-values.ts";
4
+
5
+ /**
6
+ * 要約の「XからYに」("from X to Y")を、本文が二つの条件(前と後、無いときとあるとき、2025年と2026年)で書いた同じ項目の二つの値と
7
+ * 組にして比べる。項目の名前が本文の文にあり、二つの値の条件がどちらも読めたときだけ比べる。言語の知識(から、to、前、after)は
8
+ * 語彙表から取る。
9
+ */
10
+ export type WordAt = { readonly pattern: string; readonly position: "before" | "after" };
11
+ export type ConditionWord = { readonly pattern: string; readonly group: string };
12
+
13
+ export type ChangeWords = {
14
+ /** もとの値に付く語(from、から)。 */
15
+ readonly from: readonly WordAt[];
16
+ /** 動いた先の値に付く語(to、に)。 */
17
+ readonly to: readonly WordAt[];
18
+ /** 名前と変化のあいだにあれば、変化ではなく幅を言う語("ranges from 0 to 10")。 */
19
+ readonly notChange: readonly string[];
20
+ /** 名前と値のあいだで飛ばす語(は、が)。 */
21
+ readonly subjectMarks: readonly string[];
22
+ /** 名前の語をつなぐ語(の、of)。position が after の語(の)は、前の語が後ろの語を修飾する。短い名前はその前の語を書かないことがある(「無いときの誤りの率」の「誤りの率」)。 */
23
+ readonly joiners: readonly WordAt[];
24
+ /** もとの側の条件(before、無いとき)と、動いた先の側の条件(after、あるとき)。同じ group の語どうしが組になる。 */
25
+ readonly conditionsFrom: readonly ConditionWord[];
26
+ readonly conditionsTo: readonly ConditionWord[];
27
+ };
28
+
29
+ export type ChangeSentence = { readonly span: Span; readonly text: string; readonly tokens: readonly Token[]; readonly summary: boolean };
30
+
31
+ /** 名前(subject)の付いた、もとの値と先の値の組。names は同じ項目を指す名前の書き方(修飾を落とした短い名前も)。 */
32
+ export type ValuePair = {
33
+ readonly subject: string;
34
+ readonly key: string;
35
+ readonly names: readonly string[];
36
+ readonly from: FactValue;
37
+ readonly to: FactValue;
38
+ };
39
+
40
+ export type PairConflict = { readonly summary: ValuePair; readonly body: ValuePair };
41
+
42
+ const LATIN = /^[A-Za-z]/u;
43
+ const SPACES = /\s+/gu;
44
+ /** 暦の年(2025、2026年)。条件として読み、値としては読まない。日付の一部(2011-10-26、2025年10月)は年の条件ではない。 */
45
+ const YEAR = /(?<![\d.,/-])(?:1[89]|2[01])\d{2}(?![\d.,%/-]|年\d)/gu;
46
+
47
+ const squeezed = (text: string): string => text.replace(SPACES, "").toLowerCase();
48
+
49
+ /** 語の現れる所。英字の語は語の切れ目で、ほかは書いたとおりに探す。 */
50
+ const wordSpans = (text: string, word: string, offset: number): Span[] => {
51
+ const pattern = LATIN.test(word) ? new RegExp(`\\b${escapeRegExp(word)}\\b`, "giu") : new RegExp(escapeRegExp(word), "gu");
52
+ return [...text.matchAll(pattern)].map((match) => ({ start: offset + match.index, end: offset + match.index + match[0].length }));
53
+ };
54
+
55
+ const endsWithWord = (text: string, word: string): boolean => {
56
+ const lowered = text.trimEnd().toLowerCase();
57
+ if (!lowered.endsWith(word.toLowerCase())) return false;
58
+ return !LATIN.test(word) || !/[A-Za-z]$/u.test(lowered.slice(0, lowered.length - word.length));
59
+ };
60
+
61
+ const startsWithWord = (text: string, word: string): boolean => {
62
+ const lowered = text.trimStart().toLowerCase();
63
+ if (!lowered.startsWith(word.toLowerCase())) return false;
64
+ return !LATIN.test(word) || !/^[A-Za-z]/u.test(lowered.slice(word.length));
65
+ };
66
+
67
+ const patternsAt = (words: readonly WordAt[], position: WordAt["position"]): string[] =>
68
+ words.filter((word) => word.position === position).map((word) => word.pattern);
69
+
70
+ /** 二つの値のあいだが、もとの値の後ろの語と先の値の前の語だけか(" to "、「から」)。 */
71
+ const joinsChange = (between: string, words: ChangeWords): boolean => {
72
+ const fromAfter = ["", ...patternsAt(words.from, "after")];
73
+ const toBefore = ["", ...patternsAt(words.to, "before")];
74
+ const shown = squeezed(between);
75
+ return shown !== "" && fromAfter.some((first) => toBefore.some((second) => squeezed(first + second) === shown));
76
+ };
77
+
78
+ /** 前に要る語(from)があれば、その語の始まり。要らなければ値の始まり。無ければ undefined。 */
79
+ const changeStart = (source: string, value: FactValue, words: ChangeWords): number | undefined => {
80
+ const before = patternsAt(words.from, "before");
81
+ if (before.length === 0) return value.start;
82
+ const head = source.slice(0, value.start);
83
+ const found = before.find((word) => endsWithWord(head, word));
84
+ return found === undefined ? undefined : head.trimEnd().length - found.length;
85
+ };
86
+
87
+ const TAIL_LENGTH = 40;
88
+
89
+ const endsChange = (source: string, value: FactValue, words: ChangeWords): boolean => {
90
+ const after = patternsAt(words.to, "after");
91
+ const tail = source.slice(value.end, value.end + TAIL_LENGTH);
92
+ return after.length === 0 || after.some((word) => startsWithWord(tail, word));
93
+ };
94
+
95
+ const isYear = (source: string, value: FactValue): boolean => value.unit === "" && /^(?:1[89]|2[01])\d{2}$/u.test(source.slice(value.start, value.end));
96
+
97
+ const isQuantityPair = (source: string, from: FactValue, to: FactValue): boolean =>
98
+ from.kind === "quantity" && comparable(from, to) && !isYear(source, from) && !isYear(source, to);
99
+
100
+ const isBlank = (token: Token): boolean => token.surface.trim() === "";
101
+ const SKIPPED: ReadonlySet<string> = new Set(["VERB", "AUX", "ADV"]);
102
+ const NAME_WORD: ReadonlySet<string> = new Set(["NOUN", "PROPN", "ADJ"]);
103
+ const HEAD_WORD: ReadonlySet<string> = new Set(["NOUN", "PROPN"]);
104
+ const DIGIT = /\d/u;
105
+
106
+ const isSkipped = (token: Token, marks: ReadonlySet<string>): boolean => isBlank(token) || marks.has(token.surface) || SKIPPED.has(token.pos);
107
+
108
+ const joinerSet = (words: ChangeWords): ReadonlySet<string> => new Set(words.joiners.map((word) => word.pattern.toLowerCase()));
109
+
110
+ const isNameToken = (token: Token, joiners: ReadonlySet<string>): boolean =>
111
+ (NAME_WORD.has(token.pos) && !DIGIT.test(token.surface)) || joiners.has(token.surface.toLowerCase());
112
+
113
+ const keyOf = (text: string): string => text.normalize("NFKC").toLowerCase().replace(SPACES, " ");
114
+
115
+ /** 名前の並びを、つなぐ語で始まらず名詞で終わるところまで切る。 */
116
+ const trimmedName = (run: readonly Token[], joiners: ReadonlySet<string>): Token[] => {
117
+ const named = run.slice(
118
+ Math.max(
119
+ 0,
120
+ run.findIndex((token) => !joiners.has(token.surface.toLowerCase())),
121
+ ),
122
+ );
123
+ return named.slice(0, named.findLastIndex((token) => HEAD_WORD.has(token.pos)) + 1);
124
+ };
125
+
126
+ /** 一つの名前の書き方: 全体と、修飾の語(「無いときの」)を前から落としたもの。 */
127
+ const namesOf = (source: string, named: readonly Token[], words: ChangeWords): string[] => {
128
+ const last = named.at(-1);
129
+ if (last === undefined) return [];
130
+ const dropping = new Set(words.joiners.filter((word) => word.position === "after").map((word) => word.pattern.toLowerCase()));
131
+ const starts = [0, ...named.flatMap((token, index) => (dropping.has(token.surface.toLowerCase()) ? [index + 1] : []))];
132
+ return starts.flatMap((start) => {
133
+ const first = named[start];
134
+ return first === undefined ? [] : [keyOf(source.slice(first.span.start, last.span.end))];
135
+ });
136
+ };
137
+
138
+ /** 文の中の名前の並び(名詞と、つなぐ語でつながる語)ごとの、名前の書き方。 */
139
+ const namesIn = (source: string, sentence: ChangeSentence, words: ChangeWords): Set<string> => {
140
+ const joiners = joinerSet(words);
141
+ const runs = sentence.tokens.reduce<Token[][]>((found, token, index) => {
142
+ if (!isNameToken(token, joiners)) return found;
143
+ const previous = sentence.tokens[index - 1];
144
+ const current = previous !== undefined && isNameToken(previous, joiners) ? found.at(-1) : undefined;
145
+ if (current === undefined) found.push([token]);
146
+ else current.push(token);
147
+ return found;
148
+ }, []);
149
+ return new Set(runs.flatMap((run) => namesOf(source, trimmedName(run, joiners), words)));
150
+ };
151
+
152
+ /**
153
+ * 変化の前の名前の語の並び("error rate"、「誤りの率」)。その前の空白、は・が、動詞("the rate fell from")は飛ばす。
154
+ * つなぐ語で始まらず、名詞で終わる。
155
+ */
156
+ const nameTokens = (tokens: readonly Token[], words: ChangeWords): Token[] => {
157
+ const marks = new Set(words.subjectMarks);
158
+ const joiners = joinerSet(words);
159
+ const head = tokens.slice(0, tokens.findLastIndex((token) => !isSkipped(token, marks)) + 1);
160
+ const run = head.slice(head.findLastIndex((token) => !isNameToken(token, joiners)) + 1);
161
+ const named = trimmedName(run, joiners);
162
+ return HEAD_WORD.has(run.at(-1)?.pos ?? "") ? named : [];
163
+ };
164
+
165
+ type Subject = { readonly subject: string; readonly key: string; readonly names: readonly string[] };
166
+
167
+ const subjectBefore = (source: string, sentence: ChangeSentence, offset: number, words: ChangeWords): Subject | undefined => {
168
+ const named = nameTokens(
169
+ sentence.tokens.filter((token) => token.span.end <= offset),
170
+ words,
171
+ );
172
+ const [first, last] = [named[0], named.at(-1)];
173
+ if (first === undefined || last === undefined) return undefined;
174
+ const subject = source.slice(first.span.start, last.span.end);
175
+ const gap = source.slice(last.span.end, offset);
176
+ if (words.notChange.some((word) => wordSpans(gap, word, 0).length > 0)) return undefined;
177
+ return { subject, key: keyOf(subject), names: namesOf(source, named, words) };
178
+ };
179
+
180
+ /** 文の中の「XからYに」と、その前の名前。 */
181
+ const changesIn = (source: string, sentence: ChangeSentence, values: readonly FactValue[], words: ChangeWords): ValuePair[] =>
182
+ values.slice(0, -1).flatMap((from, index): ValuePair[] => {
183
+ const to = values[index + 1];
184
+ if (to === undefined || !isQuantityPair(source, from, to) || !joinsChange(source.slice(from.end, to.start), words)) return [];
185
+ const start = changeStart(source, from, words);
186
+ if (start === undefined || !endsChange(source, to, words)) return [];
187
+ const named = subjectBefore(source, sentence, start, words);
188
+ return named === undefined ? [] : [{ ...named, from, to }];
189
+ });
190
+
191
+ type Mark = Span & { readonly side: "from" | "to"; readonly group: string; readonly year?: number };
192
+
193
+ const conditionMarks = (sentence: ChangeSentence, words: readonly ConditionWord[], side: Mark["side"]): Mark[] =>
194
+ words.flatMap((word) => wordSpans(sentence.text, word.pattern, sentence.span.start).map((span): Mark => ({ ...span, side, group: word.group })));
195
+
196
+ const yearMarks = (sentence: ChangeSentence): Mark[] =>
197
+ [...sentence.text.matchAll(YEAR)].map((match) => {
198
+ const start = sentence.span.start + match.index;
199
+ return { start, end: start + match[0].length, side: "from", group: "year", year: Number(match[0]) };
200
+ });
201
+
202
+ const overlaps = (left: Span, right: Span): boolean => left.start < right.end && right.start < left.end;
203
+
204
+ /** 年の組は、早い年がもとの側。違う年がちょうど二つのときだけ。 */
205
+ const yearPair = (marks: readonly Mark[]): Mark[] | undefined => {
206
+ const years = marks.filter((mark) => mark.group === "year");
207
+ const [first, second] = years;
208
+ if (years.length !== 2 || first === undefined || second === undefined || first.year === second.year) return undefined;
209
+ const later = (first.year ?? 0) < (second.year ?? 0) ? second : first;
210
+ return years.map((mark) => (mark === later ? { ...mark, side: "to" } : mark));
211
+ };
212
+
213
+ /** 一つの組の語が、もとの側と先の側に一つずつ。そういう組がちょうど一つのときだけ、その二つ。 */
214
+ const conditionPair = (marks: readonly Mark[]): Mark[] | undefined => {
215
+ const groups = [...new Set(marks.map((mark) => mark.group))];
216
+ const pairs = groups.flatMap((group) => {
217
+ if (group === "year") return [yearPair(marks)].filter((pair) => pair !== undefined);
218
+ const inGroup = marks.filter((mark) => mark.group === group);
219
+ const sides = new Set(inGroup.map((mark) => mark.side));
220
+ return inGroup.length === 2 && sides.size === 2 ? [inGroup] : [];
221
+ });
222
+ return pairs.length === 1 ? pairs[0] : undefined;
223
+ };
224
+
225
+ const CLAUSE_BREAK = /[,;、,;]/u;
226
+
227
+ /** 二つの範囲のあいだに、句の切れ目(, ; 、)がある。 */
228
+ const brokenBetween = (sentence: ChangeSentence, left: Span, right: Span): boolean =>
229
+ CLAUSE_BREAK.test(sentence.text.slice(left.end - sentence.span.start, right.start - sentence.span.start));
230
+
231
+ /**
232
+ * 条件と値が、条件・値・条件・値か、値・条件・値・条件の順に並び、二組のあいだが句の切れ目で分かれるときだけ、どの値がどの条件の
233
+ * ものか決まる。切れ目が無いと("With breaks, against 2.4% without them, … 1.6%")、条件が前と後ろのどちらの値に付くか決まらない。
234
+ */
235
+ const pairByOrder = (sentence: ChangeSentence, conditions: readonly Mark[], values: readonly FactValue[]): { from: FactValue; to: FactValue } | undefined => {
236
+ const [c1, c2] = conditions.toSorted((left, right) => left.start - right.start);
237
+ const [v1, v2] = values;
238
+ if (c1 === undefined || c2 === undefined || v1 === undefined || v2 === undefined) return undefined;
239
+ const leads = c1.end <= v1.start && v1.end <= c2.start && c2.end <= v2.start && brokenBetween(sentence, v1, c2);
240
+ const follows = v1.end <= c1.start && c1.end <= v2.start && v2.end <= c2.start && brokenBetween(sentence, c1, v2);
241
+ if (!leads && !follows) return undefined;
242
+ return c1.side === "from" ? { from: v1, to: v2 } : { from: v2, to: v1 };
243
+ };
244
+
245
+ /** 本文の一文が、名前と、比べられる二つの値と、その二つの条件を書いていれば、その組。 */
246
+ const conditionedPair = (sentence: ChangeSentence, values: readonly FactValue[], summary: ValuePair, words: ChangeWords): ValuePair | undefined => {
247
+ const marks = [...conditionMarks(sentence, words.conditionsFrom, "from"), ...conditionMarks(sentence, words.conditionsTo, "to"), ...yearMarks(sentence)];
248
+ const free = marks.filter((mark) => mark.group === "year" || !values.some((value) => overlaps(mark, value)));
249
+ const measured = values.filter((value) => comparable(summary.from, value) && !free.some((mark) => overlaps(mark, value)));
250
+ const conditions = conditionPair(free);
251
+ if (measured.length !== 2 || conditions === undefined) return undefined;
252
+ const pair = pairByOrder(sentence, conditions, measured);
253
+ return pair === undefined ? undefined : { ...summary, ...pair };
254
+ };
255
+
256
+ const within = (span: Span, values: readonly FactValue[]): FactValue[] => values.filter((value) => value.start >= span.start && value.end <= span.end);
257
+
258
+ const samePair = (left: ValuePair, right: ValuePair): boolean => sameValue(left.from, right.from) && sameValue(left.to, right.to);
259
+
260
+ /** 本文の組。本文に書いた「XからYに」と、条件で分けて書いた二つの値。 */
261
+ const bodyPairs = (source: string, sentences: readonly ChangeSentence[], values: readonly FactValue[], summary: ValuePair, words: ChangeWords): ValuePair[] =>
262
+ sentences
263
+ .filter((sentence) => !sentence.summary)
264
+ .flatMap((sentence) => {
265
+ const inside = within(sentence.span, values);
266
+ const changes = changesIn(source, sentence, inside, words).filter((change) => change.names.includes(summary.key));
267
+ const conditioned = namesIn(source, sentence, words).has(summary.key) ? conditionedPair(sentence, inside, summary, words) : undefined;
268
+ return [...changes, ...(conditioned === undefined ? [] : [conditioned])];
269
+ })
270
+ .filter((pair) => comparable(summary.from, pair.from) && comparable(summary.to, pair.to));
271
+
272
+ /** 要約の「XからYに」が、本文で一通りに書いた同じ名前の組と違う。本文の組が無いか二通り以上なら言わない。 */
273
+ export const conditionPairConflicts = (
274
+ source: string,
275
+ sentences: readonly ChangeSentence[],
276
+ values: readonly FactValue[],
277
+ words: ChangeWords,
278
+ ): PairConflict[] =>
279
+ sentences
280
+ .filter((sentence) => sentence.summary)
281
+ .flatMap((sentence) => changesIn(source, sentence, within(sentence.span, values), words))
282
+ .flatMap((summary) => {
283
+ const distinct = bodyPairs(source, sentences, values, summary, words).reduce<ValuePair[]>(
284
+ (kept, pair) => (kept.some((seen) => samePair(seen, pair)) ? kept : [...kept, pair]),
285
+ [],
286
+ );
287
+ const [only] = distinct;
288
+ return distinct.length !== 1 || only === undefined || samePair(summary, only) ? [] : [{ summary, body: only }];
289
+ });
@@ -0,0 +1,63 @@
1
+ import type { Span } from "../plugin.ts";
2
+ import { sameValue, type FactValue } from "./fact-values.ts";
3
+
4
+ /**
5
+ * 出来事の日付。文が出来事の語(提供、release)を一つの組だけ含み、日付を一つだけ持つとき、その日付をその出来事の日付と読む。
6
+ * 冒頭や要約の文の日付を、本文の同じ組の出来事の日付と比べる。本文の日付が一通りに揃っていて、違うときだけ言う。
7
+ * 年月日まで書いた日付どうしだけを比べる。日付が二つある文(期間)や、組が二つある文(発表した日と提供する日)は読まない。
8
+ * 本文の文が、冒頭の文に無い名前(別の製品、別の催し)を持つなら、別の出来事として比べない。
9
+ */
10
+ export type EventWord = { readonly pattern: string; readonly group: string };
11
+
12
+ /** names: 文の中の固有名詞などの名前。 */
13
+ export type EventSentence = Span & { readonly text: string; readonly summary: boolean; readonly names: readonly string[] };
14
+
15
+ export type EventDateConflict = { readonly label: string; readonly value: FactValue; readonly other: FactValue };
16
+
17
+ type EventDate = { readonly group: string; readonly label: string; readonly value: FactValue; readonly sentence: EventSentence };
18
+
19
+ const FULL_DATE = /^\d{4}-\d{2}-\d{2}$/u;
20
+
21
+ const normalized = (text: string): string => text.normalize("NFKC").toLowerCase();
22
+
23
+ const startsWord = (text: string, at: number): boolean => at === 0 || !/[a-z]/u.test(text.charAt(at - 1));
24
+
25
+ /** 文の中の出来事の語。英字の語は語の頭からだけ(releases は release、prerelease は違う)。 */
26
+ const wordsIn = (text: string, words: readonly EventWord[]): EventWord[] => {
27
+ const folded = normalized(text);
28
+ return words.filter((word) => {
29
+ const pattern = normalized(word.pattern);
30
+ const at = folded.indexOf(pattern);
31
+ return at >= 0 && (!/^[a-z]/u.test(pattern) || startsWord(folded, at));
32
+ });
33
+ };
34
+
35
+ const inside = (sentence: Span, value: Span): boolean => sentence.start <= value.start && value.end <= sentence.end;
36
+
37
+ const eventDateOf = (sentence: EventSentence, dates: readonly FactValue[], words: readonly EventWord[]): EventDate[] => {
38
+ const own = dates.filter((date) => inside(sentence, date));
39
+ const found = wordsIn(sentence.text, words);
40
+ const groups = new Set(found.map((word) => word.group));
41
+ const [date, word] = [own[0], found[0]];
42
+ if (own.length !== 1 || groups.size !== 1 || date === undefined || word === undefined || !FULL_DATE.test(date.key)) return [];
43
+ return [{ group: word.group, label: word.pattern, value: date, sentence }];
44
+ };
45
+
46
+ const distinct = (values: readonly FactValue[]): FactValue[] =>
47
+ values.reduce<FactValue[]>((kept, value) => (kept.some((seen) => sameValue(seen, value)) ? kept : [...kept, value]), []);
48
+
49
+ /** 本文の文の名前が、どれも冒頭の文にある(名前の無い「提供開始日は」も同じ出来事と読む)。 */
50
+ const sameSubject = (event: EventDate, other: EventDate): boolean => other.sentence.names.every((name) => event.sentence.names.includes(name));
51
+
52
+ const conflictOf = (event: EventDate, body: readonly EventDate[]): EventDateConflict[] => {
53
+ const values = distinct(body.filter((other) => other.group === event.group && sameSubject(event, other)).map((other) => other.value));
54
+ const only = values.length === 1 ? values[0] : undefined;
55
+ return only === undefined || sameValue(event.value, only) ? [] : [{ label: event.label, value: event.value, other: only }];
56
+ };
57
+
58
+ /** 冒頭や要約の出来事の日付が、本文で揃って書かれた同じ出来事の日付と違う。dates は日付の値だけ。 */
59
+ export const eventDateConflicts = (sentences: readonly EventSentence[], dates: readonly FactValue[], words: readonly EventWord[]): EventDateConflict[] => {
60
+ const events = sentences.flatMap((sentence) => eventDateOf(sentence, dates, words));
61
+ const body = events.filter((event) => !event.sentence.summary);
62
+ return events.filter((event) => event.sentence.summary).flatMap((event) => conflictOf(event, body));
63
+ };