@postalsys/email-content 0.0.4 → 0.1.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/README.md +207 -17
- package/dist/.tsbuildinfo +1 -1
- package/dist/analyze.d.ts +55 -15
- package/dist/analyze.d.ts.map +1 -1
- package/dist/analyze.js +264 -61
- package/dist/analyze.js.map +1 -1
- package/dist/canonical/html.d.ts +21 -2
- package/dist/canonical/html.d.ts.map +1 -1
- package/dist/canonical/html.js +213 -14
- package/dist/canonical/html.js.map +1 -1
- package/dist/classify/confidence.d.ts +12 -0
- package/dist/classify/confidence.d.ts.map +1 -1
- package/dist/classify/confidence.js +54 -4
- package/dist/classify/confidence.js.map +1 -1
- package/dist/classify/reconcile.d.ts +25 -17
- package/dist/classify/reconcile.d.ts.map +1 -1
- package/dist/classify/reconcile.js +52 -20
- package/dist/classify/reconcile.js.map +1 -1
- package/dist/cli/annotate.d.ts.map +1 -1
- package/dist/cli/annotate.js +6 -3
- package/dist/cli/annotate.js.map +1 -1
- package/dist/cli/args.d.ts +14 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +48 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/benchmark.d.ts +39 -0
- package/dist/cli/benchmark.d.ts.map +1 -1
- package/dist/cli/benchmark.js +179 -66
- package/dist/cli/benchmark.js.map +1 -1
- package/dist/cli/corpus.d.ts.map +1 -1
- package/dist/cli/corpus.js +13 -8
- package/dist/cli/corpus.js.map +1 -1
- package/dist/cli/disagreements.d.ts.map +1 -1
- package/dist/cli/disagreements.js +7 -4
- package/dist/cli/disagreements.js.map +1 -1
- package/dist/cli/evaluate.d.ts.map +1 -1
- package/dist/cli/evaluate.js +34 -10
- package/dist/cli/evaluate.js.map +1 -1
- package/dist/cli/extract.d.ts.map +1 -1
- package/dist/cli/extract.js +8 -3
- package/dist/cli/extract.js.map +1 -1
- package/dist/cli/main.js +8 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/corpus/scanner.d.ts +9 -1
- package/dist/corpus/scanner.d.ts.map +1 -1
- package/dist/corpus/scanner.js +52 -13
- package/dist/corpus/scanner.js.map +1 -1
- package/dist/corpus/store.d.ts +33 -2
- package/dist/corpus/store.d.ts.map +1 -1
- package/dist/corpus/store.js +64 -4
- package/dist/corpus/store.js.map +1 -1
- package/dist/detect/patterns.d.ts +29 -0
- package/dist/detect/patterns.d.ts.map +1 -1
- package/dist/detect/patterns.js +80 -6
- package/dist/detect/patterns.js.map +1 -1
- package/dist/detect/reply-header.d.ts +14 -0
- package/dist/detect/reply-header.d.ts.map +1 -1
- package/dist/detect/reply-header.js +80 -37
- package/dist/detect/reply-header.js.map +1 -1
- package/dist/eval/oracle.d.ts +80 -0
- package/dist/eval/oracle.d.ts.map +1 -0
- package/dist/eval/oracle.js +250 -0
- package/dist/eval/oracle.js.map +1 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +94 -56
- package/dist/index.js.map +1 -1
- package/dist/mime/model.d.ts +28 -3
- package/dist/mime/model.d.ts.map +1 -1
- package/dist/mime/model.js +41 -1
- package/dist/mime/model.js.map +1 -1
- package/dist/mime/parse.d.ts.map +1 -1
- package/dist/mime/parse.js +19 -2
- package/dist/mime/parse.js.map +1 -1
- package/dist/mime/select.d.ts +71 -0
- package/dist/mime/select.d.ts.map +1 -0
- package/dist/mime/select.js +198 -0
- package/dist/mime/select.js.map +1 -0
- package/dist/segment/html-blocks.d.ts +1 -1
- package/dist/segment/html-blocks.d.ts.map +1 -1
- package/dist/segment/html-blocks.js +77 -8
- package/dist/segment/html-blocks.js.map +1 -1
- package/dist/segment/text-blocks.d.ts.map +1 -1
- package/dist/segment/text-blocks.js +18 -1
- package/dist/segment/text-blocks.js.map +1 -1
- package/dist/segment/types.d.ts +14 -0
- package/dist/segment/types.d.ts.map +1 -1
- package/dist/types.d.ts +132 -11
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +37 -3
- package/dist/types.js.map +1 -1
- package/dist/util/worker-pool.d.ts +21 -0
- package/dist/util/worker-pool.d.ts.map +1 -1
- package/dist/util/worker-pool.js +61 -13
- package/dist/util/worker-pool.js.map +1 -1
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/canonical/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgDH
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/canonical/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgDH;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAoBpD;AA2FD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmIpD;AAED,yFAAyF;AACzF,MAAM,WAAW,SAAS;IACtB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,0FAA0F;IAC1F,gBAAgB,EAAE,OAAO,CAAC;CAC7B;AAyBD,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAqBvD"}
|
package/dist/canonical/html.js
CHANGED
|
@@ -57,12 +57,18 @@ const NAMED_ENTITIES = {
|
|
|
57
57
|
zwnj: '',
|
|
58
58
|
zwj: ''
|
|
59
59
|
};
|
|
60
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* Decode HTML entities. Unknown entities are left as written rather than dropped.
|
|
62
|
+
*
|
|
63
|
+
* Both alternatives are length bounded so the pass stays linear on hostile input: a numeric
|
|
64
|
+
* reference longer than twelve digits cannot name a code point, and an unbounded `+` there would
|
|
65
|
+
* backtrack across the whole run of digits that follows an unterminated `&#`.
|
|
66
|
+
*/
|
|
61
67
|
function decodeEntities(input) {
|
|
62
68
|
if (!input.includes('&')) {
|
|
63
69
|
return input;
|
|
64
70
|
}
|
|
65
|
-
return input.replace(/&(#[xX]?[0-9a-fA-F]
|
|
71
|
+
return input.replace(/&(#[xX]?[0-9a-fA-F]{1,12}|[a-zA-Z][a-zA-Z0-9]{1,31});/g, (whole, body) => {
|
|
66
72
|
if (body.charCodeAt(0) === 35) {
|
|
67
73
|
const isHex = body[1] === 'x' || body[1] === 'X';
|
|
68
74
|
const code = parseInt(isHex ? body.slice(2) : body.slice(1), isHex ? 16 : 10);
|
|
@@ -80,26 +86,219 @@ function decodeEntities(input) {
|
|
|
80
86
|
return named === undefined ? whole : named;
|
|
81
87
|
});
|
|
82
88
|
}
|
|
83
|
-
/** Elements whose content is never
|
|
84
|
-
const
|
|
89
|
+
/** Elements whose content is code rather than prose, and must never reach the projection. */
|
|
90
|
+
const RAW_TEXT_TAGS = new Set(['script', 'style']);
|
|
91
|
+
/** Elements whose content is not rendered in the body, but is still prose if the close tag is lost. */
|
|
92
|
+
const HIDDEN_TAGS = new Set(['head', 'title', 'noscript', 'template']);
|
|
85
93
|
/** Elements that introduce a line break in the text projection. */
|
|
86
|
-
const
|
|
94
|
+
const BLOCK_BREAK_TAGS = new Set([
|
|
95
|
+
'p',
|
|
96
|
+
'div',
|
|
97
|
+
'br',
|
|
98
|
+
'tr',
|
|
99
|
+
'li',
|
|
100
|
+
'h1',
|
|
101
|
+
'h2',
|
|
102
|
+
'h3',
|
|
103
|
+
'h4',
|
|
104
|
+
'h5',
|
|
105
|
+
'h6',
|
|
106
|
+
'table',
|
|
107
|
+
'blockquote',
|
|
108
|
+
'pre',
|
|
109
|
+
'hr',
|
|
110
|
+
'section',
|
|
111
|
+
'article',
|
|
112
|
+
'ul',
|
|
113
|
+
'ol',
|
|
114
|
+
'dd',
|
|
115
|
+
'dt'
|
|
116
|
+
]);
|
|
117
|
+
/**
|
|
118
|
+
* Longest markup construct scanned before the opening `<` is given up on.
|
|
119
|
+
*
|
|
120
|
+
* Real tags are far shorter. The cap exists so that a document consisting of `<` characters with no
|
|
121
|
+
* closing delimiter cannot make the scanner re-read the suffix once per `<`.
|
|
122
|
+
*/
|
|
123
|
+
const MAX_TAG_LENGTH = 8192;
|
|
124
|
+
const CLOSE_TAG_CACHE = new Map();
|
|
125
|
+
function closeTagRegex(name) {
|
|
126
|
+
let regex = CLOSE_TAG_CACHE.get(name);
|
|
127
|
+
if (!regex) {
|
|
128
|
+
// Global, so the search can be positioned with lastIndex. Slicing the remainder instead
|
|
129
|
+
// would copy the rest of the document once per script or style element, which is quadratic
|
|
130
|
+
// on a body full of them.
|
|
131
|
+
regex = new RegExp(`</${name}(?:\\s[^>]*)?>`, 'gi');
|
|
132
|
+
CLOSE_TAG_CACHE.set(name, regex);
|
|
133
|
+
}
|
|
134
|
+
return regex;
|
|
135
|
+
}
|
|
136
|
+
function isNameStart(code) {
|
|
137
|
+
return (code >= 97 && code <= 122) || (code >= 65 && code <= 90);
|
|
138
|
+
}
|
|
139
|
+
function isNameChar(code) {
|
|
140
|
+
return isNameStart(code) || (code >= 48 && code <= 57) || code === 45 || code === 58 || code === 95;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* End of a tag that opens at `from`, or -1 when no unquoted `>` appears within the cap.
|
|
144
|
+
*
|
|
145
|
+
* Quoted attribute values are tracked, so `<a title="a>b">` is one tag rather than a tag plus the
|
|
146
|
+
* stray text `b">`.
|
|
147
|
+
*/
|
|
148
|
+
function tagEnd(html, from) {
|
|
149
|
+
const limit = Math.min(html.length, from + MAX_TAG_LENGTH);
|
|
150
|
+
let quote = 0;
|
|
151
|
+
for (let i = from; i < limit; i++) {
|
|
152
|
+
const code = html.charCodeAt(i);
|
|
153
|
+
if (quote) {
|
|
154
|
+
if (code === quote) {
|
|
155
|
+
quote = 0;
|
|
156
|
+
}
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (code === 34 || code === 39) {
|
|
160
|
+
quote = code;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (code === 62) {
|
|
164
|
+
return i;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return -1;
|
|
168
|
+
}
|
|
87
169
|
/**
|
|
88
170
|
* Cheap text projection of an HTML body.
|
|
89
171
|
*
|
|
90
172
|
* Good enough for language estimation, marker detection and length statistics. It is not a
|
|
91
173
|
* replacement for the extraction pipeline's DOM walk, and it deliberately keeps blank lines so that
|
|
92
|
-
* paragraph structure survives.
|
|
174
|
+
* paragraph structure survives. It is emphatically **not** a sanitiser: it produces a non executing
|
|
175
|
+
* textual view, and says nothing about whether the source markup is safe to render.
|
|
176
|
+
*
|
|
177
|
+
* Written as a character scanner rather than a chain of regular expressions because the obvious
|
|
178
|
+
* `/<[^>]*>/g` form is quadratic on unmatched `<`: every one of them rescans to end of input looking
|
|
179
|
+
* for a closing delimiter that is not there. Measured at 5.8 seconds on 128k `<` characters, and
|
|
180
|
+
* doubling the input quadrupled it. This is the projection the malformed HTML fallback uses, so it
|
|
181
|
+
* is reached by exactly the input that triggers the quadratic case.
|
|
182
|
+
*
|
|
183
|
+
* Every code unit is visited a constant number of times. A construct that never closes is charged
|
|
184
|
+
* to the input it covers: the scanned window is emitted as visible text and the cursor moves past
|
|
185
|
+
* it, rather than resuming one character later and reading the same suffix again. Emitting it keeps
|
|
186
|
+
* the projection on the safe side of the project's asymmetry, and matches what the previous regular
|
|
187
|
+
* expression did with an unterminated trailing tag.
|
|
93
188
|
*/
|
|
94
189
|
function stripTagsToText(html) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
190
|
+
const out = [];
|
|
191
|
+
const length = html.length;
|
|
192
|
+
let i = 0;
|
|
193
|
+
// Closing delimiter memos. The cursor only moves forward, so once a search for a closer finds
|
|
194
|
+
// nothing after some position it will find nothing after any later position either. Without
|
|
195
|
+
// this, a document of unterminated `<!--` openers searches the whole suffix once per opener,
|
|
196
|
+
// which is the same quadratic shape the tag stripper was rewritten to remove.
|
|
197
|
+
let noCommentClose = false;
|
|
198
|
+
const noRawClose = new Set();
|
|
199
|
+
while (i < length) {
|
|
200
|
+
const lt = html.indexOf('<', i);
|
|
201
|
+
if (lt === -1) {
|
|
202
|
+
out.push(html.slice(i));
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
if (lt > i) {
|
|
206
|
+
out.push(html.slice(i, lt));
|
|
207
|
+
}
|
|
208
|
+
const next = html.charCodeAt(lt + 1);
|
|
209
|
+
// Comments and declarations.
|
|
210
|
+
if (next === 33) {
|
|
211
|
+
if (html.startsWith('<!--', lt)) {
|
|
212
|
+
const close = noCommentClose ? -1 : html.indexOf('-->', lt + 4);
|
|
213
|
+
if (close === -1) {
|
|
214
|
+
noCommentClose = true;
|
|
215
|
+
// Unterminated. Keep the body as text: showing a comment is a cosmetic fault,
|
|
216
|
+
// hiding the rest of a message because one comment was never closed is not.
|
|
217
|
+
out.push(' ');
|
|
218
|
+
i = lt + 4;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
out.push(' ');
|
|
222
|
+
i = close + 3;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
// Doctypes, CDATA, and the downlevel-revealed conditional comments Word emits around
|
|
226
|
+
// every bullet list: <![if !supportLists]>. Those are not HTML comments and survived
|
|
227
|
+
// both the comment strip and the tag strip, so they appeared verbatim in extracted text.
|
|
228
|
+
const close = tagEnd(html, lt + 2);
|
|
229
|
+
if (close === -1) {
|
|
230
|
+
out.push(html.slice(lt, Math.min(length, lt + MAX_TAG_LENGTH)));
|
|
231
|
+
i = Math.min(length, lt + MAX_TAG_LENGTH);
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
out.push(' ');
|
|
235
|
+
i = close + 1;
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
// Processing instructions, including the <?xml ... ?> prologue Word emits.
|
|
239
|
+
if (next === 63) {
|
|
240
|
+
const close = tagEnd(html, lt + 2);
|
|
241
|
+
if (close === -1) {
|
|
242
|
+
out.push(html.slice(lt, Math.min(length, lt + MAX_TAG_LENGTH)));
|
|
243
|
+
i = Math.min(length, lt + MAX_TAG_LENGTH);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
out.push(' ');
|
|
247
|
+
i = close + 1;
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
const closing = next === 47;
|
|
251
|
+
const nameStart = closing ? lt + 2 : lt + 1;
|
|
252
|
+
if (!isNameStart(html.charCodeAt(nameStart))) {
|
|
253
|
+
// Not markup at all: a bare "<" in prose, "a < b", "<3". Visible text.
|
|
254
|
+
out.push('<');
|
|
255
|
+
i = lt + 1;
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
let nameEnd = nameStart;
|
|
259
|
+
while (nameEnd < length && isNameChar(html.charCodeAt(nameEnd))) {
|
|
260
|
+
nameEnd++;
|
|
261
|
+
}
|
|
262
|
+
const name = html.slice(nameStart, nameEnd).toLowerCase();
|
|
263
|
+
const close = tagEnd(html, nameEnd);
|
|
264
|
+
if (close === -1) {
|
|
265
|
+
out.push(html.slice(lt, Math.min(length, lt + MAX_TAG_LENGTH)));
|
|
266
|
+
i = Math.min(length, lt + MAX_TAG_LENGTH);
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (!closing && (RAW_TEXT_TAGS.has(name) || HIDDEN_TAGS.has(name))) {
|
|
270
|
+
let match = null;
|
|
271
|
+
if (!noRawClose.has(name)) {
|
|
272
|
+
const regex = closeTagRegex(name);
|
|
273
|
+
regex.lastIndex = close + 1;
|
|
274
|
+
match = regex.exec(html);
|
|
275
|
+
if (!match) {
|
|
276
|
+
noRawClose.add(name);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (match) {
|
|
280
|
+
out.push(' ');
|
|
281
|
+
i = match.index + match[0].length;
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
if (RAW_TEXT_TAGS.has(name)) {
|
|
285
|
+
// A script or style that is never closed swallows the rest of the document in a
|
|
286
|
+
// renderer too, and its body is code, not authored prose.
|
|
287
|
+
out.push(' ');
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
// head/title/noscript/template with no close tag: drop only the opening tag, so that
|
|
291
|
+
// whatever follows stays visible.
|
|
292
|
+
out.push(' ');
|
|
293
|
+
i = close + 1;
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
if (BLOCK_BREAK_TAGS.has(name)) {
|
|
297
|
+
out.push('\n');
|
|
298
|
+
}
|
|
299
|
+
i = close + 1;
|
|
300
|
+
}
|
|
301
|
+
let text = out.join('');
|
|
103
302
|
text = decodeEntities(text);
|
|
104
303
|
text = text.replace(/\r\n?/g, '\n');
|
|
105
304
|
// Includes U+00A0, which arrives constantly as and must collapse like a normal space.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/canonical/html.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/canonical/html.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,18 @@ export interface ConfidenceConfig {
|
|
|
15
15
|
minAnchorStrength: number;
|
|
16
16
|
}
|
|
17
17
|
export declare const DEFAULT_CONFIDENCE: ConfidenceConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Validate caller supplied confidence thresholds and fill in the defaults.
|
|
20
|
+
*
|
|
21
|
+
* Rejects, never clamps. Clamping hides a configuration mistake and makes the pipeline behave
|
|
22
|
+
* differently from what the caller asked for, on every message, silently. `NaN` is the case that
|
|
23
|
+
* matters most: every comparison against it is false, so a `NaN` threshold does not merely shift
|
|
24
|
+
* behaviour, it makes the visibility bands stop working while everything still looks fine.
|
|
25
|
+
*
|
|
26
|
+
* Takes a partial. The previous signature required a complete object, so a caller wanting to move
|
|
27
|
+
* one threshold had to copy the other two and then own them forever.
|
|
28
|
+
*/
|
|
29
|
+
export declare function validateConfidenceConfig(input?: Partial<ConfidenceConfig>): ConfidenceConfig;
|
|
18
30
|
/**
|
|
19
31
|
* Map a label and confidence to a visibility band.
|
|
20
32
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confidence.d.ts","sourceRoot":"","sources":["../../src/classify/confidence.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"confidence.d.ts","sourceRoot":"","sources":["../../src/classify/confidence.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAsB,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3E,MAAM,WAAW,gBAAgB;IAC7B,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iEAAiE;IACjE,iBAAiB,EAAE,MAAM,CAAC;CAC7B;AAED,eAAO,MAAM,kBAAkB,EAAE,gBAIhC,CAAC;AASF;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CA6B5F;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAE,gBAAqC,GAAG,UAAU,CAkBzH;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,EAAE,GAAG,MAAM,CAU9G"}
|
|
@@ -8,13 +8,59 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.DEFAULT_CONFIDENCE = void 0;
|
|
11
|
+
exports.validateConfidenceConfig = validateConfidenceConfig;
|
|
11
12
|
exports.visibilityFor = visibilityFor;
|
|
12
13
|
exports.overallConfidence = overallConfidence;
|
|
14
|
+
const types_1 = require("../types");
|
|
13
15
|
exports.DEFAULT_CONFIDENCE = {
|
|
14
16
|
hideThreshold: 0.95,
|
|
15
17
|
collapseThreshold: 0.75,
|
|
16
18
|
minAnchorStrength: 0.85
|
|
17
19
|
};
|
|
20
|
+
function requireUnitInterval(value, option) {
|
|
21
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0 || value > 1) {
|
|
22
|
+
throw new types_1.ConfigurationError(option, 'a finite number between 0 and 1');
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validate caller supplied confidence thresholds and fill in the defaults.
|
|
28
|
+
*
|
|
29
|
+
* Rejects, never clamps. Clamping hides a configuration mistake and makes the pipeline behave
|
|
30
|
+
* differently from what the caller asked for, on every message, silently. `NaN` is the case that
|
|
31
|
+
* matters most: every comparison against it is false, so a `NaN` threshold does not merely shift
|
|
32
|
+
* behaviour, it makes the visibility bands stop working while everything still looks fine.
|
|
33
|
+
*
|
|
34
|
+
* Takes a partial. The previous signature required a complete object, so a caller wanting to move
|
|
35
|
+
* one threshold had to copy the other two and then own them forever.
|
|
36
|
+
*/
|
|
37
|
+
function validateConfidenceConfig(input) {
|
|
38
|
+
if (input === undefined || input === null) {
|
|
39
|
+
return exports.DEFAULT_CONFIDENCE;
|
|
40
|
+
}
|
|
41
|
+
if (typeof input !== 'object') {
|
|
42
|
+
throw new types_1.ConfigurationError('confidence', 'an object');
|
|
43
|
+
}
|
|
44
|
+
const config = { ...exports.DEFAULT_CONFIDENCE };
|
|
45
|
+
if (input.hideThreshold !== undefined) {
|
|
46
|
+
config.hideThreshold = requireUnitInterval(input.hideThreshold, 'confidence.hideThreshold');
|
|
47
|
+
}
|
|
48
|
+
if (input.collapseThreshold !== undefined) {
|
|
49
|
+
config.collapseThreshold = requireUnitInterval(input.collapseThreshold, 'confidence.collapseThreshold');
|
|
50
|
+
}
|
|
51
|
+
if (input.minAnchorStrength !== undefined) {
|
|
52
|
+
config.minAnchorStrength = requireUnitInterval(input.minAnchorStrength, 'confidence.minAnchorStrength');
|
|
53
|
+
}
|
|
54
|
+
// Inverted bands would make `collapse` unreachable and turn every collapse decision into a
|
|
55
|
+
// hide, which is the direction that loses content.
|
|
56
|
+
if (config.collapseThreshold > config.hideThreshold) {
|
|
57
|
+
throw new types_1.ConfigurationError('confidence.collapseThreshold', 'less than or equal to confidence.hideThreshold', 'inverted_thresholds');
|
|
58
|
+
}
|
|
59
|
+
// `minAnchorStrength` is deliberately not compared against either threshold. Anchor strength
|
|
60
|
+
// measures how good the structural evidence is; the thresholds measure how confident the
|
|
61
|
+
// classification is. They are different dimensions and ordering them would be meaningless.
|
|
62
|
+
return config;
|
|
63
|
+
}
|
|
18
64
|
/**
|
|
19
65
|
* Map a label and confidence to a visibility band.
|
|
20
66
|
*
|
|
@@ -50,10 +96,14 @@ function visibilityFor(label, confidence, config = exports.DEFAULT_CONFIDENCE) {
|
|
|
50
96
|
* blocks mask one risky decision, and the risky decision is the one that loses content.
|
|
51
97
|
*/
|
|
52
98
|
function overallConfidence(decisions) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
99
|
+
// A loop, not `Math.min(...)`: spreading a segment array into a call passes one argument per
|
|
100
|
+
// element and blows V8's argument limit on a large enough message.
|
|
101
|
+
let lowest = Infinity;
|
|
102
|
+
for (const decision of decisions) {
|
|
103
|
+
if (decision.visibility !== 'show' && decision.confidence < lowest) {
|
|
104
|
+
lowest = decision.confidence;
|
|
105
|
+
}
|
|
56
106
|
}
|
|
57
|
-
return
|
|
107
|
+
return lowest === Infinity ? 1 : lowest;
|
|
58
108
|
}
|
|
59
109
|
//# sourceMappingURL=confidence.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confidence.js","sourceRoot":"","sources":["../../src/classify/confidence.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;
|
|
1
|
+
{"version":3,"file":"confidence.js","sourceRoot":"","sources":["../../src/classify/confidence.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,43 +10,51 @@
|
|
|
10
10
|
* The plain part is still classified independently, and its verdict is used two ways: to confirm,
|
|
11
11
|
* which raises nothing but costs nothing, and to contradict, which caps confidence so that a
|
|
12
12
|
* disputed region is collapsed rather than hidden.
|
|
13
|
+
*
|
|
14
|
+
* Selection runs *before* classification, and that ordering is load bearing. A message can hold
|
|
15
|
+
* several independent body sections, and the classifier has to see all of them as one linear
|
|
16
|
+
* sequence for its positional rules to mean anything. Choosing the representation first is what
|
|
17
|
+
* makes that possible, and it is possible because selection needs only length, anchor presence and
|
|
18
|
+
* whether segmentation degraded. None of those are labels. See
|
|
19
|
+
* `docs/adr-001-document-global-classification.md`.
|
|
13
20
|
*/
|
|
14
21
|
import { type Representation } from '../types';
|
|
22
|
+
import { type Block } from '../segment/types';
|
|
15
23
|
import { type BlockDecision } from './rules';
|
|
16
|
-
|
|
24
|
+
/** One representation of one body section, before any classification has run. */
|
|
25
|
+
export interface RepresentationInfo {
|
|
17
26
|
representation: Representation;
|
|
18
|
-
|
|
27
|
+
blocks: Block[];
|
|
19
28
|
/** Total characters of authored content, used to spot a stub representation. */
|
|
20
29
|
contentChars: number;
|
|
21
30
|
/** True when the representation contains at least one structural anchor. */
|
|
22
31
|
hasAnchor: boolean;
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
blockIndex: number;
|
|
26
|
-
containment: number;
|
|
27
|
-
exact: boolean;
|
|
28
|
-
isParent: boolean;
|
|
29
|
-
}[];
|
|
32
|
+
/** True when segmentation failed and the representation is one unclassified block. */
|
|
33
|
+
degraded: boolean;
|
|
30
34
|
}
|
|
31
|
-
export interface
|
|
32
|
-
primary:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
export interface PrimaryChoice {
|
|
36
|
+
primary: RepresentationInfo;
|
|
37
|
+
/** The other representation of the same section, when it is worth cross checking against. */
|
|
38
|
+
secondary: RepresentationInfo | null;
|
|
35
39
|
}
|
|
36
40
|
/**
|
|
37
|
-
* Choose which representation drives the output.
|
|
41
|
+
* Choose which representation of one section drives the output.
|
|
38
42
|
*
|
|
39
43
|
* HTML wins by default when both exist, because it is where the structure survives. Plain text
|
|
40
44
|
* wins when the HTML is a stub, which happens with clients that send a token HTML wrapper around a
|
|
41
45
|
* text body, and when only the plain part has an anchor.
|
|
42
46
|
*/
|
|
43
|
-
export declare function pickPrimary(text:
|
|
47
|
+
export declare function pickPrimary(text: RepresentationInfo | null, html: RepresentationInfo | null): PrimaryChoice;
|
|
44
48
|
/**
|
|
45
|
-
* Apply cross representation evidence to
|
|
49
|
+
* Apply cross representation evidence to one section's decisions, in place.
|
|
46
50
|
*
|
|
47
51
|
* The only adjustment made is downward. Raising confidence because the other representation agrees
|
|
48
52
|
* would let two copies of the same mistake reinforce each other, and the cost of a wrong hide is
|
|
49
53
|
* much higher than the cost of a collapse that could have been a hide.
|
|
54
|
+
*
|
|
55
|
+
* Scoped to one section on purpose. The comparison only means something between two renderings of
|
|
56
|
+
* the same content; measuring one section against another section's alternative would compare
|
|
57
|
+
* unrelated things.
|
|
50
58
|
*/
|
|
51
|
-
export declare function
|
|
59
|
+
export declare function reconcileSection(primaryRepresentation: Representation, primaryDecisions: readonly BlockDecision[], secondaryDecisions: readonly BlockDecision[] | null, collapseCeiling?: number): void;
|
|
52
60
|
//# sourceMappingURL=reconcile.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/classify/reconcile.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/classify/reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,SAAS,EAAE,OAAO,CAAC;IACnB,sFAAsF;IACtF,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,6FAA6F;IAC7F,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACxC;AAgBD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,EAAE,IAAI,EAAE,kBAAkB,GAAG,IAAI,GAAG,aAAa,CAiD3G;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC5B,qBAAqB,EAAE,cAAc,EACrC,gBAAgB,EAAE,SAAS,aAAa,EAAE,EAC1C,kBAAkB,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,EACnD,eAAe,SAAM,GACtB,IAAI,CAiCN"}
|
|
@@ -11,15 +11,22 @@
|
|
|
11
11
|
* The plain part is still classified independently, and its verdict is used two ways: to confirm,
|
|
12
12
|
* which raises nothing but costs nothing, and to contradict, which caps confidence so that a
|
|
13
13
|
* disputed region is collapsed rather than hidden.
|
|
14
|
+
*
|
|
15
|
+
* Selection runs *before* classification, and that ordering is load bearing. A message can hold
|
|
16
|
+
* several independent body sections, and the classifier has to see all of them as one linear
|
|
17
|
+
* sequence for its positional rules to mean anything. Choosing the representation first is what
|
|
18
|
+
* makes that possible, and it is possible because selection needs only length, anchor presence and
|
|
19
|
+
* whether segmentation degraded. None of those are labels. See
|
|
20
|
+
* `docs/adr-001-document-global-classification.md`.
|
|
14
21
|
*/
|
|
15
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
23
|
exports.pickPrimary = pickPrimary;
|
|
17
|
-
exports.
|
|
18
|
-
/** Fraction of characters classified as
|
|
19
|
-
function historyShare(
|
|
24
|
+
exports.reconcileSection = reconcileSection;
|
|
25
|
+
/** Fraction of characters classified as history. */
|
|
26
|
+
function historyShare(decisions) {
|
|
20
27
|
let history = 0;
|
|
21
28
|
let total = 0;
|
|
22
|
-
for (const decision of
|
|
29
|
+
for (const decision of decisions) {
|
|
23
30
|
const chars = decision.block.content.length;
|
|
24
31
|
total += chars;
|
|
25
32
|
if (decision.label === 'REPLY_HISTORY') {
|
|
@@ -29,7 +36,7 @@ function historyShare(result) {
|
|
|
29
36
|
return total > 0 ? history / total : 0;
|
|
30
37
|
}
|
|
31
38
|
/**
|
|
32
|
-
* Choose which representation drives the output.
|
|
39
|
+
* Choose which representation of one section drives the output.
|
|
33
40
|
*
|
|
34
41
|
* HTML wins by default when both exist, because it is where the structure survives. Plain text
|
|
35
42
|
* wins when the HTML is a stub, which happens with clients that send a token HTML wrapper around a
|
|
@@ -37,10 +44,10 @@ function historyShare(result) {
|
|
|
37
44
|
*/
|
|
38
45
|
function pickPrimary(text, html) {
|
|
39
46
|
if (text && !html) {
|
|
40
|
-
return { primary: text, secondary: null
|
|
47
|
+
return { primary: text, secondary: null };
|
|
41
48
|
}
|
|
42
49
|
if (html && !text) {
|
|
43
|
-
return { primary: html, secondary: null
|
|
50
|
+
return { primary: html, secondary: null };
|
|
44
51
|
}
|
|
45
52
|
if (!text || !html) {
|
|
46
53
|
throw new Error('reconcile called with no representations');
|
|
@@ -58,30 +65,56 @@ function pickPrimary(text, html) {
|
|
|
58
65
|
primary = text;
|
|
59
66
|
secondary = html;
|
|
60
67
|
}
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
// Degrading is not the same as winning.
|
|
69
|
+
//
|
|
70
|
+
// A representation that could not be segmented is one undifferentiated block. It knows nothing
|
|
71
|
+
// about quote structure, so letting it drive the output turns a message whose plain text part
|
|
72
|
+
// classified perfectly well into a single UNKNOWN blob. That did not happen before only by
|
|
73
|
+
// accident: the degraded HTML block carried no content at all, so the stub test above caught
|
|
74
|
+
// it. Giving that block its real projected text removes the accident, which is why the rule has
|
|
75
|
+
// to be written down. Stated symmetrically, so it stays correct if the text segmenter ever
|
|
76
|
+
// grows a degraded path of its own.
|
|
77
|
+
const isStub = (result) => (result === text ? textIsStub : htmlIsStub);
|
|
78
|
+
if (primary.degraded && !secondary.degraded && !isStub(secondary)) {
|
|
79
|
+
const displaced = primary;
|
|
80
|
+
primary = secondary;
|
|
81
|
+
secondary = displaced;
|
|
82
|
+
}
|
|
83
|
+
// A degraded secondary has no opinion to contradict with. Its single block is UNKNOWN by
|
|
84
|
+
// construction, so measuring it against the primary would manufacture a disagreement out of the
|
|
85
|
+
// fact that it never got to disagree.
|
|
86
|
+
if (secondary.degraded) {
|
|
87
|
+
return { primary, secondary: null };
|
|
88
|
+
}
|
|
89
|
+
return { primary, secondary };
|
|
65
90
|
}
|
|
66
91
|
/**
|
|
67
|
-
* Apply cross representation evidence to
|
|
92
|
+
* Apply cross representation evidence to one section's decisions, in place.
|
|
68
93
|
*
|
|
69
94
|
* The only adjustment made is downward. Raising confidence because the other representation agrees
|
|
70
95
|
* would let two copies of the same mistake reinforce each other, and the cost of a wrong hide is
|
|
71
96
|
* much higher than the cost of a collapse that could have been a hide.
|
|
97
|
+
*
|
|
98
|
+
* Scoped to one section on purpose. The comparison only means something between two renderings of
|
|
99
|
+
* the same content; measuring one section against another section's alternative would compare
|
|
100
|
+
* unrelated things.
|
|
72
101
|
*/
|
|
73
|
-
function
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
for (const decision of primary.decisions) {
|
|
102
|
+
function reconcileSection(primaryRepresentation, primaryDecisions, secondaryDecisions, collapseCeiling = 0.9) {
|
|
103
|
+
const reason = primaryRepresentation === 'html' ? 'html_primary_representation' : 'text_primary_representation';
|
|
104
|
+
for (const decision of primaryDecisions) {
|
|
77
105
|
if (!decision.reasons.includes(reason)) {
|
|
78
106
|
decision.reasons.push(reason);
|
|
79
107
|
}
|
|
80
108
|
}
|
|
81
|
-
if (!
|
|
82
|
-
return
|
|
109
|
+
if (!secondaryDecisions) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// Disagreement is measured on the share of content treated as history, not on block counts,
|
|
113
|
+
// because the two representations rarely segment into the same number of blocks.
|
|
114
|
+
if (Math.abs(historyShare(primaryDecisions) - historyShare(secondaryDecisions)) <= 0.25) {
|
|
115
|
+
return;
|
|
83
116
|
}
|
|
84
|
-
for (const decision of
|
|
117
|
+
for (const decision of primaryDecisions) {
|
|
85
118
|
if (decision.label !== 'REPLY_HISTORY') {
|
|
86
119
|
continue;
|
|
87
120
|
}
|
|
@@ -95,6 +128,5 @@ function reconcile(outcome, collapseCeiling = 0.9) {
|
|
|
95
128
|
decision.reasons.push('representations_disagree');
|
|
96
129
|
}
|
|
97
130
|
}
|
|
98
|
-
return primary.decisions;
|
|
99
131
|
}
|
|
100
132
|
//# sourceMappingURL=reconcile.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/classify/reconcile.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/classify/reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotate.d.ts","sourceRoot":"","sources":["../../src/cli/annotate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAM9C,OAAO,
|
|
1
|
+
{"version":3,"file":"annotate.d.ts","sourceRoot":"","sources":["../../src/cli/annotate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAM9C,OAAO,EAAyC,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AA0DhF,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA2LvE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CA2DzE"}
|