@postalsys/email-content 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +288 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/analyze.d.ts +91 -0
- package/dist/analyze.d.ts.map +1 -0
- package/dist/analyze.js +274 -0
- package/dist/analyze.js.map +1 -0
- package/dist/annotate/client.d.ts +64 -0
- package/dist/annotate/client.d.ts.map +1 -0
- package/dist/annotate/client.js +139 -0
- package/dist/annotate/client.js.map +1 -0
- package/dist/annotate/llm.d.ts +46 -0
- package/dist/annotate/llm.d.ts.map +1 -0
- package/dist/annotate/llm.js +107 -0
- package/dist/annotate/llm.js.map +1 -0
- package/dist/annotate/prompt.d.ts +38 -0
- package/dist/annotate/prompt.d.ts.map +1 -0
- package/dist/annotate/prompt.js +165 -0
- package/dist/annotate/prompt.js.map +1 -0
- package/dist/annotate/store.d.ts +43 -0
- package/dist/annotate/store.d.ts.map +1 -0
- package/dist/annotate/store.js +46 -0
- package/dist/annotate/store.js.map +1 -0
- package/dist/canonical/html.d.ts +33 -0
- package/dist/canonical/html.d.ts.map +1 -0
- package/dist/canonical/html.js +156 -0
- package/dist/canonical/html.js.map +1 -0
- package/dist/canonical/text.d.ts +75 -0
- package/dist/canonical/text.d.ts.map +1 -0
- package/dist/canonical/text.js +217 -0
- package/dist/canonical/text.js.map +1 -0
- package/dist/classify/confidence.d.ts +38 -0
- package/dist/classify/confidence.d.ts.map +1 -0
- package/dist/classify/confidence.js +59 -0
- package/dist/classify/confidence.js.map +1 -0
- package/dist/classify/reconcile.d.ts +52 -0
- package/dist/classify/reconcile.d.ts.map +1 -0
- package/dist/classify/reconcile.js +100 -0
- package/dist/classify/reconcile.js.map +1 -0
- package/dist/classify/rules.d.ts +51 -0
- package/dist/classify/rules.d.ts.map +1 -0
- package/dist/classify/rules.js +648 -0
- package/dist/classify/rules.js.map +1 -0
- package/dist/cli/annotate.d.ts +23 -0
- package/dist/cli/annotate.d.ts.map +1 -0
- package/dist/cli/annotate.js +328 -0
- package/dist/cli/annotate.js.map +1 -0
- package/dist/cli/args.d.ts +17 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +72 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/benchmark.d.ts +13 -0
- package/dist/cli/benchmark.d.ts.map +1 -0
- package/dist/cli/benchmark.js +172 -0
- package/dist/cli/benchmark.js.map +1 -0
- package/dist/cli/corpus.d.ts +9 -0
- package/dist/cli/corpus.d.ts.map +1 -0
- package/dist/cli/corpus.js +152 -0
- package/dist/cli/corpus.js.map +1 -0
- package/dist/cli/disagreements.d.ts +14 -0
- package/dist/cli/disagreements.d.ts.map +1 -0
- package/dist/cli/disagreements.js +133 -0
- package/dist/cli/disagreements.js.map +1 -0
- package/dist/cli/evaluate.d.ts +15 -0
- package/dist/cli/evaluate.d.ts.map +1 -0
- package/dist/cli/evaluate.js +215 -0
- package/dist/cli/evaluate.js.map +1 -0
- package/dist/cli/extract.d.ts +10 -0
- package/dist/cli/extract.d.ts.map +1 -0
- package/dist/cli/extract.js +139 -0
- package/dist/cli/extract.js.map +1 -0
- package/dist/cli/main.d.ts +9 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +147 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/corpus/analyze.d.ts +66 -0
- package/dist/corpus/analyze.d.ts.map +1 -0
- package/dist/corpus/analyze.js +214 -0
- package/dist/corpus/analyze.js.map +1 -0
- package/dist/corpus/migrations/index.d.ts +14 -0
- package/dist/corpus/migrations/index.d.ts.map +1 -0
- package/dist/corpus/migrations/index.js +158 -0
- package/dist/corpus/migrations/index.js.map +1 -0
- package/dist/corpus/sample.d.ts +66 -0
- package/dist/corpus/sample.d.ts.map +1 -0
- package/dist/corpus/sample.js +98 -0
- package/dist/corpus/sample.js.map +1 -0
- package/dist/corpus/scanner.d.ts +79 -0
- package/dist/corpus/scanner.d.ts.map +1 -0
- package/dist/corpus/scanner.js +256 -0
- package/dist/corpus/scanner.js.map +1 -0
- package/dist/corpus/stats.d.ts +76 -0
- package/dist/corpus/stats.d.ts.map +1 -0
- package/dist/corpus/stats.js +240 -0
- package/dist/corpus/stats.js.map +1 -0
- package/dist/corpus/store.d.ts +67 -0
- package/dist/corpus/store.d.ts.map +1 -0
- package/dist/corpus/store.js +196 -0
- package/dist/corpus/store.js.map +1 -0
- package/dist/corpus/thread-index.d.ts +31 -0
- package/dist/corpus/thread-index.d.ts.map +1 -0
- package/dist/corpus/thread-index.js +182 -0
- package/dist/corpus/thread-index.js.map +1 -0
- package/dist/corpus/worker.d.ts +21 -0
- package/dist/corpus/worker.d.ts.map +1 -0
- package/dist/corpus/worker.js +74 -0
- package/dist/corpus/worker.js.map +1 -0
- package/dist/detect/client.d.ts +28 -0
- package/dist/detect/client.d.ts.map +1 -0
- package/dist/detect/client.js +121 -0
- package/dist/detect/client.js.map +1 -0
- package/dist/detect/disclaimer.d.ts +12 -0
- package/dist/detect/disclaimer.d.ts.map +1 -0
- package/dist/detect/disclaimer.js +28 -0
- package/dist/detect/disclaimer.js.map +1 -0
- package/dist/detect/forward-header.d.ts +10 -0
- package/dist/detect/forward-header.d.ts.map +1 -0
- package/dist/detect/forward-header.js +35 -0
- package/dist/detect/forward-header.js.map +1 -0
- package/dist/detect/patterns/disclaimers.json +113 -0
- package/dist/detect/patterns/forward-headers.json +40 -0
- package/dist/detect/patterns/html-clients.json +157 -0
- package/dist/detect/patterns/quoted-headers.json +41 -0
- package/dist/detect/patterns/reply-headers.json +139 -0
- package/dist/detect/patterns/signatures.json +58 -0
- package/dist/detect/patterns.d.ts +43 -0
- package/dist/detect/patterns.d.ts.map +1 -0
- package/dist/detect/patterns.js +125 -0
- package/dist/detect/patterns.js.map +1 -0
- package/dist/detect/reply-header.d.ts +44 -0
- package/dist/detect/reply-header.d.ts.map +1 -0
- package/dist/detect/reply-header.js +134 -0
- package/dist/detect/reply-header.js.map +1 -0
- package/dist/detect/signature.d.ts +28 -0
- package/dist/detect/signature.d.ts.map +1 -0
- package/dist/detect/signature.js +77 -0
- package/dist/detect/signature.js.map +1 -0
- package/dist/detect/traffic.d.ts +26 -0
- package/dist/detect/traffic.d.ts.map +1 -0
- package/dist/detect/traffic.js +98 -0
- package/dist/detect/traffic.js.map +1 -0
- package/dist/eval/metrics.d.ts +87 -0
- package/dist/eval/metrics.d.ts.map +1 -0
- package/dist/eval/metrics.js +185 -0
- package/dist/eval/metrics.js.map +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +163 -0
- package/dist/index.js.map +1 -0
- package/dist/match/history.d.ts +62 -0
- package/dist/match/history.d.ts.map +1 -0
- package/dist/match/history.js +128 -0
- package/dist/match/history.js.map +1 -0
- package/dist/match/normalize.d.ts +33 -0
- package/dist/match/normalize.d.ts.map +1 -0
- package/dist/match/normalize.js +63 -0
- package/dist/match/normalize.js.map +1 -0
- package/dist/match/shingle.d.ts +44 -0
- package/dist/match/shingle.d.ts.map +1 -0
- package/dist/match/shingle.js +78 -0
- package/dist/match/shingle.js.map +1 -0
- package/dist/mime/charset.d.ts +33 -0
- package/dist/mime/charset.d.ts.map +1 -0
- package/dist/mime/charset.js +118 -0
- package/dist/mime/charset.js.map +1 -0
- package/dist/mime/headers.d.ts +32 -0
- package/dist/mime/headers.d.ts.map +1 -0
- package/dist/mime/headers.js +127 -0
- package/dist/mime/headers.js.map +1 -0
- package/dist/mime/model.d.ts +111 -0
- package/dist/mime/model.d.ts.map +1 -0
- package/dist/mime/model.js +17 -0
- package/dist/mime/model.js.map +1 -0
- package/dist/mime/parse.d.ts +27 -0
- package/dist/mime/parse.d.ts.map +1 -0
- package/dist/mime/parse.js +343 -0
- package/dist/mime/parse.js.map +1 -0
- package/dist/segment/features.d.ts +29 -0
- package/dist/segment/features.d.ts.map +1 -0
- package/dist/segment/features.js +102 -0
- package/dist/segment/features.js.map +1 -0
- package/dist/segment/html-blocks.d.ts +28 -0
- package/dist/segment/html-blocks.d.ts.map +1 -0
- package/dist/segment/html-blocks.js +596 -0
- package/dist/segment/html-blocks.js.map +1 -0
- package/dist/segment/text-blocks.d.ts +30 -0
- package/dist/segment/text-blocks.d.ts.map +1 -0
- package/dist/segment/text-blocks.js +204 -0
- package/dist/segment/text-blocks.js.map +1 -0
- package/dist/segment/types.d.ts +88 -0
- package/dist/segment/types.d.ts.map +1 -0
- package/dist/segment/types.js +11 -0
- package/dist/segment/types.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -0
- package/dist/util/hash.d.ts +49 -0
- package/dist/util/hash.d.ts.map +1 -0
- package/dist/util/hash.js +0 -0
- package/dist/util/hash.js.map +1 -0
- package/dist/util/lang.d.ts +25 -0
- package/dist/util/lang.d.ts.map +1 -0
- package/dist/util/lang.js +135 -0
- package/dist/util/lang.js.map +1 -0
- package/dist/util/worker-pool.d.ts +51 -0
- package/dist/util/worker-pool.d.ts.map +1 -0
- package/dist/util/worker-pool.js +155 -0
- package/dist/util/worker-pool.js.map +1 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Postal Systems OÜ
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# email-content
|
|
2
|
+
|
|
3
|
+
Extract the conversationally relevant content from arbitrary email messages.
|
|
4
|
+
|
|
5
|
+
Given a raw RFC 5322 message, the library separates what the sender actually wrote from the reply
|
|
6
|
+
history their mail client embedded automatically, and returns both, classified, with a confidence
|
|
7
|
+
and a machine readable reason for every decision.
|
|
8
|
+
|
|
9
|
+
It is built for a chat style application that uses ordinary email as its transport, where the other
|
|
10
|
+
participants use whatever client they like and do not know their mail is being read as chat.
|
|
11
|
+
|
|
12
|
+
## The rule everything follows from
|
|
13
|
+
|
|
14
|
+
Hiding a sentence the sender wrote is a silent data loss the reader may never notice. Showing a
|
|
15
|
+
paragraph of redundant quoted history is a cosmetic annoyance. The first is treated as at least ten
|
|
16
|
+
times worse than the second, and every design decision follows from that.
|
|
17
|
+
|
|
18
|
+
In practice that means:
|
|
19
|
+
|
|
20
|
+
- Content is only ever hidden when something structural says it is history: an attribution line, a
|
|
21
|
+
client quote container, or a match against a message that demonstrably existed earlier. Quote
|
|
22
|
+
characters alone are never enough.
|
|
23
|
+
- Nothing is deleted. Hidden segments are returned in full next to the visible ones, and the
|
|
24
|
+
original message is always available. "Hidden" is a rendering hint.
|
|
25
|
+
- Ambiguous content is labelled `UNKNOWN` and stays visible.
|
|
26
|
+
- No generative model touches the sender's words. The pipeline selects and classifies existing
|
|
27
|
+
spans; it never rewrites, summarises or paraphrases.
|
|
28
|
+
|
|
29
|
+
## Install and build
|
|
30
|
+
|
|
31
|
+
Requires Node 24 or later, for the built in `node:sqlite` and native TypeScript execution.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install
|
|
35
|
+
npm run build
|
|
36
|
+
npm test
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Library
|
|
40
|
+
|
|
41
|
+
The primary entry point takes content you have already parsed. Most callers hold
|
|
42
|
+
`{ text, html, subject }` from mailparser, postal-mime, EmailEngine or an IMAP client, and never
|
|
43
|
+
have a raw message to hand.
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
const { analyze } = require('email-content');
|
|
47
|
+
|
|
48
|
+
const result = await analyze({
|
|
49
|
+
text: plainTextBody, // optional
|
|
50
|
+
html: htmlBody, // optional
|
|
51
|
+
subject: 'Re: Deploy window', // optional
|
|
52
|
+
from: 'Bob <bob@example.net>', // optional, improves signature detection
|
|
53
|
+
inReplyTo: '<parent@example.com>' // optional
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
for (const segment of result.segments) {
|
|
57
|
+
console.log(segment.type, segment.confidence, segment.text);
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Either body may be omitted. When both are present the HTML drives the classification, because that
|
|
62
|
+
is where quote structure survives, and the plain text is used as a cross check.
|
|
63
|
+
|
|
64
|
+
If you do have a raw RFC 5322 message, `extract()` parses it and runs the same pipeline:
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
const { extract } = require('email-content');
|
|
68
|
+
const result = await extract(fs.readFileSync('message.eml'));
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Result
|
|
72
|
+
|
|
73
|
+
```jsonc
|
|
74
|
+
{
|
|
75
|
+
"segments": [ // render these
|
|
76
|
+
{
|
|
77
|
+
"type": "NEW_CONTENT",
|
|
78
|
+
"text": "No, wait until Monday.",
|
|
79
|
+
"html": "<div>No, wait until Monday.</div>",
|
|
80
|
+
"confidence": 0.95,
|
|
81
|
+
"visibility": "show", // show | collapse | hide
|
|
82
|
+
"reasons": ["new_content_default", "html_primary_representation"],
|
|
83
|
+
"source": {
|
|
84
|
+
"mimePart": "1.2", // IMAP style part path
|
|
85
|
+
"representation": "html",
|
|
86
|
+
"blockIndex": 0,
|
|
87
|
+
"start": 0, // character offsets into the canonical part text
|
|
88
|
+
"end": 79,
|
|
89
|
+
"domPath": "/0/1"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"hiddenSegments": [ /* same shape, retained in full */ ],
|
|
94
|
+
"overallConfidence": 0.97,
|
|
95
|
+
"warnings": [],
|
|
96
|
+
"originalAvailable": true,
|
|
97
|
+
"primaryRepresentation": "html",
|
|
98
|
+
"extractorVersion": "0.1.0",
|
|
99
|
+
"historyUsed": false,
|
|
100
|
+
"isReply": true
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Segment types: `NEW_CONTENT`, `INLINE_QUOTE`, `REPLY_HISTORY`, `FORWARDED_CONTENT`, `SIGNATURE`,
|
|
105
|
+
`DISCLAIMER`, `UNKNOWN`.
|
|
106
|
+
|
|
107
|
+
Render `segments`. `hiddenSegments` holds what the extractor is confident is embedded reply
|
|
108
|
+
history, in full, so a client can offer to reveal it. Nothing is ever discarded.
|
|
109
|
+
|
|
110
|
+
### Thread history
|
|
111
|
+
|
|
112
|
+
If earlier messages in the thread are available, pass them. A block whose text provably existed
|
|
113
|
+
before this message was written is history by definition, which is far stronger evidence than any
|
|
114
|
+
markup heuristic. Measured on the reference set, supplying history cuts the share of reply history
|
|
115
|
+
left visible from 70.9 percent to 60.1 percent, with no loss of new content.
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
const result = await analyze(
|
|
119
|
+
{ text, html },
|
|
120
|
+
{ history: [{ text: parentText, html: parentHtml }] } // nearest ancestor first
|
|
121
|
+
);
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
History is always optional. Extraction works without it and never depends on it.
|
|
125
|
+
|
|
126
|
+
`analyze()` and `extract()` never throw. Malformed input produces a result whose body is a single
|
|
127
|
+
visible `UNKNOWN` segment plus a warning.
|
|
128
|
+
|
|
129
|
+
## Command line
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Classify one message
|
|
133
|
+
email-content extract message.eml
|
|
134
|
+
email-content extract message.eml --json
|
|
135
|
+
email-content extract message.eml --explain # per block evidence, features and reasons
|
|
136
|
+
|
|
137
|
+
# Label blocks with an LLM instead of a human (opt in, sends content to OpenAI)
|
|
138
|
+
email-content annotate --sample 60 --model gpt-5.4-mini
|
|
139
|
+
email-content disagreements --direction expensive
|
|
140
|
+
|
|
141
|
+
# Scan a corpus of .eml files into a local SQLite database
|
|
142
|
+
email-content corpus scan /path/to/eml-folder
|
|
143
|
+
email-content corpus scan /path/to/eml-folder --sample 2000 --seed phase1
|
|
144
|
+
email-content corpus scan /path/to/eml-folder --concurrency 14
|
|
145
|
+
|
|
146
|
+
# Report on it
|
|
147
|
+
email-content corpus stats --out docs/corpus-report.md
|
|
148
|
+
email-content corpus stats --json
|
|
149
|
+
email-content corpus threads # in-corpus thread parent resolution
|
|
150
|
+
|
|
151
|
+
# Throughput and catastrophic error rates
|
|
152
|
+
email-content benchmark --sample 3000
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## What it gets right
|
|
156
|
+
|
|
157
|
+
The two cases that define the problem:
|
|
158
|
+
|
|
159
|
+
```text
|
|
160
|
+
> Should we deploy this today?
|
|
161
|
+
|
|
162
|
+
No, wait until Monday.
|
|
163
|
+
|
|
164
|
+
> Should I notify the customer?
|
|
165
|
+
|
|
166
|
+
Yes, please.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Both questions are `INLINE_QUOTE` and stay visible: they are the context the answers depend on.
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
Yes, Monday works.
|
|
173
|
+
|
|
174
|
+
On Friday, Alice wrote:
|
|
175
|
+
> Can we meet on Monday?
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The trailing quote is `REPLY_HISTORY` and is hidden, because an attribution line anchors it and no
|
|
179
|
+
authored content follows.
|
|
180
|
+
|
|
181
|
+
Beyond that, the deterministic baseline handles Gmail, Outlook desktop, Outlook Web, Apple Mail,
|
|
182
|
+
Thunderbird, Proton, Yahoo and Zimbra quote structures; forwarded messages with a comment above
|
|
183
|
+
them; bottom posted replies, which are collapsed rather than hidden because the reader is more
|
|
184
|
+
likely to need the context; `format=flowed`; legacy charsets; and messages whose plain text part
|
|
185
|
+
has lost its quote markers entirely, which is now the majority case for recent mail.
|
|
186
|
+
|
|
187
|
+
It also, deliberately, does not fire on ordinary prose that merely looks like email structure. Text
|
|
188
|
+
containing `From:` and `Subject:` lines is only treated as an embedded header block when the values
|
|
189
|
+
look like header values, so a support message explaining which headers to include stays visible.
|
|
190
|
+
|
|
191
|
+
## Accuracy
|
|
192
|
+
|
|
193
|
+
Measured against a 452 message stratified reference set annotated by gpt-5.6-sol under the
|
|
194
|
+
conventions in [docs/annotation-guide.md](docs/annotation-guide.md), with thread history enabled.
|
|
195
|
+
|
|
196
|
+
The reference is not ground truth, but it is close. Two strong models (gpt-5.5 and gpt-5.6-sol)
|
|
197
|
+
given identical input agree with each other on **98.6 percent** of blocks, and **99.2 percent** once
|
|
198
|
+
a single spam message of machine generated word salad is excluded. That is the practical ceiling.
|
|
199
|
+
|
|
200
|
+
| property | measured |
|
|
201
|
+
| --- | ---: |
|
|
202
|
+
| block label agreement | 79.8% |
|
|
203
|
+
| new content characters retained | **100.0%** |
|
|
204
|
+
| new content blocks retained | **100.0%** |
|
|
205
|
+
| hidden content genuinely history | 99.4% |
|
|
206
|
+
| reply history correctly hidden | 60.3% |
|
|
207
|
+
| messages losing all new content | 0 |
|
|
208
|
+
| messages losing an inline answer | 0 |
|
|
209
|
+
|
|
210
|
+
Not one character the reference considers newly written is hidden, across 452 messages and 206,368
|
|
211
|
+
characters of new content.
|
|
212
|
+
|
|
213
|
+
Per label F1: REPLY_HISTORY 90.4, FORWARDED_CONTENT 81.5, NEW_CONTENT 70.1, SIGNATURE 48.8,
|
|
214
|
+
INLINE_QUOTE 35.9, DISCLAIMER 30.1.
|
|
215
|
+
|
|
216
|
+
With thread history available the numbers are materially better than the aggregate suggests, and a
|
|
217
|
+
chat application always has the thread it is rendering:
|
|
218
|
+
|
|
219
|
+
| | messages | agreement | history hidden |
|
|
220
|
+
| --- | ---: | ---: | ---: |
|
|
221
|
+
| history available | 305 | 85.9% | 64.7% |
|
|
222
|
+
| history unavailable | 147 | 64.9% | 37.0% |
|
|
223
|
+
|
|
224
|
+
## Limitations
|
|
225
|
+
|
|
226
|
+
- **It still errs towards showing too much.** Around 40 percent of reply history remains displayed.
|
|
227
|
+
That is the cheap direction of error and it is deliberate, but it is the largest remaining gap.
|
|
228
|
+
- **Disclaimer recall is 18.1 percent** at 87.8 percent precision. The generic notification footer
|
|
229
|
+
shapes are covered; what remains is per-sender templates, which hand written rules cannot reach
|
|
230
|
+
without overfitting to one vendor. This is the clearest case for a learned model.
|
|
231
|
+
- **Signature recall is 36.7 percent** at 73.1 percent precision. Two independent signals are
|
|
232
|
+
required, such as a closing greeting plus contact details, or the sender's own name plus either.
|
|
233
|
+
- **INLINE_QUOTE precision is 27.2 percent.** Blocks wrongly called inline quote stay visible, so
|
|
234
|
+
this costs tidiness, not content.
|
|
235
|
+
- **Outlook remains the weakest client**, around 62 percent against 92 percent for Gmail and Apple
|
|
236
|
+
Mail.
|
|
237
|
+
- **No learned model.** This is the deterministic baseline. The labelled data, a settled labelling
|
|
238
|
+
convention and the evaluation harness all exist to train one.
|
|
239
|
+
|
|
240
|
+
## Privacy
|
|
241
|
+
|
|
242
|
+
The corpus this was built against is private email, and the project is built accordingly:
|
|
243
|
+
|
|
244
|
+
- Nothing contacts the network by default. The runtime dependency tree is three packages and none
|
|
245
|
+
opens a socket. The one exception is `email-content annotate`, an opt in command that sends block
|
|
246
|
+
text to an LLM API; see [docs/annotation.md](docs/annotation.md).
|
|
247
|
+
- Source `.eml` files are opened read only and never modified.
|
|
248
|
+
- No message body, subject or address is written to logs, to the terminal, or to the corpus
|
|
249
|
+
database. Subjects and addresses are stored as salted hashes; sender domains are kept because
|
|
250
|
+
stratified sampling needs them.
|
|
251
|
+
- The corpus database is derived from private mail and is not anonymised. It is gitignored. See
|
|
252
|
+
[docs/threat-model.md](docs/threat-model.md) for exactly what it can still reveal.
|
|
253
|
+
|
|
254
|
+
## Documentation
|
|
255
|
+
|
|
256
|
+
| document | contents |
|
|
257
|
+
| --- | --- |
|
|
258
|
+
| [docs/architecture.md](docs/architecture.md) | Pipeline stages, dependency choices and why, safety invariants |
|
|
259
|
+
| [docs/implementation-plan.md](docs/implementation-plan.md) | Phases, decisions taken, open questions |
|
|
260
|
+
| [docs/threat-model.md](docs/threat-model.md) | What is stored, what it reveals, hostile content handling |
|
|
261
|
+
| [docs/corpus-report.md](docs/corpus-report.md) | Statistics over the working corpus (generated, gitignored) |
|
|
262
|
+
| [docs/benchmark.md](docs/benchmark.md) | Throughput, memory, and where the time goes |
|
|
263
|
+
| [docs/annotation.md](docs/annotation.md) | Using an LLM as annotator: method, results, limitations |
|
|
264
|
+
|
|
265
|
+
## Project layout
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
src/mime/ MIME parsing, charset decoding, normalised message model
|
|
269
|
+
src/canonical/ Plain text and HTML canonicalisation
|
|
270
|
+
src/segment/ Block segmentation and feature extraction
|
|
271
|
+
src/detect/ Detectors, with pattern sets as JSON data
|
|
272
|
+
src/classify/ Rules, reconciliation, confidence
|
|
273
|
+
src/corpus/ Scanner, worker pool, SQLite store, statistics
|
|
274
|
+
src/cli/ Command line entry points
|
|
275
|
+
test/ Tests and hand written fixtures
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Pattern sets in `src/detect/patterns/` can be overridden at runtime by pointing
|
|
279
|
+
`EMAIL_CONTENT_PATTERNS` at a directory containing replacements.
|
|
280
|
+
|
|
281
|
+
## Status
|
|
282
|
+
|
|
283
|
+
Working and measured: the MIME parser, canonicalisation, block segmentation, the deterministic rule
|
|
284
|
+
baseline, thread history matching, the corpus scanner over 320k messages, LLM assisted annotation,
|
|
285
|
+
the evaluation harness, the CLI, and 123 tests including fuzzing and performance bounds.
|
|
286
|
+
|
|
287
|
+
Not built: the local annotation app for adjudicating disagreements, and a learned sequence model.
|
|
288
|
+
Both are described in [docs/implementation-plan.md](docs/implementation-plan.md).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fileNames":["../node_modules/typescript/lib/lib.es5.d.ts","../node_modules/typescript/lib/lib.es2015.d.ts","../node_modules/typescript/lib/lib.es2016.d.ts","../node_modules/typescript/lib/lib.es2017.d.ts","../node_modules/typescript/lib/lib.es2018.d.ts","../node_modules/typescript/lib/lib.es2019.d.ts","../node_modules/typescript/lib/lib.es2020.d.ts","../node_modules/typescript/lib/lib.es2021.d.ts","../node_modules/typescript/lib/lib.es2022.d.ts","../node_modules/typescript/lib/lib.es2023.d.ts","../node_modules/typescript/lib/lib.es2015.core.d.ts","../node_modules/typescript/lib/lib.es2015.collection.d.ts","../node_modules/typescript/lib/lib.es2015.generator.d.ts","../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../node_modules/typescript/lib/lib.es2015.promise.d.ts","../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../node_modules/typescript/lib/lib.es2016.intl.d.ts","../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../node_modules/typescript/lib/lib.es2017.date.d.ts","../node_modules/typescript/lib/lib.es2017.object.d.ts","../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2017.string.d.ts","../node_modules/typescript/lib/lib.es2017.intl.d.ts","../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../node_modules/typescript/lib/lib.es2018.intl.d.ts","../node_modules/typescript/lib/lib.es2018.promise.d.ts","../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../node_modules/typescript/lib/lib.es2019.array.d.ts","../node_modules/typescript/lib/lib.es2019.object.d.ts","../node_modules/typescript/lib/lib.es2019.string.d.ts","../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../node_modules/typescript/lib/lib.es2019.intl.d.ts","../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../node_modules/typescript/lib/lib.es2020.date.d.ts","../node_modules/typescript/lib/lib.es2020.promise.d.ts","../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2020.string.d.ts","../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2020.intl.d.ts","../node_modules/typescript/lib/lib.es2020.number.d.ts","../node_modules/typescript/lib/lib.es2021.promise.d.ts","../node_modules/typescript/lib/lib.es2021.string.d.ts","../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../node_modules/typescript/lib/lib.es2021.intl.d.ts","../node_modules/typescript/lib/lib.es2022.array.d.ts","../node_modules/typescript/lib/lib.es2022.error.d.ts","../node_modules/typescript/lib/lib.es2022.intl.d.ts","../node_modules/typescript/lib/lib.es2022.object.d.ts","../node_modules/typescript/lib/lib.es2022.string.d.ts","../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../node_modules/typescript/lib/lib.es2023.array.d.ts","../node_modules/typescript/lib/lib.es2023.collection.d.ts","../node_modules/typescript/lib/lib.es2023.intl.d.ts","../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../node_modules/typescript/lib/lib.esnext.float16.d.ts","../node_modules/typescript/lib/lib.decorators.d.ts","../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../node_modules/node-html-parser/dist/index.d.ts","../src/detect/patterns.ts","../src/types.ts","../src/segment/types.ts","../src/detect/reply-header.ts","../src/detect/forward-header.ts","../src/detect/signature.ts","../src/detect/disclaimer.ts","../src/canonical/html.ts","../src/segment/features.ts","../src/segment/html-blocks.ts","../src/canonical/text.ts","../src/segment/text-blocks.ts","../src/classify/confidence.ts","../src/classify/rules.ts","../src/classify/reconcile.ts","../node_modules/@types/node/compatibility/iterators.d.ts","../node_modules/@types/node/globals.typedarray.d.ts","../node_modules/@types/node/buffer.buffer.d.ts","../node_modules/@types/node/globals.d.ts","../node_modules/@types/node/web-globals/abortcontroller.d.ts","../node_modules/@types/node/web-globals/crypto.d.ts","../node_modules/@types/node/web-globals/domexception.d.ts","../node_modules/@types/node/web-globals/events.d.ts","../node_modules/undici-types/utility.d.ts","../node_modules/undici-types/header.d.ts","../node_modules/undici-types/readable.d.ts","../node_modules/undici-types/fetch.d.ts","../node_modules/undici-types/formdata.d.ts","../node_modules/undici-types/connector.d.ts","../node_modules/undici-types/client-stats.d.ts","../node_modules/undici-types/client.d.ts","../node_modules/undici-types/errors.d.ts","../node_modules/undici-types/dispatcher.d.ts","../node_modules/undici-types/global-dispatcher.d.ts","../node_modules/undici-types/global-origin.d.ts","../node_modules/undici-types/pool-stats.d.ts","../node_modules/undici-types/pool.d.ts","../node_modules/undici-types/handlers.d.ts","../node_modules/undici-types/balanced-pool.d.ts","../node_modules/undici-types/round-robin-pool.d.ts","../node_modules/undici-types/h2c-client.d.ts","../node_modules/undici-types/agent.d.ts","../node_modules/undici-types/mock-interceptor.d.ts","../node_modules/undici-types/mock-call-history.d.ts","../node_modules/undici-types/mock-agent.d.ts","../node_modules/undici-types/mock-client.d.ts","../node_modules/undici-types/mock-pool.d.ts","../node_modules/undici-types/snapshot-agent.d.ts","../node_modules/undici-types/mock-errors.d.ts","../node_modules/undici-types/proxy-agent.d.ts","../node_modules/undici-types/env-http-proxy-agent.d.ts","../node_modules/undici-types/retry-handler.d.ts","../node_modules/undici-types/retry-agent.d.ts","../node_modules/undici-types/api.d.ts","../node_modules/undici-types/cache-interceptor.d.ts","../node_modules/undici-types/interceptors.d.ts","../node_modules/undici-types/util.d.ts","../node_modules/undici-types/cookies.d.ts","../node_modules/undici-types/patch.d.ts","../node_modules/undici-types/websocket.d.ts","../node_modules/undici-types/eventsource.d.ts","../node_modules/undici-types/diagnostics-channel.d.ts","../node_modules/undici-types/content-type.d.ts","../node_modules/undici-types/cache.d.ts","../node_modules/undici-types/index.d.ts","../node_modules/@types/node/web-globals/fetch.d.ts","../node_modules/@types/node/web-globals/navigator.d.ts","../node_modules/@types/node/web-globals/storage.d.ts","../node_modules/@types/node/web-globals/streams.d.ts","../node_modules/@types/node/assert.d.ts","../node_modules/@types/node/assert/strict.d.ts","../node_modules/@types/node/async_hooks.d.ts","../node_modules/@types/node/buffer.d.ts","../node_modules/@types/node/child_process.d.ts","../node_modules/@types/node/cluster.d.ts","../node_modules/@types/node/console.d.ts","../node_modules/@types/node/constants.d.ts","../node_modules/@types/node/crypto.d.ts","../node_modules/@types/node/dgram.d.ts","../node_modules/@types/node/diagnostics_channel.d.ts","../node_modules/@types/node/dns.d.ts","../node_modules/@types/node/dns/promises.d.ts","../node_modules/@types/node/domain.d.ts","../node_modules/@types/node/events.d.ts","../node_modules/@types/node/fs.d.ts","../node_modules/@types/node/fs/promises.d.ts","../node_modules/@types/node/http.d.ts","../node_modules/@types/node/http2.d.ts","../node_modules/@types/node/https.d.ts","../node_modules/@types/node/inspector.d.ts","../node_modules/@types/node/inspector.generated.d.ts","../node_modules/@types/node/module.d.ts","../node_modules/@types/node/net.d.ts","../node_modules/@types/node/os.d.ts","../node_modules/@types/node/path.d.ts","../node_modules/@types/node/perf_hooks.d.ts","../node_modules/@types/node/process.d.ts","../node_modules/@types/node/punycode.d.ts","../node_modules/@types/node/querystring.d.ts","../node_modules/@types/node/readline.d.ts","../node_modules/@types/node/readline/promises.d.ts","../node_modules/@types/node/repl.d.ts","../node_modules/@types/node/sea.d.ts","../node_modules/@types/node/sqlite.d.ts","../node_modules/@types/node/stream.d.ts","../node_modules/@types/node/stream/promises.d.ts","../node_modules/@types/node/stream/consumers.d.ts","../node_modules/@types/node/stream/web.d.ts","../node_modules/@types/node/string_decoder.d.ts","../node_modules/@types/node/test.d.ts","../node_modules/@types/node/timers.d.ts","../node_modules/@types/node/timers/promises.d.ts","../node_modules/@types/node/tls.d.ts","../node_modules/@types/node/trace_events.d.ts","../node_modules/@types/node/tty.d.ts","../node_modules/@types/node/url.d.ts","../node_modules/@types/node/util.d.ts","../node_modules/@types/node/v8.d.ts","../node_modules/@types/node/vm.d.ts","../node_modules/@types/node/wasi.d.ts","../node_modules/@types/node/worker_threads.d.ts","../node_modules/@types/node/zlib.d.ts","../node_modules/@types/node/index.d.ts","../node_modules/@zone-eu/mailsplit/lib/headers.d.ts","../node_modules/@zone-eu/mailsplit/lib/types.d.ts","../node_modules/@zone-eu/mailsplit/lib/message-splitter.d.ts","../node_modules/@zone-eu/mailsplit/lib/message-joiner.d.ts","../node_modules/@zone-eu/mailsplit/lib/node-rewriter.d.ts","../node_modules/@zone-eu/mailsplit/lib/node-streamer.d.ts","../node_modules/@zone-eu/mailsplit/lib/chunked-passthrough.d.ts","../node_modules/@zone-eu/mailsplit/lib/mime-node.d.ts","../node_modules/@zone-eu/mailsplit/index.d.ts","../src/mime/charset.ts","../src/mime/model.ts","../src/mime/headers.ts","../src/mime/parse.ts","../src/util/hash.ts","../src/match/normalize.ts","../src/match/shingle.ts","../src/match/history.ts","../src/analyze.ts","../src/corpus/migrations/index.ts","../src/detect/client.ts","../src/detect/traffic.ts","../src/util/lang.ts","../src/corpus/analyze.ts","../src/corpus/store.ts","../src/corpus/thread-index.ts","../src/index.ts","../src/vendor.d.ts","../src/annotate/client.ts","../src/annotate/prompt.ts","../src/annotate/llm.ts","../src/annotate/store.ts","../src/cli/args.ts","../src/corpus/sample.ts","../src/cli/annotate.ts","../src/cli/benchmark.ts","../src/util/worker-pool.ts","../src/corpus/worker.ts","../src/corpus/scanner.ts","../src/corpus/stats.ts","../src/cli/corpus.ts","../src/cli/disagreements.ts","../src/eval/metrics.ts","../src/cli/evaluate.ts","../src/cli/extract.ts","../src/cli/main.ts","../node_modules/@types/esrecurse/index.d.ts","../node_modules/@types/estree/index.d.ts","../node_modules/@types/json-schema/index.d.ts"],"fileIdsList":[[82,137,154,155],[82,134,135,137,154,155],[82,136,137,154,155],[137,154,155],[82,137,142,154,155,172],[82,137,138,143,148,154,155,157,169,180],[82,137,138,139,148,154,155,157],[82,137,140,154,155,181],[82,137,141,142,149,154,155,158],[82,137,142,154,155,169,177],[82,137,143,145,148,154,155,157],[82,136,137,144,154,155],[82,137,145,146,154,155],[82,137,147,148,154,155],[82,136,137,148,154,155],[82,137,148,149,150,154,155,169,180],[82,137,148,149,150,154,155,164,169,172],[82,129,137,145,148,151,154,155,157,169,180],[82,137,148,149,151,152,154,155,157,169,177,180],[82,137,151,153,154,155,169,177,180],[80,81,82,83,84,85,86,87,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186],[82,137,148,154,155],[82,137,154,155,156,180],[82,137,145,148,154,155,157,169],[82,137,154,155,158],[82,137,154,155,159],[82,136,137,154,155,160],[82,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186],[82,137,154,155,162],[82,137,154,155,163],[82,137,148,154,155,164,165],[82,137,154,155,164,166,181,183],[82,137,149,154,155],[82,137,148,154,155,169,170,172],[82,137,154,155,171,172],[82,137,154,155,169,170],[82,137,154,155,172],[82,137,154,155,173],[82,134,137,154,155,169,174,180],[82,137,148,154,155,175,176],[82,137,154,155,175,176],[82,137,142,154,155,157,169,177],[82,137,154,155,178],[82,137,154,155,157,179],[82,137,151,154,155,163,180],[82,137,142,154,155,181],[82,137,154,155,169,182],[82,137,154,155,156,183],[82,137,154,155,184],[82,137,142,154,155],[82,129,137,154,155],[82,137,154,155,185],[82,129,137,148,150,154,155,160,169,172,180,182,183,185],[82,137,154,155,169,186],[82,137,154,155,187,188,189,190,191,192,193,194,195],[82,137,154,155,169,189],[82,137,154,155,189],[82,137,154,155,169],[82,137,154,155,188,189],[82,137,154,155,169,188],[82,94,97,100,101,137,154,155,180],[82,97,137,154,155,169,180],[82,97,101,137,154,155,180],[82,91,137,154,155],[82,95,137,154,155],[82,93,94,97,137,154,155,180],[82,137,154,155,157,177],[82,137,154,155,187],[82,91,137,154,155,187],[82,93,97,137,154,155,157,180],[82,88,89,90,92,96,137,148,154,155,169,180],[82,97,106,114,137,154,155],[82,89,95,137,154,155],[82,97,123,124,137,154,155],[82,89,92,97,137,154,155,172,180,187],[82,97,137,154,155],[82,93,97,137,154,155,180],[82,88,137,154,155],[82,91,92,93,95,96,97,98,99,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,124,125,126,127,128,137,154,155],[82,97,116,119,137,145,154,155],[82,97,106,107,108,137,154,155],[82,95,97,107,109,137,154,155],[82,96,137,154,155],[82,89,91,97,137,154,155],[82,97,101,107,109,137,154,155],[82,101,137,154,155],[82,95,97,100,137,154,155,180],[82,89,93,97,106,137,154,155],[82,97,116,137,154,155],[82,109,137,154,155],[82,91,97,123,137,154,155,172,185,187],[66,67,74,76,77,78,79,82,137,154,155,204],[66,67,82,137,154,155,215,216],[66,82,137,154,155,211],[66,82,137,154,155],[66,78,82,137,154,155],[66,67,77,82,137,154,155],[66,67,74,76,78,82,137,149,154,155,159,200,201,211,215,216,217,218,219,220],[66,82,137,149,154,155,159,211,213,219],[82,137,149,154,155,159,211,219,225,226],[67,74,76,78,82,137,149,154,155,159,200,211,219],[66,82,137,149,154,155,159,200,211,212,213,219,229],[66,82,137,149,154,155,200,204,211,212,213,219],[66,82,137,154,155,219,221,222,227,228,230,231],[65,72,75,82,137,154,155,198,201,207,208,209],[82,137,154,155,201,211],[82,137,149,154,155,158,159,201,211,223,224],[82,137,154,155,211],[66,82,137,149,154,155,159,168,201,206,210],[82,137,149,154,155,159,198,200,204,211],[82,137,149,154,155,159,185,200,201,210,211],[82,137,154,155,198],[65,67,82,137,154,155],[82,137,149,154,155,159],[66,67,77,82,137,154,155,198,200,204,205,212],[67,72,75,82,137,154,155,200,202,203],[82,137,154,155,201,202],[82,137,154,155,214],[82,137,154,155,198,214],[66,82,137,154,155,195,196,197,198,199,214],[64,65,67,68,69,70,71,72,73,82,137,154,155],[67,68,69,70,71,73,75,82,137,154,155],[82,137,148,154,155,185]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"0df3024c30df0b1bb7d123ea4b8ee02a669173b62515d96ecf8c7e6f80aaae51","impliedFormat":1},{"version":"31b18451a893dfdcc66e8158b545da91e4948defb7ecbf9655cdf764cdf16239","signature":"3acd4da63638c7f7ee8bd049117425286058b47d0b4f52f8a8e5f55707b3aef8"},{"version":"589b47edf2106984d1eb908cab2720ead5919362c3796f79be66c20e58e0c76e","signature":"98fc5091348128b56fd52a3f2f37fd6ea59f1739843163453d8809c26fb36430"},{"version":"71412a49e2a7383a1674be29ea0cc45d7c16094aa5bfe711811d34bd46cf1b7e","signature":"8dd93c97330b19206ecbc709c795304dec3143a813e1f0463f36c9009864fc6b"},{"version":"dbf8bd57043a0f093276f0668aafa27d9a0f63089c52d4bbf5b43360001d6562","signature":"8ea1f140369b9c745f0a8c9963bd5c26c837e3b67183ee37d914ed6a620e5a7a"},{"version":"6a7e55aef75c0e68fc7e788911278a5c3d1c3c9cbb67587db892c4fcc544c62e","signature":"a96c5beada828ea39e62963f8018b3cd73857a032cc69a26cb6ba06cd966b6ad"},{"version":"79d598d0be628a468f5ab4b75eb27d259851a05a4ea1cfa1ced68f13ea571729","signature":"963923058134a645699c7b1dcad788fb8378e955c4a5890932f8d21cbddef28b"},{"version":"49fc7d2956791bc79441e11cbd5773a77f324b7f32600ffbf624ff40665493d0","signature":"0095ec48dc2766276d1621694338e6b1c658a2754f1f9af1158ef7f95cd6198b"},{"version":"9ce5670123e3a99ae5d7edfa65c760f1ca8a5556af0fc53f1ce60b0a245b3bd4","signature":"59d1fe7f70a440cc262e4868b4b2810e54f788c7a40946410f9a058181b55a47"},{"version":"6ce9079d89f12c26cb55518558d0987760cd30806c578f661f398428520c6cf5","signature":"0d63d11d1c95b31ae4c7ef989ea38ca143597e3b0735fdf6e6ca89293f0dd72f"},{"version":"c8871748edb776546cb7970a919140ceb6653bd675b267f23b1a803c3a1d68a0","signature":"1857b762e2f35181f6c8d1bbe24485a887419dedee4e819978639ea3c256da64"},{"version":"593b93111f455184a408520ed50e1b861fddb542e297493ab48fee71753fd2fa","signature":"4d21491fade0dd125a6e4031ef487dbd7ff91ec1a2e13cf1854b7f74f1148f39"},{"version":"454538c4cc7a9bc50de0705b7f77d8b67ed2585478855d885bfddb8bc6949669","signature":"85fb0955c01b197f4650b8b8d1c98514d588b4112910d57d1b1888fa62b5d1b0"},{"version":"a27f461ff9434170bdb6fdc071aa2f81aa871dca8b8e37499bdc0b5e9f7a6469","signature":"7df15809a3a5761352fa4bf926bf0d69796777a2719ec2a053eed24f0e25bc7b"},{"version":"8e513cc75a85891e691af088e1988d3b40ee37106442412d9067a1f9e1eea1c9","signature":"cc10c19641eb586ced803854607aec353b01236deb1001b87df6ec1df9593f83"},{"version":"04758008b53814c382bb3d73e3f0df7f457d4ca06de84a4bd7e1c2bca5cbf2a1","signature":"e6cff38bf49d2494d0830baee5e3f436d748371858f8310db2006879ccc6b964"},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"378281aa35786c27d5811af7e6bcaa492eebd0c7013d48137c35bbc69a2b9751","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"1b2dd1cbeb0cc6ae20795958ba5950395ebb2849b7c8326853dd15530c77ab0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"387a023d363f755eb63450a66c28b14cdd7bc30a104565e2dbf0a8988bb4a56c","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"cdcf9ea426ad970f96ac930cd176d5c69c6c24eebd9fc580e1572d6c6a88f62c","impliedFormat":1},{"version":"23cd712e2ce083d68afe69224587438e5914b457b8acf87073c22494d706a3d0","impliedFormat":1},{"version":"156a859e21ef3244d13afeeba4e49760a6afa035c149dda52f0c45ea8903b338","impliedFormat":1},{"version":"10ec5e82144dfac6f04fa5d1d6c11763b3e4dbbac6d99101427219ab3e2ae887","impliedFormat":1},{"version":"615754924717c0b1e293e083b83503c0a872717ad5aa60ed7f1a699eb1b4ea5c","impliedFormat":1},{"version":"074de5b2fdead0165a2757e3aaef20f27a6347b1c36adea27d51456795b37682","impliedFormat":1},{"version":"68834d631c8838c715f225509cfc3927913b9cc7a4870460b5b60c8dbdb99baf","impliedFormat":1},{"version":"24371e69a38fc33e268d4a8716dbcda430d6c2c414a99ff9669239c4b8f40dea","impliedFormat":1},{"version":"ccab02f3920fc75c01174c47fcf67882a11daf16baf9e81701d0a94636e94556","impliedFormat":1},{"version":"3e11fce78ad8c0e1d1db4ba5f0652285509be3acdd519529bc8fcef85f7dafd9","impliedFormat":1},{"version":"ea6bc8de8b59f90a7a3960005fd01988f98fd0784e14bc6922dde2e93305ec7d","impliedFormat":1},{"version":"36107995674b29284a115e21a0618c4c2751b32a8766dd4cb3ba740308b16d59","impliedFormat":1},{"version":"914a0ae30d96d71915fc519ccb4efbf2b62c0ddfb3a3fc6129151076bc01dc60","impliedFormat":1},{"version":"9c32412007b5662fd34a8eb04292fb5314ec370d7016d1c2fb8aa193c807fe22","impliedFormat":1},{"version":"7fd1b31fd35876b0aa650811c25ec2c97a3c6387e5473eb18004bed86cdd76b6","impliedFormat":1},{"version":"4d327f7d72ad0918275cea3eee49a6a8dc8114ae1d5b7f3f5d0774de75f7439a","impliedFormat":1},{"version":"6ebe8ebb8659aaa9d1acbf3710d7dae3e923e97610238b9511c25dc39023a166","impliedFormat":1},{"version":"e85d7f8068f6a26710bff0cc8c0fc5e47f71089c3780fbede05857331d2ddec9","impliedFormat":1},{"version":"7befaf0e76b5671be1d47b77fcc65f2b0aad91cc26529df1904f4a7c46d216e9","impliedFormat":1},{"version":"0a60a292b89ca7218b8616f78e5bbd1c96b87e048849469cccb4355e98af959a","impliedFormat":1},{"version":"0b6e25234b4eec6ed96ab138d96eb70b135690d7dd01f3dd8a8ab291c35a683a","impliedFormat":1},{"version":"9666f2f84b985b62400d2e5ab0adae9ff44de9b2a34803c2c5bd3c8325b17dc0","impliedFormat":1},{"version":"40cd35c95e9cf22cfa5bd84e96408b6fcbca55295f4ff822390abb11afbc3dca","impliedFormat":1},{"version":"b1616b8959bf557feb16369c6124a97a0e74ed6f49d1df73bb4b9ddf68acf3f3","impliedFormat":1},{"version":"5b03a034c72146b61573aab280f295b015b9168470f2df05f6080a2122f9b4df","impliedFormat":1},{"version":"40b463c6766ca1b689bfcc46d26b5e295954f32ad43e37ee6953c0a677e4ae2b","impliedFormat":1},{"version":"249b9cab7f5d628b71308c7d9bb0a808b50b091e640ba3ed6e2d0516f4a8d91d","impliedFormat":1},{"version":"80aae6afc67faa5ac0b32b5b8bc8cc9f7fa299cff15cf09cc2e11fd28c6ae29e","impliedFormat":1},{"version":"f473cd2288991ff3221165dcf73cd5d24da30391f87e85b3dd4d0450c787a391","impliedFormat":1},{"version":"499e5b055a5aba1e1998f7311a6c441a369831c70905cc565ceac93c28083d53","impliedFormat":1},{"version":"8aee8b6d4f9f62cf3776cda1305fb18763e2aade7e13cea5bbe699112df85214","impliedFormat":1},{"version":"c63b9ada8c72f95aac5db92aea07e5e87ec810353cdf63b2d78f49a58662cf6c","impliedFormat":1},{"version":"1cc2a09e1a61a5222d4174ab358a9f9de5e906afe79dbf7363d871a7edda3955","impliedFormat":1},{"version":"5d0375ca7310efb77e3ef18d068d53784faf62705e0ad04569597ae0e755c401","impliedFormat":1},{"version":"59af37caec41ecf7b2e76059c9672a49e682c1a2aa6f9d7dc78878f53aa284d6","impliedFormat":1},{"version":"addf417b9eb3f938fddf8d81e96393a165e4be0d4a8b6402292f9c634b1cb00d","impliedFormat":1},{"version":"b64d4d1c5f877f9c666e98e833f0205edb9384acc46e98a1fef344f64d6aba44","impliedFormat":1},{"version":"adf27937dba6af9f08a68c5b1d3fce0ca7d4b960c57e6d6c844e7d1a8e53adae","impliedFormat":1},{"version":"12950411eeab8563b349cb7959543d92d8d02c289ed893d78499a19becb5a8cc","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"c9381908473a1c92cb8c516b184e75f4d226dad95c3a85a5af35f670064d9a2f","impliedFormat":1},{"version":"f724236417941ea77ec8d38c6b7021f5fb7f8521c7f8c1538e87661f2c6a0774","affectsGlobalScope":true,"impliedFormat":1},{"version":"1cf059eaf468efcc649f8cf6075d3cb98e9a35a0fe9c44419ec3d2f5428d7123","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d97fb21da858fb18b8ae72c314e9743fd52f73ebe2764e12af1db32fc03f853f","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ea15fd99b2e34cb25fe8346c955000bb70c8b423ae4377a972ef46bfb37f595","impliedFormat":1},{"version":"7cf69dd5502c41644c9e5106210b5da7144800670cbe861f66726fa209e231c4","impliedFormat":1},{"version":"72c1f5e0a28e473026074817561d1bc9647909cf253c8d56c41d1df8d95b85f7","impliedFormat":1},{"version":"f9b4137a0d285bd77dba2e6e895530112264310ae47e07bf311feae428fb8b61","affectsGlobalScope":true,"impliedFormat":1},{"version":"c06b2652ffeb89afd0f1c52c165ced77032f9cd09bc481153fbd6b5504c69494","impliedFormat":1},{"version":"51aecd2df90a3cffea1eb4696b33b2d78594ea2aa2138e6b9471ec4841c6c2ee","impliedFormat":1},{"version":"9d8f9e63e29a3396285620908e7f14d874d066caea747dc4b2c378f0599166b4","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"612422d5ba6b4a5c4537f423e9199645468ad80a689801da63ab7edb43f7b835","impliedFormat":1},{"version":"db9ada976f9e52e13f7ae8b9a320f4b67b87685938c5879187d8864b2fbe97f3","impliedFormat":1},{"version":"9f39e70a354d0fba29ac3cdf6eca00b7f9e96f64b2b2780c432e8ea27f133743","impliedFormat":1},{"version":"0dace96cc0f7bc6d0ee2044921bdf19fe42d16284dbcc8ae200800d1c9579335","impliedFormat":1},{"version":"a2e2bbde231b65c53c764c12313897ffdfb6c49183dd31823ee2405f2f7b5378","impliedFormat":1},{"version":"1cbdcdef62bf42688e5d825898c3a59458466c48ad8a4ef3f88d8a1cd04310d6","impliedFormat":1},{"version":"c64e1888baaa3253ca4405b455e4bf44f76357868a1bd0a52998ade9a092ad78","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc8c6f5322961b56d9906601b20798725df60baeab45ec014fba9f795d5596fd","impliedFormat":1},{"version":"67e435fa530778903f5525904e6645b7368eb5ac622055febd19bb399e328ccd","impliedFormat":1},{"version":"060d305fe4494d8cb2b99d620928d369d1ee55c1645f5e729a2aca07d0f108cb","impliedFormat":1},{"version":"5b22bf96be06fca1e134e3a85351ffe7aa2edf0c9a5bd175b7239ee48186dbf5","impliedFormat":1},{"version":"0c50296ee73dae94efc3f0da4936b1146ca6ce2217acfabb44c19c9a33fa30e5","impliedFormat":1},{"version":"bbf42f98a5819f4f06e18c8b669a994afe9a17fe520ae3454a195e6eabf7700d","impliedFormat":1},{"version":"5b48cc670da1dfe926036deaf349085caf822def460a6d50de23f1cc12a5f8cd","impliedFormat":1},{"version":"418f34087d52d001e2688a6282a5de9bf583ff771ed5546af0ae36e4f60a458b","affectsGlobalScope":true,"impliedFormat":1},{"version":"036c9a03b01281f99f8251fdc7088e894566be44b3f139a9d48501a978b611df","impliedFormat":1},{"version":"ff65b8a8bd380c6d129becc35de02f7c29ad7ce03300331ca91311fb4044d1a9","impliedFormat":1},{"version":"04bf1aa481d1adfb16d93d76e44ce71c51c8ef68039d849926551199489637f6","impliedFormat":1},{"version":"2c9adcc85574b002c9a6311ff2141055769e0071856ec979d92ff989042b1f1b","affectsGlobalScope":true,"impliedFormat":1},{"version":"1569ad5969ae0de6ad0bdfaaab0dabcd8878bc3147ab096206eed2019bb84e7f","affectsGlobalScope":true,"impliedFormat":1},{"version":"a58a15da4c5ba3df60c910a043281256fa52d36a0fcdef9b9100c646282e88dd","impliedFormat":1},{"version":"b36beffbf8acdc3ebc58c8bb4b75574b31a2169869c70fc03f82895b93950a12","impliedFormat":1},{"version":"42a350ce4f6f291198dc89833afcc4fd078248b4e1fdc9d05c846c66a670f710","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"8c81fd4a110490c43d7c578e8c6f69b3af01717189196899a6a44f93daa57a3a","impliedFormat":1},{"version":"5fb39858b2459864b139950a09adae4f38dad87c25bf572ce414f10e4bd7baab","impliedFormat":1},{"version":"b03754211d839cdc48979996525a32eb62130682c2f9801dfc2f25533ce7238d","impliedFormat":1},{"version":"3910dab597c40e173bf0e0d419d3ce9682c54ebf6ae84849f9b829b1451a17ec","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"486c074a5c0f2254345c0d1c9540380f5463999e42d7e1a159305ea823d3c4b1","affectsGlobalScope":true,"impliedFormat":1},{"version":"c119835edf36415081dfd9ed15fc0cd37aaa28d232be029ad073f15f3d88c323","impliedFormat":1},{"version":"f4d99ac08c4097a3cc202bec2c7198c19dcdd80d4ec6c62d1356b10d03b119d5","impliedFormat":1},{"version":"9705cd157ffbb91c5cab48bdd2de5a437a372e63f870f8a8472e72ff634d47c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"ae86f30d5d10e4f75ce8dcb6e1bd3a12ecec3d071a21e8f462c5c85c678efb41","impliedFormat":1},{"version":"ca77e83162eccec633513723d178d4203bdd5465297267696be08013bab0aa1d","impliedFormat":1},{"version":"e03460fe72b259f6d25ad029f085e4bedc3f90477da4401d8fbc1efa9793230e","impliedFormat":1},{"version":"4286a3a6619514fca656089aee160bb6f2e77f4dd53dc5a96b26a0b4fc778055","impliedFormat":1},{"version":"f61c153d5abbe4381a1fba0d41be0babdd5de51c626ee7ff14cede14dedc33f1","affectsGlobalScope":true,"impliedFormat":1},{"version":"7803171d745ab18e77f16bf82e742268ff72b7f7382ab191e4277527580c2d89","affectsGlobalScope":true,"impliedFormat":1},{"version":"0e9ba65cd3d6d194bdda7343f9f2917f7144ead96a924ca58d1a14919992dc20","impliedFormat":1},{"version":"255d948f87f24ffd57bcb2fdf95792fd418a2e1f712a98cf2cce88744d75085c","impliedFormat":1},{"version":"0d5b085f36e6dc55bc6332ecb9c733be3a534958c238fb8d8d18d4a2b6f2a15a","impliedFormat":1},{"version":"0b0dfb2d3e8420ead06f6a11acfb02ddcec42257e6ce391993e895ba0af86de4","affectsGlobalScope":true,"impliedFormat":1},{"version":"bfd3b3c21a56104693183942e221c1896ee23bcb8f8d91ab0b941f7b32985411","impliedFormat":1},{"version":"d7e9ab1b0996639047c61c1e62f85c620e4382206b3abb430d9a21fb7bc23c77","impliedFormat":1},{"version":"d2806f7b68a1533831bcfa0a72d50e4336a7341c1b8802ce9480d6799e9bc4f5","impliedFormat":1},{"version":"b9a9bf93f049cb3c766efa0ea6241991193a696d9838f7c16e5be854a48bceaf","impliedFormat":1},{"version":"994ab2ef8a87be9c16d2ddca21b0844eb14d6726fe05468c0e93d467c415b8a1","impliedFormat":1},{"version":"a356a366101a10fa309f074625eec5d51d5b0c90656ed62c0e8bdec5219837b5","impliedFormat":1},{"version":"7fb37e219b6e91f4295061b63868cd231e9f4021c307f396d6648df79766229a","impliedFormat":1},{"version":"de4e54f9dd0999029654135d5ad4716666c205f9324450baf982e10b19da4dd4","impliedFormat":1},{"version":"d6c16d18b8caf63c80e695525173e66bd771ff15bb4e1bbfbbf6c0045a236feb","impliedFormat":1},{"version":"7d59dcc9197c9a872c0d8bec846b3ad69b1d0ce8e78f5658a05c9c2d83ca1447","impliedFormat":1},{"version":"1a5e6c29ab30e8fe3b718b491303e4552b47c7930f8e6a1433ef62f1b45b9e32","impliedFormat":1},{"version":"cd758f1c3d4dedc862498f41d6544f390305fbc4fe1902c90ed50ff46802bcfa","signature":"f02a40c5b7520d527a400339836f67438927a52cc6b11a2c1d38bb7daf0df8b1"},{"version":"f0444158c4e84b2a656b6f8114ea363f48aae8c3a8720293dfa2df91b0fd675a","signature":"7d53549e4dde88f72b0b3db9f995f82cb68d6b3c171a7905d023d401a08318d2"},{"version":"c5e080893f95250d20a35df576fc13f85aa4259d3a3254b82db4e8797527c608","signature":"2dcd42dc3972f42e3b415b96f9072439ab6b7972a513d905a6d96dbdf2f869cf"},{"version":"909a53a6badbca96af14ee6fc635998d52074b80fd605114b77f8f26cc33b6e5","signature":"529ff564b0513164a1c6c2541fa7514131b4c816d65dbc172bd2130575d6d415"},{"version":"78e37a971813094af55aeb94a984975ac89fc93203ef9be3e8a04aad0c95cec1","signature":"784c4ce29dd51057ad472792a2437695b7345e8665738a49ef2153dcf09e4bc3"},{"version":"78e842f7a636b1f527ddc06fa27181282107b96234336f12a18fa95b68e44678","signature":"8509edb79c73edcde72ef16b57074af687efe3e8b5e3d73eae84ce68a67d9461"},{"version":"50ccf50d645d807e728ccead1ea6e8adea5f88bca6260b5e120772b0fcd87188","signature":"173b207c54834c37f208c98a03eddac27d5798260dfe95d38d482ebd3352e0a7"},{"version":"10fb4a09e37fc09c69ed578e8b2cee83c827cf18ed5812a22e4b3eb731268722","signature":"6b1560d38d963df46db84b648279801e19cb507dd016ae97a881ad0649954335"},{"version":"aefe3521550274d45e1eafc12acf8bd53a9f4f14b8271a82ccee62fccc82d833","signature":"b85fbb124083a076d5243a06aebcb7827af70d60a79d1bd3103005841f48f786"},{"version":"772236ee9d8380768b08362318c73460af14d4fb6b4945880002fca9ec7fc188","signature":"2fc2385a4df49a6855a2011b1d17b637a9c10ca3f6ab9f6caf9bd70e969073b5"},{"version":"4f0f521c3e550596664c0e2f7b1e00144cf003a1bbf95a6110bfcebff1943d2c","signature":"ef9feead1e6743148e5c4e85a0563a0fd92d59f5138c30c4527bf744ac3a0d55"},{"version":"5c855ee0553535df3fd43f77b4b0c46ca17357362ff321d1e541fa7e065900af","signature":"7752534b78a62464a2930a4778bf88e4c75bdd203d02e91ecef7982415735604"},{"version":"6781b8b0fa7aab693ed88853c874605879a0b17ee736b7ec1d6542100d1d95fb","signature":"eb24ac4188e14d346953e727dce4cff9862dba15938f2583929777553093c6f9"},{"version":"514fa467bed37b3bbf4fa295cd8db133b213dcdfe4aef9a19e9e99dd868c4937","signature":"2ac458815ba13b80da711c935e7a73a7fe4466015d5a11d90804ec07513ace89"},{"version":"c92f6f330888e60777ad64851e67c3b0290fd78d2fcbf6dc6ab42babbbbfb1a6","signature":"aad6f02558a19f62dd28836c98b36b0e087f950914953805a89bdbd3a8b927ad"},{"version":"e299652f5e5959b894cfd17545e668292bb64e9a58dbd316c68868ef90a76afc","signature":"b686d4582f744ca222e6c29871e7114ce83d805efe4286ab155dc1b014b5bf07"},{"version":"4704a596458f58bc97ed19af71c7284975877f7a4c008ba8225a23e3cfd7b982","signature":"5b498abd6ecfc929411994bd3b268ac8a1d930057f92f088f2d3b21cdcee3ff2"},"761042f7def8ac25af4395ef3fcbe3ee9a01bbf88aaf1a959435710020dc33e7",{"version":"9139f4769fe4a9737a03a25c0de887c2e51d0790eb69db33290ea563d1a19816","signature":"c4fb8a0f3f3d4ca3b9c3ccf8c841450caad67bb2d1cf9870d3fba9d7afd906e2"},{"version":"0f41fd58527b6191b294c8dc8f6547e584dbfc7811b33786f5c540969d7c24ab","signature":"a3be6822a6e3f9b309af7f4adfc5327c9af6db546e82077ef9262d997b236df6"},{"version":"ec38c06860ce480ad66069e64ffca2ad6098d1b78386e0e3b52ace8f4ce5d6b8","signature":"ed1c0a9834df25b836f147e57eed95e662ec7bb3ed563c29023fe35e6e7f2781"},{"version":"5976c615e8a5c03480bd11d0e309a88a252e914857dedaec94a55cd7ffd3f814","signature":"9a66ee5f0d928381f26c2b6a2a7164d23bb17696ea371b6027d1d939bf9cbcbb"},{"version":"5fa3f03aae0f8c0d455a742c8d13415c654c592551bbeafd7340071d7e63b6d4","signature":"8b92d8c784772b011c19170c3698e8caa724e7936cfb053888b0e798a6ab9c34"},{"version":"e2de8e78f329083f9d63aa04da8c9788f8087c503f9d688597f4a89459cc2638","signature":"58b8a92502891f00e8525f156ef0f4cb1f31088fe5c7afe371b75c5b9d6de6ef"},{"version":"6addcfb754a091abca4ec952330421d85cd5de44a68c8d0bc04a55f07aa629f5","signature":"c7cf07567328a1256168b6b20aa0e3c68ce394cab81ba50a63bc37b1f4964117"},{"version":"419e60fcda0e1a42092e173f63d12c4954e41e3fcb2c5d0f9bb819ec5f0bcef7","signature":"f0f23fb249e8a350554f074841f4fd81b533af2e585eca66c8337972a85bb9f9"},{"version":"9241ec0a181d4058d7a5d6061a633ed160730343fb9f936f2abb1eb0c47d0be6","signature":"05a26a029742d2bb5be847aa08ff97e32eafccd632a2874787397af1e1615045"},{"version":"2d97baa4c69ec4e5e8e878d331fbd2e6b55703795911e79e9b01859dc7c83e8f","signature":"fd0114eab35d9a4663f0c43d5753d169701a3e2d826c88d2ce70018708ce2b0a"},{"version":"a7aebaad76069144de1aa3260e880c9293c7d0f4c463a9c3240f02e55a610e51","signature":"b090778e899e8c650ed8576cd1397bb4829fea5a42cb876ea9eb15130717247b"},{"version":"2b438b959baddb6a435f39192f2af29a083e9686eeef1b64831246397fbd2456","signature":"f6444f20af7fb78da6fa1c2741a13c3992ba56e003cfd8e11765ed6a76eb8702"},{"version":"8194b458b91478dee20dff591cf489da6c86a4f0149764b0c7d0fc222add3bbb","signature":"ce0d69997971e7911d0678361cc90a5db735f777775552005bcad4df909e7cc9"},{"version":"4da1276835404d327af8d2473045d38ecfa729afae23db7bb8a3cbbc5731785a","signature":"ac6c2d13a2611ecd493a4559bc38edd3e717b794819c2f0793d57aaf8124c315"},{"version":"db86e53523e57f90fb85c6f716cc667e09b8adaade43dcd56862496e95c91d42","signature":"6e83177938d46f22dfd0617b424bf8ddb8d4021b10f36df5f7d49b6ac44a572f"},{"version":"1411ab908072924d565a80c630d52dde1410753a9d9e558d376f0586e565cb91","signature":"eff12d10abc71233147232e6013930694e84664a969aa4276711da23d7c237f8"},{"version":"91432dc8f7edc1bbb00ac3a7ceda5d76d2e27d3930d534226853d3c70a9d72c5","signature":"26df63a4cf13e015eb455000154dc5d28701fb99d8da156da7003897b5ddaa0a"},{"version":"6e4ee2c61ba1fa1e24b41a4a663641dc963203f0e36b9e36cf0596acc0ebd66f","signature":"8d5d974b6af785f4533176dd3e13d50497b869d5dbe56204d05ed2f6d19a4690"},{"version":"d5799bcf7fe4e6de3063abf4e321c14b051706f03cf5716d8a19f22fe1f69519","impliedFormat":1},{"version":"751764bb94219b4ce8f5475dc35d3de2e432fea01a0c9610cd7f69ad05e398c6","impliedFormat":1},{"version":"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","impliedFormat":1}],"root":[[65,79],[197,232]],"options":{"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":false,"module":1,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":false,"noUncheckedIndexedAccess":true,"outDir":"./","rootDir":"../src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":10,"tsBuildInfoFile":"./.tsbuildinfo"},"referencedMap":[[233,1],[234,1],[235,1],[134,2],[135,2],[136,3],[82,4],[137,5],[138,6],[139,7],[80,1],[140,8],[141,9],[142,10],[143,11],[144,12],[145,13],[146,13],[147,14],[148,15],[149,16],[150,17],[83,1],[81,1],[151,18],[152,19],[153,20],[187,21],[154,22],[155,1],[156,23],[157,24],[158,25],[159,26],[160,27],[161,28],[162,29],[163,30],[164,31],[165,31],[166,32],[167,1],[168,33],[169,34],[171,35],[170,36],[172,37],[173,38],[174,39],[175,40],[176,41],[177,42],[178,43],[179,44],[180,45],[181,46],[182,47],[183,48],[184,49],[84,1],[85,50],[86,1],[87,1],[130,51],[131,52],[132,1],[133,37],[185,53],[186,54],[196,55],[194,56],[188,57],[191,58],[190,56],[195,59],[192,56],[193,56],[189,60],[64,1],[62,1],[63,1],[12,1],[11,1],[2,1],[13,1],[14,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],[3,1],[21,1],[22,1],[4,1],[23,1],[27,1],[24,1],[25,1],[26,1],[28,1],[29,1],[30,1],[5,1],[31,1],[32,1],[33,1],[34,1],[6,1],[38,1],[35,1],[36,1],[37,1],[39,1],[7,1],[40,1],[45,1],[46,1],[41,1],[42,1],[43,1],[44,1],[8,1],[50,1],[47,1],[48,1],[49,1],[51,1],[9,1],[52,1],[53,1],[54,1],[56,1],[55,1],[57,1],[58,1],[10,1],[59,1],[1,1],[60,1],[61,1],[106,61],[118,62],[103,63],[119,58],[128,64],[94,65],[95,66],[93,67],[127,68],[122,69],[126,70],[97,71],[115,72],[96,73],[125,74],[91,75],[92,69],[98,76],[99,1],[105,77],[102,76],[89,78],[129,79],[120,80],[109,81],[108,76],[110,82],[113,83],[107,84],[111,85],[123,68],[100,86],[101,87],[114,88],[90,58],[117,89],[116,76],[104,87],[112,90],[121,1],[88,1],[124,91],[205,92],[215,1],[217,93],[216,1],[218,94],[72,1],[75,1],[77,95],[79,96],[78,97],[221,98],[219,1],[222,99],[227,100],[228,101],[230,102],[231,103],[232,104],[210,105],[206,1],[220,106],[225,107],[226,108],[211,109],[212,110],[224,111],[207,112],[71,113],[69,113],[65,114],[68,113],[70,113],[208,112],[229,95],[213,115],[204,116],[202,1],[203,117],[197,118],[199,119],[198,95],[200,120],[73,113],[74,121],[76,122],[67,95],[66,1],[201,50],[209,1],[223,123],[214,1]],"version":"5.9.3"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content first API.
|
|
3
|
+
*
|
|
4
|
+
* `extract()` takes a raw RFC 5322 message and does its own MIME parsing. Most callers do not have
|
|
5
|
+
* one: they have already parsed the message, with mailparser, postal-mime, EmailEngine or an IMAP
|
|
6
|
+
* client, and hold `{ text, html, subject }`. Re-serialising that back into a message just to parse
|
|
7
|
+
* it again would be wasteful and lossy.
|
|
8
|
+
*
|
|
9
|
+
* `analyze()` is the same pipeline entered one stage later. Stage 1 is skipped, Stages 2 to 8 are
|
|
10
|
+
* identical, and the result has the same shape. Everything the extractor decides is derived from
|
|
11
|
+
* the bodies themselves, so nothing is lost by not having the envelope.
|
|
12
|
+
*/
|
|
13
|
+
import { type ConfidenceConfig } from './classify/confidence';
|
|
14
|
+
import { type HistoryDocument } from './match/history';
|
|
15
|
+
import { type Reason, type Segment, type Warning } from './types';
|
|
16
|
+
/** A message body, in whichever representations are available. */
|
|
17
|
+
export interface MessageContent {
|
|
18
|
+
/** Plain text body, already transfer and charset decoded. */
|
|
19
|
+
text?: string | null;
|
|
20
|
+
/** HTML body, already transfer and charset decoded. */
|
|
21
|
+
html?: string | null;
|
|
22
|
+
/** Subject line. Optional, and never allowed to change a label on its own. */
|
|
23
|
+
subject?: string | null;
|
|
24
|
+
/** Sender, as a display name and/or address. Used only as signature evidence. */
|
|
25
|
+
from?: string | null;
|
|
26
|
+
/** Threading hints. Optional, used only to note whether the message looks like a reply. */
|
|
27
|
+
inReplyTo?: string | null;
|
|
28
|
+
references?: readonly string[];
|
|
29
|
+
/** MIME part ids, when the caller knows them, purely for traceability in the output. */
|
|
30
|
+
textPartId?: string;
|
|
31
|
+
htmlPartId?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface AnalyzeOptions {
|
|
34
|
+
confidence?: ConfidenceConfig;
|
|
35
|
+
/**
|
|
36
|
+
* Earlier messages in the thread, nearest first. Each may be raw RFC 5322 or already split
|
|
37
|
+
* content. History is optional and only ever adds evidence.
|
|
38
|
+
*/
|
|
39
|
+
history?: readonly (MessageContent | string | Buffer)[];
|
|
40
|
+
/** Pre-built history documents, for callers that resolve and cache threads themselves. */
|
|
41
|
+
historyDocuments?: readonly HistoryDocument[];
|
|
42
|
+
explain?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface AnalyzeResult {
|
|
45
|
+
/** Segments the client should render, in document order. */
|
|
46
|
+
segments: Segment[];
|
|
47
|
+
/** Segments the client may hide or collapse. Retained in full so nothing is ever lost. */
|
|
48
|
+
hiddenSegments: Segment[];
|
|
49
|
+
overallConfidence: number;
|
|
50
|
+
warnings: Warning[];
|
|
51
|
+
originalAvailable: true;
|
|
52
|
+
primaryRepresentation: 'text' | 'html' | 'none';
|
|
53
|
+
extractorVersion: string;
|
|
54
|
+
historyUsed: boolean;
|
|
55
|
+
/** True when the input looked like a reply, from threading headers or a subject prefix. */
|
|
56
|
+
isReply: boolean;
|
|
57
|
+
diagnostics?: {
|
|
58
|
+
primaryPart: string | null;
|
|
59
|
+
blocks: {
|
|
60
|
+
index: number;
|
|
61
|
+
kind: string;
|
|
62
|
+
label: string;
|
|
63
|
+
confidence: number;
|
|
64
|
+
reasons: Reason[];
|
|
65
|
+
evidence: {
|
|
66
|
+
id: string;
|
|
67
|
+
kind: string;
|
|
68
|
+
strength: number;
|
|
69
|
+
}[];
|
|
70
|
+
features: Record<string, unknown>;
|
|
71
|
+
preview: string;
|
|
72
|
+
}[];
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Name tokens from a From header, for signature detection.
|
|
77
|
+
*
|
|
78
|
+
* Takes the display name words and the address local part, keeping tokens long enough to be
|
|
79
|
+
* distinctive. Short tokens are dropped because a two letter name fragment matches everywhere.
|
|
80
|
+
*/
|
|
81
|
+
export declare function senderTokensFrom(from: string | null | undefined): string[];
|
|
82
|
+
/** Turn whatever the caller supplied as history into searchable documents. */
|
|
83
|
+
export declare function resolveHistory(options: AnalyzeOptions): Promise<HistoryDocument[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Analyse an already parsed message body.
|
|
86
|
+
*
|
|
87
|
+
* Never throws. A body that cannot be segmented is returned whole as a single visible `UNKNOWN`
|
|
88
|
+
* segment, because showing too much is always preferable to showing nothing.
|
|
89
|
+
*/
|
|
90
|
+
export declare function analyze(content: MessageContent, options?: AnalyzeOptions): Promise<AnalyzeResult>;
|
|
91
|
+
//# sourceMappingURL=analyze.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../src/analyze.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,EAAwD,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACpH,OAAO,EAAsF,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC3I,OAAO,EAAqB,KAAK,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAErF,kEAAkE;AAClE,MAAM,WAAW,cAAc;IAC3B,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,2FAA2F;IAC3F,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC3B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACxD,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC1B,4DAA4D;IAC5D,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,0FAA0F;IAC1F,cAAc,EAAE,OAAO,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,iBAAiB,EAAE,IAAI,CAAC;IACxB,qBAAqB,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,2FAA2F;IAC3F,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE;QACV,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,MAAM,EAAE;YACJ,KAAK,EAAE,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,EAAE,MAAM,CAAC;YACnB,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,QAAQ,EAAE;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAC;gBAAC,QAAQ,EAAE,MAAM,CAAA;aAAE,EAAE,CAAC;YAC3D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAClC,OAAO,EAAE,MAAM,CAAC;SACnB,EAAE,CAAC;KACP,CAAC;CACL;AAiBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE,CAa1E;AAoED,8EAA8E;AAC9E,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAkBxF;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAuI3G"}
|