chaffjs 0.28.0 → 0.30.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.
- package/dist/ai-score/of-document.d.ts.map +1 -1
- package/dist/ai-score/of-document.js +23 -14
- package/dist/ai-score/of-document.js.map +1 -1
- package/dist/ai-score/render.d.ts.map +1 -1
- package/dist/ai-score/render.js +13 -4
- package/dist/ai-score/render.js.map +1 -1
- package/dist/ai-score/score.d.ts +16 -1
- package/dist/ai-score/score.d.ts.map +1 -1
- package/dist/ai-score/score.js +15 -3
- package/dist/ai-score/score.js.map +1 -1
- package/dist/ai-score/signals.d.ts +2 -4
- package/dist/ai-score/signals.d.ts.map +1 -1
- package/dist/ai-score/signals.js +11 -2
- package/dist/ai-score/signals.js.map +1 -1
- package/dist/ai-score/text.d.ts +2 -0
- package/dist/ai-score/text.d.ts.map +1 -1
- package/dist/ai-score/text.js +4 -2
- package/dist/ai-score/text.js.map +1 -1
- package/dist/announced-count.d.ts +2 -0
- package/dist/announced-count.d.ts.map +1 -1
- package/dist/announced-count.js +14 -7
- package/dist/announced-count.js.map +1 -1
- package/dist/check-source.d.ts +3 -1
- package/dist/check-source.d.ts.map +1 -1
- package/dist/check-source.js +3 -1
- package/dist/check-source.js.map +1 -1
- package/dist/cli-text.d.ts.map +1 -1
- package/dist/cli-text.js +38 -16
- package/dist/cli-text.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/cite-claims.d.ts +36 -0
- package/dist/commands/cite-claims.d.ts.map +1 -0
- package/dist/commands/cite-claims.js +81 -0
- package/dist/commands/cite-claims.js.map +1 -0
- package/dist/commands/cite-page.d.ts +14 -0
- package/dist/commands/cite-page.d.ts.map +1 -0
- package/dist/commands/cite-page.js +47 -0
- package/dist/commands/cite-page.js.map +1 -0
- package/dist/commands/cite-scaffold.d.ts +16 -0
- package/dist/commands/cite-scaffold.d.ts.map +1 -0
- package/dist/commands/cite-scaffold.js +21 -0
- package/dist/commands/cite-scaffold.js.map +1 -0
- package/dist/commands/cite.d.ts +3 -12
- package/dist/commands/cite.d.ts.map +1 -1
- package/dist/commands/cite.js +110 -51
- package/dist/commands/cite.js.map +1 -1
- package/dist/company-names.d.ts +34 -0
- package/dist/company-names.d.ts.map +1 -0
- package/dist/company-names.js +158 -0
- package/dist/company-names.js.map +1 -0
- package/dist/default-values.d.ts +17 -0
- package/dist/default-values.d.ts.map +1 -0
- package/dist/default-values.js +134 -0
- package/dist/default-values.js.map +1 -0
- package/dist/deprecated-use.d.ts +17 -0
- package/dist/deprecated-use.d.ts.map +1 -0
- package/dist/deprecated-use.js +95 -0
- package/dist/deprecated-use.js.map +1 -0
- package/dist/derived/session-hours.d.ts +26 -0
- package/dist/derived/session-hours.d.ts.map +1 -0
- package/dist/derived/session-hours.js +29 -0
- package/dist/derived/session-hours.js.map +1 -0
- package/dist/derived/stays.d.ts +43 -0
- package/dist/derived/stays.d.ts.map +1 -0
- package/dist/derived/stays.js +105 -0
- package/dist/derived/stays.js.map +1 -0
- package/dist/derived/time-lengths.d.ts +37 -0
- package/dist/derived/time-lengths.d.ts.map +1 -0
- package/dist/derived/time-lengths.js +168 -0
- package/dist/derived/time-lengths.js.map +1 -0
- package/dist/derived/unit-counts.d.ts +7 -0
- package/dist/derived/unit-counts.d.ts.map +1 -0
- package/dist/derived/unit-counts.js +13 -0
- package/dist/derived/unit-counts.js.map +1 -0
- package/dist/derived/working-hours.d.ts +36 -0
- package/dist/derived/working-hours.d.ts.map +1 -0
- package/dist/derived/working-hours.js +55 -0
- package/dist/derived/working-hours.js.map +1 -0
- package/dist/detectors/acronym-context.d.ts +2 -2
- package/dist/detectors/acronym-context.d.ts.map +1 -1
- package/dist/detectors/acronym-context.js +6 -0
- package/dist/detectors/acronym-context.js.map +1 -1
- package/dist/detectors/acronym-expansion.d.ts +1 -1
- package/dist/detectors/acronym-expansion.d.ts.map +1 -1
- package/dist/detectors/acronym-expansion.js +46 -2
- package/dist/detectors/acronym-expansion.js.map +1 -1
- package/dist/detectors/address-word.d.ts +3 -0
- package/dist/detectors/address-word.d.ts.map +1 -0
- package/dist/detectors/address-word.js +7 -0
- package/dist/detectors/address-word.js.map +1 -0
- package/dist/detectors/agreement-slip.d.ts.map +1 -1
- package/dist/detectors/agreement-slip.js +4 -1
- package/dist/detectors/agreement-slip.js.map +1 -1
- package/dist/detectors/ai-phrasing.d.ts +0 -4
- package/dist/detectors/ai-phrasing.d.ts.map +1 -1
- package/dist/detectors/ai-phrasing.js +5 -1
- package/dist/detectors/ai-phrasing.js.map +1 -1
- package/dist/detectors/amount-range.d.ts +3 -0
- package/dist/detectors/amount-range.d.ts.map +1 -0
- package/dist/detectors/amount-range.js +38 -0
- package/dist/detectors/amount-range.js.map +1 -0
- package/dist/detectors/amount-scale.d.ts +6 -1
- package/dist/detectors/amount-scale.d.ts.map +1 -1
- package/dist/detectors/amount-scale.js +33 -9
- package/dist/detectors/amount-scale.js.map +1 -1
- package/dist/detectors/announced-count.d.ts +1 -1
- package/dist/detectors/announced-count.d.ts.map +1 -1
- package/dist/detectors/announced-count.js +18 -3
- package/dist/detectors/announced-count.js.map +1 -1
- package/dist/detectors/bare-comparative.d.ts.map +1 -1
- package/dist/detectors/bare-comparative.js +4 -1
- package/dist/detectors/bare-comparative.js.map +1 -1
- package/dist/detectors/block-quotation.d.ts +13 -0
- package/dist/detectors/block-quotation.d.ts.map +1 -0
- package/dist/detectors/block-quotation.js +86 -0
- package/dist/detectors/block-quotation.js.map +1 -0
- package/dist/detectors/bracket-label.d.ts +10 -0
- package/dist/detectors/bracket-label.d.ts.map +1 -0
- package/dist/detectors/bracket-label.js +51 -0
- package/dist/detectors/bracket-label.js.map +1 -0
- package/dist/detectors/capitalised-term.d.ts +44 -0
- package/dist/detectors/capitalised-term.d.ts.map +1 -0
- package/dist/detectors/capitalised-term.js +101 -0
- package/dist/detectors/capitalised-term.js.map +1 -0
- package/dist/detectors/citation-entry.d.ts +5 -0
- package/dist/detectors/citation-entry.d.ts.map +1 -1
- package/dist/detectors/citation-entry.js +19 -5
- package/dist/detectors/citation-entry.js.map +1 -1
- package/dist/detectors/code-before.d.ts +6 -0
- package/dist/detectors/code-before.d.ts.map +1 -0
- package/dist/detectors/code-before.js +15 -0
- package/dist/detectors/code-before.js.map +1 -0
- package/dist/detectors/connective-hierarchy.d.ts +11 -1
- package/dist/detectors/connective-hierarchy.d.ts.map +1 -1
- package/dist/detectors/connective-hierarchy.js +26 -6
- package/dist/detectors/connective-hierarchy.js.map +1 -1
- package/dist/detectors/currency-notation.d.ts.map +1 -1
- package/dist/detectors/currency-notation.js +2 -1
- package/dist/detectors/currency-notation.js.map +1 -1
- package/dist/detectors/date-outside-period.d.ts +4 -0
- package/dist/detectors/date-outside-period.d.ts.map +1 -0
- package/dist/detectors/date-outside-period.js +37 -0
- package/dist/detectors/date-outside-period.js.map +1 -0
- package/dist/detectors/default-values.d.ts +3 -0
- package/dist/detectors/default-values.d.ts.map +1 -0
- package/dist/detectors/default-values.js +14 -0
- package/dist/detectors/default-values.js.map +1 -0
- package/dist/detectors/defined-term-form.d.ts +6 -2
- package/dist/detectors/defined-term-form.d.ts.map +1 -1
- package/dist/detectors/defined-term-form.js +72 -12
- package/dist/detectors/defined-term-form.js.map +1 -1
- package/dist/detectors/definition-use.d.ts.map +1 -1
- package/dist/detectors/definition-use.js +8 -1
- package/dist/detectors/definition-use.js.map +1 -1
- package/dist/detectors/deprecated-use.d.ts +3 -0
- package/dist/detectors/deprecated-use.d.ts.map +1 -0
- package/dist/detectors/deprecated-use.js +14 -0
- package/dist/detectors/deprecated-use.js.map +1 -0
- package/dist/detectors/derived-numbers.d.ts +3 -1
- package/dist/detectors/derived-numbers.d.ts.map +1 -1
- package/dist/detectors/derived-numbers.js +119 -10
- package/dist/detectors/derived-numbers.js.map +1 -1
- package/dist/detectors/document-shape.d.ts +1 -0
- package/dist/detectors/document-shape.d.ts.map +1 -1
- package/dist/detectors/document-shape.js +4 -1
- package/dist/detectors/document-shape.js.map +1 -1
- package/dist/detectors/due-date.d.ts +3 -0
- package/dist/detectors/due-date.d.ts.map +1 -0
- package/dist/detectors/due-date.js +38 -0
- package/dist/detectors/due-date.js.map +1 -0
- package/dist/detectors/en-shape.d.ts.map +1 -1
- package/dist/detectors/en-shape.js +17 -9
- package/dist/detectors/en-shape.js.map +1 -1
- package/dist/detectors/fact-consistency.d.ts.map +1 -1
- package/dist/detectors/fact-consistency.js +76 -2
- package/dist/detectors/fact-consistency.js.map +1 -1
- package/dist/detectors/heading-echo.d.ts.map +1 -1
- package/dist/detectors/heading-echo.js +10 -1
- package/dist/detectors/heading-echo.js.map +1 -1
- package/dist/detectors/kana-function-word.d.ts +12 -0
- package/dist/detectors/kana-function-word.d.ts.map +1 -0
- package/dist/detectors/kana-function-word.js +59 -0
- package/dist/detectors/kana-function-word.js.map +1 -0
- package/dist/detectors/line-amount.d.ts +3 -0
- package/dist/detectors/line-amount.d.ts.map +1 -0
- package/dist/detectors/line-amount.js +22 -0
- package/dist/detectors/line-amount.js.map +1 -0
- package/dist/detectors/location-pointer.d.ts +6 -0
- package/dist/detectors/location-pointer.d.ts.map +1 -0
- package/dist/detectors/location-pointer.js +22 -0
- package/dist/detectors/location-pointer.js.map +1 -0
- package/dist/detectors/mark-shape.d.ts.map +1 -1
- package/dist/detectors/mark-shape.js +13 -1
- package/dist/detectors/mark-shape.js.map +1 -1
- package/dist/detectors/nado-closed-list.d.ts +3 -0
- package/dist/detectors/nado-closed-list.d.ts.map +1 -0
- package/dist/detectors/nado-closed-list.js +21 -0
- package/dist/detectors/nado-closed-list.js.map +1 -0
- package/dist/detectors/name-variant.d.ts.map +1 -1
- package/dist/detectors/name-variant.js +129 -8
- package/dist/detectors/name-variant.js.map +1 -1
- package/dist/detectors/next-word.d.ts.map +1 -1
- package/dist/detectors/next-word.js +41 -8
- package/dist/detectors/next-word.js.map +1 -1
- package/dist/detectors/number-word-figure.d.ts +5 -0
- package/dist/detectors/number-word-figure.d.ts.map +1 -0
- package/dist/detectors/number-word-figure.js +32 -0
- package/dist/detectors/number-word-figure.js.map +1 -0
- package/dist/detectors/obligation-without-deadline.d.ts +39 -0
- package/dist/detectors/obligation-without-deadline.d.ts.map +1 -0
- package/dist/detectors/obligation-without-deadline.js +148 -0
- package/dist/detectors/obligation-without-deadline.js.map +1 -0
- package/dist/detectors/open-end-names.d.ts +23 -0
- package/dist/detectors/open-end-names.d.ts.map +1 -0
- package/dist/detectors/open-end-names.js +95 -0
- package/dist/detectors/open-end-names.js.map +1 -0
- package/dist/detectors/ordinal-run-gaps.d.ts +8 -0
- package/dist/detectors/ordinal-run-gaps.d.ts.map +1 -0
- package/dist/detectors/ordinal-run-gaps.js +80 -0
- package/dist/detectors/ordinal-run-gaps.js.map +1 -0
- package/dist/detectors/orthographic-variant.d.ts.map +1 -1
- package/dist/detectors/orthographic-variant.js +26 -9
- package/dist/detectors/orthographic-variant.js.map +1 -1
- package/dist/detectors/orthography.d.ts.map +1 -1
- package/dist/detectors/orthography.js +5 -0
- package/dist/detectors/orthography.js.map +1 -1
- package/dist/detectors/parameter-table.d.ts +3 -0
- package/dist/detectors/parameter-table.d.ts.map +1 -0
- package/dist/detectors/parameter-table.js +16 -0
- package/dist/detectors/parameter-table.js.map +1 -0
- package/dist/detectors/party-order.d.ts +3 -0
- package/dist/detectors/party-order.d.ts.map +1 -0
- package/dist/detectors/party-order.js +46 -0
- package/dist/detectors/party-order.js.map +1 -0
- package/dist/detectors/phone-number-variant.d.ts +3 -0
- package/dist/detectors/phone-number-variant.d.ts.map +1 -0
- package/dist/detectors/phone-number-variant.js +18 -0
- package/dist/detectors/phone-number-variant.js.map +1 -0
- package/dist/detectors/prerequisite-order.d.ts +3 -0
- package/dist/detectors/prerequisite-order.d.ts.map +1 -0
- package/dist/detectors/prerequisite-order.js +30 -0
- package/dist/detectors/prerequisite-order.js.map +1 -0
- package/dist/detectors/quote-unnamed-speaker.d.ts +3 -0
- package/dist/detectors/quote-unnamed-speaker.d.ts.map +1 -0
- package/dist/detectors/quote-unnamed-speaker.js +18 -0
- package/dist/detectors/quote-unnamed-speaker.js.map +1 -0
- package/dist/detectors/quote-without-source.d.ts +12 -2
- package/dist/detectors/quote-without-source.d.ts.map +1 -1
- package/dist/detectors/quote-without-source.js +45 -11
- package/dist/detectors/quote-without-source.js.map +1 -1
- package/dist/detectors/registry/amount-range.d.ts +3 -0
- package/dist/detectors/registry/amount-range.d.ts.map +1 -0
- package/dist/detectors/registry/amount-range.js +3 -0
- package/dist/detectors/registry/amount-range.js.map +1 -0
- package/dist/detectors/registry/arrival-before-departure.d.ts +3 -0
- package/dist/detectors/registry/arrival-before-departure.d.ts.map +1 -0
- package/dist/detectors/registry/arrival-before-departure.js +3 -0
- package/dist/detectors/registry/arrival-before-departure.js.map +1 -0
- package/dist/detectors/registry/connection-time-short.d.ts +3 -0
- package/dist/detectors/registry/connection-time-short.d.ts.map +1 -0
- package/dist/detectors/registry/connection-time-short.js +3 -0
- package/dist/detectors/registry/connection-time-short.js.map +1 -0
- package/dist/detectors/registry/date-outside-period.d.ts +3 -0
- package/dist/detectors/registry/date-outside-period.d.ts.map +1 -0
- package/dist/detectors/registry/date-outside-period.js +3 -0
- package/dist/detectors/registry/date-outside-period.js.map +1 -0
- package/dist/detectors/registry/default-values.d.ts +3 -0
- package/dist/detectors/registry/default-values.d.ts.map +1 -0
- package/dist/detectors/registry/default-values.js +3 -0
- package/dist/detectors/registry/default-values.js.map +1 -0
- package/dist/detectors/registry/deprecated-use.d.ts +3 -0
- package/dist/detectors/registry/deprecated-use.d.ts.map +1 -0
- package/dist/detectors/registry/deprecated-use.js +3 -0
- package/dist/detectors/registry/deprecated-use.js.map +1 -0
- package/dist/detectors/registry/due-date.d.ts +3 -0
- package/dist/detectors/registry/due-date.d.ts.map +1 -0
- package/dist/detectors/registry/due-date.js +3 -0
- package/dist/detectors/registry/due-date.js.map +1 -0
- package/dist/detectors/registry/duration-product-mismatch.d.ts +3 -0
- package/dist/detectors/registry/duration-product-mismatch.d.ts.map +1 -0
- package/dist/detectors/registry/duration-product-mismatch.js +3 -0
- package/dist/detectors/registry/duration-product-mismatch.js.map +1 -0
- package/dist/detectors/registry/kana-function-word.d.ts +3 -0
- package/dist/detectors/registry/kana-function-word.d.ts.map +1 -0
- package/dist/detectors/registry/kana-function-word.js +3 -0
- package/dist/detectors/registry/kana-function-word.js.map +1 -0
- package/dist/detectors/registry/line-amount.d.ts +3 -0
- package/dist/detectors/registry/line-amount.d.ts.map +1 -0
- package/dist/detectors/registry/line-amount.js +3 -0
- package/dist/detectors/registry/line-amount.js.map +1 -0
- package/dist/detectors/registry/nado-closed-list.d.ts +3 -0
- package/dist/detectors/registry/nado-closed-list.d.ts.map +1 -0
- package/dist/detectors/registry/nado-closed-list.js +3 -0
- package/dist/detectors/registry/nado-closed-list.js.map +1 -0
- package/dist/detectors/registry/number-word-figure.d.ts +3 -0
- package/dist/detectors/registry/number-word-figure.d.ts.map +1 -0
- package/dist/detectors/registry/number-word-figure.js +3 -0
- package/dist/detectors/registry/number-word-figure.js.map +1 -0
- package/dist/detectors/registry/obligation-without-deadline.d.ts +3 -0
- package/dist/detectors/registry/obligation-without-deadline.d.ts.map +1 -0
- package/dist/detectors/registry/obligation-without-deadline.js +3 -0
- package/dist/detectors/registry/obligation-without-deadline.js.map +1 -0
- package/dist/detectors/registry/parameter-table.d.ts +3 -0
- package/dist/detectors/registry/parameter-table.d.ts.map +1 -0
- package/dist/detectors/registry/parameter-table.js +3 -0
- package/dist/detectors/registry/parameter-table.js.map +1 -0
- package/dist/detectors/registry/party-order.d.ts +3 -0
- package/dist/detectors/registry/party-order.d.ts.map +1 -0
- package/dist/detectors/registry/party-order.js +3 -0
- package/dist/detectors/registry/party-order.js.map +1 -0
- package/dist/detectors/registry/phone-number-variant.d.ts +3 -0
- package/dist/detectors/registry/phone-number-variant.d.ts.map +1 -0
- package/dist/detectors/registry/phone-number-variant.js +3 -0
- package/dist/detectors/registry/phone-number-variant.js.map +1 -0
- package/dist/detectors/registry/prerequisite-order.d.ts +3 -0
- package/dist/detectors/registry/prerequisite-order.d.ts.map +1 -0
- package/dist/detectors/registry/prerequisite-order.js +3 -0
- package/dist/detectors/registry/prerequisite-order.js.map +1 -0
- package/dist/detectors/registry/quote-unnamed-speaker.d.ts +3 -0
- package/dist/detectors/registry/quote-unnamed-speaker.d.ts.map +1 -0
- package/dist/detectors/registry/quote-unnamed-speaker.js +3 -0
- package/dist/detectors/registry/quote-unnamed-speaker.js.map +1 -0
- package/dist/detectors/registry/requirement-lists.d.ts +3 -0
- package/dist/detectors/registry/requirement-lists.d.ts.map +1 -0
- package/dist/detectors/registry/requirement-lists.js +3 -0
- package/dist/detectors/registry/requirement-lists.js.map +1 -0
- package/dist/detectors/registry/return-type.d.ts +3 -0
- package/dist/detectors/registry/return-type.d.ts.map +1 -0
- package/dist/detectors/registry/return-type.js +3 -0
- package/dist/detectors/registry/return-type.js.map +1 -0
- package/dist/detectors/registry/tax-amount.d.ts +3 -0
- package/dist/detectors/registry/tax-amount.d.ts.map +1 -0
- package/dist/detectors/registry/tax-amount.js +3 -0
- package/dist/detectors/registry/tax-amount.js.map +1 -0
- package/dist/detectors/registry/time-order.d.ts +3 -0
- package/dist/detectors/registry/time-order.d.ts.map +1 -0
- package/dist/detectors/registry/time-order.js +3 -0
- package/dist/detectors/registry/time-order.js.map +1 -0
- package/dist/detectors/registry/ui-label.d.ts +3 -0
- package/dist/detectors/registry/ui-label.d.ts.map +1 -0
- package/dist/detectors/registry/ui-label.js +3 -0
- package/dist/detectors/registry/ui-label.js.map +1 -0
- package/dist/detectors/registry/undefined-call.d.ts +3 -0
- package/dist/detectors/registry/undefined-call.d.ts.map +1 -0
- package/dist/detectors/registry/undefined-call.js +3 -0
- package/dist/detectors/registry/undefined-call.js.map +1 -0
- package/dist/detectors/registry/undefined-term.d.ts +3 -0
- package/dist/detectors/registry/undefined-term.d.ts.map +1 -0
- package/dist/detectors/registry/undefined-term.js +3 -0
- package/dist/detectors/registry/undefined-term.js.map +1 -0
- package/dist/detectors/registry/version-order.d.ts +3 -0
- package/dist/detectors/registry/version-order.d.ts.map +1 -0
- package/dist/detectors/registry/version-order.js +3 -0
- package/dist/detectors/registry/version-order.js.map +1 -0
- package/dist/detectors/registry/warning-action.d.ts +3 -0
- package/dist/detectors/registry/warning-action.d.ts.map +1 -0
- package/dist/detectors/registry/warning-action.js +3 -0
- package/dist/detectors/registry/warning-action.js.map +1 -0
- package/dist/detectors/requirement-lists.d.ts +3 -0
- package/dist/detectors/requirement-lists.d.ts.map +1 -0
- package/dist/detectors/requirement-lists.js +46 -0
- package/dist/detectors/requirement-lists.js.map +1 -0
- package/dist/detectors/requirement-smell.d.ts.map +1 -1
- package/dist/detectors/requirement-smell.js +25 -8
- package/dist/detectors/requirement-smell.js.map +1 -1
- package/dist/detectors/return-type.d.ts +3 -0
- package/dist/detectors/return-type.d.ts.map +1 -0
- package/dist/detectors/return-type.js +24 -0
- package/dist/detectors/return-type.js.map +1 -0
- package/dist/detectors/structure-tree.d.ts +12 -4
- package/dist/detectors/structure-tree.d.ts.map +1 -1
- package/dist/detectors/structure-tree.js +40 -15
- package/dist/detectors/structure-tree.js.map +1 -1
- package/dist/detectors/superlative-scope.d.ts.map +1 -1
- package/dist/detectors/superlative-scope.js +11 -1
- package/dist/detectors/superlative-scope.js.map +1 -1
- package/dist/detectors/tax-amount.d.ts +3 -0
- package/dist/detectors/tax-amount.d.ts.map +1 -0
- package/dist/detectors/tax-amount.js +19 -0
- package/dist/detectors/tax-amount.js.map +1 -0
- package/dist/detectors/technical-docs.d.ts.map +1 -1
- package/dist/detectors/technical-docs.js +5 -1
- package/dist/detectors/technical-docs.js.map +1 -1
- package/dist/detectors/term-extension.d.ts +14 -0
- package/dist/detectors/term-extension.d.ts.map +1 -0
- package/dist/detectors/term-extension.js +67 -0
- package/dist/detectors/term-extension.js.map +1 -0
- package/dist/detectors/time-order.d.ts +5 -0
- package/dist/detectors/time-order.d.ts.map +1 -0
- package/dist/detectors/time-order.js +58 -0
- package/dist/detectors/time-order.js.map +1 -0
- package/dist/detectors/ui-label.d.ts +3 -0
- package/dist/detectors/ui-label.d.ts.map +1 -0
- package/dist/detectors/ui-label.js +16 -0
- package/dist/detectors/ui-label.js.map +1 -0
- package/dist/detectors/unbalanced-bracket.d.ts.map +1 -1
- package/dist/detectors/unbalanced-bracket.js +8 -13
- package/dist/detectors/unbalanced-bracket.js.map +1 -1
- package/dist/detectors/undefined-call.d.ts +3 -0
- package/dist/detectors/undefined-call.d.ts.map +1 -0
- package/dist/detectors/undefined-call.js +18 -0
- package/dist/detectors/undefined-call.js.map +1 -0
- package/dist/detectors/undefined-term.d.ts +22 -0
- package/dist/detectors/undefined-term.d.ts.map +1 -0
- package/dist/detectors/undefined-term.js +101 -0
- package/dist/detectors/undefined-term.js.map +1 -0
- package/dist/detectors/unknown-word.d.ts +1 -1
- package/dist/detectors/unknown-word.js +3 -3
- package/dist/detectors/unknown-word.js.map +1 -1
- package/dist/detectors/vague-deadline.d.ts +4 -0
- package/dist/detectors/vague-deadline.d.ts.map +1 -1
- package/dist/detectors/vague-deadline.js +3 -3
- package/dist/detectors/vague-deadline.js.map +1 -1
- package/dist/detectors/version-mismatch.d.ts.map +1 -1
- package/dist/detectors/version-mismatch.js +18 -1
- package/dist/detectors/version-mismatch.js.map +1 -1
- package/dist/detectors/version-order.d.ts +3 -0
- package/dist/detectors/version-order.d.ts.map +1 -0
- package/dist/detectors/version-order.js +43 -0
- package/dist/detectors/version-order.js.map +1 -0
- package/dist/detectors/warning-action.d.ts +3 -0
- package/dist/detectors/warning-action.d.ts.map +1 -0
- package/dist/detectors/warning-action.js +48 -0
- package/dist/detectors/warning-action.js.map +1 -0
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +4 -1
- package/dist/document.js.map +1 -1
- package/dist/facts/condition-pairs.d.ts +51 -0
- package/dist/facts/condition-pairs.d.ts.map +1 -0
- package/dist/facts/condition-pairs.js +203 -0
- package/dist/facts/condition-pairs.js.map +1 -0
- package/dist/facts/event-dates.d.ts +26 -0
- package/dist/facts/event-dates.d.ts.map +1 -0
- package/dist/facts/event-dates.js +38 -0
- package/dist/facts/event-dates.js.map +1 -0
- package/dist/facts/fact-scope.d.ts +2 -0
- package/dist/facts/fact-scope.d.ts.map +1 -1
- package/dist/facts/fact-scope.js +5 -0
- package/dist/facts/fact-scope.js.map +1 -1
- package/dist/facts/labelled-facts.d.ts +2 -0
- package/dist/facts/labelled-facts.d.ts.map +1 -1
- package/dist/facts/labelled-facts.js +9 -1
- package/dist/facts/labelled-facts.js.map +1 -1
- package/dist/facts/table-facts.d.ts +18 -0
- package/dist/facts/table-facts.d.ts.map +1 -1
- package/dist/facts/table-facts.js +4 -2
- package/dist/facts/table-facts.js.map +1 -1
- package/dist/grade/ai-score.d.ts +1 -1
- package/dist/grade/ai-score.d.ts.map +1 -1
- package/dist/grade/text.js +2 -2
- package/dist/grade/text.js.map +1 -1
- package/dist/heading-numbering.js +2 -2
- package/dist/heading-numbering.js.map +1 -1
- package/dist/html/fetch-page.d.ts +20 -0
- package/dist/html/fetch-page.d.ts.map +1 -0
- package/dist/html/fetch-page.js +51 -0
- package/dist/html/fetch-page.js.map +1 -0
- package/dist/html/fetched-text.d.ts +5 -0
- package/dist/html/fetched-text.d.ts.map +1 -0
- package/dist/html/fetched-text.js +25 -0
- package/dist/html/fetched-text.js.map +1 -0
- package/dist/html/html-content-block.d.ts +6 -0
- package/dist/html/html-content-block.d.ts.map +1 -0
- package/dist/html/html-content-block.js +86 -0
- package/dist/html/html-content-block.js.map +1 -0
- package/dist/html/html-elements.d.ts +41 -0
- package/dist/html/html-elements.d.ts.map +1 -0
- package/dist/html/html-elements.js +91 -0
- package/dist/html/html-elements.js.map +1 -0
- package/dist/html/html-footnote-marks.d.ts +2 -0
- package/dist/html/html-footnote-marks.d.ts.map +1 -0
- package/dist/html/html-footnote-marks.js +15 -0
- package/dist/html/html-footnote-marks.js.map +1 -0
- package/dist/html/html-heading-links.d.ts +6 -0
- package/dist/html/html-heading-links.d.ts.map +1 -0
- package/dist/html/html-heading-links.js +71 -0
- package/dist/html/html-heading-links.js.map +1 -0
- package/dist/html/html-lost-tags.d.ts +3 -0
- package/dist/html/html-lost-tags.d.ts.map +1 -0
- package/dist/html/html-lost-tags.js +11 -0
- package/dist/html/html-lost-tags.js.map +1 -0
- package/dist/html/html-markdown.d.ts +2 -0
- package/dist/html/html-markdown.d.ts.map +1 -0
- package/dist/html/html-markdown.js +347 -0
- package/dist/html/html-markdown.js.map +1 -0
- package/dist/html/html-preformatted.d.ts +17 -0
- package/dist/html/html-preformatted.d.ts.map +1 -0
- package/dist/html/html-preformatted.js +82 -0
- package/dist/html/html-preformatted.js.map +1 -0
- package/dist/html/html-reader-only.d.ts +6 -0
- package/dist/html/html-reader-only.d.ts.map +1 -0
- package/dist/html/html-reader-only.js +63 -0
- package/dist/html/html-reader-only.js.map +1 -0
- package/dist/html/html-run-in-headings.d.ts +2 -0
- package/dist/html/html-run-in-headings.d.ts.map +1 -0
- package/dist/html/html-run-in-headings.js +36 -0
- package/dist/html/html-run-in-headings.js.map +1 -0
- package/dist/html/html-tables.d.ts +3 -0
- package/dist/html/html-tables.d.ts.map +1 -0
- package/dist/html/html-tables.js +58 -0
- package/dist/html/html-tables.js.map +1 -0
- package/dist/html/html-widgets.d.ts +3 -0
- package/dist/html/html-widgets.d.ts.map +1 -0
- package/dist/html/html-widgets.js +71 -0
- package/dist/html/html-widgets.js.map +1 -0
- package/dist/html/markup-text.d.ts +5 -0
- package/dist/html/markup-text.d.ts.map +1 -0
- package/dist/html/markup-text.js +32 -0
- package/dist/html/markup-text.js.map +1 -0
- package/dist/html/page-document.d.ts +9 -0
- package/dist/html/page-document.d.ts.map +1 -0
- package/dist/html/page-document.js +19 -0
- package/dist/html/page-document.js.map +1 -0
- package/dist/inline-count.d.ts +19 -0
- package/dist/inline-count.d.ts.map +1 -0
- package/dist/inline-count.js +109 -0
- package/dist/inline-count.js.map +1 -0
- package/dist/kana-spelling.d.ts +5 -0
- package/dist/kana-spelling.d.ts.map +1 -1
- package/dist/kana-spelling.js +5 -0
- package/dist/kana-spelling.js.map +1 -1
- package/dist/location-part.d.ts +13 -0
- package/dist/location-part.d.ts.map +1 -0
- package/dist/location-part.js +24 -0
- package/dist/location-part.js.map +1 -0
- package/dist/nado-closed-list.d.ts +20 -0
- package/dist/nado-closed-list.d.ts.map +1 -0
- package/dist/nado-closed-list.js +72 -0
- package/dist/nado-closed-list.js.map +1 -0
- package/dist/name-cue.d.ts +17 -0
- package/dist/name-cue.d.ts.map +1 -0
- package/dist/name-cue.js +29 -0
- package/dist/name-cue.js.map +1 -0
- package/dist/name-variants.d.ts +29 -2
- package/dist/name-variants.d.ts.map +1 -1
- package/dist/name-variants.js +107 -8
- package/dist/name-variants.js.map +1 -1
- package/dist/name-word-order.d.ts +49 -0
- package/dist/name-word-order.d.ts.map +1 -0
- package/dist/name-word-order.js +114 -0
- package/dist/name-word-order.js.map +1 -0
- package/dist/paragraph-runs.d.ts +6 -1
- package/dist/paragraph-runs.d.ts.map +1 -1
- package/dist/paragraph-runs.js +9 -2
- package/dist/paragraph-runs.js.map +1 -1
- package/dist/parameter-table.d.ts +19 -0
- package/dist/parameter-table.d.ts.map +1 -0
- package/dist/parameter-table.js +191 -0
- package/dist/parameter-table.js.map +1 -0
- package/dist/phone-numbers.d.ts +23 -0
- package/dist/phone-numbers.d.ts.map +1 -0
- package/dist/phone-numbers.js +83 -0
- package/dist/phone-numbers.js.map +1 -0
- package/dist/place-names.d.ts +55 -0
- package/dist/place-names.d.ts.map +1 -0
- package/dist/place-names.js +196 -0
- package/dist/place-names.js.map +1 -0
- package/dist/plugin.d.ts +11 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/prerequisite-order.d.ts +16 -0
- package/dist/prerequisite-order.d.ts.map +1 -0
- package/dist/prerequisite-order.js +29 -0
- package/dist/prerequisite-order.js.map +1 -0
- package/dist/profile/parse.d.ts.map +1 -1
- package/dist/profile/parse.js +10 -1
- package/dist/profile/parse.js.map +1 -1
- package/dist/reasons.d.ts +2 -0
- package/dist/reasons.d.ts.map +1 -1
- package/dist/reasons.js +2 -0
- package/dist/reasons.js.map +1 -1
- package/dist/render/rules-json.d.ts.map +1 -1
- package/dist/render/rules-json.js +4 -0
- package/dist/render/rules-json.js.map +1 -1
- package/dist/render/rules-table.d.ts.map +1 -1
- package/dist/render/rules-table.js +6 -2
- package/dist/render/rules-table.js.map +1 -1
- package/dist/return-type.d.ts +33 -0
- package/dist/return-type.d.ts.map +1 -0
- package/dist/return-type.js +302 -0
- package/dist/return-type.js.map +1 -0
- package/dist/rule-genres.d.ts +5 -2
- package/dist/rule-genres.d.ts.map +1 -1
- package/dist/rule-genres.js +2 -0
- package/dist/rule-genres.js.map +1 -1
- package/dist/rule-load.d.ts.map +1 -1
- package/dist/rule-load.js +2 -1
- package/dist/rule-load.js.map +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +5 -1
- package/dist/run.js.map +1 -1
- package/dist/spelling.d.ts +2 -0
- package/dist/spelling.d.ts.map +1 -1
- package/dist/spelling.js +6 -0
- package/dist/spelling.js.map +1 -1
- package/dist/structure/action-due.d.ts +21 -0
- package/dist/structure/action-due.d.ts.map +1 -0
- package/dist/structure/action-due.js +126 -0
- package/dist/structure/action-due.js.map +1 -0
- package/dist/structure/amount-range.d.ts +30 -0
- package/dist/structure/amount-range.d.ts.map +1 -0
- package/dist/structure/amount-range.js +153 -0
- package/dist/structure/amount-range.js.map +1 -0
- package/dist/structure/amount-scale.d.ts +6 -0
- package/dist/structure/amount-scale.d.ts.map +1 -1
- package/dist/structure/amount-scale.js +13 -0
- package/dist/structure/amount-scale.js.map +1 -1
- package/dist/structure/cite.d.ts +5 -2
- package/dist/structure/cite.d.ts.map +1 -1
- package/dist/structure/cite.js +20 -1
- package/dist/structure/cite.js.map +1 -1
- package/dist/structure/connection-times.d.ts +56 -0
- package/dist/structure/connection-times.d.ts.map +1 -0
- package/dist/structure/connection-times.js +165 -0
- package/dist/structure/connection-times.js.map +1 -0
- package/dist/structure/counted-amounts.d.ts +12 -0
- package/dist/structure/counted-amounts.d.ts.map +1 -0
- package/dist/structure/counted-amounts.js +30 -0
- package/dist/structure/counted-amounts.js.map +1 -0
- package/dist/structure/date-order-tie.d.ts +13 -0
- package/dist/structure/date-order-tie.d.ts.map +1 -0
- package/dist/structure/date-order-tie.js +61 -0
- package/dist/structure/date-order-tie.js.map +1 -0
- package/dist/structure/date-order.d.ts +24 -3
- package/dist/structure/date-order.d.ts.map +1 -1
- package/dist/structure/date-order.js +66 -17
- package/dist/structure/date-order.js.map +1 -1
- package/dist/structure/date-outside-period.d.ts +33 -0
- package/dist/structure/date-outside-period.d.ts.map +1 -0
- package/dist/structure/date-outside-period.js +132 -0
- package/dist/structure/date-outside-period.js.map +1 -0
- package/dist/structure/date-range.d.ts +5 -2
- package/dist/structure/date-range.d.ts.map +1 -1
- package/dist/structure/date-range.js +37 -9
- package/dist/structure/date-range.js.map +1 -1
- package/dist/structure/definition-use.d.ts +5 -2
- package/dist/structure/definition-use.d.ts.map +1 -1
- package/dist/structure/definition-use.js +11 -3
- package/dist/structure/definition-use.js.map +1 -1
- package/dist/structure/due-date.d.ts +19 -0
- package/dist/structure/due-date.d.ts.map +1 -0
- package/dist/structure/due-date.js +30 -0
- package/dist/structure/due-date.js.map +1 -0
- package/dist/structure/heading-runs.d.ts +9 -0
- package/dist/structure/heading-runs.d.ts.map +1 -0
- package/dist/structure/heading-runs.js +23 -0
- package/dist/structure/heading-runs.js.map +1 -0
- package/dist/structure/install-pin.d.ts +46 -0
- package/dist/structure/install-pin.d.ts.map +1 -0
- package/dist/structure/install-pin.js +85 -0
- package/dist/structure/install-pin.js.map +1 -0
- package/dist/structure/leg-times.d.ts +36 -0
- package/dist/structure/leg-times.d.ts.map +1 -0
- package/dist/structure/leg-times.js +148 -0
- package/dist/structure/leg-times.js.map +1 -0
- package/dist/structure/line-amount-unit.d.ts +24 -0
- package/dist/structure/line-amount-unit.d.ts.map +1 -0
- package/dist/structure/line-amount-unit.js +24 -0
- package/dist/structure/line-amount-unit.js.map +1 -0
- package/dist/structure/line-amount.d.ts +40 -0
- package/dist/structure/line-amount.d.ts.map +1 -0
- package/dist/structure/line-amount.js +118 -0
- package/dist/structure/line-amount.js.map +1 -0
- package/dist/structure/number-word-figure.d.ts +37 -0
- package/dist/structure/number-word-figure.d.ts.map +1 -0
- package/dist/structure/number-word-figure.js +151 -0
- package/dist/structure/number-word-figure.js.map +1 -0
- package/dist/structure/numbering.d.ts +1 -0
- package/dist/structure/numbering.d.ts.map +1 -1
- package/dist/structure/numbering.js +3 -0
- package/dist/structure/numbering.js.map +1 -1
- package/dist/structure/ordinal-runs.d.ts +45 -0
- package/dist/structure/ordinal-runs.d.ts.map +1 -0
- package/dist/structure/ordinal-runs.js +78 -0
- package/dist/structure/ordinal-runs.js.map +1 -0
- package/dist/structure/party-order.d.ts +33 -0
- package/dist/structure/party-order.d.ts.map +1 -0
- package/dist/structure/party-order.js +79 -0
- package/dist/structure/party-order.js.map +1 -0
- package/dist/structure/percent-sum-prose.d.ts +1 -1
- package/dist/structure/percent-sum-prose.d.ts.map +1 -1
- package/dist/structure/percent-sum-prose.js +45 -3
- package/dist/structure/percent-sum-prose.js.map +1 -1
- package/dist/structure/percent-sum.d.ts +8 -0
- package/dist/structure/percent-sum.d.ts.map +1 -1
- package/dist/structure/percent-sum.js +8 -1
- package/dist/structure/percent-sum.js.map +1 -1
- package/dist/structure/release-list.d.ts +9 -0
- package/dist/structure/release-list.d.ts.map +1 -0
- package/dist/structure/release-list.js +46 -0
- package/dist/structure/release-list.js.map +1 -0
- package/dist/structure/requirement-lists.d.ts +37 -0
- package/dist/structure/requirement-lists.d.ts.map +1 -0
- package/dist/structure/requirement-lists.js +89 -0
- package/dist/structure/requirement-lists.js.map +1 -0
- package/dist/structure/share-column.d.ts +7 -0
- package/dist/structure/share-column.d.ts.map +1 -0
- package/dist/structure/share-column.js +22 -0
- package/dist/structure/share-column.js.map +1 -0
- package/dist/structure/stated-period.d.ts +31 -0
- package/dist/structure/stated-period.d.ts.map +1 -0
- package/dist/structure/stated-period.js +127 -0
- package/dist/structure/stated-period.js.map +1 -0
- package/dist/structure/tax.d.ts +25 -0
- package/dist/structure/tax.d.ts.map +1 -0
- package/dist/structure/tax.js +86 -0
- package/dist/structure/tax.js.map +1 -0
- package/dist/structure/time-marks.d.ts +58 -0
- package/dist/structure/time-marks.d.ts.map +1 -0
- package/dist/structure/time-marks.js +74 -0
- package/dist/structure/time-marks.js.map +1 -0
- package/dist/structure/time-order.d.ts +42 -0
- package/dist/structure/time-order.d.ts.map +1 -0
- package/dist/structure/time-order.js +107 -0
- package/dist/structure/time-order.js.map +1 -0
- package/dist/structure/title-lines.d.ts +8 -0
- package/dist/structure/title-lines.d.ts.map +1 -0
- package/dist/structure/title-lines.js +27 -0
- package/dist/structure/title-lines.js.map +1 -0
- package/dist/structure/total.d.ts.map +1 -1
- package/dist/structure/total.js +3 -1
- package/dist/structure/total.js.map +1 -1
- package/dist/structure/version-mismatch.d.ts +1 -5
- package/dist/structure/version-mismatch.d.ts.map +1 -1
- package/dist/structure/version-mismatch.js +65 -12
- package/dist/structure/version-mismatch.js.map +1 -1
- package/dist/structure/version-order.d.ts +25 -0
- package/dist/structure/version-order.d.ts.map +1 -0
- package/dist/structure/version-order.js +77 -0
- package/dist/structure/version-order.js.map +1 -0
- package/dist/surname-near.d.ts +6 -0
- package/dist/surname-near.d.ts.map +1 -0
- package/dist/surname-near.js +31 -0
- package/dist/surname-near.js.map +1 -0
- package/dist/table-cells.d.ts +13 -0
- package/dist/table-cells.d.ts.map +1 -0
- package/dist/table-cells.js +36 -0
- package/dist/table-cells.js.map +1 -0
- package/dist/table-names.d.ts +42 -0
- package/dist/table-names.d.ts.map +1 -0
- package/dist/table-names.js +94 -0
- package/dist/table-names.js.map +1 -0
- package/dist/table-text.d.ts +9 -0
- package/dist/table-text.d.ts.map +1 -0
- package/dist/table-text.js +36 -0
- package/dist/table-text.js.map +1 -0
- package/dist/ui-labels.d.ts +16 -0
- package/dist/ui-labels.d.ts.map +1 -0
- package/dist/ui-labels.js +42 -0
- package/dist/ui-labels.js.map +1 -0
- package/dist/undefined-call.d.ts +13 -0
- package/dist/undefined-call.d.ts.map +1 -0
- package/dist/undefined-call.js +55 -0
- package/dist/undefined-call.js.map +1 -0
- package/dist/unnamed-speaker.d.ts +23 -0
- package/dist/unnamed-speaker.d.ts.map +1 -0
- package/dist/unnamed-speaker.js +176 -0
- package/dist/unnamed-speaker.js.map +1 -0
- package/dist/warning-action.d.ts +22 -0
- package/dist/warning-action.d.ts.map +1 -0
- package/dist/warning-action.js +58 -0
- package/dist/warning-action.js.map +1 -0
- package/genres.yaml +2 -0
- package/package.json +4 -3
- package/profiles/statute.yaml +8 -0
- package/rules/agreement-slip.yaml +2 -2
- package/rules/amount-range-reversed.yaml +52 -0
- package/rules/amount-scale-consistency.yaml +4 -4
- package/rules/announced-count-mismatch.yaml +9 -4
- package/rules/arrival-before-departure.yaml +48 -0
- package/rules/connection-time-short.yaml +52 -0
- package/rules/connective-hierarchy.yaml +3 -3
- package/rules/currency-notation-consistency.yaml +2 -2
- package/rules/date-order.yaml +9 -4
- package/rules/date-outside-period.yaml +64 -0
- package/rules/default-value-mismatch.yaml +79 -0
- package/rules/defined-term-form.yaml +9 -7
- package/rules/deprecated-option-used.yaml +78 -0
- package/rules/doubled-nado.yaml +28 -12
- package/rules/due-before-issue.yaml +68 -0
- package/rules/duplicate-definition.yaml +2 -2
- package/rules/duration-mismatch.yaml +15 -4
- package/rules/duration-product-mismatch.yaml +73 -0
- package/rules/heading-echo.yaml +2 -2
- package/rules/hyphen-as-dash.yaml +2 -2
- package/rules/kana-function-word.yaml +58 -0
- package/rules/latin-spacing.yaml +6 -5
- package/rules/line-amount-mismatch.yaml +58 -0
- package/rules/nado-closed-list.yaml +77 -0
- package/rules/name-variant.yaml +20 -2
- package/rules/number-word-figure-mismatch.yaml +76 -0
- package/rules/numbering-gap.yaml +2 -2
- package/rules/obligation-without-deadline.yaml +95 -0
- package/rules/one-sentence-paragraph-run.yaml +2 -3
- package/rules/parameter-table-mismatch.yaml +90 -0
- package/rules/party-order.yaml +84 -0
- package/rules/percent-sum-mismatch.yaml +2 -2
- package/rules/phone-number-variant.yaml +68 -0
- package/rules/prerequisite-after-step.yaml +78 -0
- package/rules/quote-unnamed-speaker.yaml +67 -0
- package/rules/quote-without-source.yaml +6 -6
- package/rules/required-listed-as-preferred.yaml +102 -0
- package/rules/requirement-smell.yaml +3 -3
- package/rules/return-type-mismatch.yaml +79 -0
- package/rules/sentence-initial-conjunction-run.yaml +13 -7
- package/rules/summary-fact-mismatch.yaml +4 -4
- package/rules/tax-mismatch.yaml +71 -0
- package/rules/time-order.yaml +65 -0
- package/rules/title-length.yaml +2 -2
- package/rules/ui-label-variant.yaml +70 -0
- package/rules/unbalanced-bracket.yaml +4 -4
- package/rules/uncomparable-graded.yaml +29 -10
- package/rules/undefined-function-call.yaml +77 -0
- package/rules/undefined-term.yaml +86 -0
- package/rules/unknown-word.yaml +2 -2
- package/rules/unqualified-superlative.yaml +2 -2
- package/rules/use-before-definition.yaml +2 -2
- package/rules/version-mismatch.yaml +12 -4
- package/rules/version-order.yaml +85 -0
- package/rules/very-adjective.yaml +31 -13
- package/rules/warning-without-action.yaml +64 -0
- package/rules/wordy-phrase.yaml +27 -9
- package/src/ai-score/of-document.ts +19 -9
- package/src/ai-score/render.ts +24 -4
- package/src/ai-score/score.ts +24 -3
- package/src/ai-score/signals.ts +12 -2
- package/src/ai-score/text.ts +7 -2
- package/src/announced-count.ts +19 -12
- package/src/check-source.ts +11 -2
- package/src/cli-text.ts +38 -16
- package/src/cli.ts +2 -1
- package/src/commands/cite-claims.ts +103 -0
- package/src/commands/cite-page.ts +61 -0
- package/src/commands/cite-scaffold.ts +27 -0
- package/src/commands/cite.ts +127 -58
- package/src/company-names.ts +202 -0
- package/src/default-values.ts +158 -0
- package/src/deprecated-use.ts +122 -0
- package/src/derived/session-hours.ts +62 -0
- package/src/derived/stays.ts +145 -0
- package/src/derived/time-lengths.ts +226 -0
- package/src/derived/unit-counts.ts +18 -0
- package/src/derived/working-hours.ts +97 -0
- package/src/detectors/acronym-context.ts +10 -2
- package/src/detectors/acronym-expansion.ts +57 -2
- package/src/detectors/address-word.ts +9 -0
- package/src/detectors/agreement-slip.ts +7 -1
- package/src/detectors/ai-phrasing.ts +6 -1
- package/src/detectors/amount-range.ts +54 -0
- package/src/detectors/amount-scale.ts +50 -17
- package/src/detectors/announced-count.ts +29 -11
- package/src/detectors/bare-comparative.ts +7 -2
- package/src/detectors/block-quotation.ts +95 -0
- package/src/detectors/bracket-label.ts +58 -0
- package/src/detectors/capitalised-term.ts +147 -0
- package/src/detectors/citation-entry.ts +20 -5
- package/src/detectors/code-before.ts +14 -0
- package/src/detectors/connective-hierarchy.ts +39 -11
- package/src/detectors/currency-notation.ts +2 -1
- package/src/detectors/date-outside-period.ts +41 -0
- package/src/detectors/default-values.ts +17 -0
- package/src/detectors/defined-term-form.ts +84 -15
- package/src/detectors/definition-use.ts +10 -2
- package/src/detectors/deprecated-use.ts +17 -0
- package/src/detectors/derived-numbers.ts +174 -10
- package/src/detectors/document-shape.ts +6 -1
- package/src/detectors/due-date.ts +47 -0
- package/src/detectors/en-shape.ts +27 -11
- package/src/detectors/fact-consistency.ts +95 -3
- package/src/detectors/heading-echo.ts +11 -1
- package/src/detectors/kana-function-word.ts +71 -0
- package/src/detectors/line-amount.ts +33 -0
- package/src/detectors/location-pointer.ts +30 -0
- package/src/detectors/mark-shape.ts +18 -1
- package/src/detectors/nado-closed-list.ts +25 -0
- package/src/detectors/name-variant.ts +164 -13
- package/src/detectors/next-word.ts +56 -9
- package/src/detectors/number-word-figure.ts +43 -0
- package/src/detectors/obligation-without-deadline.ts +192 -0
- package/src/detectors/open-end-names.ts +140 -0
- package/src/detectors/ordinal-run-gaps.ts +101 -0
- package/src/detectors/orthographic-variant.ts +39 -14
- package/src/detectors/orthography.ts +6 -1
- package/src/detectors/parameter-table.ts +17 -0
- package/src/detectors/party-order.ts +50 -0
- package/src/detectors/phone-number-variant.ts +18 -0
- package/src/detectors/prerequisite-order.ts +35 -0
- package/src/detectors/quote-unnamed-speaker.ts +19 -0
- package/src/detectors/quote-without-source.ts +57 -10
- package/src/detectors/registry/amount-range.ts +4 -0
- package/src/detectors/registry/arrival-before-departure.ts +4 -0
- package/src/detectors/registry/connection-time-short.ts +4 -0
- package/src/detectors/registry/date-outside-period.ts +4 -0
- package/src/detectors/registry/default-values.ts +4 -0
- package/src/detectors/registry/deprecated-use.ts +4 -0
- package/src/detectors/registry/due-date.ts +4 -0
- package/src/detectors/registry/duration-product-mismatch.ts +4 -0
- package/src/detectors/registry/kana-function-word.ts +4 -0
- package/src/detectors/registry/line-amount.ts +4 -0
- package/src/detectors/registry/nado-closed-list.ts +4 -0
- package/src/detectors/registry/number-word-figure.ts +4 -0
- package/src/detectors/registry/obligation-without-deadline.ts +4 -0
- package/src/detectors/registry/parameter-table.ts +4 -0
- package/src/detectors/registry/party-order.ts +4 -0
- package/src/detectors/registry/phone-number-variant.ts +4 -0
- package/src/detectors/registry/prerequisite-order.ts +4 -0
- package/src/detectors/registry/quote-unnamed-speaker.ts +4 -0
- package/src/detectors/registry/requirement-lists.ts +4 -0
- package/src/detectors/registry/return-type.ts +4 -0
- package/src/detectors/registry/tax-amount.ts +4 -0
- package/src/detectors/registry/time-order.ts +4 -0
- package/src/detectors/registry/ui-label.ts +4 -0
- package/src/detectors/registry/undefined-call.ts +4 -0
- package/src/detectors/registry/undefined-term.ts +4 -0
- package/src/detectors/registry/version-order.ts +4 -0
- package/src/detectors/registry/warning-action.ts +4 -0
- package/src/detectors/requirement-lists.ts +65 -0
- package/src/detectors/requirement-smell.ts +29 -9
- package/src/detectors/return-type.ts +30 -0
- package/src/detectors/structure-tree.ts +55 -22
- package/src/detectors/superlative-scope.ts +13 -1
- package/src/detectors/tax-amount.ts +25 -0
- package/src/detectors/technical-docs.ts +7 -1
- package/src/detectors/term-extension.ts +67 -0
- package/src/detectors/time-order.ts +84 -0
- package/src/detectors/ui-label.ts +17 -0
- package/src/detectors/unbalanced-bracket.ts +7 -14
- package/src/detectors/undefined-call.ts +19 -0
- package/src/detectors/undefined-term.ts +120 -0
- package/src/detectors/unknown-word.ts +3 -3
- package/src/detectors/vague-deadline.ts +3 -3
- package/src/detectors/version-mismatch.ts +26 -5
- package/src/detectors/version-order.ts +50 -0
- package/src/detectors/warning-action.ts +49 -0
- package/src/document.ts +4 -1
- package/src/facts/condition-pairs.ts +289 -0
- package/src/facts/event-dates.ts +63 -0
- package/src/facts/fact-scope.ts +6 -0
- package/src/facts/labelled-facts.ts +13 -1
- package/src/facts/table-facts.ts +6 -3
- package/src/grade/ai-score.ts +1 -1
- package/src/grade/text.ts +2 -2
- package/src/heading-numbering.ts +2 -2
- package/src/html/fetch-page.ts +64 -0
- package/src/html/fetched-text.ts +32 -0
- package/src/html/html-content-block.ts +107 -0
- package/src/html/html-elements.ts +127 -0
- package/src/html/html-footnote-marks.ts +20 -0
- package/src/html/html-heading-links.ts +93 -0
- package/src/html/html-lost-tags.ts +14 -0
- package/src/html/html-markdown.ts +481 -0
- package/src/html/html-preformatted.ts +110 -0
- package/src/html/html-reader-only.ts +82 -0
- package/src/html/html-run-in-headings.ts +43 -0
- package/src/html/html-tables.ts +76 -0
- package/src/html/html-widgets.ts +114 -0
- package/src/html/markup-text.ts +35 -0
- package/src/html/page-document.ts +22 -0
- package/src/inline-count.ts +146 -0
- package/src/kana-spelling.ts +7 -0
- package/src/location-part.ts +30 -0
- package/src/nado-closed-list.ts +106 -0
- package/src/name-cue.ts +35 -0
- package/src/name-variants.ts +133 -12
- package/src/name-word-order.ts +149 -0
- package/src/paragraph-runs.ts +12 -2
- package/src/parameter-table.ts +208 -0
- package/src/phone-numbers.ts +98 -0
- package/src/place-names.ts +248 -0
- package/src/plugin.ts +9 -0
- package/src/prerequisite-order.ts +39 -0
- package/src/profile/parse.ts +10 -1
- package/src/reasons.ts +4 -0
- package/src/render/rules-json.ts +4 -0
- package/src/render/rules-table.ts +6 -3
- package/src/return-type.ts +361 -0
- package/src/rule-genres.ts +5 -2
- package/src/rule-load.ts +3 -2
- package/src/run.ts +3 -1
- package/src/spelling.ts +8 -0
- package/src/structure/action-due.ts +179 -0
- package/src/structure/amount-range.ts +219 -0
- package/src/structure/amount-scale.ts +18 -0
- package/src/structure/cite.ts +21 -2
- package/src/structure/connection-times.ts +226 -0
- package/src/structure/counted-amounts.ts +42 -0
- package/src/structure/date-order-tie.ts +86 -0
- package/src/structure/date-order.ts +100 -23
- package/src/structure/date-outside-period.ts +192 -0
- package/src/structure/date-range.ts +45 -9
- package/src/structure/definition-use.ts +24 -3
- package/src/structure/due-date.ts +46 -0
- package/src/structure/heading-runs.ts +24 -0
- package/src/structure/install-pin.ts +115 -0
- package/src/structure/leg-times.ts +213 -0
- package/src/structure/line-amount-unit.ts +35 -0
- package/src/structure/line-amount.ts +162 -0
- package/src/structure/number-word-figure.ts +199 -0
- package/src/structure/numbering.ts +3 -0
- package/src/structure/ordinal-runs.ts +107 -0
- package/src/structure/party-order.ts +115 -0
- package/src/structure/percent-sum-prose.ts +46 -3
- package/src/structure/percent-sum.ts +16 -2
- package/src/structure/release-list.ts +69 -0
- package/src/structure/requirement-lists.ts +145 -0
- package/src/structure/share-column.ts +25 -0
- package/src/structure/stated-period.ts +161 -0
- package/src/structure/tax.ts +114 -0
- package/src/structure/time-marks.ts +127 -0
- package/src/structure/time-order.ts +141 -0
- package/src/structure/title-lines.ts +33 -0
- package/src/structure/total.ts +5 -1
- package/src/structure/version-mismatch.ts +67 -13
- package/src/structure/version-order.ts +94 -0
- package/src/surname-near.ts +31 -0
- package/src/table-cells.ts +41 -0
- package/src/table-names.ts +113 -0
- package/src/table-text.ts +39 -0
- package/src/ui-labels.ts +55 -0
- package/src/undefined-call.ts +65 -0
- package/src/unnamed-speaker.ts +224 -0
- package/src/warning-action.ts +73 -0
- package/styles/koyobun.yaml +7 -4
|
@@ -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
|
+
};
|
package/src/facts/fact-scope.ts
CHANGED
|
@@ -139,3 +139,9 @@ export const scopedFacts = (facts: readonly Fact[], tree: StructureNode, source:
|
|
|
139
139
|
return { ...fact, ...scopeOf(fact, around.at(-1), at), part: partOf(around, tree, fact.value.start, summaryWords) };
|
|
140
140
|
});
|
|
141
141
|
};
|
|
142
|
+
|
|
143
|
+
/** 文書のその位置が、冒頭、要約の節、本文のどれか。 */
|
|
144
|
+
export const partsAt = (offsets: readonly number[], tree: StructureNode, summaryWords: readonly string[]): FactPart[] => {
|
|
145
|
+
const nodes = inDocumentOrder(tree).filter((node) => CONTAINERS.has(node.kind));
|
|
146
|
+
return offsets.map((offset) => partOf(containersAt(nodes, offset), tree, offset, summaryWords));
|
|
147
|
+
};
|
|
@@ -19,6 +19,8 @@ export type FactWords = {
|
|
|
19
19
|
readonly determiners: readonly string[];
|
|
20
20
|
/** 名前にならない語(それ、it)。 */
|
|
21
21
|
readonly vague: readonly string[];
|
|
22
|
+
/** 名前の前に置かれる決定の前置き(協議の結果、, it was decided that)。読点を含んでも条件ではないので、外してから名前を読む。 */
|
|
23
|
+
readonly leads: readonly string[];
|
|
22
24
|
readonly attributes: readonly AttributePhrase[];
|
|
23
25
|
};
|
|
24
26
|
|
|
@@ -38,6 +40,7 @@ const LETTER = /\p{L}/u;
|
|
|
38
40
|
/** 名前に書かない記号。コードや属性({style="…"}、"key"=)の中の値は、項目の値ではない。 */
|
|
39
41
|
const CODE_MARK = /[{}<>=[\]"`]/u;
|
|
40
42
|
const LATIN_WORD = /^[a-z ]+$/iu;
|
|
43
|
+
const LATIN_LETTER = /^[a-z]$/iu;
|
|
41
44
|
|
|
42
45
|
const lineStartOf = (source: string, offset: number): number => source.lastIndexOf("\n", offset - 1) + 1;
|
|
43
46
|
|
|
@@ -54,6 +57,15 @@ const beforeSeparator = (head: string, separator: string): string | undefined =>
|
|
|
54
57
|
return rest;
|
|
55
58
|
};
|
|
56
59
|
|
|
60
|
+
/** 英字の前置きが語の途中で切れているか(「we agreed that」は「we agreed thatching」の頭ではない)。 */
|
|
61
|
+
const endsInsideWord = (text: string, length: number): boolean => LATIN_LETTER.test(text.charAt(length - 1)) && LATIN_LETTER.test(text.charAt(length));
|
|
62
|
+
|
|
63
|
+
/** 頭の決定の前置きを外した節。 */
|
|
64
|
+
const withoutLead = (clause: string, words: FactWords): string => {
|
|
65
|
+
const lead = words.leads.find((phrase) => clause.toLowerCase().startsWith(phrase.toLowerCase()) && !endsInsideWord(clause, phrase.length));
|
|
66
|
+
return lead === undefined ? clause : clause.slice(lead.length).trimStart();
|
|
67
|
+
};
|
|
68
|
+
|
|
57
69
|
/** 最後の文の切れ目より後ろ。 */
|
|
58
70
|
const afterLastBreak = (text: string): string => {
|
|
59
71
|
const breaks = [...text.matchAll(SENTENCE_BREAK)];
|
|
@@ -97,7 +109,7 @@ const labelledFact = (source: string, value: FactValue, words: FactWords): Fact
|
|
|
97
109
|
for (const separator of words.separators) {
|
|
98
110
|
const before = beforeSeparator(head, separator);
|
|
99
111
|
if (before === undefined) continue;
|
|
100
|
-
const clause = afterLastBreak(before).replace(BLOCK_MARK, "").replace(ITEM_MARK, "");
|
|
112
|
+
const clause = withoutLead(afterLastBreak(before).replace(BLOCK_MARK, "").replace(ITEM_MARK, "").trimStart(), words);
|
|
101
113
|
if (CLAUSE_COMMA.test(clause)) return undefined;
|
|
102
114
|
const label = withoutEdgeMarks(clause);
|
|
103
115
|
const key = keyOf(label, words);
|
package/src/facts/table-facts.ts
CHANGED
|
@@ -11,12 +11,12 @@ import { withoutEdgeMarks } from "./trim-marks.ts";
|
|
|
11
11
|
* 升に値だけを書いたときだけ読む。「3,000円(税込)」のように条件を書いた升は読まない。
|
|
12
12
|
* 行の見出しが値を含むか字を含まない表(日付の列から始まる日程表)は、行に名前が無いので読まない。
|
|
13
13
|
*/
|
|
14
|
-
type Cell = Span & { readonly text: string };
|
|
14
|
+
export type Cell = Span & { readonly text: string };
|
|
15
15
|
|
|
16
16
|
const LETTER = /\p{L}/u;
|
|
17
17
|
const TWO_COLUMNS = 2;
|
|
18
18
|
|
|
19
|
-
const cellsOf = (line: Line): Cell[] => {
|
|
19
|
+
export const cellsOf = (line: Line): Cell[] => {
|
|
20
20
|
const bounds = [-1, ...[...line.text.matchAll(CELL_SEPARATOR)].map((match) => match.index), line.text.length];
|
|
21
21
|
const cells = bounds.slice(1).map((end, index) => {
|
|
22
22
|
const from = (bounds[index] ?? 0) + 1;
|
|
@@ -29,7 +29,7 @@ const cellsOf = (line: Line): Cell[] => {
|
|
|
29
29
|
const plain = withoutEdgeMarks;
|
|
30
30
|
|
|
31
31
|
/** 区切り行(|---|)の前の行が見出し、後ろに続く | の行が本体。 */
|
|
32
|
-
const tablesOf = (lines: readonly Line[]): { header: Line; rows: Line[] }[] =>
|
|
32
|
+
export const tablesOf = (lines: readonly Line[]): { header: Line; rows: Line[] }[] =>
|
|
33
33
|
lines.flatMap((line, index) => {
|
|
34
34
|
const header = lines[index - 1];
|
|
35
35
|
if (!TABLE_RULE.test(line.text) || header === undefined || !header.text.includes("|")) return [];
|
|
@@ -69,3 +69,6 @@ export const tableFacts = (source: string, values: readonly FactValue[]): Fact[]
|
|
|
69
69
|
const headings = cellsOf(table.header).map((cell) => plain(cell.text));
|
|
70
70
|
return table.rows.flatMap((row) => rowFacts(row, headings, values, source));
|
|
71
71
|
});
|
|
72
|
+
|
|
73
|
+
/** 文書の表すべての、本体の行の升(見出しの行を除く)。text は書いたまま。 */
|
|
74
|
+
export const tableBodyCells = (source: string): Cell[] => tablesOf(linesOf(source)).flatMap((table) => table.rows.flatMap(cellsOf));
|
package/src/grade/ai-score.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type GradeAiScore = {
|
|
|
8
8
|
readonly notScored: NotScored["reason"] | null;
|
|
9
9
|
readonly signs: number;
|
|
10
10
|
readonly compared: number;
|
|
11
|
-
/** The signs that counted: rule ids,
|
|
11
|
+
/** The signs that counted: rule ids, structure measures as structure:<id>, and ai-generated-composite:strict. */
|
|
12
12
|
readonly shown: readonly string[];
|
|
13
13
|
};
|
|
14
14
|
|
package/src/grade/text.ts
CHANGED
|
@@ -103,7 +103,7 @@ const aside = (open: string, inner: string, close: string): string => (inner ===
|
|
|
103
103
|
export const GRADE_TEXT: Texts<GradeText> = {
|
|
104
104
|
ja: {
|
|
105
105
|
usage:
|
|
106
|
-
"使い方: chaff grade <items.jsonl> [--out <results.jsonl>] [--baseline <前の results.jsonl>] [--variant-key <欄の名前>] [--format text|json|markdown] [--json] [--compact] [--experimental] [--genre <ジャンル>]",
|
|
106
|
+
"使い方: chaff grade <items.jsonl> [--out <results.jsonl>] [--baseline <前の results.jsonl>] [--allow-stamp-mismatch] [--variant-key <欄の名前>] [--format text|json|markdown] [--json] [--compact] [--experimental] [--genre <ジャンル>]",
|
|
107
107
|
noReference: "reference が無い(事実は reference と照らす)",
|
|
108
108
|
noCitations: "citations が無い(chaff は出力から引用を推測しない)",
|
|
109
109
|
noContexts: "contexts が無い(回答の事実は、検索で取った一節と照らす)",
|
|
@@ -135,7 +135,7 @@ export const GRADE_TEXT: Texts<GradeText> = {
|
|
|
135
135
|
},
|
|
136
136
|
en: {
|
|
137
137
|
usage:
|
|
138
|
-
"usage: chaff grade <items.jsonl> [--out <results.jsonl>] [--baseline <earlier results.jsonl>] [--variant-key <field>] [--format text|json|markdown] [--json] [--compact] [--experimental] [--genre <genre>]",
|
|
138
|
+
"usage: chaff grade <items.jsonl> [--out <results.jsonl>] [--baseline <earlier results.jsonl>] [--allow-stamp-mismatch] [--variant-key <field>] [--format text|json|markdown] [--json] [--compact] [--experimental] [--genre <genre>]",
|
|
139
139
|
noReference: "no reference given (facts are checked against a reference)",
|
|
140
140
|
noCitations: "no citations given (chaff does not guess quotations from the output)",
|
|
141
141
|
noContexts: "no contexts given (the output's facts are checked against retrieved passages)",
|
package/src/heading-numbering.ts
CHANGED
|
@@ -11,8 +11,8 @@ const ARABIC = "[0-90-9]+";
|
|
|
11
11
|
const KANJI = "[一二三四五六七八九十百]+";
|
|
12
12
|
const ROMAN = "[IVXⅠ-Ⅻ]+";
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
const WORDS_FOLLOW =
|
|
14
|
+
/** 番号の後ろに続く見出しの言葉の頭。字か、コードや引用の開き(`check()`、「概要」)で始まる。「8.2.3 (2026-08-06)」の版や「3 reasons」の数量は番号と読まない。 */
|
|
15
|
+
const WORDS_FOLLOW = '(?=\\s*[\\p{L}`「『“"])';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* 字だけで決まる書き方。上から順に試す。ラテン文字一字とローマ数字(A. と II.)は同じ書き方とする。どちらも番号の後ろに言葉が続くときだけ。
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Fetches a page as text, in the encoding it declares, with a timeout. A non-2xx answer throws an error whose cause
|
|
2
|
+
// carries the HTTP status, so a caller can tell a dead page (404) from a transient one (503). Every error names the URL.
|
|
3
|
+
import { decodeFetched } from "./fetched-text.ts";
|
|
4
|
+
|
|
5
|
+
export class HttpStatusError extends Error {
|
|
6
|
+
readonly status: number;
|
|
7
|
+
|
|
8
|
+
constructor(status: number) {
|
|
9
|
+
super(`HTTP ${String(status)}`);
|
|
10
|
+
this.status = status;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** The page's text and the Content-Type it was sent with (null when it had none). */
|
|
15
|
+
export type FetchedPage = { readonly text: string; readonly contentType: string | null };
|
|
16
|
+
|
|
17
|
+
/** What fetches: the global fetch, or a stand-in in tests. */
|
|
18
|
+
export type Fetcher = (url: string, init: { readonly signal: AbortSignal }) => Promise<Response>;
|
|
19
|
+
|
|
20
|
+
export type FetchLimits = {
|
|
21
|
+
readonly timeout_ms: number;
|
|
22
|
+
/** A body longer than this is refused while it is read, before it is decoded. Undefined: no limit. */
|
|
23
|
+
readonly max_bytes?: number | undefined;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const tooLarge = (max_bytes: number): Error => new Error(`the page is larger than ${String(max_bytes)} bytes`);
|
|
27
|
+
|
|
28
|
+
/** A read that gave bytes; a finished read (done) is not one. */
|
|
29
|
+
const isChunk = (read: unknown): read is { readonly value: Uint8Array } =>
|
|
30
|
+
typeof read === "object" && read !== null && Reflect.get(read, "done") !== true && Reflect.get(read, "value") instanceof Uint8Array;
|
|
31
|
+
|
|
32
|
+
/** The body's bytes, stopping as soon as they pass max_bytes. */
|
|
33
|
+
const bodyBytes = async (response: Response, max_bytes: number | undefined): Promise<Uint8Array> => {
|
|
34
|
+
if (max_bytes === undefined || response.body === null) return new Uint8Array(await response.arrayBuffer());
|
|
35
|
+
const declared = Number(response.headers.get("content-length") ?? Number.NaN);
|
|
36
|
+
if (declared > max_bytes) throw tooLarge(max_bytes);
|
|
37
|
+
const reader = response.body.getReader();
|
|
38
|
+
const chunks: Uint8Array[] = [];
|
|
39
|
+
let size = 0;
|
|
40
|
+
for (let read: unknown = await reader.read(); isChunk(read); read = await reader.read()) {
|
|
41
|
+
size += read.value.byteLength;
|
|
42
|
+
if (size > max_bytes) {
|
|
43
|
+
await reader.cancel();
|
|
44
|
+
throw tooLarge(max_bytes);
|
|
45
|
+
}
|
|
46
|
+
chunks.push(read.value);
|
|
47
|
+
}
|
|
48
|
+
return Buffer.concat(chunks);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const fetchPage = async (url: string, limits: FetchLimits, fetcher: Fetcher = fetch): Promise<FetchedPage> => {
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
const timer = setTimeout(() => controller.abort(), limits.timeout_ms);
|
|
54
|
+
try {
|
|
55
|
+
const response = await fetcher(url, { signal: controller.signal });
|
|
56
|
+
if (!response.ok) throw new HttpStatusError(response.status);
|
|
57
|
+
const contentType = response.headers.get("content-type");
|
|
58
|
+
return { text: decodeFetched(await bodyBytes(response, limits.max_bytes), contentType), contentType };
|
|
59
|
+
} catch (err) {
|
|
60
|
+
throw new Error(`${url}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
61
|
+
} finally {
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// The text of a fetched body in the encoding it declares: the Content-Type header first, then a <meta charset> or an
|
|
2
|
+
// XML declaration near the top of an HTML or XML body, otherwise UTF-8. Many Japanese government pages are still
|
|
3
|
+
// Shift_JIS. Pure.
|
|
4
|
+
|
|
5
|
+
/** How far into the body a declaration is looked for; HTML requires <meta charset> within the first 1024 bytes. */
|
|
6
|
+
const DECLARATION_BYTES = 1024;
|
|
7
|
+
|
|
8
|
+
const CHARSET = /charset\s*=\s*["']?([\w.:-]+)/iu;
|
|
9
|
+
|
|
10
|
+
const declaredInHead = (head: string): string | undefined =>
|
|
11
|
+
/<meta\b[^>]*\bcharset\s*=\s*["']?([\w.:-]+)/iu.exec(head)?.[1] ?? /^\s*<\?xml\b[^>]*\bencoding\s*=\s*["']([\w.:-]+)["']/iu.exec(head)?.[1];
|
|
12
|
+
|
|
13
|
+
/** Only a markup body can declare its own encoding; Markdown or JSON that quotes a <meta> tag declares nothing. */
|
|
14
|
+
const isMarkup = (contentType: string | null): boolean => contentType === null || /html|xml/iu.test(contentType);
|
|
15
|
+
|
|
16
|
+
/** The label the body declares, lower-cased, or "utf-8" when it declares none. */
|
|
17
|
+
export const charsetOf = (contentType: string | null, head: string): string =>
|
|
18
|
+
(CHARSET.exec(contentType ?? "")?.[1] ?? (isMarkup(contentType) ? declaredInHead(head) : undefined) ?? "utf-8").toLowerCase();
|
|
19
|
+
|
|
20
|
+
const decoderFor = (label: string): TextDecoder => {
|
|
21
|
+
try {
|
|
22
|
+
return new TextDecoder(label);
|
|
23
|
+
} catch {
|
|
24
|
+
return new TextDecoder("utf-8");
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** An unknown label is read as UTF-8, as before a declaration was looked for. */
|
|
29
|
+
export const decodeFetched = (bytes: Uint8Array, contentType: string | null): string => {
|
|
30
|
+
const head = new TextDecoder("latin1").decode(bytes.subarray(0, DECLARATION_BYTES));
|
|
31
|
+
return decoderFor(charsetOf(contentType, head)).decode(bytes);
|
|
32
|
+
};
|