@spooky-sync/core 0.0.1-canary.240 → 0.0.1-canary.241
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/AGENTS.md +34 -15
- package/README.md +56 -16
- package/dist/index.d.ts +1136 -1846
- package/dist/index.js +10168 -11267
- package/dist/types.d.ts +22 -79
- package/package.json +8 -4
- package/skills/sp00ky-core/SKILL.md +18 -0
- package/src/boot/auth-flip.saga.test.ts +82 -0
- package/src/boot/auth-flip.saga.ts +62 -0
- package/src/boot/boot.saga.test.ts +151 -0
- package/src/boot/boot.saga.ts +128 -0
- package/src/boot/bucket-switch.saga.test.ts +158 -0
- package/src/boot/bucket-switch.saga.ts +115 -0
- package/src/boot/preload.saga.test.ts +51 -0
- package/src/boot/preload.saga.ts +31 -0
- package/src/client/bucket-handle.test.ts +117 -0
- package/src/client/bucket-handle.ts +227 -0
- package/src/client/router.test.ts +56 -0
- package/src/client/router.ts +94 -0
- package/src/client/runtime.test.ts +192 -0
- package/src/client/runtime.ts +296 -0
- package/src/client/services.ts +349 -0
- package/src/client/sp00ky-client.test.ts +241 -0
- package/src/client/sp00ky-client.ts +482 -0
- package/src/index.ts +1 -0
- package/src/kernel/constants.test.ts +19 -0
- package/src/kernel/constants.ts +54 -0
- package/src/kernel/effects.test.ts +40 -0
- package/src/kernel/effects.ts +159 -0
- package/src/kernel/events.ts +55 -0
- package/src/kernel/interpreter.test.ts +116 -0
- package/src/kernel/interpreter.ts +143 -0
- package/src/kernel/saga.test.ts +89 -0
- package/src/kernel/saga.ts +73 -0
- package/src/modules/app-release/index.ts +13 -5
- package/src/modules/devtools/index.ts +10 -3
- package/src/modules/devtools/state-shape.test.ts +4 -1
- package/src/modules/feature-flag/index.ts +13 -5
- package/src/mutation/jobs.test.ts +25 -0
- package/src/mutation/jobs.ts +41 -0
- package/src/{modules/data → mutation}/mutation-id.test.ts +12 -0
- package/src/mutation/push.saga.test.ts +285 -0
- package/src/mutation/push.saga.ts +215 -0
- package/src/mutation/rows.test.ts +201 -0
- package/src/mutation/rows.ts +377 -0
- package/src/mutation/tray.saga.test.ts +63 -0
- package/src/mutation/tray.saga.ts +48 -0
- package/src/mutation/write.saga.test.ts +163 -0
- package/src/mutation/write.saga.ts +166 -0
- package/src/query/env.test.ts +23 -0
- package/src/query/env.ts +56 -0
- package/src/query/fetch.saga.test.ts +156 -0
- package/src/query/fetch.saga.ts +109 -0
- package/src/query/hash.test.ts +14 -0
- package/src/query/hash.ts +18 -0
- package/src/{modules/data → query}/id-set-plan.test.ts +12 -2
- package/src/query/lifecycle.saga.test.ts +122 -0
- package/src/query/lifecycle.saga.ts +101 -0
- package/src/query/materialize.saga.test.ts +82 -0
- package/src/query/materialize.saga.ts +75 -0
- package/src/query/materialize.test.ts +50 -0
- package/src/query/materialize.ts +44 -0
- package/src/query/membership.saga.test.ts +246 -0
- package/src/query/membership.saga.ts +208 -0
- package/src/query/membership.test.ts +118 -0
- package/src/query/membership.ts +158 -0
- package/src/query/register.saga.test.ts +251 -0
- package/src/query/register.saga.ts +190 -0
- package/src/query/render-set.test.ts +36 -0
- package/src/query/render-set.ts +60 -0
- package/src/query/sql.test.ts +62 -0
- package/src/query/sql.ts +79 -0
- package/src/{modules/data → query}/window-query.test.ts +18 -0
- package/src/{modules/data → query}/window-query.ts +2 -1
- package/src/services/database/connection-supervisor.test.ts +29 -0
- package/src/services/database/connection-supervisor.ts +7 -0
- package/src/services/database/database.responses.test.ts +43 -0
- package/src/services/database/database.ts +25 -10
- package/src/services/database/local-migrator.ts +2 -2
- package/src/services/database/plan-render.test.ts +1 -1
- package/src/services/database/sqlite-cache-engine.test.ts +4 -3
- package/src/services/database/sqlite-cache-engine.ts +2 -11
- package/src/services/database/sqlite-devtools-queries.integration.test.ts +1 -1
- package/src/services/tabs/protocol.ts +7 -3
- package/src/sp00ky.ts +5 -1854
- package/src/state/client-state.ts +184 -0
- package/src/state/lifecycle.test.ts +118 -0
- package/src/state/lifecycle.ts +86 -0
- package/src/state/reducers.test.ts +280 -0
- package/src/state/reducers.ts +476 -0
- package/src/state/selectors.test.ts +149 -0
- package/src/state/selectors.ts +184 -0
- package/src/sync/connection.saga.test.ts +86 -0
- package/src/sync/connection.saga.ts +85 -0
- package/src/sync/live.saga.test.ts +69 -0
- package/src/sync/live.saga.ts +49 -0
- package/src/sync/policy.health.test.ts +56 -0
- package/src/{modules/sync/utils.test.ts → sync/policy.test.ts} +31 -3
- package/src/{modules/sync/utils.ts → sync/policy.ts} +67 -5
- package/src/sync/poll.saga.test.ts +51 -0
- package/src/sync/poll.saga.ts +36 -0
- package/src/sync/tabs.saga.test.ts +74 -0
- package/src/sync/tabs.saga.ts +92 -0
- package/src/testing/adapters.ts +133 -0
- package/src/testing/build.ts +61 -0
- package/src/testing/fake-services.ts +34 -0
- package/src/testing/run-pure.test.ts +92 -0
- package/src/testing/run-pure.ts +128 -0
- package/src/testing/services.ts +17 -0
- package/src/types.ts +8 -7
- package/src/utils/utils.test.ts +2 -1
- package/vitest.config.ts +48 -0
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -476
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -210
- package/coverage/lcov-report/src/boot/auth-flip.saga.ts.html +0 -271
- package/coverage/lcov-report/src/boot/boot.saga.ts.html +0 -469
- package/coverage/lcov-report/src/boot/bucket-switch.saga.ts.html +0 -430
- package/coverage/lcov-report/src/boot/index.html +0 -161
- package/coverage/lcov-report/src/boot/preload.saga.ts.html +0 -178
- package/coverage/lcov-report/src/client/bucket-handle.ts.html +0 -766
- package/coverage/lcov-report/src/client/index.html +0 -161
- package/coverage/lcov-report/src/client/router.ts.html +0 -367
- package/coverage/lcov-report/src/client/runtime.ts.html +0 -940
- package/coverage/lcov-report/src/client/sp00ky-client.ts.html +0 -1531
- package/coverage/lcov-report/src/events/index.html +0 -116
- package/coverage/lcov-report/src/events/index.ts.html +0 -877
- package/coverage/lcov-report/src/index.html +0 -146
- package/coverage/lcov-report/src/index.ts.html +0 -202
- package/coverage/lcov-report/src/kernel/constants.ts.html +0 -247
- package/coverage/lcov-report/src/kernel/effects.ts.html +0 -562
- package/coverage/lcov-report/src/kernel/events.ts.html +0 -250
- package/coverage/lcov-report/src/kernel/index.html +0 -176
- package/coverage/lcov-report/src/kernel/interpreter.ts.html +0 -514
- package/coverage/lcov-report/src/kernel/saga.ts.html +0 -304
- package/coverage/lcov-report/src/modules/app-release/index.html +0 -116
- package/coverage/lcov-report/src/modules/app-release/index.ts.html +0 -712
- package/coverage/lcov-report/src/modules/auth/events/index.html +0 -116
- package/coverage/lcov-report/src/modules/auth/events/index.ts.html +0 -142
- package/coverage/lcov-report/src/modules/auth/index.html +0 -116
- package/coverage/lcov-report/src/modules/auth/index.ts.html +0 -1225
- package/coverage/lcov-report/src/modules/crdt/crdt-field.ts.html +0 -967
- package/coverage/lcov-report/src/modules/crdt/index.html +0 -146
- package/coverage/lcov-report/src/modules/crdt/index.ts.html +0 -1474
- package/coverage/lcov-report/src/modules/crdt/loro-loader.ts.html +0 -160
- package/coverage/lcov-report/src/modules/devtools/flags.ts.html +0 -1132
- package/coverage/lcov-report/src/modules/devtools/index.html +0 -161
- package/coverage/lcov-report/src/modules/devtools/index.ts.html +0 -2413
- package/coverage/lcov-report/src/modules/devtools/storage-info.ts.html +0 -589
- package/coverage/lcov-report/src/modules/devtools/versions.ts.html +0 -415
- package/coverage/lcov-report/src/modules/feature-flag/index.html +0 -116
- package/coverage/lcov-report/src/modules/feature-flag/index.ts.html +0 -1033
- package/coverage/lcov-report/src/modules/index.html +0 -116
- package/coverage/lcov-report/src/modules/ref-tables.ts.html +0 -349
- package/coverage/lcov-report/src/mutation/index.html +0 -191
- package/coverage/lcov-report/src/mutation/jobs.ts.html +0 -208
- package/coverage/lcov-report/src/mutation/mutation-id.ts.html +0 -190
- package/coverage/lcov-report/src/mutation/push.saga.ts.html +0 -730
- package/coverage/lcov-report/src/mutation/rows.ts.html +0 -1216
- package/coverage/lcov-report/src/mutation/tray.saga.ts.html +0 -229
- package/coverage/lcov-report/src/mutation/write.saga.ts.html +0 -583
- package/coverage/lcov-report/src/otel/index.html +0 -116
- package/coverage/lcov-report/src/otel/index.ts.html +0 -466
- package/coverage/lcov-report/src/query/env.ts.html +0 -253
- package/coverage/lcov-report/src/query/fetch.saga.ts.html +0 -412
- package/coverage/lcov-report/src/query/hash.ts.html +0 -139
- package/coverage/lcov-report/src/query/index.html +0 -281
- package/coverage/lcov-report/src/query/lifecycle.saga.ts.html +0 -388
- package/coverage/lcov-report/src/query/materialize.saga.ts.html +0 -310
- package/coverage/lcov-report/src/query/materialize.ts.html +0 -217
- package/coverage/lcov-report/src/query/membership.saga.ts.html +0 -709
- package/coverage/lcov-report/src/query/membership.ts.html +0 -559
- package/coverage/lcov-report/src/query/register.saga.ts.html +0 -655
- package/coverage/lcov-report/src/query/render-set.ts.html +0 -265
- package/coverage/lcov-report/src/query/sql.ts.html +0 -322
- package/coverage/lcov-report/src/query/window-query.ts.html +0 -670
- package/coverage/lcov-report/src/services/blobs/blob-cache.ts.html +0 -1894
- package/coverage/lcov-report/src/services/blobs/blob-manifest.ts.html +0 -766
- package/coverage/lcov-report/src/services/blobs/blob-store.ts.html +0 -1162
- package/coverage/lcov-report/src/services/blobs/index.html +0 -161
- package/coverage/lcov-report/src/services/blobs/index.ts.html +0 -295
- package/coverage/lcov-report/src/services/database/cache-engine.ts.html +0 -664
- package/coverage/lcov-report/src/services/database/connection-supervisor.ts.html +0 -1330
- package/coverage/lcov-report/src/services/database/database.ts.html +0 -658
- package/coverage/lcov-report/src/services/database/engine-factory.ts.html +0 -184
- package/coverage/lcov-report/src/services/database/errors.ts.html +0 -187
- package/coverage/lcov-report/src/services/database/events/index.html +0 -116
- package/coverage/lcov-report/src/services/database/events/index.ts.html +0 -184
- package/coverage/lcov-report/src/services/database/index.html +0 -386
- package/coverage/lcov-report/src/services/database/index.ts.html +0 -121
- package/coverage/lcov-report/src/services/database/local-migrator.ts.html +0 -703
- package/coverage/lcov-report/src/services/database/local.ts.html +0 -1633
- package/coverage/lcov-report/src/services/database/plan-render.ts.html +0 -409
- package/coverage/lcov-report/src/services/database/relation-resolver.ts.html +0 -682
- package/coverage/lcov-report/src/services/database/remote.ts.html +0 -1036
- package/coverage/lcov-report/src/services/database/sqlite-cache-engine.ts.html +0 -4132
- package/coverage/lcov-report/src/services/database/sqlite-lock-verify.ts.html +0 -220
- package/coverage/lcov-report/src/services/database/sqlite-open.ts.html +0 -577
- package/coverage/lcov-report/src/services/database/sqlite-plan-sql.ts.html +0 -499
- package/coverage/lcov-report/src/services/database/sqlite-select.ts.html +0 -478
- package/coverage/lcov-report/src/services/database/sqlite-transport.ts.html +0 -757
- package/coverage/lcov-report/src/services/database/surql-translate.ts.html +0 -1333
- package/coverage/lcov-report/src/services/database/surreal-cache-engine.ts.html +0 -568
- package/coverage/lcov-report/src/services/logger/index.html +0 -116
- package/coverage/lcov-report/src/services/logger/index.ts.html +0 -154
- package/coverage/lcov-report/src/services/persistence/index.html +0 -146
- package/coverage/lcov-report/src/services/persistence/localstorage.ts.html +0 -163
- package/coverage/lcov-report/src/services/persistence/resilient.ts.html +0 -208
- package/coverage/lcov-report/src/services/persistence/surrealdb.ts.html +0 -271
- package/coverage/lcov-report/src/services/stream-processor/index.html +0 -146
- package/coverage/lcov-report/src/services/stream-processor/index.ts.html +0 -3313
- package/coverage/lcov-report/src/services/stream-processor/permissions.ts.html +0 -244
- package/coverage/lcov-report/src/services/stream-processor/wasm-types.ts.html +0 -346
- package/coverage/lcov-report/src/services/tabs/broker-client.ts.html +0 -934
- package/coverage/lcov-report/src/services/tabs/coordinator.ts.html +0 -1984
- package/coverage/lcov-report/src/services/tabs/index.html +0 -191
- package/coverage/lcov-report/src/services/tabs/leader-locks.ts.html +0 -310
- package/coverage/lcov-report/src/services/tabs/protocol.ts.html +0 -871
- package/coverage/lcov-report/src/services/tabs/support.ts.html +0 -193
- package/coverage/lcov-report/src/services/tabs/tabs-broker-worker.ts.html +0 -2005
- package/coverage/lcov-report/src/sp00ky.ts.html +0 -100
- package/coverage/lcov-report/src/state/client-state.ts.html +0 -637
- package/coverage/lcov-report/src/state/index.html +0 -161
- package/coverage/lcov-report/src/state/lifecycle.ts.html +0 -343
- package/coverage/lcov-report/src/state/reducers.ts.html +0 -1471
- package/coverage/lcov-report/src/state/selectors.ts.html +0 -637
- package/coverage/lcov-report/src/sync/connection.saga.ts.html +0 -343
- package/coverage/lcov-report/src/sync/index.html +0 -176
- package/coverage/lcov-report/src/sync/live.saga.ts.html +0 -232
- package/coverage/lcov-report/src/sync/policy.ts.html +0 -1606
- package/coverage/lcov-report/src/sync/poll.saga.ts.html +0 -193
- package/coverage/lcov-report/src/sync/tabs.saga.ts.html +0 -361
- package/coverage/lcov-report/src/types.ts.html +0 -2419
- package/coverage/lcov-report/src/utils/blurhash.ts.html +0 -355
- package/coverage/lcov-report/src/utils/error-classification.ts.html +0 -244
- package/coverage/lcov-report/src/utils/index.html +0 -191
- package/coverage/lcov-report/src/utils/index.ts.html +0 -820
- package/coverage/lcov-report/src/utils/parser.ts.html +0 -313
- package/coverage/lcov-report/src/utils/semver.ts.html +0 -175
- package/coverage/lcov-report/src/utils/surql.ts.html +0 -667
- package/coverage/lcov.info +0 -19079
- package/src/modules/cache/cache.relay.test.ts +0 -95
- package/src/modules/cache/index.ts +0 -361
- package/src/modules/cache/types.ts +0 -19
- package/src/modules/data/data.activity.test.ts +0 -109
- package/src/modules/data/data.authority.test.ts +0 -122
- package/src/modules/data/data.heartbeat-wake.test.ts +0 -115
- package/src/modules/data/data.hydration.test.ts +0 -142
- package/src/modules/data/data.membership.test.ts +0 -623
- package/src/modules/data/data.notify-table.test.ts +0 -41
- package/src/modules/data/data.pending-ids.test.ts +0 -199
- package/src/modules/data/data.rebind.test.ts +0 -170
- package/src/modules/data/data.rematerialize.test.ts +0 -114
- package/src/modules/data/data.run.test.ts +0 -113
- package/src/modules/data/data.settled-writes.test.ts +0 -235
- package/src/modules/data/data.status.test.ts +0 -249
- package/src/modules/data/data.test.ts +0 -58
- package/src/modules/data/index.ts +0 -2745
- package/src/modules/sync/engine.ts +0 -250
- package/src/modules/sync/events/index.ts +0 -84
- package/src/modules/sync/index.ts +0 -3
- package/src/modules/sync/queue/index.ts +0 -2
- package/src/modules/sync/queue/queue-down.test.ts +0 -228
- package/src/modules/sync/queue/queue-down.ts +0 -184
- package/src/modules/sync/queue/queue-up.forwarded.test.ts +0 -164
- package/src/modules/sync/queue/queue-up.ts +0 -407
- package/src/modules/sync/scheduler.pause.test.ts +0 -109
- package/src/modules/sync/scheduler.retry.test.ts +0 -237
- package/src/modules/sync/scheduler.ts +0 -286
- package/src/modules/sync/sync.cleanup.test.ts +0 -116
- package/src/modules/sync/sync.health.test.ts +0 -167
- package/src/modules/sync/sync.heartbeat.test.ts +0 -80
- package/src/modules/sync/sync.list-ref-meta.test.ts +0 -193
- package/src/modules/sync/sync.live-removal.test.ts +0 -289
- package/src/modules/sync/sync.reconnect.test.ts +0 -145
- package/src/modules/sync/sync.rematerialize-after-fetch.test.ts +0 -93
- package/src/modules/sync/sync.settled-poll.test.ts +0 -58
- package/src/modules/sync/sync.subquery.test.ts +0 -82
- package/src/modules/sync/sync.tabs.test.ts +0 -249
- package/src/modules/sync/sync.ts +0 -2626
- package/src/sp00ky.auth-order.test.ts +0 -112
- package/src/sp00ky.init-query.test.ts +0 -183
- package/src/sp00ky.local-first.test.ts +0 -60
- /package/src/{modules/data → mutation}/mutation-id.ts +0 -0
|
@@ -1,682 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
<!doctype html>
|
|
3
|
-
<html lang="en">
|
|
4
|
-
|
|
5
|
-
<head>
|
|
6
|
-
<title>Code coverage report for src/services/database/relation-resolver.ts</title>
|
|
7
|
-
<meta charset="utf-8" />
|
|
8
|
-
<link rel="stylesheet" href="../../../prettify.css" />
|
|
9
|
-
<link rel="stylesheet" href="../../../base.css" />
|
|
10
|
-
<link rel="shortcut icon" type="image/x-icon" href="../../../favicon.png" />
|
|
11
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
-
<style type='text/css'>
|
|
13
|
-
.coverage-summary .sorter {
|
|
14
|
-
background-image: url(../../../sort-arrow-sprite.png);
|
|
15
|
-
}
|
|
16
|
-
</style>
|
|
17
|
-
</head>
|
|
18
|
-
|
|
19
|
-
<body>
|
|
20
|
-
<div class='wrapper'>
|
|
21
|
-
<div class='pad1'>
|
|
22
|
-
<h1><a href="../../../index.html">All files</a> / <a href="index.html">src/services/database</a> relation-resolver.ts</h1>
|
|
23
|
-
<div class='clearfix'>
|
|
24
|
-
|
|
25
|
-
<div class='fl pad1y space-right2'>
|
|
26
|
-
<span class="strong">95.08% </span>
|
|
27
|
-
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>116/122</span>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<div class='fl pad1y space-right2'>
|
|
33
|
-
<span class="strong">90.47% </span>
|
|
34
|
-
<span class="quiet">Branches</span>
|
|
35
|
-
<span class='fraction'>76/84</span>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<div class='fl pad1y space-right2'>
|
|
40
|
-
<span class="strong">100% </span>
|
|
41
|
-
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>7/7</span>
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<div class='fl pad1y space-right2'>
|
|
47
|
-
<span class="strong">95.08% </span>
|
|
48
|
-
<span class="quiet">Lines</span>
|
|
49
|
-
<span class='fraction'>116/122</span>
|
|
50
|
-
</div>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
</div>
|
|
54
|
-
<p class="quiet">
|
|
55
|
-
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
-
</p>
|
|
57
|
-
<template id="filterTemplate">
|
|
58
|
-
<div class="quiet">
|
|
59
|
-
Filter:
|
|
60
|
-
<input type="search" id="fileSearch">
|
|
61
|
-
</div>
|
|
62
|
-
</template>
|
|
63
|
-
</div>
|
|
64
|
-
<div class='status-line high'></div>
|
|
65
|
-
<pre><table class="coverage">
|
|
66
|
-
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
-
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
-
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
-
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
-
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
-
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
-
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
-
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
-
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
-
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
-
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
-
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
-
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
-
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
-
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
-
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
-
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
-
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
-
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
-
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
-
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
-
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
-
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
-
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
-
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
-
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
-
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
-
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
-
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
-
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
-
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
-
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
-
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
-
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
-
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
-
<a name='L36'></a><a href='#L36'>36</a>
|
|
102
|
-
<a name='L37'></a><a href='#L37'>37</a>
|
|
103
|
-
<a name='L38'></a><a href='#L38'>38</a>
|
|
104
|
-
<a name='L39'></a><a href='#L39'>39</a>
|
|
105
|
-
<a name='L40'></a><a href='#L40'>40</a>
|
|
106
|
-
<a name='L41'></a><a href='#L41'>41</a>
|
|
107
|
-
<a name='L42'></a><a href='#L42'>42</a>
|
|
108
|
-
<a name='L43'></a><a href='#L43'>43</a>
|
|
109
|
-
<a name='L44'></a><a href='#L44'>44</a>
|
|
110
|
-
<a name='L45'></a><a href='#L45'>45</a>
|
|
111
|
-
<a name='L46'></a><a href='#L46'>46</a>
|
|
112
|
-
<a name='L47'></a><a href='#L47'>47</a>
|
|
113
|
-
<a name='L48'></a><a href='#L48'>48</a>
|
|
114
|
-
<a name='L49'></a><a href='#L49'>49</a>
|
|
115
|
-
<a name='L50'></a><a href='#L50'>50</a>
|
|
116
|
-
<a name='L51'></a><a href='#L51'>51</a>
|
|
117
|
-
<a name='L52'></a><a href='#L52'>52</a>
|
|
118
|
-
<a name='L53'></a><a href='#L53'>53</a>
|
|
119
|
-
<a name='L54'></a><a href='#L54'>54</a>
|
|
120
|
-
<a name='L55'></a><a href='#L55'>55</a>
|
|
121
|
-
<a name='L56'></a><a href='#L56'>56</a>
|
|
122
|
-
<a name='L57'></a><a href='#L57'>57</a>
|
|
123
|
-
<a name='L58'></a><a href='#L58'>58</a>
|
|
124
|
-
<a name='L59'></a><a href='#L59'>59</a>
|
|
125
|
-
<a name='L60'></a><a href='#L60'>60</a>
|
|
126
|
-
<a name='L61'></a><a href='#L61'>61</a>
|
|
127
|
-
<a name='L62'></a><a href='#L62'>62</a>
|
|
128
|
-
<a name='L63'></a><a href='#L63'>63</a>
|
|
129
|
-
<a name='L64'></a><a href='#L64'>64</a>
|
|
130
|
-
<a name='L65'></a><a href='#L65'>65</a>
|
|
131
|
-
<a name='L66'></a><a href='#L66'>66</a>
|
|
132
|
-
<a name='L67'></a><a href='#L67'>67</a>
|
|
133
|
-
<a name='L68'></a><a href='#L68'>68</a>
|
|
134
|
-
<a name='L69'></a><a href='#L69'>69</a>
|
|
135
|
-
<a name='L70'></a><a href='#L70'>70</a>
|
|
136
|
-
<a name='L71'></a><a href='#L71'>71</a>
|
|
137
|
-
<a name='L72'></a><a href='#L72'>72</a>
|
|
138
|
-
<a name='L73'></a><a href='#L73'>73</a>
|
|
139
|
-
<a name='L74'></a><a href='#L74'>74</a>
|
|
140
|
-
<a name='L75'></a><a href='#L75'>75</a>
|
|
141
|
-
<a name='L76'></a><a href='#L76'>76</a>
|
|
142
|
-
<a name='L77'></a><a href='#L77'>77</a>
|
|
143
|
-
<a name='L78'></a><a href='#L78'>78</a>
|
|
144
|
-
<a name='L79'></a><a href='#L79'>79</a>
|
|
145
|
-
<a name='L80'></a><a href='#L80'>80</a>
|
|
146
|
-
<a name='L81'></a><a href='#L81'>81</a>
|
|
147
|
-
<a name='L82'></a><a href='#L82'>82</a>
|
|
148
|
-
<a name='L83'></a><a href='#L83'>83</a>
|
|
149
|
-
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
|
-
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
|
-
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
-
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
-
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
-
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
-
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
-
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
-
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
-
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
-
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
-
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
-
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
-
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
-
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
-
<a name='L99'></a><a href='#L99'>99</a>
|
|
165
|
-
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
-
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
-
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
-
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
-
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
-
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
-
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
-
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
-
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
-
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
-
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
-
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
-
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
-
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
-
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
-
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
-
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
-
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
-
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
|
-
<a name='L119'></a><a href='#L119'>119</a>
|
|
185
|
-
<a name='L120'></a><a href='#L120'>120</a>
|
|
186
|
-
<a name='L121'></a><a href='#L121'>121</a>
|
|
187
|
-
<a name='L122'></a><a href='#L122'>122</a>
|
|
188
|
-
<a name='L123'></a><a href='#L123'>123</a>
|
|
189
|
-
<a name='L124'></a><a href='#L124'>124</a>
|
|
190
|
-
<a name='L125'></a><a href='#L125'>125</a>
|
|
191
|
-
<a name='L126'></a><a href='#L126'>126</a>
|
|
192
|
-
<a name='L127'></a><a href='#L127'>127</a>
|
|
193
|
-
<a name='L128'></a><a href='#L128'>128</a>
|
|
194
|
-
<a name='L129'></a><a href='#L129'>129</a>
|
|
195
|
-
<a name='L130'></a><a href='#L130'>130</a>
|
|
196
|
-
<a name='L131'></a><a href='#L131'>131</a>
|
|
197
|
-
<a name='L132'></a><a href='#L132'>132</a>
|
|
198
|
-
<a name='L133'></a><a href='#L133'>133</a>
|
|
199
|
-
<a name='L134'></a><a href='#L134'>134</a>
|
|
200
|
-
<a name='L135'></a><a href='#L135'>135</a>
|
|
201
|
-
<a name='L136'></a><a href='#L136'>136</a>
|
|
202
|
-
<a name='L137'></a><a href='#L137'>137</a>
|
|
203
|
-
<a name='L138'></a><a href='#L138'>138</a>
|
|
204
|
-
<a name='L139'></a><a href='#L139'>139</a>
|
|
205
|
-
<a name='L140'></a><a href='#L140'>140</a>
|
|
206
|
-
<a name='L141'></a><a href='#L141'>141</a>
|
|
207
|
-
<a name='L142'></a><a href='#L142'>142</a>
|
|
208
|
-
<a name='L143'></a><a href='#L143'>143</a>
|
|
209
|
-
<a name='L144'></a><a href='#L144'>144</a>
|
|
210
|
-
<a name='L145'></a><a href='#L145'>145</a>
|
|
211
|
-
<a name='L146'></a><a href='#L146'>146</a>
|
|
212
|
-
<a name='L147'></a><a href='#L147'>147</a>
|
|
213
|
-
<a name='L148'></a><a href='#L148'>148</a>
|
|
214
|
-
<a name='L149'></a><a href='#L149'>149</a>
|
|
215
|
-
<a name='L150'></a><a href='#L150'>150</a>
|
|
216
|
-
<a name='L151'></a><a href='#L151'>151</a>
|
|
217
|
-
<a name='L152'></a><a href='#L152'>152</a>
|
|
218
|
-
<a name='L153'></a><a href='#L153'>153</a>
|
|
219
|
-
<a name='L154'></a><a href='#L154'>154</a>
|
|
220
|
-
<a name='L155'></a><a href='#L155'>155</a>
|
|
221
|
-
<a name='L156'></a><a href='#L156'>156</a>
|
|
222
|
-
<a name='L157'></a><a href='#L157'>157</a>
|
|
223
|
-
<a name='L158'></a><a href='#L158'>158</a>
|
|
224
|
-
<a name='L159'></a><a href='#L159'>159</a>
|
|
225
|
-
<a name='L160'></a><a href='#L160'>160</a>
|
|
226
|
-
<a name='L161'></a><a href='#L161'>161</a>
|
|
227
|
-
<a name='L162'></a><a href='#L162'>162</a>
|
|
228
|
-
<a name='L163'></a><a href='#L163'>163</a>
|
|
229
|
-
<a name='L164'></a><a href='#L164'>164</a>
|
|
230
|
-
<a name='L165'></a><a href='#L165'>165</a>
|
|
231
|
-
<a name='L166'></a><a href='#L166'>166</a>
|
|
232
|
-
<a name='L167'></a><a href='#L167'>167</a>
|
|
233
|
-
<a name='L168'></a><a href='#L168'>168</a>
|
|
234
|
-
<a name='L169'></a><a href='#L169'>169</a>
|
|
235
|
-
<a name='L170'></a><a href='#L170'>170</a>
|
|
236
|
-
<a name='L171'></a><a href='#L171'>171</a>
|
|
237
|
-
<a name='L172'></a><a href='#L172'>172</a>
|
|
238
|
-
<a name='L173'></a><a href='#L173'>173</a>
|
|
239
|
-
<a name='L174'></a><a href='#L174'>174</a>
|
|
240
|
-
<a name='L175'></a><a href='#L175'>175</a>
|
|
241
|
-
<a name='L176'></a><a href='#L176'>176</a>
|
|
242
|
-
<a name='L177'></a><a href='#L177'>177</a>
|
|
243
|
-
<a name='L178'></a><a href='#L178'>178</a>
|
|
244
|
-
<a name='L179'></a><a href='#L179'>179</a>
|
|
245
|
-
<a name='L180'></a><a href='#L180'>180</a>
|
|
246
|
-
<a name='L181'></a><a href='#L181'>181</a>
|
|
247
|
-
<a name='L182'></a><a href='#L182'>182</a>
|
|
248
|
-
<a name='L183'></a><a href='#L183'>183</a>
|
|
249
|
-
<a name='L184'></a><a href='#L184'>184</a>
|
|
250
|
-
<a name='L185'></a><a href='#L185'>185</a>
|
|
251
|
-
<a name='L186'></a><a href='#L186'>186</a>
|
|
252
|
-
<a name='L187'></a><a href='#L187'>187</a>
|
|
253
|
-
<a name='L188'></a><a href='#L188'>188</a>
|
|
254
|
-
<a name='L189'></a><a href='#L189'>189</a>
|
|
255
|
-
<a name='L190'></a><a href='#L190'>190</a>
|
|
256
|
-
<a name='L191'></a><a href='#L191'>191</a>
|
|
257
|
-
<a name='L192'></a><a href='#L192'>192</a>
|
|
258
|
-
<a name='L193'></a><a href='#L193'>193</a>
|
|
259
|
-
<a name='L194'></a><a href='#L194'>194</a>
|
|
260
|
-
<a name='L195'></a><a href='#L195'>195</a>
|
|
261
|
-
<a name='L196'></a><a href='#L196'>196</a>
|
|
262
|
-
<a name='L197'></a><a href='#L197'>197</a>
|
|
263
|
-
<a name='L198'></a><a href='#L198'>198</a>
|
|
264
|
-
<a name='L199'></a><a href='#L199'>199</a>
|
|
265
|
-
<a name='L200'></a><a href='#L200'>200</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
|
|
266
|
-
<span class="cline-any cline-neutral"> </span>
|
|
267
|
-
<span class="cline-any cline-neutral"> </span>
|
|
268
|
-
<span class="cline-any cline-neutral"> </span>
|
|
269
|
-
<span class="cline-any cline-neutral"> </span>
|
|
270
|
-
<span class="cline-any cline-neutral"> </span>
|
|
271
|
-
<span class="cline-any cline-neutral"> </span>
|
|
272
|
-
<span class="cline-any cline-neutral"> </span>
|
|
273
|
-
<span class="cline-any cline-neutral"> </span>
|
|
274
|
-
<span class="cline-any cline-neutral"> </span>
|
|
275
|
-
<span class="cline-any cline-neutral"> </span>
|
|
276
|
-
<span class="cline-any cline-neutral"> </span>
|
|
277
|
-
<span class="cline-any cline-neutral"> </span>
|
|
278
|
-
<span class="cline-any cline-neutral"> </span>
|
|
279
|
-
<span class="cline-any cline-neutral"> </span>
|
|
280
|
-
<span class="cline-any cline-neutral"> </span>
|
|
281
|
-
<span class="cline-any cline-neutral"> </span>
|
|
282
|
-
<span class="cline-any cline-neutral"> </span>
|
|
283
|
-
<span class="cline-any cline-neutral"> </span>
|
|
284
|
-
<span class="cline-any cline-neutral"> </span>
|
|
285
|
-
<span class="cline-any cline-neutral"> </span>
|
|
286
|
-
<span class="cline-any cline-neutral"> </span>
|
|
287
|
-
<span class="cline-any cline-neutral"> </span>
|
|
288
|
-
<span class="cline-any cline-neutral"> </span>
|
|
289
|
-
<span class="cline-any cline-neutral"> </span>
|
|
290
|
-
<span class="cline-any cline-neutral"> </span>
|
|
291
|
-
<span class="cline-any cline-neutral"> </span>
|
|
292
|
-
<span class="cline-any cline-neutral"> </span>
|
|
293
|
-
<span class="cline-any cline-yes">449x</span>
|
|
294
|
-
<span class="cline-any cline-yes">449x</span>
|
|
295
|
-
<span class="cline-any cline-yes">449x</span>
|
|
296
|
-
<span class="cline-any cline-yes">449x</span>
|
|
297
|
-
<span class="cline-any cline-yes">449x</span>
|
|
298
|
-
<span class="cline-any cline-yes">449x</span>
|
|
299
|
-
<span class="cline-any cline-yes">449x</span>
|
|
300
|
-
<span class="cline-any cline-yes">449x</span>
|
|
301
|
-
<span class="cline-any cline-yes">449x</span>
|
|
302
|
-
<span class="cline-any cline-yes">1x</span>
|
|
303
|
-
<span class="cline-any cline-yes">1x</span>
|
|
304
|
-
<span class="cline-any cline-neutral"> </span>
|
|
305
|
-
<span class="cline-any cline-neutral"> </span>
|
|
306
|
-
<span class="cline-any cline-yes">190x</span>
|
|
307
|
-
<span class="cline-any cline-yes">190x</span>
|
|
308
|
-
<span class="cline-any cline-yes">190x</span>
|
|
309
|
-
<span class="cline-any cline-yes">178x</span>
|
|
310
|
-
<span class="cline-any cline-neutral"> </span>
|
|
311
|
-
<span class="cline-any cline-yes">262x</span>
|
|
312
|
-
<span class="cline-any cline-yes">262x</span>
|
|
313
|
-
<span class="cline-any cline-yes">262x</span>
|
|
314
|
-
<span class="cline-any cline-yes">262x</span>
|
|
315
|
-
<span class="cline-any cline-yes">262x</span>
|
|
316
|
-
<span class="cline-any cline-yes">262x</span>
|
|
317
|
-
<span class="cline-any cline-yes">262x</span>
|
|
318
|
-
<span class="cline-any cline-yes">262x</span>
|
|
319
|
-
<span class="cline-any cline-neutral"> </span>
|
|
320
|
-
<span class="cline-any cline-yes">262x</span>
|
|
321
|
-
<span class="cline-any cline-neutral"> </span>
|
|
322
|
-
<span class="cline-any cline-yes">262x</span>
|
|
323
|
-
<span class="cline-any cline-neutral"> </span>
|
|
324
|
-
<span class="cline-any cline-neutral"> </span>
|
|
325
|
-
<span class="cline-any cline-neutral"> </span>
|
|
326
|
-
<span class="cline-any cline-neutral"> </span>
|
|
327
|
-
<span class="cline-any cline-neutral"> </span>
|
|
328
|
-
<span class="cline-any cline-neutral"> </span>
|
|
329
|
-
<span class="cline-any cline-neutral"> </span>
|
|
330
|
-
<span class="cline-any cline-yes">262x</span>
|
|
331
|
-
<span class="cline-any cline-yes">262x</span>
|
|
332
|
-
<span class="cline-any cline-yes">528x</span>
|
|
333
|
-
<span class="cline-any cline-yes">528x</span>
|
|
334
|
-
<span class="cline-any cline-yes">528x</span>
|
|
335
|
-
<span class="cline-any cline-yes">461x</span>
|
|
336
|
-
<span class="cline-any cline-yes">528x</span>
|
|
337
|
-
<span class="cline-any cline-yes">528x</span>
|
|
338
|
-
<span class="cline-any cline-neutral"> </span>
|
|
339
|
-
<span class="cline-any cline-yes">262x</span>
|
|
340
|
-
<span class="cline-any cline-yes">262x</span>
|
|
341
|
-
<span class="cline-any cline-yes">250x</span>
|
|
342
|
-
<span class="cline-any cline-yes">250x</span>
|
|
343
|
-
<span class="cline-any cline-yes">250x</span>
|
|
344
|
-
<span class="cline-any cline-yes">250x</span>
|
|
345
|
-
<span class="cline-any cline-yes">250x</span>
|
|
346
|
-
<span class="cline-any cline-yes">250x</span>
|
|
347
|
-
<span class="cline-any cline-yes">250x</span>
|
|
348
|
-
<span class="cline-any cline-yes">250x</span>
|
|
349
|
-
<span class="cline-any cline-neutral"> </span>
|
|
350
|
-
<span class="cline-any cline-neutral"> </span>
|
|
351
|
-
<span class="cline-any cline-neutral"> </span>
|
|
352
|
-
<span class="cline-any cline-neutral"> </span>
|
|
353
|
-
<span class="cline-any cline-neutral"> </span>
|
|
354
|
-
<span class="cline-any cline-neutral"> </span>
|
|
355
|
-
<span class="cline-any cline-yes">250x</span>
|
|
356
|
-
<span class="cline-any cline-yes">250x</span>
|
|
357
|
-
<span class="cline-any cline-yes">250x</span>
|
|
358
|
-
<span class="cline-any cline-yes">250x</span>
|
|
359
|
-
<span class="cline-any cline-neutral"> </span>
|
|
360
|
-
<span class="cline-any cline-yes">250x</span>
|
|
361
|
-
<span class="cline-any cline-yes">135x</span>
|
|
362
|
-
<span class="cline-any cline-yes">135x</span>
|
|
363
|
-
<span class="cline-any cline-yes">135x</span>
|
|
364
|
-
<span class="cline-any cline-yes">116x</span>
|
|
365
|
-
<span class="cline-any cline-yes">135x</span>
|
|
366
|
-
<span class="cline-any cline-yes">238x</span>
|
|
367
|
-
<span class="cline-any cline-neutral"> </span>
|
|
368
|
-
<span class="cline-any cline-yes">262x</span>
|
|
369
|
-
<span class="cline-any cline-yes">516x</span>
|
|
370
|
-
<span class="cline-any cline-yes">516x</span>
|
|
371
|
-
<span class="cline-any cline-neutral"> </span>
|
|
372
|
-
<span class="cline-any cline-neutral"> </span>
|
|
373
|
-
<span class="cline-any cline-neutral"> </span>
|
|
374
|
-
<span class="cline-any cline-yes">516x</span>
|
|
375
|
-
<span class="cline-any cline-yes">229x</span>
|
|
376
|
-
<span class="cline-any cline-yes">229x</span>
|
|
377
|
-
<span class="cline-any cline-yes">516x</span>
|
|
378
|
-
<span class="cline-any cline-yes">216x</span>
|
|
379
|
-
<span class="cline-any cline-yes">216x</span>
|
|
380
|
-
<span class="cline-any cline-neutral"> </span>
|
|
381
|
-
<span class="cline-any cline-yes">516x</span>
|
|
382
|
-
<span class="cline-any cline-neutral"> </span>
|
|
383
|
-
<span class="cline-any cline-neutral"> </span>
|
|
384
|
-
<span class="cline-any cline-neutral"> </span>
|
|
385
|
-
<span class="cline-any cline-neutral"> </span>
|
|
386
|
-
<span class="cline-any cline-neutral"> </span>
|
|
387
|
-
<span class="cline-any cline-yes">263x</span>
|
|
388
|
-
<span class="cline-any cline-yes">263x</span>
|
|
389
|
-
<span class="cline-any cline-yes">263x</span>
|
|
390
|
-
<span class="cline-any cline-yes">263x</span>
|
|
391
|
-
<span class="cline-any cline-yes">516x</span>
|
|
392
|
-
<span class="cline-any cline-yes">253x</span>
|
|
393
|
-
<span class="cline-any cline-yes">253x</span>
|
|
394
|
-
<span class="cline-any cline-yes">516x</span>
|
|
395
|
-
<span class="cline-any cline-yes">250x</span>
|
|
396
|
-
<span class="cline-any cline-neutral"> </span>
|
|
397
|
-
<span class="cline-any cline-neutral"> </span>
|
|
398
|
-
<span class="cline-any cline-neutral"> </span>
|
|
399
|
-
<span class="cline-any cline-neutral"> </span>
|
|
400
|
-
<span class="cline-any cline-neutral"> </span>
|
|
401
|
-
<span class="cline-any cline-neutral"> </span>
|
|
402
|
-
<span class="cline-any cline-yes">1x</span>
|
|
403
|
-
<span class="cline-any cline-yes">231x</span>
|
|
404
|
-
<span class="cline-any cline-yes">231x</span>
|
|
405
|
-
<span class="cline-any cline-yes">225x</span>
|
|
406
|
-
<span class="cline-any cline-yes">3x</span>
|
|
407
|
-
<span class="cline-any cline-yes">3x</span>
|
|
408
|
-
<span class="cline-any cline-yes">3x</span>
|
|
409
|
-
<span class="cline-any cline-yes">1x</span>
|
|
410
|
-
<span class="cline-any cline-yes">1x</span>
|
|
411
|
-
<span class="cline-any cline-neutral"> </span>
|
|
412
|
-
<span class="cline-any cline-neutral"> </span>
|
|
413
|
-
<span class="cline-any cline-neutral"> </span>
|
|
414
|
-
<span class="cline-any cline-neutral"> </span>
|
|
415
|
-
<span class="cline-any cline-neutral"> </span>
|
|
416
|
-
<span class="cline-any cline-neutral"> </span>
|
|
417
|
-
<span class="cline-any cline-yes">1x</span>
|
|
418
|
-
<span class="cline-any cline-yes">3449x</span>
|
|
419
|
-
<span class="cline-any cline-yes">3449x</span>
|
|
420
|
-
<span class="cline-any cline-yes">3449x</span>
|
|
421
|
-
<span class="cline-any cline-yes">4x</span>
|
|
422
|
-
<span class="cline-any cline-yes">4x</span>
|
|
423
|
-
<span class="cline-any cline-neutral"> </span>
|
|
424
|
-
<span class="cline-any cline-yes">16x</span>
|
|
425
|
-
<span class="cline-any cline-yes">16x</span>
|
|
426
|
-
<span class="cline-any cline-yes">16x</span>
|
|
427
|
-
<span class="cline-any cline-yes">7x</span>
|
|
428
|
-
<span class="cline-any cline-yes">7x</span>
|
|
429
|
-
<span class="cline-any cline-yes">9x</span>
|
|
430
|
-
<span class="cline-any cline-yes">9x</span>
|
|
431
|
-
<span class="cline-any cline-yes">9x</span>
|
|
432
|
-
<span class="cline-any cline-yes">9x</span>
|
|
433
|
-
<span class="cline-any cline-no"> </span>
|
|
434
|
-
<span class="cline-any cline-no"> </span>
|
|
435
|
-
<span class="cline-any cline-no"> </span>
|
|
436
|
-
<span class="cline-any cline-no"> </span>
|
|
437
|
-
<span class="cline-any cline-neutral"> </span>
|
|
438
|
-
<span class="cline-any cline-neutral"> </span>
|
|
439
|
-
<span class="cline-any cline-neutral"> </span>
|
|
440
|
-
<span class="cline-any cline-neutral"> </span>
|
|
441
|
-
<span class="cline-any cline-neutral"> </span>
|
|
442
|
-
<span class="cline-any cline-neutral"> </span>
|
|
443
|
-
<span class="cline-any cline-yes">1x</span>
|
|
444
|
-
<span class="cline-any cline-yes">764x</span>
|
|
445
|
-
<span class="cline-any cline-yes">764x</span>
|
|
446
|
-
<span class="cline-any cline-yes">42x</span>
|
|
447
|
-
<span class="cline-any cline-yes">42x</span>
|
|
448
|
-
<span class="cline-any cline-yes">42x</span>
|
|
449
|
-
<span class="cline-any cline-yes">42x</span>
|
|
450
|
-
<span class="cline-any cline-yes">8x</span>
|
|
451
|
-
<span class="cline-any cline-yes">764x</span>
|
|
452
|
-
<span class="cline-any cline-yes">764x</span>
|
|
453
|
-
<span class="cline-any cline-yes">764x</span>
|
|
454
|
-
<span class="cline-any cline-neutral"> </span>
|
|
455
|
-
<span class="cline-any cline-yes">42x</span>
|
|
456
|
-
<span class="cline-any cline-yes">42x</span>
|
|
457
|
-
<span class="cline-any cline-yes">42x</span>
|
|
458
|
-
<span class="cline-any cline-yes">42x</span>
|
|
459
|
-
<span class="cline-any cline-yes">42x</span>
|
|
460
|
-
<span class="cline-any cline-no"> </span>
|
|
461
|
-
<span class="cline-any cline-no"> </span>
|
|
462
|
-
<span class="cline-any cline-yes">42x</span>
|
|
463
|
-
<span class="cline-any cline-yes">42x</span>
|
|
464
|
-
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import type { RelationPlan } from '@spooky-sync/query-builder';
|
|
465
|
-
import {
|
|
466
|
-
MAX_RELATION_DEPTH,
|
|
467
|
-
RelationCycleError,
|
|
468
|
-
type OrderBy,
|
|
469
|
-
type Row,
|
|
470
|
-
type RowFetcher,
|
|
471
|
-
} from './cache-engine';
|
|
472
|
-
|
|
473
|
-
/**
|
|
474
|
-
* Resolve the `.related()` tree of a query by **level-ordered, batched
|
|
475
|
-
* fan-out** — the engine-neutral replacement for SurrealQL's nested
|
|
476
|
-
* `(SELECT..) AS alias` projections. One batched fetch per relation per level
|
|
477
|
-
* (never per-row N+1, never a flat join); grouping, per-parent ORDER/LIMIT and
|
|
478
|
-
* attachment happen in JS.
|
|
479
|
-
*
|
|
480
|
-
* Correlation (mirrors `buildSubquery`):
|
|
481
|
-
* - `one` → parent[`foreignKeyField`] = child.id → attach `bucket[0] ?? null`
|
|
482
|
-
* - `many` → child[`foreignKeyField`] = parent.id → attach `bucket`
|
|
483
|
-
*
|
|
484
|
-
* Cross-level dependency is handled by ordering: a child's correlation key is a
|
|
485
|
-
* field on its parent, known only once the parent level has resolved, so each
|
|
486
|
-
* level's batch runs after the previous level's rows exist. `parents` is
|
|
487
|
-
* mutated in place — each resolved alias is appended LAST so key order matches
|
|
488
|
-
* SurrealQL's `SELECT *, <sub> AS alias` (base fields, then alias).
|
|
489
|
-
*
|
|
490
|
-
* @throws {RelationCycleError} if nesting exceeds {@link MAX_RELATION_DEPTH}.
|
|
491
|
-
*/
|
|
492
|
-
export async function resolveRelations(
|
|
493
|
-
parents: Row[],
|
|
494
|
-
relations: RelationPlan[] | undefined,
|
|
495
|
-
fetcher: RowFetcher,
|
|
496
|
-
depth = 0,
|
|
497
|
-
path: string[] = []
|
|
498
|
-
): Promise<void> {
|
|
499
|
-
if (!relations || relations.length === 0 || parents.length === 0) return;
|
|
500
|
-
if (depth >= MAX_RELATION_DEPTH) {
|
|
501
|
-
throw new RelationCycleError([...path, relations.map((r) => r.alias).join('|')]);
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
// Siblings are independent — resolve them concurrently.
|
|
505
|
-
await Promise.all(
|
|
506
|
-
relations.map((relation) => resolveOne(parents, relation, fetcher, depth, path))
|
|
507
|
-
);
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
async function resolveOne(
|
|
511
|
-
parents: Row[],
|
|
512
|
-
relation: RelationPlan,
|
|
513
|
-
fetcher: RowFetcher,
|
|
514
|
-
depth: number,
|
|
515
|
-
path: string[]
|
|
516
|
-
): Promise<void> {
|
|
517
|
-
const isOne = relation.cardinality === 'one';
|
|
518
|
-
// The child field to match parent keys against.
|
|
519
|
-
const matchField = isOne ? 'id' : relation.foreignKeyField;
|
|
520
|
-
// How to read a parent's correlation key.
|
|
521
|
-
const parentKeyOf = (parent: Row): unknown => (isOne ? parent[relation.foreignKeyField] : parent['id']);
|
|
522
|
-
|
|
523
|
-
// Distinct, defined correlation keys — a null/absent FK contributes nothing
|
|
524
|
-
// (never a spurious `WHERE id = null` fetch). For a to-one relation the key
|
|
525
|
-
// must also LOOK like a record id: a `string | record<t>` column (whitepawn's
|
|
526
|
-
// `game.white`, a legacy plain player name in old rows) carries values that
|
|
527
|
-
// are not links, and `type::record(<string> "Magnus")` in the batched fetch
|
|
528
|
-
// would throw and take every sibling's name down with it.
|
|
529
|
-
const keySet = new Map<string, unknown>();
|
|
530
|
-
for (const parent of parents) {
|
|
531
|
-
const key = parentKeyOf(parent);
|
|
532
|
-
if (key == null) continue;
|
|
533
|
-
if (isOne && !looksLikeRecordId(key)) continue;
|
|
534
|
-
const k = stableKey(key);
|
|
535
|
-
if (!keySet.has(k)) keySet.set(k, key);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
const grouped = new Map<string, Row[]>();
|
|
539
|
-
if (keySet.size > 0) {
|
|
540
|
-
const children = await fetcher.fetchRelation({
|
|
541
|
-
table: relation.table,
|
|
542
|
-
matchField,
|
|
543
|
-
keys: [...keySet.values()],
|
|
544
|
-
where: relation.where,
|
|
545
|
-
orderBy: relation.orderBy,
|
|
546
|
-
select: relation.select,
|
|
547
|
-
});
|
|
548
|
-
|
|
549
|
-
// Recurse into the next level BEFORE grouping — each child is a parent for
|
|
550
|
-
// its own relations. Resolving the full deduped child set once (rather than
|
|
551
|
-
// per parent) keeps nested fan-out at O(depth) batches. Children later
|
|
552
|
-
// dropped by a per-parent LIMIT carry resolved nested data harmlessly (they
|
|
553
|
-
// are never attached to any output row).
|
|
554
|
-
await resolveRelations(children, relation.relations, fetcher, depth + 1, [
|
|
555
|
-
...path,
|
|
556
|
-
relation.alias,
|
|
557
|
-
]);
|
|
558
|
-
|
|
559
|
-
for (const child of children) {
|
|
560
|
-
const k = stableKey(child[matchField]);
|
|
561
|
-
const bucket = grouped.get(k);
|
|
562
|
-
if (bucket) bucket.push(child);
|
|
563
|
-
else grouped.set(k, [child]);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
for (const parent of parents) {
|
|
568
|
-
const key = parentKeyOf(parent);
|
|
569
|
-
let bucket = key == null ? [] : grouped.get(stableKey(key)) ?? [];
|
|
570
|
-
|
|
571
|
-
// Per-parent ORDER then LIMIT — the batch fetch's order is only a hint; a
|
|
572
|
-
// shared batch cannot express "top N per parent", so re-apply here.
|
|
573
|
-
if (relation.orderBy && relation.orderBy.length > 0) {
|
|
574
|
-
bucket = sortRows(bucket, relation.orderBy);
|
|
575
|
-
}
|
|
576
|
-
if (relation.limit !== undefined) {
|
|
577
|
-
bucket = bucket.slice(0, relation.limit);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
if (isOne) {
|
|
581
|
-
// A to-one alias usually IS the foreign-key column (`.related('white')`
|
|
582
|
-
// projects onto `white`). A dangling LINK resolves to null, as SurrealQL's
|
|
583
|
-
// `(SELECT …)[0] AS alias` would. A value that is not a link at all (a
|
|
584
|
-
// legacy plain player name in a `string | record<t>` column) is kept: it
|
|
585
|
-
// was never going to resolve, and a renderer's fallback still needs it.
|
|
586
|
-
const raw = parent[relation.alias];
|
|
587
|
-
const keepRaw =
|
|
588
|
-
relation.alias === relation.foreignKeyField && raw != null && !looksLikeRecordId(raw);
|
|
589
|
-
parent[relation.alias] = bucket[0] ?? (keepRaw ? raw : null);
|
|
590
|
-
} else {
|
|
591
|
-
parent[relation.alias] = bucket;
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
/**
|
|
597
|
-
* Whether a correlation value can address a record: a RecordId (duck-typed) or
|
|
598
|
-
* a `table:id` string. Anything else (a plain display string, a number) cannot
|
|
599
|
-
* be the target of a to-one relation and is skipped rather than fetched.
|
|
600
|
-
*/
|
|
601
|
-
export function looksLikeRecordId(value: unknown): boolean {
|
|
602
|
-
if (value == null) return false;
|
|
603
|
-
if (typeof value === 'string') return /^[A-Za-z_][A-Za-z0-9_]*:.+/.test(value);
|
|
604
|
-
if (typeof value === 'object') {
|
|
605
|
-
const rid = value as { tb?: unknown; id?: unknown };
|
|
606
|
-
return rid.tb !== undefined && rid.id !== undefined;
|
|
607
|
-
}
|
|
608
|
-
return false;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
/**
|
|
612
|
-
* Stable grouping key for a correlation value. A `RecordId` (duck-typed to
|
|
613
|
-
* avoid a hard surrealdb dependency here) and its `table:id` string form must
|
|
614
|
-
* collapse to the same key so a parent FK stored either way matches the child.
|
|
615
|
-
*/
|
|
616
|
-
export function stableKey(value: unknown): string {
|
|
617
|
-
if (value == null) return 'null';
|
|
618
|
-
if (typeof value === 'string') return value;
|
|
619
|
-
if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {
|
|
620
|
-
return String(value);
|
|
621
|
-
}
|
|
622
|
-
// Duck-type RecordId: { tb, id } or a toString yielding `table:id`.
|
|
623
|
-
if (typeof value === 'object') {
|
|
624
|
-
const rid = value as { tb?: unknown; id?: unknown; toString?: () => string };
|
|
625
|
-
if (rid.tb !== undefined && rid.id !== undefined) {
|
|
626
|
-
return `${String(rid.tb)}:${stableKey(rid.id)}`;
|
|
627
|
-
}
|
|
628
|
-
if (typeof rid.toString === 'function') {
|
|
629
|
-
const s = rid.toString();
|
|
630
|
-
if (s !== '[object Object]') return s;
|
|
631
|
-
<span class="branch-0 cbranch-no" title="branch not covered" > }</span>
|
|
632
|
-
<span class="cstat-no" title="statement not covered" > return JSON.stringify(value);</span>
|
|
633
|
-
<span class="cstat-no" title="statement not covered" ><span class="branch-0 cbranch-no" title="branch not covered" > }</span></span>
|
|
634
|
-
<span class="cstat-no" title="statement not covered" > return String(value);</span>
|
|
635
|
-
<span class="cstat-no" title="statement not covered" >}</span>
|
|
636
|
-
|
|
637
|
-
/**
|
|
638
|
-
* Stable, multi-key sort matching SurrealQL `ORDER BY` semantics closely
|
|
639
|
-
* enough for cache display order: ascending null-last, type-aware compare, and
|
|
640
|
-
* a stable tiebreak (original index) so equal rows keep input order.
|
|
641
|
-
*/
|
|
642
|
-
export function sortRows(rows: Row[], orderBy: OrderBy): Row[] {
|
|
643
|
-
const indexed = rows.map((row, i) => [row, i] as const);
|
|
644
|
-
indexed.sort((a, b) => {
|
|
645
|
-
for (const [field, direction] of orderBy) {
|
|
646
|
-
const cmp = compareValues(a[0][field], b[0][field]);
|
|
647
|
-
if (cmp !== 0) return direction === 'desc' ? -cmp : cmp;
|
|
648
|
-
}
|
|
649
|
-
return a[1] - b[1]; // stable tiebreak
|
|
650
|
-
});
|
|
651
|
-
return indexed.map(([row]) => row);
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
function compareValues(a: unknown, b: unknown): number {
|
|
655
|
-
if (a == <span class="branch-0 cbranch-no" title="branch not covered" >null && b == null) <span class="branch-0 cbranch-no" title="branch not covered" >r</span>eturn 0;</span>
|
|
656
|
-
if (a == null) <span class="branch-0 cbranch-no" title="branch not covered" >return 1; // nulls sort last (ascending)</span>
|
|
657
|
-
if (b == null) <span class="branch-0 cbranch-no" title="branch not covered" >return -1;</span>
|
|
658
|
-
if (typeof a === 'number' && typeof b === 'number') return a - <span class="branch-0 cbranch-no" title="branch not covered" >b;</span>
|
|
659
|
-
<span class="cstat-no" title="statement not covered" > const as = stableKey(a);</span>
|
|
660
|
-
<span class="cstat-no" title="statement not covered" > const bs = stableKey(b);</span>
|
|
661
|
-
return as < bs ? <span class="branch-0 cbranch-no" title="branch not covered" >-1 : as > bs ? 1 : 0;</span>
|
|
662
|
-
}
|
|
663
|
-
</pre></td></tr></table></pre>
|
|
664
|
-
|
|
665
|
-
<div class='push'></div><!-- for sticky footer -->
|
|
666
|
-
</div><!-- /wrapper -->
|
|
667
|
-
<div class='footer quiet pad2 space-top1 center small'>
|
|
668
|
-
Code coverage generated by
|
|
669
|
-
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
670
|
-
at 2026-09-09T09:49:51.780Z
|
|
671
|
-
</div>
|
|
672
|
-
<script src="../../../prettify.js"></script>
|
|
673
|
-
<script>
|
|
674
|
-
window.onload = function () {
|
|
675
|
-
prettyPrint();
|
|
676
|
-
};
|
|
677
|
-
</script>
|
|
678
|
-
<script src="../../../sorter.js"></script>
|
|
679
|
-
<script src="../../../block-navigation.js"></script>
|
|
680
|
-
</body>
|
|
681
|
-
</html>
|
|
682
|
-
|