@toa.io/extensions.fetch 1.0.0-alpha.273 → 1.0.0-alpha.277
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/CHANGELOG.md +7 -0
- package/package.json +5 -8
- package/source/Aspect.test.ts +71 -73
- package/source/Factory.ts +1 -1
- package/source/index.ts +2 -2
- package/transpiled/Aspect.js +4 -8
- package/transpiled/Aspect.js.map +1 -1
- package/transpiled/Aspect.test.js +73 -79
- package/transpiled/Aspect.test.js.map +1 -1
- package/transpiled/Factory.js +3 -7
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/index.d.ts +2 -2
- package/transpiled/index.js +1 -5
- package/transpiled/index.js.map +1 -1
- package/tsconfig.json +2 -1
- package/tsconfig.tsbuildinfo +1 -0
- package/transpiled/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [1.0.0-alpha.277](https://github.com/toa-io/toa/compare/v1.0.0-alpha.276...v1.0.0-alpha.277) (2026-09-03)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* drop the build output that landed beside the sources ([a724f69](https://github.com/toa-io/toa/commit/a724f6921190e5c9d945e33c6035bb12d832e5c8))
|
|
11
|
+
|
|
12
|
+
|
|
6
13
|
# [1.0.0-alpha.273](https://github.com/toa-io/toa/compare/v1.0.0-alpha.272...v1.0.0-alpha.273) (2026-09-02)
|
|
7
14
|
|
|
8
15
|
**Note:** Version bump only for package @toa.io/extensions.fetch
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/extensions.fetch",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.277",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Toa Fetch extension",
|
|
5
6
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
7
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -20,12 +21,8 @@
|
|
|
20
21
|
"transpile": "tsc"
|
|
21
22
|
},
|
|
22
23
|
"dependencies": {
|
|
23
|
-
"@toa.io/core": "1.0.0-alpha.
|
|
24
|
-
"openspan": "1.0.0-alpha.
|
|
24
|
+
"@toa.io/core": "1.0.0-alpha.277",
|
|
25
|
+
"openspan": "1.0.0-alpha.277"
|
|
25
26
|
},
|
|
26
|
-
"
|
|
27
|
-
"preset": "ts-jest",
|
|
28
|
-
"testEnvironment": "node"
|
|
29
|
-
},
|
|
30
|
-
"gitHead": "ad3284850ece95ffd5325fd0995707fc144c9c3d"
|
|
27
|
+
"gitHead": "0c0071418c2c56a44e621ba5ced5cdd23dff1738"
|
|
31
28
|
}
|
package/source/Aspect.test.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
|
+
import { it, beforeEach, afterEach, mock } from 'node:test'
|
|
2
|
+
import type { Mock } from 'node:test'
|
|
3
|
+
import assert from 'node:assert/strict'
|
|
4
|
+
|
|
1
5
|
import { Locator } from '@toa.io/core'
|
|
2
6
|
import { consoleExporter, exporting } from 'openspan'
|
|
3
|
-
import { Aspect } from './Aspect'
|
|
7
|
+
import { Aspect } from './Aspect.js'
|
|
4
8
|
import type { Span } from 'openspan'
|
|
5
9
|
|
|
6
10
|
const nativeFetch = globalThis.fetch
|
|
7
11
|
|
|
8
12
|
let aspect: Aspect
|
|
9
|
-
let fetchMock:
|
|
13
|
+
let fetchMock: Mock<typeof fetch>
|
|
10
14
|
let spans: Span[]
|
|
11
15
|
|
|
12
16
|
beforeEach(() => {
|
|
13
17
|
aspect = new Aspect(new Locator('users', 'identity'))
|
|
14
|
-
fetchMock =
|
|
18
|
+
fetchMock = mock.fn()
|
|
15
19
|
globalThis.fetch = fetchMock
|
|
16
20
|
spans = []
|
|
17
21
|
exporting([{ export: (span) => spans.push(span) }])
|
|
@@ -25,7 +29,7 @@ afterEach(() => {
|
|
|
25
29
|
it('delegates to native fetch and returns its Response', async () => {
|
|
26
30
|
const response = new Response('ok', { status: 201, headers: { 'x-test': 'yes' } })
|
|
27
31
|
|
|
28
|
-
fetchMock.
|
|
32
|
+
fetchMock.mock.mockImplementation(async () => response)
|
|
29
33
|
|
|
30
34
|
const result = await aspect.invoke('create', 'https://example.com/items?secret=yes', {
|
|
31
35
|
method: 'POST',
|
|
@@ -33,52 +37,50 @@ it('delegates to native fetch and returns its Response', async () => {
|
|
|
33
37
|
body: '{}'
|
|
34
38
|
})
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
assert.strictEqual(result, response)
|
|
41
|
+
assert.strictEqual(fetchMock.mock.callCount(), 1)
|
|
38
42
|
|
|
39
|
-
const request = fetchMock.mock.calls[0][0] as Request
|
|
43
|
+
const request = fetchMock.mock.calls[0].arguments[0] as Request
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
await
|
|
45
|
+
assert.ok(request instanceof Request)
|
|
46
|
+
assert.strictEqual(request.method, 'POST')
|
|
47
|
+
assert.strictEqual(request.url, 'https://example.com/items?secret=yes')
|
|
48
|
+
await assert.strictEqual(await request.text(), '{}')
|
|
45
49
|
})
|
|
46
50
|
|
|
47
51
|
it('does not retry by default', async () => {
|
|
48
|
-
fetchMock.
|
|
52
|
+
fetchMock.mock.mockImplementation(async () => new Response(null, { status: 503 }))
|
|
49
53
|
|
|
50
54
|
const response = await aspect.invoke('get', 'https://example.com')
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
assert.strictEqual(response.status, 503)
|
|
57
|
+
assert.strictEqual(fetchMock.mock.callCount(), 1)
|
|
54
58
|
})
|
|
55
59
|
|
|
56
60
|
it('retries unexpected responses and returns an expected response', async () => {
|
|
57
|
-
fetchMock
|
|
58
|
-
|
|
59
|
-
.mockResolvedValueOnce(new Response(null, { status: 201 }))
|
|
61
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 503 }), fetchMock.mock.callCount())
|
|
62
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 201 }), fetchMock.mock.callCount() + 1)
|
|
60
63
|
|
|
61
64
|
const response = await aspect.invoke('create', 'https://example.com', {
|
|
62
65
|
retry: { attempts: 3, expected: [201], delay: 0 }
|
|
63
66
|
})
|
|
64
67
|
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
assert.strictEqual(response.status, 201)
|
|
69
|
+
assert.strictEqual(fetchMock.mock.callCount(), 2)
|
|
67
70
|
})
|
|
68
71
|
|
|
69
72
|
it('cancels an unexpected response body before retrying', async () => {
|
|
70
|
-
const cancel =
|
|
73
|
+
const cancel = mock.fn()
|
|
71
74
|
const body = new ReadableStream({ cancel })
|
|
72
75
|
|
|
73
|
-
fetchMock
|
|
74
|
-
|
|
75
|
-
.mockResolvedValueOnce(new Response(null, { status: 200 }))
|
|
76
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(body, { status: 503 }), fetchMock.mock.callCount())
|
|
77
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 200 }), fetchMock.mock.callCount() + 1)
|
|
76
78
|
|
|
77
79
|
await aspect.invoke('get', 'https://example.com', {
|
|
78
80
|
retry: { attempts: 2, delay: 0 }
|
|
79
81
|
})
|
|
80
82
|
|
|
81
|
-
|
|
83
|
+
assert.strictEqual(cancel.mock.callCount(), 1)
|
|
82
84
|
})
|
|
83
85
|
|
|
84
86
|
it('continues retrying when response body cancellation fails', async () => {
|
|
@@ -88,21 +90,19 @@ it('continues retrying when response body cancellation fails', async () => {
|
|
|
88
90
|
}
|
|
89
91
|
})
|
|
90
92
|
|
|
91
|
-
fetchMock
|
|
92
|
-
|
|
93
|
-
.mockResolvedValueOnce(new Response(null, { status: 200 }))
|
|
93
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(body, { status: 503 }), fetchMock.mock.callCount())
|
|
94
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 200 }), fetchMock.mock.callCount() + 1)
|
|
94
95
|
|
|
95
96
|
const response = await aspect.invoke('get', 'https://example.com', {
|
|
96
97
|
retry: { attempts: 2, delay: 0 }
|
|
97
98
|
})
|
|
98
99
|
|
|
99
|
-
|
|
100
|
+
assert.strictEqual(response.status, 200)
|
|
100
101
|
})
|
|
101
102
|
|
|
102
103
|
it('replays a regular request body', async () => {
|
|
103
|
-
fetchMock
|
|
104
|
-
|
|
105
|
-
.mockResolvedValueOnce(new Response(null, { status: 200 }))
|
|
104
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 503 }), fetchMock.mock.callCount())
|
|
105
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 200 }), fetchMock.mock.callCount() + 1)
|
|
106
106
|
|
|
107
107
|
await aspect.invoke('create', 'https://example.com', {
|
|
108
108
|
method: 'POST',
|
|
@@ -110,58 +110,57 @@ it('replays a regular request body', async () => {
|
|
|
110
110
|
retry: { attempts: 2, delay: 0 }
|
|
111
111
|
})
|
|
112
112
|
|
|
113
|
-
const first = fetchMock.mock.calls[0][0] as Request
|
|
114
|
-
const second = fetchMock.mock.calls[1][0] as Request
|
|
113
|
+
const first = fetchMock.mock.calls[0].arguments[0] as Request
|
|
114
|
+
const second = fetchMock.mock.calls[1].arguments[0] as Request
|
|
115
115
|
|
|
116
|
-
await
|
|
117
|
-
await
|
|
116
|
+
await assert.strictEqual(await first.text(), 'hello')
|
|
117
|
+
await assert.strictEqual(await second.text(), 'hello')
|
|
118
118
|
})
|
|
119
119
|
|
|
120
120
|
it('honors Retry-After instead of the configured delay', async () => {
|
|
121
|
-
fetchMock
|
|
122
|
-
.mockResolvedValueOnce(new Response(null, {
|
|
121
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, {
|
|
123
122
|
status: 503,
|
|
124
123
|
headers: { 'retry-after': '0' }
|
|
125
|
-
}))
|
|
126
|
-
|
|
124
|
+
}), fetchMock.mock.callCount())
|
|
125
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 200 }), fetchMock.mock.callCount() + 1)
|
|
127
126
|
|
|
128
127
|
const response = await aspect.invoke('get', 'https://example.com', {
|
|
129
128
|
retry: { attempts: 2, delay: 60_000 }
|
|
130
129
|
})
|
|
131
130
|
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
assert.strictEqual(response.status, 200)
|
|
132
|
+
assert.strictEqual(fetchMock.mock.callCount(), 2)
|
|
134
133
|
})
|
|
135
134
|
|
|
136
135
|
it('returns the last unexpected response', async () => {
|
|
137
|
-
fetchMock
|
|
138
|
-
|
|
139
|
-
.mockResolvedValueOnce(new Response(null, { status: 502 }))
|
|
136
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 500 }), fetchMock.mock.callCount())
|
|
137
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 502 }), fetchMock.mock.callCount() + 1)
|
|
140
138
|
|
|
141
139
|
const response = await aspect.invoke('get', 'https://example.com', {
|
|
142
140
|
retry: { attempts: 2, delay: 0 }
|
|
143
141
|
})
|
|
144
142
|
|
|
145
|
-
|
|
143
|
+
assert.strictEqual(response.status, 502)
|
|
146
144
|
})
|
|
147
145
|
|
|
148
146
|
it('retries network errors and throws the final error', async () => {
|
|
149
147
|
const first = new Error('first')
|
|
150
148
|
const last = new Error('last')
|
|
151
149
|
|
|
152
|
-
fetchMock.
|
|
150
|
+
fetchMock.mock.mockImplementationOnce(async () => { throw first }, fetchMock.mock.callCount())
|
|
151
|
+
fetchMock.mock.mockImplementationOnce(async () => { throw last }, fetchMock.mock.callCount() + 1)
|
|
153
152
|
|
|
154
|
-
await
|
|
153
|
+
await assert.rejects(aspect.invoke('get', 'https://example.com', {
|
|
155
154
|
retry: { attempts: 2, delay: 0 }
|
|
156
|
-
})).
|
|
155
|
+
}), (error: any) => { assert.strictEqual(error, last); return true })
|
|
157
156
|
|
|
158
|
-
|
|
157
|
+
assert.strictEqual(fetchMock.mock.callCount(), 2)
|
|
159
158
|
})
|
|
160
159
|
|
|
161
160
|
it('aborts while waiting for another attempt', async () => {
|
|
162
161
|
const controller = new AbortController()
|
|
163
162
|
|
|
164
|
-
fetchMock.
|
|
163
|
+
fetchMock.mock.mockImplementation(async () => new Response(null, { status: 503 }))
|
|
165
164
|
|
|
166
165
|
const promise = aspect.invoke('get', 'https://example.com', {
|
|
167
166
|
signal: controller.signal,
|
|
@@ -171,61 +170,60 @@ it('aborts while waiting for another attempt', async () => {
|
|
|
171
170
|
await new Promise((resolve) => setImmediate(resolve))
|
|
172
171
|
controller.abort(new Error('cancelled'))
|
|
173
172
|
|
|
174
|
-
await
|
|
175
|
-
|
|
173
|
+
await assert.rejects(promise, (error: any) => /cancelled/.test(error.message))
|
|
174
|
+
assert.strictEqual(fetchMock.mock.callCount(), 1)
|
|
176
175
|
})
|
|
177
176
|
|
|
178
177
|
it('rejects invalid retry options', async () => {
|
|
179
|
-
await
|
|
178
|
+
await assert.rejects(aspect.invoke('get', 'https://example.com', {
|
|
180
179
|
retry: { attempts: 0 }
|
|
181
|
-
}))
|
|
180
|
+
}), (error: any) => /retry\.attempts/.test(error.message))
|
|
182
181
|
|
|
183
|
-
await
|
|
182
|
+
await assert.rejects(aspect.invoke('get', 'https://example.com', {
|
|
184
183
|
retry: { attempts: 2, expected: [] }
|
|
185
|
-
}))
|
|
184
|
+
}), (error: any) => /retry\.expected/.test(error.message))
|
|
186
185
|
})
|
|
187
186
|
|
|
188
187
|
it('rejects an explicit streaming body before sending it', async () => {
|
|
189
188
|
const body = new ReadableStream()
|
|
190
189
|
|
|
191
|
-
await
|
|
190
|
+
await assert.rejects(aspect.invoke('create', 'https://example.com', {
|
|
192
191
|
method: 'POST',
|
|
193
192
|
body,
|
|
194
193
|
// Required by Node.js for a streaming request body.
|
|
195
194
|
// @ts-expect-error -- duplex is implemented by Node but absent from lib.dom RequestInit.
|
|
196
195
|
duplex: 'half',
|
|
197
196
|
retry: { attempts: 2 }
|
|
198
|
-
}))
|
|
197
|
+
}), (error: any) => /non-replayable/.test(error.message))
|
|
199
198
|
|
|
200
|
-
|
|
199
|
+
assert.strictEqual(fetchMock.mock.callCount(), 0)
|
|
201
200
|
})
|
|
202
201
|
|
|
203
202
|
it('rejects a Request input with a body before retrying', async () => {
|
|
204
203
|
const request = new Request('https://example.com', { method: 'POST', body: 'hello' })
|
|
205
204
|
|
|
206
|
-
await
|
|
205
|
+
await assert.rejects(aspect.invoke('create', request, {
|
|
207
206
|
retry: { attempts: 2 }
|
|
208
|
-
}))
|
|
207
|
+
}), (error: any) => /non-replayable/.test(error.message))
|
|
209
208
|
|
|
210
|
-
|
|
209
|
+
assert.strictEqual(fetchMock.mock.callCount(), 0)
|
|
211
210
|
})
|
|
212
211
|
|
|
213
212
|
it('creates a scoped parent span with a client span for each attempt', async () => {
|
|
214
|
-
fetchMock
|
|
215
|
-
|
|
216
|
-
.mockResolvedValueOnce(new Response(null, { status: 204 }))
|
|
213
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 503 }), fetchMock.mock.callCount())
|
|
214
|
+
fetchMock.mock.mockImplementationOnce(async () => new Response(null, { status: 204 }), fetchMock.mock.callCount() + 1)
|
|
217
215
|
|
|
218
216
|
await aspect.invoke('update', 'https://example.com/items?token=secret', {
|
|
219
217
|
method: 'PUT',
|
|
220
218
|
retry: { attempts: 2, delay: 0 }
|
|
221
219
|
})
|
|
222
220
|
|
|
223
|
-
|
|
221
|
+
assert.strictEqual(spans.length, 3)
|
|
224
222
|
|
|
225
223
|
const parent = spans.find((span) => span.name === 'PUT https://example.com')!
|
|
226
224
|
const attempts = spans.filter((span) => span.parentId === parent.spanId)
|
|
227
225
|
|
|
228
|
-
|
|
226
|
+
assert.partialDeepStrictEqual(parent, {
|
|
229
227
|
name: 'PUT https://example.com',
|
|
230
228
|
kind: 'internal',
|
|
231
229
|
scope: {
|
|
@@ -241,7 +239,7 @@ it('creates a scoped parent span with a client span for each attempt', async ()
|
|
|
241
239
|
'retry.attempts': 2
|
|
242
240
|
}
|
|
243
241
|
})
|
|
244
|
-
|
|
242
|
+
assert.partialDeepStrictEqual(attempts, [
|
|
245
243
|
{
|
|
246
244
|
name: 'attempt 1',
|
|
247
245
|
kind: 'client',
|
|
@@ -259,14 +257,14 @@ it('creates a scoped parent span with a client span for each attempt', async ()
|
|
|
259
257
|
}
|
|
260
258
|
}
|
|
261
259
|
])
|
|
262
|
-
|
|
260
|
+
assert.ok(!(JSON.stringify(spans).includes('token=secret')))
|
|
263
261
|
})
|
|
264
262
|
|
|
265
263
|
it('marks the span as failed after a final network error', async () => {
|
|
266
|
-
fetchMock.
|
|
264
|
+
fetchMock.mock.mockImplementation(async () => { throw new Error('unavailable') })
|
|
267
265
|
|
|
268
|
-
await
|
|
266
|
+
await assert.rejects(aspect.invoke('get', 'https://example.com'), (error: any) => /unavailable/.test(error.message))
|
|
269
267
|
|
|
270
|
-
|
|
271
|
-
|
|
268
|
+
assert.strictEqual(spans.length, 2)
|
|
269
|
+
assert.strictEqual(spans.every((span) => span.status === 'error'), true)
|
|
272
270
|
})
|
package/source/Factory.ts
CHANGED
package/source/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Factory } from './Factory'
|
|
2
|
-
export type { FetchInit, RetryOptions } from './Aspect'
|
|
1
|
+
export { Factory } from './Factory.js'
|
|
2
|
+
export type { FetchInit, RetryOptions } from './Aspect.js'
|
package/transpiled/Aspect.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const core_1 = require("@toa.io/core");
|
|
5
|
-
const openspan_1 = require("openspan");
|
|
6
|
-
class Aspect extends core_1.Connector {
|
|
1
|
+
import { Connector } from '@toa.io/core';
|
|
2
|
+
import { console } from 'openspan';
|
|
3
|
+
export class Aspect extends Connector {
|
|
7
4
|
name = 'fetch';
|
|
8
5
|
locator;
|
|
9
6
|
consoles = {};
|
|
@@ -38,7 +35,7 @@ class Aspect extends core_1.Connector {
|
|
|
38
35
|
});
|
|
39
36
|
}
|
|
40
37
|
output(operation) {
|
|
41
|
-
this.consoles[operation] ??=
|
|
38
|
+
this.consoles[operation] ??= console.fork({
|
|
42
39
|
namespace: this.locator.namespace,
|
|
43
40
|
component: this.locator.name,
|
|
44
41
|
operation
|
|
@@ -46,7 +43,6 @@ class Aspect extends core_1.Connector {
|
|
|
46
43
|
return this.consoles[operation];
|
|
47
44
|
}
|
|
48
45
|
}
|
|
49
|
-
exports.Aspect = Aspect;
|
|
50
46
|
async function invoke(request, options, telemetry) {
|
|
51
47
|
const retry = normalize(options);
|
|
52
48
|
let response;
|
package/transpiled/Aspect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Aspect.js","sourceRoot":"","sources":["../source/Aspect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Aspect.js","sourceRoot":"","sources":["../source/Aspect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxC,OAAO,EAAE,OAAO,EAAkC,MAAM,UAAU,CAAA;AAGlE,MAAM,OAAO,MAAO,SAAQ,SAAS;IACnB,IAAI,GAAG,OAAO,CAAA;IACb,OAAO,CAAS;IAChB,QAAQ,GAA4B,EAAE,CAAA;IAEvD,YAAoB,OAAgB;QAClC,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAEM,KAAK,CAAC,MAAM,CAAE,SAAiB,EAAE,KAAwB,EAAE,IAAgB;QAChF,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,EAAE,GAAG,IAAI,IAAI,EAAE,CAAA;QAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,CAAC,KAAK,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QAE9E,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,IAAI,IAAI,YAAY,cAAc;YAC7E,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAA;QAE1E,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;QAE9C,MAAM,UAAU,GAA4B;YAC1C,qBAAqB,EAAE,OAAO,CAAC,MAAM;YACrC,YAAY,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACvD,gBAAgB,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ;SAC/C,CAAA;QAED,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;QAE/B,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE;YAAE,UAAU,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAEjE,MAAM,OAAO,GAAgB;YAC3B,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE;YACvC,IAAI,EAAE,UAAU;YAChB,UAAU;SACX,CAAA;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAErC,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;YAC3C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAA;YAEvF,UAAU,CAAC,2BAA2B,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAA;YAEzD,OAAO,QAAQ,CAAA;QACjB,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,MAAM,CAAE,SAAiB;QAC/B,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC;YACxC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YACjC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YAC5B,SAAS;SACV,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;IACjC,CAAC;CACF;AAED,KAAK,UAAU,MAAM,CAAE,OAAgB,EAAE,OAAiC,EACxE,SAA8B;IAC9B,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;IAEhC,IAAI,QAA8B,CAAA;IAElC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3D,SAAS,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAA;QAEtD,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;YAC7D,SAAQ;QACV,CAAC;QAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,OAAO,KAAK,KAAK,CAAC,QAAQ;YACzE,OAAO,QAAQ,CAAA;QAEjB,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAEzF,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAA;QACvB,MAAM,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACtC,CAAC;IAED,OAAO,QAAS,CAAA;AAClB,CAAC;AAED,KAAK,UAAU,IAAI,CAAE,OAAgB,EAAE,OAAe,EAAE,SAA8B;IACpF,MAAM,UAAU,GAA4B;QAC1C,GAAG,SAAS,CAAC,gBAAgB;QAC7B,eAAe,EAAE,OAAO;KACzB,CAAA;IAED,OAAO,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAEnC,OAAO,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC;QACjC,IAAI,EAAE,WAAW,OAAO,EAAE;QAC1B,IAAI,EAAE,QAAQ;QACd,UAAU;KACX,EAAE,KAAK,IAAI,EAAE;QACZ,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;QAExD,UAAU,CAAC,2BAA2B,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAA;QAEzD,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,UAAU,CAAE,KAAc,EAAE,UAAgC;IACzE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,UAAU,CAAA;IAEhD,IAAI,OAAO,KAAK,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO;QAAE,MAAM,KAAK,CAAA;IAEvE,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;AACrD,CAAC;AAED,KAAK,UAAU,OAAO,CAAE,QAAkB;IACxC,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,6EAA6E;IAC/E,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAE,OAAsB;IACxC,IAAI,OAAO,KAAK,SAAS;QACvB,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAE3F,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC;QAC7D,MAAM,IAAI,SAAS,CAAC,8DAA8D,CAAC,CAAA;IAErF,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS;QAChC,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CACjE,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC;QAC7D,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAA;IAEtE,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC;QACvF,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAA;IAElE,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAC1F,MAAM,IAAI,SAAS,CAAC,4CAA4C,CAAC,CAAA;IAEnE,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,aAAa;QACrC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,cAAc;KACzC,CAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAE,MAAc,EAAE,QAAmB;IACpD,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;AAC3F,CAAC;AAED,SAAS,KAAK,CAAE,OAA+B,EAAE,OAAe;IAC9D,OAAO,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED,SAAS,UAAU,CAAE,KAAoB;IACvC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IAEpC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAE7B,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,OAAO,GAAG,IAAI,CAAA;IAEnE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAE9B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAA;IAExC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;AACvC,CAAC;AAED,KAAK,UAAU,IAAI,CAAE,YAAoB,EAAE,MAAmB;IAC5D,IAAI,MAAM,CAAC,OAAO;QAAE,MAAM,MAAM,CAAC,MAAM,CAAA;IAEvC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;QAE9C,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QAEzD,SAAS,IAAI;YACX,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC5C,OAAO,EAAE,CAAA;QACX,CAAC;QAED,SAAS,OAAO;YACd,YAAY,CAAC,OAAO,CAAC,CAAA;YACrB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACvB,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,UAAU,CAAE,OAAgB;IACnC,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AAC7B,CAAC;AA+BD,MAAM,aAAa,GAAG,GAAG,CAAA;AACzB,MAAM,cAAc,GAAG,CAAC,CAAA"}
|