@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.
Files changed (289) hide show
  1. package/AGENTS.md +34 -15
  2. package/README.md +56 -16
  3. package/dist/index.d.ts +1136 -1846
  4. package/dist/index.js +10168 -11267
  5. package/dist/types.d.ts +22 -79
  6. package/package.json +8 -4
  7. package/skills/sp00ky-core/SKILL.md +18 -0
  8. package/src/boot/auth-flip.saga.test.ts +82 -0
  9. package/src/boot/auth-flip.saga.ts +62 -0
  10. package/src/boot/boot.saga.test.ts +151 -0
  11. package/src/boot/boot.saga.ts +128 -0
  12. package/src/boot/bucket-switch.saga.test.ts +158 -0
  13. package/src/boot/bucket-switch.saga.ts +115 -0
  14. package/src/boot/preload.saga.test.ts +51 -0
  15. package/src/boot/preload.saga.ts +31 -0
  16. package/src/client/bucket-handle.test.ts +117 -0
  17. package/src/client/bucket-handle.ts +227 -0
  18. package/src/client/router.test.ts +56 -0
  19. package/src/client/router.ts +94 -0
  20. package/src/client/runtime.test.ts +192 -0
  21. package/src/client/runtime.ts +296 -0
  22. package/src/client/services.ts +349 -0
  23. package/src/client/sp00ky-client.test.ts +241 -0
  24. package/src/client/sp00ky-client.ts +482 -0
  25. package/src/index.ts +1 -0
  26. package/src/kernel/constants.test.ts +19 -0
  27. package/src/kernel/constants.ts +54 -0
  28. package/src/kernel/effects.test.ts +40 -0
  29. package/src/kernel/effects.ts +159 -0
  30. package/src/kernel/events.ts +55 -0
  31. package/src/kernel/interpreter.test.ts +116 -0
  32. package/src/kernel/interpreter.ts +143 -0
  33. package/src/kernel/saga.test.ts +89 -0
  34. package/src/kernel/saga.ts +73 -0
  35. package/src/modules/app-release/index.ts +13 -5
  36. package/src/modules/devtools/index.ts +10 -3
  37. package/src/modules/devtools/state-shape.test.ts +4 -1
  38. package/src/modules/feature-flag/index.ts +13 -5
  39. package/src/mutation/jobs.test.ts +25 -0
  40. package/src/mutation/jobs.ts +41 -0
  41. package/src/{modules/data → mutation}/mutation-id.test.ts +12 -0
  42. package/src/mutation/push.saga.test.ts +285 -0
  43. package/src/mutation/push.saga.ts +215 -0
  44. package/src/mutation/rows.test.ts +201 -0
  45. package/src/mutation/rows.ts +377 -0
  46. package/src/mutation/tray.saga.test.ts +63 -0
  47. package/src/mutation/tray.saga.ts +48 -0
  48. package/src/mutation/write.saga.test.ts +163 -0
  49. package/src/mutation/write.saga.ts +166 -0
  50. package/src/query/env.test.ts +23 -0
  51. package/src/query/env.ts +56 -0
  52. package/src/query/fetch.saga.test.ts +156 -0
  53. package/src/query/fetch.saga.ts +109 -0
  54. package/src/query/hash.test.ts +14 -0
  55. package/src/query/hash.ts +18 -0
  56. package/src/{modules/data → query}/id-set-plan.test.ts +12 -2
  57. package/src/query/lifecycle.saga.test.ts +122 -0
  58. package/src/query/lifecycle.saga.ts +101 -0
  59. package/src/query/materialize.saga.test.ts +82 -0
  60. package/src/query/materialize.saga.ts +75 -0
  61. package/src/query/materialize.test.ts +50 -0
  62. package/src/query/materialize.ts +44 -0
  63. package/src/query/membership.saga.test.ts +246 -0
  64. package/src/query/membership.saga.ts +208 -0
  65. package/src/query/membership.test.ts +118 -0
  66. package/src/query/membership.ts +158 -0
  67. package/src/query/register.saga.test.ts +251 -0
  68. package/src/query/register.saga.ts +190 -0
  69. package/src/query/render-set.test.ts +36 -0
  70. package/src/query/render-set.ts +60 -0
  71. package/src/query/sql.test.ts +62 -0
  72. package/src/query/sql.ts +79 -0
  73. package/src/{modules/data → query}/window-query.test.ts +18 -0
  74. package/src/{modules/data → query}/window-query.ts +2 -1
  75. package/src/services/database/connection-supervisor.test.ts +29 -0
  76. package/src/services/database/connection-supervisor.ts +7 -0
  77. package/src/services/database/database.responses.test.ts +43 -0
  78. package/src/services/database/database.ts +25 -10
  79. package/src/services/database/local-migrator.ts +2 -2
  80. package/src/services/database/plan-render.test.ts +1 -1
  81. package/src/services/database/sqlite-cache-engine.test.ts +4 -3
  82. package/src/services/database/sqlite-cache-engine.ts +2 -11
  83. package/src/services/database/sqlite-devtools-queries.integration.test.ts +1 -1
  84. package/src/services/tabs/protocol.ts +7 -3
  85. package/src/sp00ky.ts +5 -1854
  86. package/src/state/client-state.ts +184 -0
  87. package/src/state/lifecycle.test.ts +118 -0
  88. package/src/state/lifecycle.ts +86 -0
  89. package/src/state/reducers.test.ts +280 -0
  90. package/src/state/reducers.ts +476 -0
  91. package/src/state/selectors.test.ts +149 -0
  92. package/src/state/selectors.ts +184 -0
  93. package/src/sync/connection.saga.test.ts +86 -0
  94. package/src/sync/connection.saga.ts +85 -0
  95. package/src/sync/live.saga.test.ts +69 -0
  96. package/src/sync/live.saga.ts +49 -0
  97. package/src/sync/policy.health.test.ts +56 -0
  98. package/src/{modules/sync/utils.test.ts → sync/policy.test.ts} +31 -3
  99. package/src/{modules/sync/utils.ts → sync/policy.ts} +67 -5
  100. package/src/sync/poll.saga.test.ts +51 -0
  101. package/src/sync/poll.saga.ts +36 -0
  102. package/src/sync/tabs.saga.test.ts +74 -0
  103. package/src/sync/tabs.saga.ts +92 -0
  104. package/src/testing/adapters.ts +133 -0
  105. package/src/testing/build.ts +61 -0
  106. package/src/testing/fake-services.ts +34 -0
  107. package/src/testing/run-pure.test.ts +92 -0
  108. package/src/testing/run-pure.ts +128 -0
  109. package/src/testing/services.ts +17 -0
  110. package/src/types.ts +8 -7
  111. package/src/utils/utils.test.ts +2 -1
  112. package/vitest.config.ts +48 -0
  113. package/coverage/lcov-report/base.css +0 -224
  114. package/coverage/lcov-report/block-navigation.js +0 -87
  115. package/coverage/lcov-report/favicon.png +0 -0
  116. package/coverage/lcov-report/index.html +0 -476
  117. package/coverage/lcov-report/prettify.css +0 -1
  118. package/coverage/lcov-report/prettify.js +0 -2
  119. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  120. package/coverage/lcov-report/sorter.js +0 -210
  121. package/coverage/lcov-report/src/boot/auth-flip.saga.ts.html +0 -271
  122. package/coverage/lcov-report/src/boot/boot.saga.ts.html +0 -469
  123. package/coverage/lcov-report/src/boot/bucket-switch.saga.ts.html +0 -430
  124. package/coverage/lcov-report/src/boot/index.html +0 -161
  125. package/coverage/lcov-report/src/boot/preload.saga.ts.html +0 -178
  126. package/coverage/lcov-report/src/client/bucket-handle.ts.html +0 -766
  127. package/coverage/lcov-report/src/client/index.html +0 -161
  128. package/coverage/lcov-report/src/client/router.ts.html +0 -367
  129. package/coverage/lcov-report/src/client/runtime.ts.html +0 -940
  130. package/coverage/lcov-report/src/client/sp00ky-client.ts.html +0 -1531
  131. package/coverage/lcov-report/src/events/index.html +0 -116
  132. package/coverage/lcov-report/src/events/index.ts.html +0 -877
  133. package/coverage/lcov-report/src/index.html +0 -146
  134. package/coverage/lcov-report/src/index.ts.html +0 -202
  135. package/coverage/lcov-report/src/kernel/constants.ts.html +0 -247
  136. package/coverage/lcov-report/src/kernel/effects.ts.html +0 -562
  137. package/coverage/lcov-report/src/kernel/events.ts.html +0 -250
  138. package/coverage/lcov-report/src/kernel/index.html +0 -176
  139. package/coverage/lcov-report/src/kernel/interpreter.ts.html +0 -514
  140. package/coverage/lcov-report/src/kernel/saga.ts.html +0 -304
  141. package/coverage/lcov-report/src/modules/app-release/index.html +0 -116
  142. package/coverage/lcov-report/src/modules/app-release/index.ts.html +0 -712
  143. package/coverage/lcov-report/src/modules/auth/events/index.html +0 -116
  144. package/coverage/lcov-report/src/modules/auth/events/index.ts.html +0 -142
  145. package/coverage/lcov-report/src/modules/auth/index.html +0 -116
  146. package/coverage/lcov-report/src/modules/auth/index.ts.html +0 -1225
  147. package/coverage/lcov-report/src/modules/crdt/crdt-field.ts.html +0 -967
  148. package/coverage/lcov-report/src/modules/crdt/index.html +0 -146
  149. package/coverage/lcov-report/src/modules/crdt/index.ts.html +0 -1474
  150. package/coverage/lcov-report/src/modules/crdt/loro-loader.ts.html +0 -160
  151. package/coverage/lcov-report/src/modules/devtools/flags.ts.html +0 -1132
  152. package/coverage/lcov-report/src/modules/devtools/index.html +0 -161
  153. package/coverage/lcov-report/src/modules/devtools/index.ts.html +0 -2413
  154. package/coverage/lcov-report/src/modules/devtools/storage-info.ts.html +0 -589
  155. package/coverage/lcov-report/src/modules/devtools/versions.ts.html +0 -415
  156. package/coverage/lcov-report/src/modules/feature-flag/index.html +0 -116
  157. package/coverage/lcov-report/src/modules/feature-flag/index.ts.html +0 -1033
  158. package/coverage/lcov-report/src/modules/index.html +0 -116
  159. package/coverage/lcov-report/src/modules/ref-tables.ts.html +0 -349
  160. package/coverage/lcov-report/src/mutation/index.html +0 -191
  161. package/coverage/lcov-report/src/mutation/jobs.ts.html +0 -208
  162. package/coverage/lcov-report/src/mutation/mutation-id.ts.html +0 -190
  163. package/coverage/lcov-report/src/mutation/push.saga.ts.html +0 -730
  164. package/coverage/lcov-report/src/mutation/rows.ts.html +0 -1216
  165. package/coverage/lcov-report/src/mutation/tray.saga.ts.html +0 -229
  166. package/coverage/lcov-report/src/mutation/write.saga.ts.html +0 -583
  167. package/coverage/lcov-report/src/otel/index.html +0 -116
  168. package/coverage/lcov-report/src/otel/index.ts.html +0 -466
  169. package/coverage/lcov-report/src/query/env.ts.html +0 -253
  170. package/coverage/lcov-report/src/query/fetch.saga.ts.html +0 -412
  171. package/coverage/lcov-report/src/query/hash.ts.html +0 -139
  172. package/coverage/lcov-report/src/query/index.html +0 -281
  173. package/coverage/lcov-report/src/query/lifecycle.saga.ts.html +0 -388
  174. package/coverage/lcov-report/src/query/materialize.saga.ts.html +0 -310
  175. package/coverage/lcov-report/src/query/materialize.ts.html +0 -217
  176. package/coverage/lcov-report/src/query/membership.saga.ts.html +0 -709
  177. package/coverage/lcov-report/src/query/membership.ts.html +0 -559
  178. package/coverage/lcov-report/src/query/register.saga.ts.html +0 -655
  179. package/coverage/lcov-report/src/query/render-set.ts.html +0 -265
  180. package/coverage/lcov-report/src/query/sql.ts.html +0 -322
  181. package/coverage/lcov-report/src/query/window-query.ts.html +0 -670
  182. package/coverage/lcov-report/src/services/blobs/blob-cache.ts.html +0 -1894
  183. package/coverage/lcov-report/src/services/blobs/blob-manifest.ts.html +0 -766
  184. package/coverage/lcov-report/src/services/blobs/blob-store.ts.html +0 -1162
  185. package/coverage/lcov-report/src/services/blobs/index.html +0 -161
  186. package/coverage/lcov-report/src/services/blobs/index.ts.html +0 -295
  187. package/coverage/lcov-report/src/services/database/cache-engine.ts.html +0 -664
  188. package/coverage/lcov-report/src/services/database/connection-supervisor.ts.html +0 -1330
  189. package/coverage/lcov-report/src/services/database/database.ts.html +0 -658
  190. package/coverage/lcov-report/src/services/database/engine-factory.ts.html +0 -184
  191. package/coverage/lcov-report/src/services/database/errors.ts.html +0 -187
  192. package/coverage/lcov-report/src/services/database/events/index.html +0 -116
  193. package/coverage/lcov-report/src/services/database/events/index.ts.html +0 -184
  194. package/coverage/lcov-report/src/services/database/index.html +0 -386
  195. package/coverage/lcov-report/src/services/database/index.ts.html +0 -121
  196. package/coverage/lcov-report/src/services/database/local-migrator.ts.html +0 -703
  197. package/coverage/lcov-report/src/services/database/local.ts.html +0 -1633
  198. package/coverage/lcov-report/src/services/database/plan-render.ts.html +0 -409
  199. package/coverage/lcov-report/src/services/database/relation-resolver.ts.html +0 -682
  200. package/coverage/lcov-report/src/services/database/remote.ts.html +0 -1036
  201. package/coverage/lcov-report/src/services/database/sqlite-cache-engine.ts.html +0 -4132
  202. package/coverage/lcov-report/src/services/database/sqlite-lock-verify.ts.html +0 -220
  203. package/coverage/lcov-report/src/services/database/sqlite-open.ts.html +0 -577
  204. package/coverage/lcov-report/src/services/database/sqlite-plan-sql.ts.html +0 -499
  205. package/coverage/lcov-report/src/services/database/sqlite-select.ts.html +0 -478
  206. package/coverage/lcov-report/src/services/database/sqlite-transport.ts.html +0 -757
  207. package/coverage/lcov-report/src/services/database/surql-translate.ts.html +0 -1333
  208. package/coverage/lcov-report/src/services/database/surreal-cache-engine.ts.html +0 -568
  209. package/coverage/lcov-report/src/services/logger/index.html +0 -116
  210. package/coverage/lcov-report/src/services/logger/index.ts.html +0 -154
  211. package/coverage/lcov-report/src/services/persistence/index.html +0 -146
  212. package/coverage/lcov-report/src/services/persistence/localstorage.ts.html +0 -163
  213. package/coverage/lcov-report/src/services/persistence/resilient.ts.html +0 -208
  214. package/coverage/lcov-report/src/services/persistence/surrealdb.ts.html +0 -271
  215. package/coverage/lcov-report/src/services/stream-processor/index.html +0 -146
  216. package/coverage/lcov-report/src/services/stream-processor/index.ts.html +0 -3313
  217. package/coverage/lcov-report/src/services/stream-processor/permissions.ts.html +0 -244
  218. package/coverage/lcov-report/src/services/stream-processor/wasm-types.ts.html +0 -346
  219. package/coverage/lcov-report/src/services/tabs/broker-client.ts.html +0 -934
  220. package/coverage/lcov-report/src/services/tabs/coordinator.ts.html +0 -1984
  221. package/coverage/lcov-report/src/services/tabs/index.html +0 -191
  222. package/coverage/lcov-report/src/services/tabs/leader-locks.ts.html +0 -310
  223. package/coverage/lcov-report/src/services/tabs/protocol.ts.html +0 -871
  224. package/coverage/lcov-report/src/services/tabs/support.ts.html +0 -193
  225. package/coverage/lcov-report/src/services/tabs/tabs-broker-worker.ts.html +0 -2005
  226. package/coverage/lcov-report/src/sp00ky.ts.html +0 -100
  227. package/coverage/lcov-report/src/state/client-state.ts.html +0 -637
  228. package/coverage/lcov-report/src/state/index.html +0 -161
  229. package/coverage/lcov-report/src/state/lifecycle.ts.html +0 -343
  230. package/coverage/lcov-report/src/state/reducers.ts.html +0 -1471
  231. package/coverage/lcov-report/src/state/selectors.ts.html +0 -637
  232. package/coverage/lcov-report/src/sync/connection.saga.ts.html +0 -343
  233. package/coverage/lcov-report/src/sync/index.html +0 -176
  234. package/coverage/lcov-report/src/sync/live.saga.ts.html +0 -232
  235. package/coverage/lcov-report/src/sync/policy.ts.html +0 -1606
  236. package/coverage/lcov-report/src/sync/poll.saga.ts.html +0 -193
  237. package/coverage/lcov-report/src/sync/tabs.saga.ts.html +0 -361
  238. package/coverage/lcov-report/src/types.ts.html +0 -2419
  239. package/coverage/lcov-report/src/utils/blurhash.ts.html +0 -355
  240. package/coverage/lcov-report/src/utils/error-classification.ts.html +0 -244
  241. package/coverage/lcov-report/src/utils/index.html +0 -191
  242. package/coverage/lcov-report/src/utils/index.ts.html +0 -820
  243. package/coverage/lcov-report/src/utils/parser.ts.html +0 -313
  244. package/coverage/lcov-report/src/utils/semver.ts.html +0 -175
  245. package/coverage/lcov-report/src/utils/surql.ts.html +0 -667
  246. package/coverage/lcov.info +0 -19079
  247. package/src/modules/cache/cache.relay.test.ts +0 -95
  248. package/src/modules/cache/index.ts +0 -361
  249. package/src/modules/cache/types.ts +0 -19
  250. package/src/modules/data/data.activity.test.ts +0 -109
  251. package/src/modules/data/data.authority.test.ts +0 -122
  252. package/src/modules/data/data.heartbeat-wake.test.ts +0 -115
  253. package/src/modules/data/data.hydration.test.ts +0 -142
  254. package/src/modules/data/data.membership.test.ts +0 -623
  255. package/src/modules/data/data.notify-table.test.ts +0 -41
  256. package/src/modules/data/data.pending-ids.test.ts +0 -199
  257. package/src/modules/data/data.rebind.test.ts +0 -170
  258. package/src/modules/data/data.rematerialize.test.ts +0 -114
  259. package/src/modules/data/data.run.test.ts +0 -113
  260. package/src/modules/data/data.settled-writes.test.ts +0 -235
  261. package/src/modules/data/data.status.test.ts +0 -249
  262. package/src/modules/data/data.test.ts +0 -58
  263. package/src/modules/data/index.ts +0 -2745
  264. package/src/modules/sync/engine.ts +0 -250
  265. package/src/modules/sync/events/index.ts +0 -84
  266. package/src/modules/sync/index.ts +0 -3
  267. package/src/modules/sync/queue/index.ts +0 -2
  268. package/src/modules/sync/queue/queue-down.test.ts +0 -228
  269. package/src/modules/sync/queue/queue-down.ts +0 -184
  270. package/src/modules/sync/queue/queue-up.forwarded.test.ts +0 -164
  271. package/src/modules/sync/queue/queue-up.ts +0 -407
  272. package/src/modules/sync/scheduler.pause.test.ts +0 -109
  273. package/src/modules/sync/scheduler.retry.test.ts +0 -237
  274. package/src/modules/sync/scheduler.ts +0 -286
  275. package/src/modules/sync/sync.cleanup.test.ts +0 -116
  276. package/src/modules/sync/sync.health.test.ts +0 -167
  277. package/src/modules/sync/sync.heartbeat.test.ts +0 -80
  278. package/src/modules/sync/sync.list-ref-meta.test.ts +0 -193
  279. package/src/modules/sync/sync.live-removal.test.ts +0 -289
  280. package/src/modules/sync/sync.reconnect.test.ts +0 -145
  281. package/src/modules/sync/sync.rematerialize-after-fetch.test.ts +0 -93
  282. package/src/modules/sync/sync.settled-poll.test.ts +0 -58
  283. package/src/modules/sync/sync.subquery.test.ts +0 -82
  284. package/src/modules/sync/sync.tabs.test.ts +0 -249
  285. package/src/modules/sync/sync.ts +0 -2626
  286. package/src/sp00ky.auth-order.test.ts +0 -112
  287. package/src/sp00ky.init-query.test.ts +0 -183
  288. package/src/sp00ky.local-first.test.ts +0 -60
  289. /package/src/{modules/data → mutation}/mutation-id.ts +0 -0
@@ -1,3313 +0,0 @@
1
-
2
- <!doctype html>
3
- <html lang="en">
4
-
5
- <head>
6
- <title>Code coverage report for src/services/stream-processor/index.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/stream-processor</a> index.ts</h1>
23
- <div class='clearfix'>
24
-
25
- <div class='fl pad1y space-right2'>
26
- <span class="strong">78.32% </span>
27
- <span class="quiet">Statements</span>
28
- <span class='fraction'>560/715</span>
29
- </div>
30
-
31
-
32
- <div class='fl pad1y space-right2'>
33
- <span class="strong">68.45% </span>
34
- <span class="quiet">Branches</span>
35
- <span class='fraction'>115/168</span>
36
- </div>
37
-
38
-
39
- <div class='fl pad1y space-right2'>
40
- <span class="strong">86.84% </span>
41
- <span class="quiet">Functions</span>
42
- <span class='fraction'>33/38</span>
43
- </div>
44
-
45
-
46
- <div class='fl pad1y space-right2'>
47
- <span class="strong">78.32% </span>
48
- <span class="quiet">Lines</span>
49
- <span class='fraction'>560/715</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 medium'></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>
266
- <a name='L201'></a><a href='#L201'>201</a>
267
- <a name='L202'></a><a href='#L202'>202</a>
268
- <a name='L203'></a><a href='#L203'>203</a>
269
- <a name='L204'></a><a href='#L204'>204</a>
270
- <a name='L205'></a><a href='#L205'>205</a>
271
- <a name='L206'></a><a href='#L206'>206</a>
272
- <a name='L207'></a><a href='#L207'>207</a>
273
- <a name='L208'></a><a href='#L208'>208</a>
274
- <a name='L209'></a><a href='#L209'>209</a>
275
- <a name='L210'></a><a href='#L210'>210</a>
276
- <a name='L211'></a><a href='#L211'>211</a>
277
- <a name='L212'></a><a href='#L212'>212</a>
278
- <a name='L213'></a><a href='#L213'>213</a>
279
- <a name='L214'></a><a href='#L214'>214</a>
280
- <a name='L215'></a><a href='#L215'>215</a>
281
- <a name='L216'></a><a href='#L216'>216</a>
282
- <a name='L217'></a><a href='#L217'>217</a>
283
- <a name='L218'></a><a href='#L218'>218</a>
284
- <a name='L219'></a><a href='#L219'>219</a>
285
- <a name='L220'></a><a href='#L220'>220</a>
286
- <a name='L221'></a><a href='#L221'>221</a>
287
- <a name='L222'></a><a href='#L222'>222</a>
288
- <a name='L223'></a><a href='#L223'>223</a>
289
- <a name='L224'></a><a href='#L224'>224</a>
290
- <a name='L225'></a><a href='#L225'>225</a>
291
- <a name='L226'></a><a href='#L226'>226</a>
292
- <a name='L227'></a><a href='#L227'>227</a>
293
- <a name='L228'></a><a href='#L228'>228</a>
294
- <a name='L229'></a><a href='#L229'>229</a>
295
- <a name='L230'></a><a href='#L230'>230</a>
296
- <a name='L231'></a><a href='#L231'>231</a>
297
- <a name='L232'></a><a href='#L232'>232</a>
298
- <a name='L233'></a><a href='#L233'>233</a>
299
- <a name='L234'></a><a href='#L234'>234</a>
300
- <a name='L235'></a><a href='#L235'>235</a>
301
- <a name='L236'></a><a href='#L236'>236</a>
302
- <a name='L237'></a><a href='#L237'>237</a>
303
- <a name='L238'></a><a href='#L238'>238</a>
304
- <a name='L239'></a><a href='#L239'>239</a>
305
- <a name='L240'></a><a href='#L240'>240</a>
306
- <a name='L241'></a><a href='#L241'>241</a>
307
- <a name='L242'></a><a href='#L242'>242</a>
308
- <a name='L243'></a><a href='#L243'>243</a>
309
- <a name='L244'></a><a href='#L244'>244</a>
310
- <a name='L245'></a><a href='#L245'>245</a>
311
- <a name='L246'></a><a href='#L246'>246</a>
312
- <a name='L247'></a><a href='#L247'>247</a>
313
- <a name='L248'></a><a href='#L248'>248</a>
314
- <a name='L249'></a><a href='#L249'>249</a>
315
- <a name='L250'></a><a href='#L250'>250</a>
316
- <a name='L251'></a><a href='#L251'>251</a>
317
- <a name='L252'></a><a href='#L252'>252</a>
318
- <a name='L253'></a><a href='#L253'>253</a>
319
- <a name='L254'></a><a href='#L254'>254</a>
320
- <a name='L255'></a><a href='#L255'>255</a>
321
- <a name='L256'></a><a href='#L256'>256</a>
322
- <a name='L257'></a><a href='#L257'>257</a>
323
- <a name='L258'></a><a href='#L258'>258</a>
324
- <a name='L259'></a><a href='#L259'>259</a>
325
- <a name='L260'></a><a href='#L260'>260</a>
326
- <a name='L261'></a><a href='#L261'>261</a>
327
- <a name='L262'></a><a href='#L262'>262</a>
328
- <a name='L263'></a><a href='#L263'>263</a>
329
- <a name='L264'></a><a href='#L264'>264</a>
330
- <a name='L265'></a><a href='#L265'>265</a>
331
- <a name='L266'></a><a href='#L266'>266</a>
332
- <a name='L267'></a><a href='#L267'>267</a>
333
- <a name='L268'></a><a href='#L268'>268</a>
334
- <a name='L269'></a><a href='#L269'>269</a>
335
- <a name='L270'></a><a href='#L270'>270</a>
336
- <a name='L271'></a><a href='#L271'>271</a>
337
- <a name='L272'></a><a href='#L272'>272</a>
338
- <a name='L273'></a><a href='#L273'>273</a>
339
- <a name='L274'></a><a href='#L274'>274</a>
340
- <a name='L275'></a><a href='#L275'>275</a>
341
- <a name='L276'></a><a href='#L276'>276</a>
342
- <a name='L277'></a><a href='#L277'>277</a>
343
- <a name='L278'></a><a href='#L278'>278</a>
344
- <a name='L279'></a><a href='#L279'>279</a>
345
- <a name='L280'></a><a href='#L280'>280</a>
346
- <a name='L281'></a><a href='#L281'>281</a>
347
- <a name='L282'></a><a href='#L282'>282</a>
348
- <a name='L283'></a><a href='#L283'>283</a>
349
- <a name='L284'></a><a href='#L284'>284</a>
350
- <a name='L285'></a><a href='#L285'>285</a>
351
- <a name='L286'></a><a href='#L286'>286</a>
352
- <a name='L287'></a><a href='#L287'>287</a>
353
- <a name='L288'></a><a href='#L288'>288</a>
354
- <a name='L289'></a><a href='#L289'>289</a>
355
- <a name='L290'></a><a href='#L290'>290</a>
356
- <a name='L291'></a><a href='#L291'>291</a>
357
- <a name='L292'></a><a href='#L292'>292</a>
358
- <a name='L293'></a><a href='#L293'>293</a>
359
- <a name='L294'></a><a href='#L294'>294</a>
360
- <a name='L295'></a><a href='#L295'>295</a>
361
- <a name='L296'></a><a href='#L296'>296</a>
362
- <a name='L297'></a><a href='#L297'>297</a>
363
- <a name='L298'></a><a href='#L298'>298</a>
364
- <a name='L299'></a><a href='#L299'>299</a>
365
- <a name='L300'></a><a href='#L300'>300</a>
366
- <a name='L301'></a><a href='#L301'>301</a>
367
- <a name='L302'></a><a href='#L302'>302</a>
368
- <a name='L303'></a><a href='#L303'>303</a>
369
- <a name='L304'></a><a href='#L304'>304</a>
370
- <a name='L305'></a><a href='#L305'>305</a>
371
- <a name='L306'></a><a href='#L306'>306</a>
372
- <a name='L307'></a><a href='#L307'>307</a>
373
- <a name='L308'></a><a href='#L308'>308</a>
374
- <a name='L309'></a><a href='#L309'>309</a>
375
- <a name='L310'></a><a href='#L310'>310</a>
376
- <a name='L311'></a><a href='#L311'>311</a>
377
- <a name='L312'></a><a href='#L312'>312</a>
378
- <a name='L313'></a><a href='#L313'>313</a>
379
- <a name='L314'></a><a href='#L314'>314</a>
380
- <a name='L315'></a><a href='#L315'>315</a>
381
- <a name='L316'></a><a href='#L316'>316</a>
382
- <a name='L317'></a><a href='#L317'>317</a>
383
- <a name='L318'></a><a href='#L318'>318</a>
384
- <a name='L319'></a><a href='#L319'>319</a>
385
- <a name='L320'></a><a href='#L320'>320</a>
386
- <a name='L321'></a><a href='#L321'>321</a>
387
- <a name='L322'></a><a href='#L322'>322</a>
388
- <a name='L323'></a><a href='#L323'>323</a>
389
- <a name='L324'></a><a href='#L324'>324</a>
390
- <a name='L325'></a><a href='#L325'>325</a>
391
- <a name='L326'></a><a href='#L326'>326</a>
392
- <a name='L327'></a><a href='#L327'>327</a>
393
- <a name='L328'></a><a href='#L328'>328</a>
394
- <a name='L329'></a><a href='#L329'>329</a>
395
- <a name='L330'></a><a href='#L330'>330</a>
396
- <a name='L331'></a><a href='#L331'>331</a>
397
- <a name='L332'></a><a href='#L332'>332</a>
398
- <a name='L333'></a><a href='#L333'>333</a>
399
- <a name='L334'></a><a href='#L334'>334</a>
400
- <a name='L335'></a><a href='#L335'>335</a>
401
- <a name='L336'></a><a href='#L336'>336</a>
402
- <a name='L337'></a><a href='#L337'>337</a>
403
- <a name='L338'></a><a href='#L338'>338</a>
404
- <a name='L339'></a><a href='#L339'>339</a>
405
- <a name='L340'></a><a href='#L340'>340</a>
406
- <a name='L341'></a><a href='#L341'>341</a>
407
- <a name='L342'></a><a href='#L342'>342</a>
408
- <a name='L343'></a><a href='#L343'>343</a>
409
- <a name='L344'></a><a href='#L344'>344</a>
410
- <a name='L345'></a><a href='#L345'>345</a>
411
- <a name='L346'></a><a href='#L346'>346</a>
412
- <a name='L347'></a><a href='#L347'>347</a>
413
- <a name='L348'></a><a href='#L348'>348</a>
414
- <a name='L349'></a><a href='#L349'>349</a>
415
- <a name='L350'></a><a href='#L350'>350</a>
416
- <a name='L351'></a><a href='#L351'>351</a>
417
- <a name='L352'></a><a href='#L352'>352</a>
418
- <a name='L353'></a><a href='#L353'>353</a>
419
- <a name='L354'></a><a href='#L354'>354</a>
420
- <a name='L355'></a><a href='#L355'>355</a>
421
- <a name='L356'></a><a href='#L356'>356</a>
422
- <a name='L357'></a><a href='#L357'>357</a>
423
- <a name='L358'></a><a href='#L358'>358</a>
424
- <a name='L359'></a><a href='#L359'>359</a>
425
- <a name='L360'></a><a href='#L360'>360</a>
426
- <a name='L361'></a><a href='#L361'>361</a>
427
- <a name='L362'></a><a href='#L362'>362</a>
428
- <a name='L363'></a><a href='#L363'>363</a>
429
- <a name='L364'></a><a href='#L364'>364</a>
430
- <a name='L365'></a><a href='#L365'>365</a>
431
- <a name='L366'></a><a href='#L366'>366</a>
432
- <a name='L367'></a><a href='#L367'>367</a>
433
- <a name='L368'></a><a href='#L368'>368</a>
434
- <a name='L369'></a><a href='#L369'>369</a>
435
- <a name='L370'></a><a href='#L370'>370</a>
436
- <a name='L371'></a><a href='#L371'>371</a>
437
- <a name='L372'></a><a href='#L372'>372</a>
438
- <a name='L373'></a><a href='#L373'>373</a>
439
- <a name='L374'></a><a href='#L374'>374</a>
440
- <a name='L375'></a><a href='#L375'>375</a>
441
- <a name='L376'></a><a href='#L376'>376</a>
442
- <a name='L377'></a><a href='#L377'>377</a>
443
- <a name='L378'></a><a href='#L378'>378</a>
444
- <a name='L379'></a><a href='#L379'>379</a>
445
- <a name='L380'></a><a href='#L380'>380</a>
446
- <a name='L381'></a><a href='#L381'>381</a>
447
- <a name='L382'></a><a href='#L382'>382</a>
448
- <a name='L383'></a><a href='#L383'>383</a>
449
- <a name='L384'></a><a href='#L384'>384</a>
450
- <a name='L385'></a><a href='#L385'>385</a>
451
- <a name='L386'></a><a href='#L386'>386</a>
452
- <a name='L387'></a><a href='#L387'>387</a>
453
- <a name='L388'></a><a href='#L388'>388</a>
454
- <a name='L389'></a><a href='#L389'>389</a>
455
- <a name='L390'></a><a href='#L390'>390</a>
456
- <a name='L391'></a><a href='#L391'>391</a>
457
- <a name='L392'></a><a href='#L392'>392</a>
458
- <a name='L393'></a><a href='#L393'>393</a>
459
- <a name='L394'></a><a href='#L394'>394</a>
460
- <a name='L395'></a><a href='#L395'>395</a>
461
- <a name='L396'></a><a href='#L396'>396</a>
462
- <a name='L397'></a><a href='#L397'>397</a>
463
- <a name='L398'></a><a href='#L398'>398</a>
464
- <a name='L399'></a><a href='#L399'>399</a>
465
- <a name='L400'></a><a href='#L400'>400</a>
466
- <a name='L401'></a><a href='#L401'>401</a>
467
- <a name='L402'></a><a href='#L402'>402</a>
468
- <a name='L403'></a><a href='#L403'>403</a>
469
- <a name='L404'></a><a href='#L404'>404</a>
470
- <a name='L405'></a><a href='#L405'>405</a>
471
- <a name='L406'></a><a href='#L406'>406</a>
472
- <a name='L407'></a><a href='#L407'>407</a>
473
- <a name='L408'></a><a href='#L408'>408</a>
474
- <a name='L409'></a><a href='#L409'>409</a>
475
- <a name='L410'></a><a href='#L410'>410</a>
476
- <a name='L411'></a><a href='#L411'>411</a>
477
- <a name='L412'></a><a href='#L412'>412</a>
478
- <a name='L413'></a><a href='#L413'>413</a>
479
- <a name='L414'></a><a href='#L414'>414</a>
480
- <a name='L415'></a><a href='#L415'>415</a>
481
- <a name='L416'></a><a href='#L416'>416</a>
482
- <a name='L417'></a><a href='#L417'>417</a>
483
- <a name='L418'></a><a href='#L418'>418</a>
484
- <a name='L419'></a><a href='#L419'>419</a>
485
- <a name='L420'></a><a href='#L420'>420</a>
486
- <a name='L421'></a><a href='#L421'>421</a>
487
- <a name='L422'></a><a href='#L422'>422</a>
488
- <a name='L423'></a><a href='#L423'>423</a>
489
- <a name='L424'></a><a href='#L424'>424</a>
490
- <a name='L425'></a><a href='#L425'>425</a>
491
- <a name='L426'></a><a href='#L426'>426</a>
492
- <a name='L427'></a><a href='#L427'>427</a>
493
- <a name='L428'></a><a href='#L428'>428</a>
494
- <a name='L429'></a><a href='#L429'>429</a>
495
- <a name='L430'></a><a href='#L430'>430</a>
496
- <a name='L431'></a><a href='#L431'>431</a>
497
- <a name='L432'></a><a href='#L432'>432</a>
498
- <a name='L433'></a><a href='#L433'>433</a>
499
- <a name='L434'></a><a href='#L434'>434</a>
500
- <a name='L435'></a><a href='#L435'>435</a>
501
- <a name='L436'></a><a href='#L436'>436</a>
502
- <a name='L437'></a><a href='#L437'>437</a>
503
- <a name='L438'></a><a href='#L438'>438</a>
504
- <a name='L439'></a><a href='#L439'>439</a>
505
- <a name='L440'></a><a href='#L440'>440</a>
506
- <a name='L441'></a><a href='#L441'>441</a>
507
- <a name='L442'></a><a href='#L442'>442</a>
508
- <a name='L443'></a><a href='#L443'>443</a>
509
- <a name='L444'></a><a href='#L444'>444</a>
510
- <a name='L445'></a><a href='#L445'>445</a>
511
- <a name='L446'></a><a href='#L446'>446</a>
512
- <a name='L447'></a><a href='#L447'>447</a>
513
- <a name='L448'></a><a href='#L448'>448</a>
514
- <a name='L449'></a><a href='#L449'>449</a>
515
- <a name='L450'></a><a href='#L450'>450</a>
516
- <a name='L451'></a><a href='#L451'>451</a>
517
- <a name='L452'></a><a href='#L452'>452</a>
518
- <a name='L453'></a><a href='#L453'>453</a>
519
- <a name='L454'></a><a href='#L454'>454</a>
520
- <a name='L455'></a><a href='#L455'>455</a>
521
- <a name='L456'></a><a href='#L456'>456</a>
522
- <a name='L457'></a><a href='#L457'>457</a>
523
- <a name='L458'></a><a href='#L458'>458</a>
524
- <a name='L459'></a><a href='#L459'>459</a>
525
- <a name='L460'></a><a href='#L460'>460</a>
526
- <a name='L461'></a><a href='#L461'>461</a>
527
- <a name='L462'></a><a href='#L462'>462</a>
528
- <a name='L463'></a><a href='#L463'>463</a>
529
- <a name='L464'></a><a href='#L464'>464</a>
530
- <a name='L465'></a><a href='#L465'>465</a>
531
- <a name='L466'></a><a href='#L466'>466</a>
532
- <a name='L467'></a><a href='#L467'>467</a>
533
- <a name='L468'></a><a href='#L468'>468</a>
534
- <a name='L469'></a><a href='#L469'>469</a>
535
- <a name='L470'></a><a href='#L470'>470</a>
536
- <a name='L471'></a><a href='#L471'>471</a>
537
- <a name='L472'></a><a href='#L472'>472</a>
538
- <a name='L473'></a><a href='#L473'>473</a>
539
- <a name='L474'></a><a href='#L474'>474</a>
540
- <a name='L475'></a><a href='#L475'>475</a>
541
- <a name='L476'></a><a href='#L476'>476</a>
542
- <a name='L477'></a><a href='#L477'>477</a>
543
- <a name='L478'></a><a href='#L478'>478</a>
544
- <a name='L479'></a><a href='#L479'>479</a>
545
- <a name='L480'></a><a href='#L480'>480</a>
546
- <a name='L481'></a><a href='#L481'>481</a>
547
- <a name='L482'></a><a href='#L482'>482</a>
548
- <a name='L483'></a><a href='#L483'>483</a>
549
- <a name='L484'></a><a href='#L484'>484</a>
550
- <a name='L485'></a><a href='#L485'>485</a>
551
- <a name='L486'></a><a href='#L486'>486</a>
552
- <a name='L487'></a><a href='#L487'>487</a>
553
- <a name='L488'></a><a href='#L488'>488</a>
554
- <a name='L489'></a><a href='#L489'>489</a>
555
- <a name='L490'></a><a href='#L490'>490</a>
556
- <a name='L491'></a><a href='#L491'>491</a>
557
- <a name='L492'></a><a href='#L492'>492</a>
558
- <a name='L493'></a><a href='#L493'>493</a>
559
- <a name='L494'></a><a href='#L494'>494</a>
560
- <a name='L495'></a><a href='#L495'>495</a>
561
- <a name='L496'></a><a href='#L496'>496</a>
562
- <a name='L497'></a><a href='#L497'>497</a>
563
- <a name='L498'></a><a href='#L498'>498</a>
564
- <a name='L499'></a><a href='#L499'>499</a>
565
- <a name='L500'></a><a href='#L500'>500</a>
566
- <a name='L501'></a><a href='#L501'>501</a>
567
- <a name='L502'></a><a href='#L502'>502</a>
568
- <a name='L503'></a><a href='#L503'>503</a>
569
- <a name='L504'></a><a href='#L504'>504</a>
570
- <a name='L505'></a><a href='#L505'>505</a>
571
- <a name='L506'></a><a href='#L506'>506</a>
572
- <a name='L507'></a><a href='#L507'>507</a>
573
- <a name='L508'></a><a href='#L508'>508</a>
574
- <a name='L509'></a><a href='#L509'>509</a>
575
- <a name='L510'></a><a href='#L510'>510</a>
576
- <a name='L511'></a><a href='#L511'>511</a>
577
- <a name='L512'></a><a href='#L512'>512</a>
578
- <a name='L513'></a><a href='#L513'>513</a>
579
- <a name='L514'></a><a href='#L514'>514</a>
580
- <a name='L515'></a><a href='#L515'>515</a>
581
- <a name='L516'></a><a href='#L516'>516</a>
582
- <a name='L517'></a><a href='#L517'>517</a>
583
- <a name='L518'></a><a href='#L518'>518</a>
584
- <a name='L519'></a><a href='#L519'>519</a>
585
- <a name='L520'></a><a href='#L520'>520</a>
586
- <a name='L521'></a><a href='#L521'>521</a>
587
- <a name='L522'></a><a href='#L522'>522</a>
588
- <a name='L523'></a><a href='#L523'>523</a>
589
- <a name='L524'></a><a href='#L524'>524</a>
590
- <a name='L525'></a><a href='#L525'>525</a>
591
- <a name='L526'></a><a href='#L526'>526</a>
592
- <a name='L527'></a><a href='#L527'>527</a>
593
- <a name='L528'></a><a href='#L528'>528</a>
594
- <a name='L529'></a><a href='#L529'>529</a>
595
- <a name='L530'></a><a href='#L530'>530</a>
596
- <a name='L531'></a><a href='#L531'>531</a>
597
- <a name='L532'></a><a href='#L532'>532</a>
598
- <a name='L533'></a><a href='#L533'>533</a>
599
- <a name='L534'></a><a href='#L534'>534</a>
600
- <a name='L535'></a><a href='#L535'>535</a>
601
- <a name='L536'></a><a href='#L536'>536</a>
602
- <a name='L537'></a><a href='#L537'>537</a>
603
- <a name='L538'></a><a href='#L538'>538</a>
604
- <a name='L539'></a><a href='#L539'>539</a>
605
- <a name='L540'></a><a href='#L540'>540</a>
606
- <a name='L541'></a><a href='#L541'>541</a>
607
- <a name='L542'></a><a href='#L542'>542</a>
608
- <a name='L543'></a><a href='#L543'>543</a>
609
- <a name='L544'></a><a href='#L544'>544</a>
610
- <a name='L545'></a><a href='#L545'>545</a>
611
- <a name='L546'></a><a href='#L546'>546</a>
612
- <a name='L547'></a><a href='#L547'>547</a>
613
- <a name='L548'></a><a href='#L548'>548</a>
614
- <a name='L549'></a><a href='#L549'>549</a>
615
- <a name='L550'></a><a href='#L550'>550</a>
616
- <a name='L551'></a><a href='#L551'>551</a>
617
- <a name='L552'></a><a href='#L552'>552</a>
618
- <a name='L553'></a><a href='#L553'>553</a>
619
- <a name='L554'></a><a href='#L554'>554</a>
620
- <a name='L555'></a><a href='#L555'>555</a>
621
- <a name='L556'></a><a href='#L556'>556</a>
622
- <a name='L557'></a><a href='#L557'>557</a>
623
- <a name='L558'></a><a href='#L558'>558</a>
624
- <a name='L559'></a><a href='#L559'>559</a>
625
- <a name='L560'></a><a href='#L560'>560</a>
626
- <a name='L561'></a><a href='#L561'>561</a>
627
- <a name='L562'></a><a href='#L562'>562</a>
628
- <a name='L563'></a><a href='#L563'>563</a>
629
- <a name='L564'></a><a href='#L564'>564</a>
630
- <a name='L565'></a><a href='#L565'>565</a>
631
- <a name='L566'></a><a href='#L566'>566</a>
632
- <a name='L567'></a><a href='#L567'>567</a>
633
- <a name='L568'></a><a href='#L568'>568</a>
634
- <a name='L569'></a><a href='#L569'>569</a>
635
- <a name='L570'></a><a href='#L570'>570</a>
636
- <a name='L571'></a><a href='#L571'>571</a>
637
- <a name='L572'></a><a href='#L572'>572</a>
638
- <a name='L573'></a><a href='#L573'>573</a>
639
- <a name='L574'></a><a href='#L574'>574</a>
640
- <a name='L575'></a><a href='#L575'>575</a>
641
- <a name='L576'></a><a href='#L576'>576</a>
642
- <a name='L577'></a><a href='#L577'>577</a>
643
- <a name='L578'></a><a href='#L578'>578</a>
644
- <a name='L579'></a><a href='#L579'>579</a>
645
- <a name='L580'></a><a href='#L580'>580</a>
646
- <a name='L581'></a><a href='#L581'>581</a>
647
- <a name='L582'></a><a href='#L582'>582</a>
648
- <a name='L583'></a><a href='#L583'>583</a>
649
- <a name='L584'></a><a href='#L584'>584</a>
650
- <a name='L585'></a><a href='#L585'>585</a>
651
- <a name='L586'></a><a href='#L586'>586</a>
652
- <a name='L587'></a><a href='#L587'>587</a>
653
- <a name='L588'></a><a href='#L588'>588</a>
654
- <a name='L589'></a><a href='#L589'>589</a>
655
- <a name='L590'></a><a href='#L590'>590</a>
656
- <a name='L591'></a><a href='#L591'>591</a>
657
- <a name='L592'></a><a href='#L592'>592</a>
658
- <a name='L593'></a><a href='#L593'>593</a>
659
- <a name='L594'></a><a href='#L594'>594</a>
660
- <a name='L595'></a><a href='#L595'>595</a>
661
- <a name='L596'></a><a href='#L596'>596</a>
662
- <a name='L597'></a><a href='#L597'>597</a>
663
- <a name='L598'></a><a href='#L598'>598</a>
664
- <a name='L599'></a><a href='#L599'>599</a>
665
- <a name='L600'></a><a href='#L600'>600</a>
666
- <a name='L601'></a><a href='#L601'>601</a>
667
- <a name='L602'></a><a href='#L602'>602</a>
668
- <a name='L603'></a><a href='#L603'>603</a>
669
- <a name='L604'></a><a href='#L604'>604</a>
670
- <a name='L605'></a><a href='#L605'>605</a>
671
- <a name='L606'></a><a href='#L606'>606</a>
672
- <a name='L607'></a><a href='#L607'>607</a>
673
- <a name='L608'></a><a href='#L608'>608</a>
674
- <a name='L609'></a><a href='#L609'>609</a>
675
- <a name='L610'></a><a href='#L610'>610</a>
676
- <a name='L611'></a><a href='#L611'>611</a>
677
- <a name='L612'></a><a href='#L612'>612</a>
678
- <a name='L613'></a><a href='#L613'>613</a>
679
- <a name='L614'></a><a href='#L614'>614</a>
680
- <a name='L615'></a><a href='#L615'>615</a>
681
- <a name='L616'></a><a href='#L616'>616</a>
682
- <a name='L617'></a><a href='#L617'>617</a>
683
- <a name='L618'></a><a href='#L618'>618</a>
684
- <a name='L619'></a><a href='#L619'>619</a>
685
- <a name='L620'></a><a href='#L620'>620</a>
686
- <a name='L621'></a><a href='#L621'>621</a>
687
- <a name='L622'></a><a href='#L622'>622</a>
688
- <a name='L623'></a><a href='#L623'>623</a>
689
- <a name='L624'></a><a href='#L624'>624</a>
690
- <a name='L625'></a><a href='#L625'>625</a>
691
- <a name='L626'></a><a href='#L626'>626</a>
692
- <a name='L627'></a><a href='#L627'>627</a>
693
- <a name='L628'></a><a href='#L628'>628</a>
694
- <a name='L629'></a><a href='#L629'>629</a>
695
- <a name='L630'></a><a href='#L630'>630</a>
696
- <a name='L631'></a><a href='#L631'>631</a>
697
- <a name='L632'></a><a href='#L632'>632</a>
698
- <a name='L633'></a><a href='#L633'>633</a>
699
- <a name='L634'></a><a href='#L634'>634</a>
700
- <a name='L635'></a><a href='#L635'>635</a>
701
- <a name='L636'></a><a href='#L636'>636</a>
702
- <a name='L637'></a><a href='#L637'>637</a>
703
- <a name='L638'></a><a href='#L638'>638</a>
704
- <a name='L639'></a><a href='#L639'>639</a>
705
- <a name='L640'></a><a href='#L640'>640</a>
706
- <a name='L641'></a><a href='#L641'>641</a>
707
- <a name='L642'></a><a href='#L642'>642</a>
708
- <a name='L643'></a><a href='#L643'>643</a>
709
- <a name='L644'></a><a href='#L644'>644</a>
710
- <a name='L645'></a><a href='#L645'>645</a>
711
- <a name='L646'></a><a href='#L646'>646</a>
712
- <a name='L647'></a><a href='#L647'>647</a>
713
- <a name='L648'></a><a href='#L648'>648</a>
714
- <a name='L649'></a><a href='#L649'>649</a>
715
- <a name='L650'></a><a href='#L650'>650</a>
716
- <a name='L651'></a><a href='#L651'>651</a>
717
- <a name='L652'></a><a href='#L652'>652</a>
718
- <a name='L653'></a><a href='#L653'>653</a>
719
- <a name='L654'></a><a href='#L654'>654</a>
720
- <a name='L655'></a><a href='#L655'>655</a>
721
- <a name='L656'></a><a href='#L656'>656</a>
722
- <a name='L657'></a><a href='#L657'>657</a>
723
- <a name='L658'></a><a href='#L658'>658</a>
724
- <a name='L659'></a><a href='#L659'>659</a>
725
- <a name='L660'></a><a href='#L660'>660</a>
726
- <a name='L661'></a><a href='#L661'>661</a>
727
- <a name='L662'></a><a href='#L662'>662</a>
728
- <a name='L663'></a><a href='#L663'>663</a>
729
- <a name='L664'></a><a href='#L664'>664</a>
730
- <a name='L665'></a><a href='#L665'>665</a>
731
- <a name='L666'></a><a href='#L666'>666</a>
732
- <a name='L667'></a><a href='#L667'>667</a>
733
- <a name='L668'></a><a href='#L668'>668</a>
734
- <a name='L669'></a><a href='#L669'>669</a>
735
- <a name='L670'></a><a href='#L670'>670</a>
736
- <a name='L671'></a><a href='#L671'>671</a>
737
- <a name='L672'></a><a href='#L672'>672</a>
738
- <a name='L673'></a><a href='#L673'>673</a>
739
- <a name='L674'></a><a href='#L674'>674</a>
740
- <a name='L675'></a><a href='#L675'>675</a>
741
- <a name='L676'></a><a href='#L676'>676</a>
742
- <a name='L677'></a><a href='#L677'>677</a>
743
- <a name='L678'></a><a href='#L678'>678</a>
744
- <a name='L679'></a><a href='#L679'>679</a>
745
- <a name='L680'></a><a href='#L680'>680</a>
746
- <a name='L681'></a><a href='#L681'>681</a>
747
- <a name='L682'></a><a href='#L682'>682</a>
748
- <a name='L683'></a><a href='#L683'>683</a>
749
- <a name='L684'></a><a href='#L684'>684</a>
750
- <a name='L685'></a><a href='#L685'>685</a>
751
- <a name='L686'></a><a href='#L686'>686</a>
752
- <a name='L687'></a><a href='#L687'>687</a>
753
- <a name='L688'></a><a href='#L688'>688</a>
754
- <a name='L689'></a><a href='#L689'>689</a>
755
- <a name='L690'></a><a href='#L690'>690</a>
756
- <a name='L691'></a><a href='#L691'>691</a>
757
- <a name='L692'></a><a href='#L692'>692</a>
758
- <a name='L693'></a><a href='#L693'>693</a>
759
- <a name='L694'></a><a href='#L694'>694</a>
760
- <a name='L695'></a><a href='#L695'>695</a>
761
- <a name='L696'></a><a href='#L696'>696</a>
762
- <a name='L697'></a><a href='#L697'>697</a>
763
- <a name='L698'></a><a href='#L698'>698</a>
764
- <a name='L699'></a><a href='#L699'>699</a>
765
- <a name='L700'></a><a href='#L700'>700</a>
766
- <a name='L701'></a><a href='#L701'>701</a>
767
- <a name='L702'></a><a href='#L702'>702</a>
768
- <a name='L703'></a><a href='#L703'>703</a>
769
- <a name='L704'></a><a href='#L704'>704</a>
770
- <a name='L705'></a><a href='#L705'>705</a>
771
- <a name='L706'></a><a href='#L706'>706</a>
772
- <a name='L707'></a><a href='#L707'>707</a>
773
- <a name='L708'></a><a href='#L708'>708</a>
774
- <a name='L709'></a><a href='#L709'>709</a>
775
- <a name='L710'></a><a href='#L710'>710</a>
776
- <a name='L711'></a><a href='#L711'>711</a>
777
- <a name='L712'></a><a href='#L712'>712</a>
778
- <a name='L713'></a><a href='#L713'>713</a>
779
- <a name='L714'></a><a href='#L714'>714</a>
780
- <a name='L715'></a><a href='#L715'>715</a>
781
- <a name='L716'></a><a href='#L716'>716</a>
782
- <a name='L717'></a><a href='#L717'>717</a>
783
- <a name='L718'></a><a href='#L718'>718</a>
784
- <a name='L719'></a><a href='#L719'>719</a>
785
- <a name='L720'></a><a href='#L720'>720</a>
786
- <a name='L721'></a><a href='#L721'>721</a>
787
- <a name='L722'></a><a href='#L722'>722</a>
788
- <a name='L723'></a><a href='#L723'>723</a>
789
- <a name='L724'></a><a href='#L724'>724</a>
790
- <a name='L725'></a><a href='#L725'>725</a>
791
- <a name='L726'></a><a href='#L726'>726</a>
792
- <a name='L727'></a><a href='#L727'>727</a>
793
- <a name='L728'></a><a href='#L728'>728</a>
794
- <a name='L729'></a><a href='#L729'>729</a>
795
- <a name='L730'></a><a href='#L730'>730</a>
796
- <a name='L731'></a><a href='#L731'>731</a>
797
- <a name='L732'></a><a href='#L732'>732</a>
798
- <a name='L733'></a><a href='#L733'>733</a>
799
- <a name='L734'></a><a href='#L734'>734</a>
800
- <a name='L735'></a><a href='#L735'>735</a>
801
- <a name='L736'></a><a href='#L736'>736</a>
802
- <a name='L737'></a><a href='#L737'>737</a>
803
- <a name='L738'></a><a href='#L738'>738</a>
804
- <a name='L739'></a><a href='#L739'>739</a>
805
- <a name='L740'></a><a href='#L740'>740</a>
806
- <a name='L741'></a><a href='#L741'>741</a>
807
- <a name='L742'></a><a href='#L742'>742</a>
808
- <a name='L743'></a><a href='#L743'>743</a>
809
- <a name='L744'></a><a href='#L744'>744</a>
810
- <a name='L745'></a><a href='#L745'>745</a>
811
- <a name='L746'></a><a href='#L746'>746</a>
812
- <a name='L747'></a><a href='#L747'>747</a>
813
- <a name='L748'></a><a href='#L748'>748</a>
814
- <a name='L749'></a><a href='#L749'>749</a>
815
- <a name='L750'></a><a href='#L750'>750</a>
816
- <a name='L751'></a><a href='#L751'>751</a>
817
- <a name='L752'></a><a href='#L752'>752</a>
818
- <a name='L753'></a><a href='#L753'>753</a>
819
- <a name='L754'></a><a href='#L754'>754</a>
820
- <a name='L755'></a><a href='#L755'>755</a>
821
- <a name='L756'></a><a href='#L756'>756</a>
822
- <a name='L757'></a><a href='#L757'>757</a>
823
- <a name='L758'></a><a href='#L758'>758</a>
824
- <a name='L759'></a><a href='#L759'>759</a>
825
- <a name='L760'></a><a href='#L760'>760</a>
826
- <a name='L761'></a><a href='#L761'>761</a>
827
- <a name='L762'></a><a href='#L762'>762</a>
828
- <a name='L763'></a><a href='#L763'>763</a>
829
- <a name='L764'></a><a href='#L764'>764</a>
830
- <a name='L765'></a><a href='#L765'>765</a>
831
- <a name='L766'></a><a href='#L766'>766</a>
832
- <a name='L767'></a><a href='#L767'>767</a>
833
- <a name='L768'></a><a href='#L768'>768</a>
834
- <a name='L769'></a><a href='#L769'>769</a>
835
- <a name='L770'></a><a href='#L770'>770</a>
836
- <a name='L771'></a><a href='#L771'>771</a>
837
- <a name='L772'></a><a href='#L772'>772</a>
838
- <a name='L773'></a><a href='#L773'>773</a>
839
- <a name='L774'></a><a href='#L774'>774</a>
840
- <a name='L775'></a><a href='#L775'>775</a>
841
- <a name='L776'></a><a href='#L776'>776</a>
842
- <a name='L777'></a><a href='#L777'>777</a>
843
- <a name='L778'></a><a href='#L778'>778</a>
844
- <a name='L779'></a><a href='#L779'>779</a>
845
- <a name='L780'></a><a href='#L780'>780</a>
846
- <a name='L781'></a><a href='#L781'>781</a>
847
- <a name='L782'></a><a href='#L782'>782</a>
848
- <a name='L783'></a><a href='#L783'>783</a>
849
- <a name='L784'></a><a href='#L784'>784</a>
850
- <a name='L785'></a><a href='#L785'>785</a>
851
- <a name='L786'></a><a href='#L786'>786</a>
852
- <a name='L787'></a><a href='#L787'>787</a>
853
- <a name='L788'></a><a href='#L788'>788</a>
854
- <a name='L789'></a><a href='#L789'>789</a>
855
- <a name='L790'></a><a href='#L790'>790</a>
856
- <a name='L791'></a><a href='#L791'>791</a>
857
- <a name='L792'></a><a href='#L792'>792</a>
858
- <a name='L793'></a><a href='#L793'>793</a>
859
- <a name='L794'></a><a href='#L794'>794</a>
860
- <a name='L795'></a><a href='#L795'>795</a>
861
- <a name='L796'></a><a href='#L796'>796</a>
862
- <a name='L797'></a><a href='#L797'>797</a>
863
- <a name='L798'></a><a href='#L798'>798</a>
864
- <a name='L799'></a><a href='#L799'>799</a>
865
- <a name='L800'></a><a href='#L800'>800</a>
866
- <a name='L801'></a><a href='#L801'>801</a>
867
- <a name='L802'></a><a href='#L802'>802</a>
868
- <a name='L803'></a><a href='#L803'>803</a>
869
- <a name='L804'></a><a href='#L804'>804</a>
870
- <a name='L805'></a><a href='#L805'>805</a>
871
- <a name='L806'></a><a href='#L806'>806</a>
872
- <a name='L807'></a><a href='#L807'>807</a>
873
- <a name='L808'></a><a href='#L808'>808</a>
874
- <a name='L809'></a><a href='#L809'>809</a>
875
- <a name='L810'></a><a href='#L810'>810</a>
876
- <a name='L811'></a><a href='#L811'>811</a>
877
- <a name='L812'></a><a href='#L812'>812</a>
878
- <a name='L813'></a><a href='#L813'>813</a>
879
- <a name='L814'></a><a href='#L814'>814</a>
880
- <a name='L815'></a><a href='#L815'>815</a>
881
- <a name='L816'></a><a href='#L816'>816</a>
882
- <a name='L817'></a><a href='#L817'>817</a>
883
- <a name='L818'></a><a href='#L818'>818</a>
884
- <a name='L819'></a><a href='#L819'>819</a>
885
- <a name='L820'></a><a href='#L820'>820</a>
886
- <a name='L821'></a><a href='#L821'>821</a>
887
- <a name='L822'></a><a href='#L822'>822</a>
888
- <a name='L823'></a><a href='#L823'>823</a>
889
- <a name='L824'></a><a href='#L824'>824</a>
890
- <a name='L825'></a><a href='#L825'>825</a>
891
- <a name='L826'></a><a href='#L826'>826</a>
892
- <a name='L827'></a><a href='#L827'>827</a>
893
- <a name='L828'></a><a href='#L828'>828</a>
894
- <a name='L829'></a><a href='#L829'>829</a>
895
- <a name='L830'></a><a href='#L830'>830</a>
896
- <a name='L831'></a><a href='#L831'>831</a>
897
- <a name='L832'></a><a href='#L832'>832</a>
898
- <a name='L833'></a><a href='#L833'>833</a>
899
- <a name='L834'></a><a href='#L834'>834</a>
900
- <a name='L835'></a><a href='#L835'>835</a>
901
- <a name='L836'></a><a href='#L836'>836</a>
902
- <a name='L837'></a><a href='#L837'>837</a>
903
- <a name='L838'></a><a href='#L838'>838</a>
904
- <a name='L839'></a><a href='#L839'>839</a>
905
- <a name='L840'></a><a href='#L840'>840</a>
906
- <a name='L841'></a><a href='#L841'>841</a>
907
- <a name='L842'></a><a href='#L842'>842</a>
908
- <a name='L843'></a><a href='#L843'>843</a>
909
- <a name='L844'></a><a href='#L844'>844</a>
910
- <a name='L845'></a><a href='#L845'>845</a>
911
- <a name='L846'></a><a href='#L846'>846</a>
912
- <a name='L847'></a><a href='#L847'>847</a>
913
- <a name='L848'></a><a href='#L848'>848</a>
914
- <a name='L849'></a><a href='#L849'>849</a>
915
- <a name='L850'></a><a href='#L850'>850</a>
916
- <a name='L851'></a><a href='#L851'>851</a>
917
- <a name='L852'></a><a href='#L852'>852</a>
918
- <a name='L853'></a><a href='#L853'>853</a>
919
- <a name='L854'></a><a href='#L854'>854</a>
920
- <a name='L855'></a><a href='#L855'>855</a>
921
- <a name='L856'></a><a href='#L856'>856</a>
922
- <a name='L857'></a><a href='#L857'>857</a>
923
- <a name='L858'></a><a href='#L858'>858</a>
924
- <a name='L859'></a><a href='#L859'>859</a>
925
- <a name='L860'></a><a href='#L860'>860</a>
926
- <a name='L861'></a><a href='#L861'>861</a>
927
- <a name='L862'></a><a href='#L862'>862</a>
928
- <a name='L863'></a><a href='#L863'>863</a>
929
- <a name='L864'></a><a href='#L864'>864</a>
930
- <a name='L865'></a><a href='#L865'>865</a>
931
- <a name='L866'></a><a href='#L866'>866</a>
932
- <a name='L867'></a><a href='#L867'>867</a>
933
- <a name='L868'></a><a href='#L868'>868</a>
934
- <a name='L869'></a><a href='#L869'>869</a>
935
- <a name='L870'></a><a href='#L870'>870</a>
936
- <a name='L871'></a><a href='#L871'>871</a>
937
- <a name='L872'></a><a href='#L872'>872</a>
938
- <a name='L873'></a><a href='#L873'>873</a>
939
- <a name='L874'></a><a href='#L874'>874</a>
940
- <a name='L875'></a><a href='#L875'>875</a>
941
- <a name='L876'></a><a href='#L876'>876</a>
942
- <a name='L877'></a><a href='#L877'>877</a>
943
- <a name='L878'></a><a href='#L878'>878</a>
944
- <a name='L879'></a><a href='#L879'>879</a>
945
- <a name='L880'></a><a href='#L880'>880</a>
946
- <a name='L881'></a><a href='#L881'>881</a>
947
- <a name='L882'></a><a href='#L882'>882</a>
948
- <a name='L883'></a><a href='#L883'>883</a>
949
- <a name='L884'></a><a href='#L884'>884</a>
950
- <a name='L885'></a><a href='#L885'>885</a>
951
- <a name='L886'></a><a href='#L886'>886</a>
952
- <a name='L887'></a><a href='#L887'>887</a>
953
- <a name='L888'></a><a href='#L888'>888</a>
954
- <a name='L889'></a><a href='#L889'>889</a>
955
- <a name='L890'></a><a href='#L890'>890</a>
956
- <a name='L891'></a><a href='#L891'>891</a>
957
- <a name='L892'></a><a href='#L892'>892</a>
958
- <a name='L893'></a><a href='#L893'>893</a>
959
- <a name='L894'></a><a href='#L894'>894</a>
960
- <a name='L895'></a><a href='#L895'>895</a>
961
- <a name='L896'></a><a href='#L896'>896</a>
962
- <a name='L897'></a><a href='#L897'>897</a>
963
- <a name='L898'></a><a href='#L898'>898</a>
964
- <a name='L899'></a><a href='#L899'>899</a>
965
- <a name='L900'></a><a href='#L900'>900</a>
966
- <a name='L901'></a><a href='#L901'>901</a>
967
- <a name='L902'></a><a href='#L902'>902</a>
968
- <a name='L903'></a><a href='#L903'>903</a>
969
- <a name='L904'></a><a href='#L904'>904</a>
970
- <a name='L905'></a><a href='#L905'>905</a>
971
- <a name='L906'></a><a href='#L906'>906</a>
972
- <a name='L907'></a><a href='#L907'>907</a>
973
- <a name='L908'></a><a href='#L908'>908</a>
974
- <a name='L909'></a><a href='#L909'>909</a>
975
- <a name='L910'></a><a href='#L910'>910</a>
976
- <a name='L911'></a><a href='#L911'>911</a>
977
- <a name='L912'></a><a href='#L912'>912</a>
978
- <a name='L913'></a><a href='#L913'>913</a>
979
- <a name='L914'></a><a href='#L914'>914</a>
980
- <a name='L915'></a><a href='#L915'>915</a>
981
- <a name='L916'></a><a href='#L916'>916</a>
982
- <a name='L917'></a><a href='#L917'>917</a>
983
- <a name='L918'></a><a href='#L918'>918</a>
984
- <a name='L919'></a><a href='#L919'>919</a>
985
- <a name='L920'></a><a href='#L920'>920</a>
986
- <a name='L921'></a><a href='#L921'>921</a>
987
- <a name='L922'></a><a href='#L922'>922</a>
988
- <a name='L923'></a><a href='#L923'>923</a>
989
- <a name='L924'></a><a href='#L924'>924</a>
990
- <a name='L925'></a><a href='#L925'>925</a>
991
- <a name='L926'></a><a href='#L926'>926</a>
992
- <a name='L927'></a><a href='#L927'>927</a>
993
- <a name='L928'></a><a href='#L928'>928</a>
994
- <a name='L929'></a><a href='#L929'>929</a>
995
- <a name='L930'></a><a href='#L930'>930</a>
996
- <a name='L931'></a><a href='#L931'>931</a>
997
- <a name='L932'></a><a href='#L932'>932</a>
998
- <a name='L933'></a><a href='#L933'>933</a>
999
- <a name='L934'></a><a href='#L934'>934</a>
1000
- <a name='L935'></a><a href='#L935'>935</a>
1001
- <a name='L936'></a><a href='#L936'>936</a>
1002
- <a name='L937'></a><a href='#L937'>937</a>
1003
- <a name='L938'></a><a href='#L938'>938</a>
1004
- <a name='L939'></a><a href='#L939'>939</a>
1005
- <a name='L940'></a><a href='#L940'>940</a>
1006
- <a name='L941'></a><a href='#L941'>941</a>
1007
- <a name='L942'></a><a href='#L942'>942</a>
1008
- <a name='L943'></a><a href='#L943'>943</a>
1009
- <a name='L944'></a><a href='#L944'>944</a>
1010
- <a name='L945'></a><a href='#L945'>945</a>
1011
- <a name='L946'></a><a href='#L946'>946</a>
1012
- <a name='L947'></a><a href='#L947'>947</a>
1013
- <a name='L948'></a><a href='#L948'>948</a>
1014
- <a name='L949'></a><a href='#L949'>949</a>
1015
- <a name='L950'></a><a href='#L950'>950</a>
1016
- <a name='L951'></a><a href='#L951'>951</a>
1017
- <a name='L952'></a><a href='#L952'>952</a>
1018
- <a name='L953'></a><a href='#L953'>953</a>
1019
- <a name='L954'></a><a href='#L954'>954</a>
1020
- <a name='L955'></a><a href='#L955'>955</a>
1021
- <a name='L956'></a><a href='#L956'>956</a>
1022
- <a name='L957'></a><a href='#L957'>957</a>
1023
- <a name='L958'></a><a href='#L958'>958</a>
1024
- <a name='L959'></a><a href='#L959'>959</a>
1025
- <a name='L960'></a><a href='#L960'>960</a>
1026
- <a name='L961'></a><a href='#L961'>961</a>
1027
- <a name='L962'></a><a href='#L962'>962</a>
1028
- <a name='L963'></a><a href='#L963'>963</a>
1029
- <a name='L964'></a><a href='#L964'>964</a>
1030
- <a name='L965'></a><a href='#L965'>965</a>
1031
- <a name='L966'></a><a href='#L966'>966</a>
1032
- <a name='L967'></a><a href='#L967'>967</a>
1033
- <a name='L968'></a><a href='#L968'>968</a>
1034
- <a name='L969'></a><a href='#L969'>969</a>
1035
- <a name='L970'></a><a href='#L970'>970</a>
1036
- <a name='L971'></a><a href='#L971'>971</a>
1037
- <a name='L972'></a><a href='#L972'>972</a>
1038
- <a name='L973'></a><a href='#L973'>973</a>
1039
- <a name='L974'></a><a href='#L974'>974</a>
1040
- <a name='L975'></a><a href='#L975'>975</a>
1041
- <a name='L976'></a><a href='#L976'>976</a>
1042
- <a name='L977'></a><a href='#L977'>977</a>
1043
- <a name='L978'></a><a href='#L978'>978</a>
1044
- <a name='L979'></a><a href='#L979'>979</a>
1045
- <a name='L980'></a><a href='#L980'>980</a>
1046
- <a name='L981'></a><a href='#L981'>981</a>
1047
- <a name='L982'></a><a href='#L982'>982</a>
1048
- <a name='L983'></a><a href='#L983'>983</a>
1049
- <a name='L984'></a><a href='#L984'>984</a>
1050
- <a name='L985'></a><a href='#L985'>985</a>
1051
- <a name='L986'></a><a href='#L986'>986</a>
1052
- <a name='L987'></a><a href='#L987'>987</a>
1053
- <a name='L988'></a><a href='#L988'>988</a>
1054
- <a name='L989'></a><a href='#L989'>989</a>
1055
- <a name='L990'></a><a href='#L990'>990</a>
1056
- <a name='L991'></a><a href='#L991'>991</a>
1057
- <a name='L992'></a><a href='#L992'>992</a>
1058
- <a name='L993'></a><a href='#L993'>993</a>
1059
- <a name='L994'></a><a href='#L994'>994</a>
1060
- <a name='L995'></a><a href='#L995'>995</a>
1061
- <a name='L996'></a><a href='#L996'>996</a>
1062
- <a name='L997'></a><a href='#L997'>997</a>
1063
- <a name='L998'></a><a href='#L998'>998</a>
1064
- <a name='L999'></a><a href='#L999'>999</a>
1065
- <a name='L1000'></a><a href='#L1000'>1000</a>
1066
- <a name='L1001'></a><a href='#L1001'>1001</a>
1067
- <a name='L1002'></a><a href='#L1002'>1002</a>
1068
- <a name='L1003'></a><a href='#L1003'>1003</a>
1069
- <a name='L1004'></a><a href='#L1004'>1004</a>
1070
- <a name='L1005'></a><a href='#L1005'>1005</a>
1071
- <a name='L1006'></a><a href='#L1006'>1006</a>
1072
- <a name='L1007'></a><a href='#L1007'>1007</a>
1073
- <a name='L1008'></a><a href='#L1008'>1008</a>
1074
- <a name='L1009'></a><a href='#L1009'>1009</a>
1075
- <a name='L1010'></a><a href='#L1010'>1010</a>
1076
- <a name='L1011'></a><a href='#L1011'>1011</a>
1077
- <a name='L1012'></a><a href='#L1012'>1012</a>
1078
- <a name='L1013'></a><a href='#L1013'>1013</a>
1079
- <a name='L1014'></a><a href='#L1014'>1014</a>
1080
- <a name='L1015'></a><a href='#L1015'>1015</a>
1081
- <a name='L1016'></a><a href='#L1016'>1016</a>
1082
- <a name='L1017'></a><a href='#L1017'>1017</a>
1083
- <a name='L1018'></a><a href='#L1018'>1018</a>
1084
- <a name='L1019'></a><a href='#L1019'>1019</a>
1085
- <a name='L1020'></a><a href='#L1020'>1020</a>
1086
- <a name='L1021'></a><a href='#L1021'>1021</a>
1087
- <a name='L1022'></a><a href='#L1022'>1022</a>
1088
- <a name='L1023'></a><a href='#L1023'>1023</a>
1089
- <a name='L1024'></a><a href='#L1024'>1024</a>
1090
- <a name='L1025'></a><a href='#L1025'>1025</a>
1091
- <a name='L1026'></a><a href='#L1026'>1026</a>
1092
- <a name='L1027'></a><a href='#L1027'>1027</a>
1093
- <a name='L1028'></a><a href='#L1028'>1028</a>
1094
- <a name='L1029'></a><a href='#L1029'>1029</a>
1095
- <a name='L1030'></a><a href='#L1030'>1030</a>
1096
- <a name='L1031'></a><a href='#L1031'>1031</a>
1097
- <a name='L1032'></a><a href='#L1032'>1032</a>
1098
- <a name='L1033'></a><a href='#L1033'>1033</a>
1099
- <a name='L1034'></a><a href='#L1034'>1034</a>
1100
- <a name='L1035'></a><a href='#L1035'>1035</a>
1101
- <a name='L1036'></a><a href='#L1036'>1036</a>
1102
- <a name='L1037'></a><a href='#L1037'>1037</a>
1103
- <a name='L1038'></a><a href='#L1038'>1038</a>
1104
- <a name='L1039'></a><a href='#L1039'>1039</a>
1105
- <a name='L1040'></a><a href='#L1040'>1040</a>
1106
- <a name='L1041'></a><a href='#L1041'>1041</a>
1107
- <a name='L1042'></a><a href='#L1042'>1042</a>
1108
- <a name='L1043'></a><a href='#L1043'>1043</a>
1109
- <a name='L1044'></a><a href='#L1044'>1044</a>
1110
- <a name='L1045'></a><a href='#L1045'>1045</a>
1111
- <a name='L1046'></a><a href='#L1046'>1046</a>
1112
- <a name='L1047'></a><a href='#L1047'>1047</a>
1113
- <a name='L1048'></a><a href='#L1048'>1048</a>
1114
- <a name='L1049'></a><a href='#L1049'>1049</a>
1115
- <a name='L1050'></a><a href='#L1050'>1050</a>
1116
- <a name='L1051'></a><a href='#L1051'>1051</a>
1117
- <a name='L1052'></a><a href='#L1052'>1052</a>
1118
- <a name='L1053'></a><a href='#L1053'>1053</a>
1119
- <a name='L1054'></a><a href='#L1054'>1054</a>
1120
- <a name='L1055'></a><a href='#L1055'>1055</a>
1121
- <a name='L1056'></a><a href='#L1056'>1056</a>
1122
- <a name='L1057'></a><a href='#L1057'>1057</a>
1123
- <a name='L1058'></a><a href='#L1058'>1058</a>
1124
- <a name='L1059'></a><a href='#L1059'>1059</a>
1125
- <a name='L1060'></a><a href='#L1060'>1060</a>
1126
- <a name='L1061'></a><a href='#L1061'>1061</a>
1127
- <a name='L1062'></a><a href='#L1062'>1062</a>
1128
- <a name='L1063'></a><a href='#L1063'>1063</a>
1129
- <a name='L1064'></a><a href='#L1064'>1064</a>
1130
- <a name='L1065'></a><a href='#L1065'>1065</a>
1131
- <a name='L1066'></a><a href='#L1066'>1066</a>
1132
- <a name='L1067'></a><a href='#L1067'>1067</a>
1133
- <a name='L1068'></a><a href='#L1068'>1068</a>
1134
- <a name='L1069'></a><a href='#L1069'>1069</a>
1135
- <a name='L1070'></a><a href='#L1070'>1070</a>
1136
- <a name='L1071'></a><a href='#L1071'>1071</a>
1137
- <a name='L1072'></a><a href='#L1072'>1072</a>
1138
- <a name='L1073'></a><a href='#L1073'>1073</a>
1139
- <a name='L1074'></a><a href='#L1074'>1074</a>
1140
- <a name='L1075'></a><a href='#L1075'>1075</a>
1141
- <a name='L1076'></a><a href='#L1076'>1076</a>
1142
- <a name='L1077'></a><a href='#L1077'>1077</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
1143
- <span class="cline-any cline-neutral">&nbsp;</span>
1144
- <span class="cline-any cline-neutral">&nbsp;</span>
1145
- <span class="cline-any cline-neutral">&nbsp;</span>
1146
- <span class="cline-any cline-neutral">&nbsp;</span>
1147
- <span class="cline-any cline-neutral">&nbsp;</span>
1148
- <span class="cline-any cline-neutral">&nbsp;</span>
1149
- <span class="cline-any cline-neutral">&nbsp;</span>
1150
- <span class="cline-any cline-neutral">&nbsp;</span>
1151
- <span class="cline-any cline-neutral">&nbsp;</span>
1152
- <span class="cline-any cline-neutral">&nbsp;</span>
1153
- <span class="cline-any cline-neutral">&nbsp;</span>
1154
- <span class="cline-any cline-neutral">&nbsp;</span>
1155
- <span class="cline-any cline-neutral">&nbsp;</span>
1156
- <span class="cline-any cline-neutral">&nbsp;</span>
1157
- <span class="cline-any cline-neutral">&nbsp;</span>
1158
- <span class="cline-any cline-neutral">&nbsp;</span>
1159
- <span class="cline-any cline-neutral">&nbsp;</span>
1160
- <span class="cline-any cline-neutral">&nbsp;</span>
1161
- <span class="cline-any cline-neutral">&nbsp;</span>
1162
- <span class="cline-any cline-neutral">&nbsp;</span>
1163
- <span class="cline-any cline-neutral">&nbsp;</span>
1164
- <span class="cline-any cline-neutral">&nbsp;</span>
1165
- <span class="cline-any cline-neutral">&nbsp;</span>
1166
- <span class="cline-any cline-neutral">&nbsp;</span>
1167
- <span class="cline-any cline-neutral">&nbsp;</span>
1168
- <span class="cline-any cline-neutral">&nbsp;</span>
1169
- <span class="cline-any cline-neutral">&nbsp;</span>
1170
- <span class="cline-any cline-neutral">&nbsp;</span>
1171
- <span class="cline-any cline-neutral">&nbsp;</span>
1172
- <span class="cline-any cline-neutral">&nbsp;</span>
1173
- <span class="cline-any cline-neutral">&nbsp;</span>
1174
- <span class="cline-any cline-neutral">&nbsp;</span>
1175
- <span class="cline-any cline-neutral">&nbsp;</span>
1176
- <span class="cline-any cline-neutral">&nbsp;</span>
1177
- <span class="cline-any cline-neutral">&nbsp;</span>
1178
- <span class="cline-any cline-neutral">&nbsp;</span>
1179
- <span class="cline-any cline-neutral">&nbsp;</span>
1180
- <span class="cline-any cline-neutral">&nbsp;</span>
1181
- <span class="cline-any cline-neutral">&nbsp;</span>
1182
- <span class="cline-any cline-neutral">&nbsp;</span>
1183
- <span class="cline-any cline-neutral">&nbsp;</span>
1184
- <span class="cline-any cline-neutral">&nbsp;</span>
1185
- <span class="cline-any cline-neutral">&nbsp;</span>
1186
- <span class="cline-any cline-neutral">&nbsp;</span>
1187
- <span class="cline-any cline-neutral">&nbsp;</span>
1188
- <span class="cline-any cline-neutral">&nbsp;</span>
1189
- <span class="cline-any cline-neutral">&nbsp;</span>
1190
- <span class="cline-any cline-neutral">&nbsp;</span>
1191
- <span class="cline-any cline-neutral">&nbsp;</span>
1192
- <span class="cline-any cline-neutral">&nbsp;</span>
1193
- <span class="cline-any cline-neutral">&nbsp;</span>
1194
- <span class="cline-any cline-neutral">&nbsp;</span>
1195
- <span class="cline-any cline-neutral">&nbsp;</span>
1196
- <span class="cline-any cline-neutral">&nbsp;</span>
1197
- <span class="cline-any cline-neutral">&nbsp;</span>
1198
- <span class="cline-any cline-neutral">&nbsp;</span>
1199
- <span class="cline-any cline-neutral">&nbsp;</span>
1200
- <span class="cline-any cline-neutral">&nbsp;</span>
1201
- <span class="cline-any cline-neutral">&nbsp;</span>
1202
- <span class="cline-any cline-neutral">&nbsp;</span>
1203
- <span class="cline-any cline-neutral">&nbsp;</span>
1204
- <span class="cline-any cline-neutral">&nbsp;</span>
1205
- <span class="cline-any cline-neutral">&nbsp;</span>
1206
- <span class="cline-any cline-neutral">&nbsp;</span>
1207
- <span class="cline-any cline-neutral">&nbsp;</span>
1208
- <span class="cline-any cline-neutral">&nbsp;</span>
1209
- <span class="cline-any cline-neutral">&nbsp;</span>
1210
- <span class="cline-any cline-neutral">&nbsp;</span>
1211
- <span class="cline-any cline-neutral">&nbsp;</span>
1212
- <span class="cline-any cline-neutral">&nbsp;</span>
1213
- <span class="cline-any cline-neutral">&nbsp;</span>
1214
- <span class="cline-any cline-neutral">&nbsp;</span>
1215
- <span class="cline-any cline-neutral">&nbsp;</span>
1216
- <span class="cline-any cline-neutral">&nbsp;</span>
1217
- <span class="cline-any cline-neutral">&nbsp;</span>
1218
- <span class="cline-any cline-neutral">&nbsp;</span>
1219
- <span class="cline-any cline-neutral">&nbsp;</span>
1220
- <span class="cline-any cline-neutral">&nbsp;</span>
1221
- <span class="cline-any cline-neutral">&nbsp;</span>
1222
- <span class="cline-any cline-neutral">&nbsp;</span>
1223
- <span class="cline-any cline-neutral">&nbsp;</span>
1224
- <span class="cline-any cline-neutral">&nbsp;</span>
1225
- <span class="cline-any cline-neutral">&nbsp;</span>
1226
- <span class="cline-any cline-neutral">&nbsp;</span>
1227
- <span class="cline-any cline-neutral">&nbsp;</span>
1228
- <span class="cline-any cline-neutral">&nbsp;</span>
1229
- <span class="cline-any cline-neutral">&nbsp;</span>
1230
- <span class="cline-any cline-neutral">&nbsp;</span>
1231
- <span class="cline-any cline-neutral">&nbsp;</span>
1232
- <span class="cline-any cline-neutral">&nbsp;</span>
1233
- <span class="cline-any cline-neutral">&nbsp;</span>
1234
- <span class="cline-any cline-neutral">&nbsp;</span>
1235
- <span class="cline-any cline-neutral">&nbsp;</span>
1236
- <span class="cline-any cline-yes">1x</span>
1237
- <span class="cline-any cline-neutral">&nbsp;</span>
1238
- <span class="cline-any cline-yes">1x</span>
1239
- <span class="cline-any cline-neutral">&nbsp;</span>
1240
- <span class="cline-any cline-neutral">&nbsp;</span>
1241
- <span class="cline-any cline-neutral">&nbsp;</span>
1242
- <span class="cline-any cline-yes">1x</span>
1243
- <span class="cline-any cline-neutral">&nbsp;</span>
1244
- <span class="cline-any cline-yes">1x</span>
1245
- <span class="cline-any cline-neutral">&nbsp;</span>
1246
- <span class="cline-any cline-neutral">&nbsp;</span>
1247
- <span class="cline-any cline-yes">1x</span>
1248
- <span class="cline-any cline-neutral">&nbsp;</span>
1249
- <span class="cline-any cline-yes">1x</span>
1250
- <span class="cline-any cline-neutral">&nbsp;</span>
1251
- <span class="cline-any cline-neutral">&nbsp;</span>
1252
- <span class="cline-any cline-yes">12x</span>
1253
- <span class="cline-any cline-yes">12x</span>
1254
- <span class="cline-any cline-yes">12x</span>
1255
- <span class="cline-any cline-neutral">&nbsp;</span>
1256
- <span class="cline-any cline-yes">18x</span>
1257
- <span class="cline-any cline-yes">18x</span>
1258
- <span class="cline-any cline-yes">18x</span>
1259
- <span class="cline-any cline-yes">18x</span>
1260
- <span class="cline-any cline-yes">18x</span>
1261
- <span class="cline-any cline-neutral">&nbsp;</span>
1262
- <span class="cline-any cline-yes">1x</span>
1263
- <span class="cline-any cline-yes">21x</span>
1264
- <span class="cline-any cline-yes">21x</span>
1265
- <span class="cline-any cline-yes">21x</span>
1266
- <span class="cline-any cline-yes">21x</span>
1267
- <span class="cline-any cline-neutral">&nbsp;</span>
1268
- <span class="cline-any cline-neutral">&nbsp;</span>
1269
- <span class="cline-any cline-neutral">&nbsp;</span>
1270
- <span class="cline-any cline-neutral">&nbsp;</span>
1271
- <span class="cline-any cline-yes">21x</span>
1272
- <span class="cline-any cline-yes">21x</span>
1273
- <span class="cline-any cline-neutral">&nbsp;</span>
1274
- <span class="cline-any cline-neutral">&nbsp;</span>
1275
- <span class="cline-any cline-neutral">&nbsp;</span>
1276
- <span class="cline-any cline-neutral">&nbsp;</span>
1277
- <span class="cline-any cline-neutral">&nbsp;</span>
1278
- <span class="cline-any cline-neutral">&nbsp;</span>
1279
- <span class="cline-any cline-yes">21x</span>
1280
- <span class="cline-any cline-neutral">&nbsp;</span>
1281
- <span class="cline-any cline-neutral">&nbsp;</span>
1282
- <span class="cline-any cline-neutral">&nbsp;</span>
1283
- <span class="cline-any cline-yes">21x</span>
1284
- <span class="cline-any cline-neutral">&nbsp;</span>
1285
- <span class="cline-any cline-neutral">&nbsp;</span>
1286
- <span class="cline-any cline-yes">21x</span>
1287
- <span class="cline-any cline-neutral">&nbsp;</span>
1288
- <span class="cline-any cline-neutral">&nbsp;</span>
1289
- <span class="cline-any cline-neutral">&nbsp;</span>
1290
- <span class="cline-any cline-neutral">&nbsp;</span>
1291
- <span class="cline-any cline-neutral">&nbsp;</span>
1292
- <span class="cline-any cline-yes">21x</span>
1293
- <span class="cline-any cline-yes">21x</span>
1294
- <span class="cline-any cline-yes">21x</span>
1295
- <span class="cline-any cline-yes">21x</span>
1296
- <span class="cline-any cline-yes">21x</span>
1297
- <span class="cline-any cline-yes">21x</span>
1298
- <span class="cline-any cline-yes">21x</span>
1299
- <span class="cline-any cline-neutral">&nbsp;</span>
1300
- <span class="cline-any cline-neutral">&nbsp;</span>
1301
- <span class="cline-any cline-neutral">&nbsp;</span>
1302
- <span class="cline-any cline-yes">21x</span>
1303
- <span class="cline-any cline-neutral">&nbsp;</span>
1304
- <span class="cline-any cline-neutral">&nbsp;</span>
1305
- <span class="cline-any cline-neutral">&nbsp;</span>
1306
- <span class="cline-any cline-yes">21x</span>
1307
- <span class="cline-any cline-yes">21x</span>
1308
- <span class="cline-any cline-neutral">&nbsp;</span>
1309
- <span class="cline-any cline-neutral">&nbsp;</span>
1310
- <span class="cline-any cline-yes">21x</span>
1311
- <span class="cline-any cline-yes">21x</span>
1312
- <span class="cline-any cline-neutral">&nbsp;</span>
1313
- <span class="cline-any cline-yes">21x</span>
1314
- <span class="cline-any cline-yes">21x</span>
1315
- <span class="cline-any cline-yes">21x</span>
1316
- <span class="cline-any cline-yes">21x</span>
1317
- <span class="cline-any cline-yes">21x</span>
1318
- <span class="cline-any cline-yes">21x</span>
1319
- <span class="cline-any cline-yes">21x</span>
1320
- <span class="cline-any cline-neutral">&nbsp;</span>
1321
- <span class="cline-any cline-neutral">&nbsp;</span>
1322
- <span class="cline-any cline-neutral">&nbsp;</span>
1323
- <span class="cline-any cline-neutral">&nbsp;</span>
1324
- <span class="cline-any cline-neutral">&nbsp;</span>
1325
- <span class="cline-any cline-yes">21x</span>
1326
- <span class="cline-any cline-yes">12x</span>
1327
- <span class="cline-any cline-yes">12x</span>
1328
- <span class="cline-any cline-neutral">&nbsp;</span>
1329
- <span class="cline-any cline-yes">21x</span>
1330
- <span class="cline-any cline-yes">11x</span>
1331
- <span class="cline-any cline-neutral">&nbsp;</span>
1332
- <span class="cline-any cline-neutral">&nbsp;</span>
1333
- <span class="cline-any cline-neutral">&nbsp;</span>
1334
- <span class="cline-any cline-neutral">&nbsp;</span>
1335
- <span class="cline-any cline-neutral">&nbsp;</span>
1336
- <span class="cline-any cline-neutral">&nbsp;</span>
1337
- <span class="cline-any cline-yes">7x</span>
1338
- <span class="cline-any cline-yes">8x</span>
1339
- <span class="cline-any cline-yes">8x</span>
1340
- <span class="cline-any cline-yes">8x</span>
1341
- <span class="cline-any cline-yes">8x</span>
1342
- <span class="cline-any cline-yes">8x</span>
1343
- <span class="cline-any cline-yes">8x</span>
1344
- <span class="cline-any cline-yes">8x</span>
1345
- <span class="cline-any cline-yes">8x</span>
1346
- <span class="cline-any cline-yes">8x</span>
1347
- <span class="cline-any cline-yes">8x</span>
1348
- <span class="cline-any cline-yes">8x</span>
1349
- <span class="cline-any cline-yes">7x</span>
1350
- <span class="cline-any cline-yes">7x</span>
1351
- <span class="cline-any cline-neutral">&nbsp;</span>
1352
- <span class="cline-any cline-yes">4x</span>
1353
- <span class="cline-any cline-yes">11x</span>
1354
- <span class="cline-any cline-neutral">&nbsp;</span>
1355
- <span class="cline-any cline-yes">21x</span>
1356
- <span class="cline-any cline-yes">9x</span>
1357
- <span class="cline-any cline-yes">10x</span>
1358
- <span class="cline-any cline-yes">10x</span>
1359
- <span class="cline-any cline-yes">10x</span>
1360
- <span class="cline-any cline-yes">10x</span>
1361
- <span class="cline-any cline-yes">9x</span>
1362
- <span class="cline-any cline-neutral">&nbsp;</span>
1363
- <span class="cline-any cline-neutral">&nbsp;</span>
1364
- <span class="cline-any cline-neutral">&nbsp;</span>
1365
- <span class="cline-any cline-neutral">&nbsp;</span>
1366
- <span class="cline-any cline-neutral">&nbsp;</span>
1367
- <span class="cline-any cline-neutral">&nbsp;</span>
1368
- <span class="cline-any cline-neutral">&nbsp;</span>
1369
- <span class="cline-any cline-neutral">&nbsp;</span>
1370
- <span class="cline-any cline-neutral">&nbsp;</span>
1371
- <span class="cline-any cline-neutral">&nbsp;</span>
1372
- <span class="cline-any cline-neutral">&nbsp;</span>
1373
- <span class="cline-any cline-neutral">&nbsp;</span>
1374
- <span class="cline-any cline-neutral">&nbsp;</span>
1375
- <span class="cline-any cline-neutral">&nbsp;</span>
1376
- <span class="cline-any cline-neutral">&nbsp;</span>
1377
- <span class="cline-any cline-neutral">&nbsp;</span>
1378
- <span class="cline-any cline-yes">21x</span>
1379
- <span class="cline-any cline-yes">14x</span>
1380
- <span class="cline-any cline-neutral">&nbsp;</span>
1381
- <span class="cline-any cline-yes">14x</span>
1382
- <span class="cline-any cline-no">&nbsp;</span>
1383
- <span class="cline-any cline-no">&nbsp;</span>
1384
- <span class="cline-any cline-no">&nbsp;</span>
1385
- <span class="cline-any cline-no">&nbsp;</span>
1386
- <span class="cline-any cline-no">&nbsp;</span>
1387
- <span class="cline-any cline-no">&nbsp;</span>
1388
- <span class="cline-any cline-neutral">&nbsp;</span>
1389
- <span class="cline-any cline-yes">12x</span>
1390
- <span class="cline-any cline-yes">14x</span>
1391
- <span class="cline-any cline-neutral">&nbsp;</span>
1392
- <span class="cline-any cline-yes">3x</span>
1393
- <span class="cline-any cline-yes">3x</span>
1394
- <span class="cline-any cline-yes">3x</span>
1395
- <span class="cline-any cline-yes">8x</span>
1396
- <span class="cline-any cline-yes">8x</span>
1397
- <span class="cline-any cline-yes">3x</span>
1398
- <span class="cline-any cline-yes">3x</span>
1399
- <span class="cline-any cline-yes">3x</span>
1400
- <span class="cline-any cline-yes">3x</span>
1401
- <span class="cline-any cline-yes">3x</span>
1402
- <span class="cline-any cline-neutral">&nbsp;</span>
1403
- <span class="cline-any cline-yes">9x</span>
1404
- <span class="cline-any cline-yes">9x</span>
1405
- <span class="cline-any cline-yes">9x</span>
1406
- <span class="cline-any cline-yes">9x</span>
1407
- <span class="cline-any cline-yes">9x</span>
1408
- <span class="cline-any cline-yes">9x</span>
1409
- <span class="cline-any cline-yes">15x</span>
1410
- <span class="cline-any cline-yes">15x</span>
1411
- <span class="cline-any cline-yes">15x</span>
1412
- <span class="cline-any cline-yes">15x</span>
1413
- <span class="cline-any cline-yes">9x</span>
1414
- <span class="cline-any cline-yes">9x</span>
1415
- <span class="cline-any cline-yes">9x</span>
1416
- <span class="cline-any cline-yes">9x</span>
1417
- <span class="cline-any cline-yes">9x</span>
1418
- <span class="cline-any cline-yes">1x</span>
1419
- <span class="cline-any cline-yes">1x</span>
1420
- <span class="cline-any cline-yes">1x</span>
1421
- <span class="cline-any cline-yes">1x</span>
1422
- <span class="cline-any cline-yes">1x</span>
1423
- <span class="cline-any cline-yes">1x</span>
1424
- <span class="cline-any cline-yes">1x</span>
1425
- <span class="cline-any cline-yes">1x</span>
1426
- <span class="cline-any cline-yes">1x</span>
1427
- <span class="cline-any cline-yes">1x</span>
1428
- <span class="cline-any cline-yes">1x</span>
1429
- <span class="cline-any cline-yes">1x</span>
1430
- <span class="cline-any cline-yes">9x</span>
1431
- <span class="cline-any cline-yes">9x</span>
1432
- <span class="cline-any cline-no">&nbsp;</span>
1433
- <span class="cline-any cline-no">&nbsp;</span>
1434
- <span class="cline-any cline-no">&nbsp;</span>
1435
- <span class="cline-any cline-no">&nbsp;</span>
1436
- <span class="cline-any cline-no">&nbsp;</span>
1437
- <span class="cline-any cline-yes">9x</span>
1438
- <span class="cline-any cline-yes">9x</span>
1439
- <span class="cline-any cline-yes">9x</span>
1440
- <span class="cline-any cline-yes">9x</span>
1441
- <span class="cline-any cline-yes">9x</span>
1442
- <span class="cline-any cline-yes">9x</span>
1443
- <span class="cline-any cline-yes">9x</span>
1444
- <span class="cline-any cline-yes">9x</span>
1445
- <span class="cline-any cline-yes">9x</span>
1446
- <span class="cline-any cline-yes">9x</span>
1447
- <span class="cline-any cline-yes">14x</span>
1448
- <span class="cline-any cline-neutral">&nbsp;</span>
1449
- <span class="cline-any cline-neutral">&nbsp;</span>
1450
- <span class="cline-any cline-neutral">&nbsp;</span>
1451
- <span class="cline-any cline-neutral">&nbsp;</span>
1452
- <span class="cline-any cline-neutral">&nbsp;</span>
1453
- <span class="cline-any cline-neutral">&nbsp;</span>
1454
- <span class="cline-any cline-neutral">&nbsp;</span>
1455
- <span class="cline-any cline-neutral">&nbsp;</span>
1456
- <span class="cline-any cline-neutral">&nbsp;</span>
1457
- <span class="cline-any cline-neutral">&nbsp;</span>
1458
- <span class="cline-any cline-yes">21x</span>
1459
- <span class="cline-any cline-yes">12x</span>
1460
- <span class="cline-any cline-yes">12x</span>
1461
- <span class="cline-any cline-yes">12x</span>
1462
- <span class="cline-any cline-yes">12x</span>
1463
- <span class="cline-any cline-neutral">&nbsp;</span>
1464
- <span class="cline-any cline-neutral">&nbsp;</span>
1465
- <span class="cline-any cline-neutral">&nbsp;</span>
1466
- <span class="cline-any cline-neutral">&nbsp;</span>
1467
- <span class="cline-any cline-neutral">&nbsp;</span>
1468
- <span class="cline-any cline-neutral">&nbsp;</span>
1469
- <span class="cline-any cline-yes">21x</span>
1470
- <span class="cline-any cline-yes">12x</span>
1471
- <span class="cline-any cline-yes">12x</span>
1472
- <span class="cline-any cline-yes">12x</span>
1473
- <span class="cline-any cline-yes">12x</span>
1474
- <span class="cline-any cline-yes">12x</span>
1475
- <span class="cline-any cline-yes">3x</span>
1476
- <span class="cline-any cline-yes">3x</span>
1477
- <span class="cline-any cline-yes">12x</span>
1478
- <span class="cline-any cline-neutral">&nbsp;</span>
1479
- <span class="cline-any cline-neutral">&nbsp;</span>
1480
- <span class="cline-any cline-neutral">&nbsp;</span>
1481
- <span class="cline-any cline-neutral">&nbsp;</span>
1482
- <span class="cline-any cline-neutral">&nbsp;</span>
1483
- <span class="cline-any cline-yes">21x</span>
1484
- <span class="cline-any cline-yes">15x</span>
1485
- <span class="cline-any cline-neutral">&nbsp;</span>
1486
- <span class="cline-any cline-yes">15x</span>
1487
- <span class="cline-any cline-yes">15x</span>
1488
- <span class="cline-any cline-yes">15x</span>
1489
- <span class="cline-any cline-yes">15x</span>
1490
- <span class="cline-any cline-yes">15x</span>
1491
- <span class="cline-any cline-yes">15x</span>
1492
- <span class="cline-any cline-neutral">&nbsp;</span>
1493
- <span class="cline-any cline-yes">15x</span>
1494
- <span class="cline-any cline-yes">15x</span>
1495
- <span class="cline-any cline-neutral">&nbsp;</span>
1496
- <span class="cline-any cline-yes">15x</span>
1497
- <span class="cline-any cline-yes">15x</span>
1498
- <span class="cline-any cline-yes">15x</span>
1499
- <span class="cline-any cline-yes">15x</span>
1500
- <span class="cline-any cline-yes">15x</span>
1501
- <span class="cline-any cline-yes">15x</span>
1502
- <span class="cline-any cline-no">&nbsp;</span>
1503
- <span class="cline-any cline-no">&nbsp;</span>
1504
- <span class="cline-any cline-no">&nbsp;</span>
1505
- <span class="cline-any cline-no">&nbsp;</span>
1506
- <span class="cline-any cline-no">&nbsp;</span>
1507
- <span class="cline-any cline-no">&nbsp;</span>
1508
- <span class="cline-any cline-yes">15x</span>
1509
- <span class="cline-any cline-neutral">&nbsp;</span>
1510
- <span class="cline-any cline-neutral">&nbsp;</span>
1511
- <span class="cline-any cline-neutral">&nbsp;</span>
1512
- <span class="cline-any cline-neutral">&nbsp;</span>
1513
- <span class="cline-any cline-neutral">&nbsp;</span>
1514
- <span class="cline-any cline-neutral">&nbsp;</span>
1515
- <span class="cline-any cline-neutral">&nbsp;</span>
1516
- <span class="cline-any cline-neutral">&nbsp;</span>
1517
- <span class="cline-any cline-neutral">&nbsp;</span>
1518
- <span class="cline-any cline-neutral">&nbsp;</span>
1519
- <span class="cline-any cline-neutral">&nbsp;</span>
1520
- <span class="cline-any cline-neutral">&nbsp;</span>
1521
- <span class="cline-any cline-yes">21x</span>
1522
- <span class="cline-any cline-yes">3x</span>
1523
- <span class="cline-any cline-yes">3x</span>
1524
- <span class="cline-any cline-yes">3x</span>
1525
- <span class="cline-any cline-yes">3x</span>
1526
- <span class="cline-any cline-yes">3x</span>
1527
- <span class="cline-any cline-yes">3x</span>
1528
- <span class="cline-any cline-yes">3x</span>
1529
- <span class="cline-any cline-yes">3x</span>
1530
- <span class="cline-any cline-yes">3x</span>
1531
- <span class="cline-any cline-yes">3x</span>
1532
- <span class="cline-any cline-yes">3x</span>
1533
- <span class="cline-any cline-yes">3x</span>
1534
- <span class="cline-any cline-yes">3x</span>
1535
- <span class="cline-any cline-yes">3x</span>
1536
- <span class="cline-any cline-yes">3x</span>
1537
- <span class="cline-any cline-yes">3x</span>
1538
- <span class="cline-any cline-neutral">&nbsp;</span>
1539
- <span class="cline-any cline-neutral">&nbsp;</span>
1540
- <span class="cline-any cline-neutral">&nbsp;</span>
1541
- <span class="cline-any cline-neutral">&nbsp;</span>
1542
- <span class="cline-any cline-neutral">&nbsp;</span>
1543
- <span class="cline-any cline-neutral">&nbsp;</span>
1544
- <span class="cline-any cline-yes">21x</span>
1545
- <span class="cline-any cline-no">&nbsp;</span>
1546
- <span class="cline-any cline-no">&nbsp;</span>
1547
- <span class="cline-any cline-no">&nbsp;</span>
1548
- <span class="cline-any cline-no">&nbsp;</span>
1549
- <span class="cline-any cline-no">&nbsp;</span>
1550
- <span class="cline-any cline-no">&nbsp;</span>
1551
- <span class="cline-any cline-no">&nbsp;</span>
1552
- <span class="cline-any cline-no">&nbsp;</span>
1553
- <span class="cline-any cline-no">&nbsp;</span>
1554
- <span class="cline-any cline-neutral">&nbsp;</span>
1555
- <span class="cline-any cline-neutral">&nbsp;</span>
1556
- <span class="cline-any cline-neutral">&nbsp;</span>
1557
- <span class="cline-any cline-neutral">&nbsp;</span>
1558
- <span class="cline-any cline-neutral">&nbsp;</span>
1559
- <span class="cline-any cline-yes">21x</span>
1560
- <span class="cline-any cline-yes">3x</span>
1561
- <span class="cline-any cline-yes">3x</span>
1562
- <span class="cline-any cline-yes">3x</span>
1563
- <span class="cline-any cline-yes">3x</span>
1564
- <span class="cline-any cline-no">&nbsp;</span>
1565
- <span class="cline-any cline-no">&nbsp;</span>
1566
- <span class="cline-any cline-no">&nbsp;</span>
1567
- <span class="cline-any cline-no">&nbsp;</span>
1568
- <span class="cline-any cline-no">&nbsp;</span>
1569
- <span class="cline-any cline-yes">3x</span>
1570
- <span class="cline-any cline-neutral">&nbsp;</span>
1571
- <span class="cline-any cline-neutral">&nbsp;</span>
1572
- <span class="cline-any cline-yes">21x</span>
1573
- <span class="cline-any cline-yes">1x</span>
1574
- <span class="cline-any cline-yes">1x</span>
1575
- <span class="cline-any cline-yes">1x</span>
1576
- <span class="cline-any cline-neutral">&nbsp;</span>
1577
- <span class="cline-any cline-neutral">&nbsp;</span>
1578
- <span class="cline-any cline-neutral">&nbsp;</span>
1579
- <span class="cline-any cline-neutral">&nbsp;</span>
1580
- <span class="cline-any cline-neutral">&nbsp;</span>
1581
- <span class="cline-any cline-neutral">&nbsp;</span>
1582
- <span class="cline-any cline-yes">21x</span>
1583
- <span class="cline-any cline-yes">12x</span>
1584
- <span class="cline-any cline-yes">12x</span>
1585
- <span class="cline-any cline-yes">12x</span>
1586
- <span class="cline-any cline-yes">12x</span>
1587
- <span class="cline-any cline-neutral">&nbsp;</span>
1588
- <span class="cline-any cline-neutral">&nbsp;</span>
1589
- <span class="cline-any cline-neutral">&nbsp;</span>
1590
- <span class="cline-any cline-neutral">&nbsp;</span>
1591
- <span class="cline-any cline-neutral">&nbsp;</span>
1592
- <span class="cline-any cline-yes">21x</span>
1593
- <span class="cline-any cline-no">&nbsp;</span>
1594
- <span class="cline-any cline-no">&nbsp;</span>
1595
- <span class="cline-any cline-no">&nbsp;</span>
1596
- <span class="cline-any cline-neutral">&nbsp;</span>
1597
- <span class="cline-any cline-yes">21x</span>
1598
- <span class="cline-any cline-yes">18x</span>
1599
- <span class="cline-any cline-yes">18x</span>
1600
- <span class="cline-any cline-yes">18x</span>
1601
- <span class="cline-any cline-yes">18x</span>
1602
- <span class="cline-any cline-no">&nbsp;</span>
1603
- <span class="cline-any cline-no">&nbsp;</span>
1604
- <span class="cline-any cline-no">&nbsp;</span>
1605
- <span class="cline-any cline-no">&nbsp;</span>
1606
- <span class="cline-any cline-no">&nbsp;</span>
1607
- <span class="cline-any cline-yes">18x</span>
1608
- <span class="cline-any cline-neutral">&nbsp;</span>
1609
- <span class="cline-any cline-neutral">&nbsp;</span>
1610
- <span class="cline-any cline-yes">21x</span>
1611
- <span class="cline-any cline-yes">1x</span>
1612
- <span class="cline-any cline-yes">1x</span>
1613
- <span class="cline-any cline-neutral">&nbsp;</span>
1614
- <span class="cline-any cline-neutral">&nbsp;</span>
1615
- <span class="cline-any cline-neutral">&nbsp;</span>
1616
- <span class="cline-any cline-neutral">&nbsp;</span>
1617
- <span class="cline-any cline-neutral">&nbsp;</span>
1618
- <span class="cline-any cline-neutral">&nbsp;</span>
1619
- <span class="cline-any cline-neutral">&nbsp;</span>
1620
- <span class="cline-any cline-neutral">&nbsp;</span>
1621
- <span class="cline-any cline-neutral">&nbsp;</span>
1622
- <span class="cline-any cline-neutral">&nbsp;</span>
1623
- <span class="cline-any cline-neutral">&nbsp;</span>
1624
- <span class="cline-any cline-neutral">&nbsp;</span>
1625
- <span class="cline-any cline-neutral">&nbsp;</span>
1626
- <span class="cline-any cline-neutral">&nbsp;</span>
1627
- <span class="cline-any cline-yes">21x</span>
1628
- <span class="cline-any cline-yes">11x</span>
1629
- <span class="cline-any cline-yes">11x</span>
1630
- <span class="cline-any cline-no">&nbsp;</span>
1631
- <span class="cline-any cline-no">&nbsp;</span>
1632
- <span class="cline-any cline-no">&nbsp;</span>
1633
- <span class="cline-any cline-no">&nbsp;</span>
1634
- <span class="cline-any cline-yes">11x</span>
1635
- <span class="cline-any cline-yes">11x</span>
1636
- <span class="cline-any cline-yes">11x</span>
1637
- <span class="cline-any cline-yes">11x</span>
1638
- <span class="cline-any cline-neutral">&nbsp;</span>
1639
- <span class="cline-any cline-yes">21x</span>
1640
- <span class="cline-any cline-yes">11x</span>
1641
- <span class="cline-any cline-yes">11x</span>
1642
- <span class="cline-any cline-yes">10x</span>
1643
- <span class="cline-any cline-yes">10x</span>
1644
- <span class="cline-any cline-neutral">&nbsp;</span>
1645
- <span class="cline-any cline-neutral">&nbsp;</span>
1646
- <span class="cline-any cline-yes">10x</span>
1647
- <span class="cline-any cline-yes">27x</span>
1648
- <span class="cline-any cline-yes">10x</span>
1649
- <span class="cline-any cline-neutral">&nbsp;</span>
1650
- <span class="cline-any cline-yes">10x</span>
1651
- <span class="cline-any cline-yes">10x</span>
1652
- <span class="cline-any cline-yes">10x</span>
1653
- <span class="cline-any cline-yes">10x</span>
1654
- <span class="cline-any cline-yes">10x</span>
1655
- <span class="cline-any cline-yes">11x</span>
1656
- <span class="cline-any cline-yes">10x</span>
1657
- <span class="cline-any cline-yes">10x</span>
1658
- <span class="cline-any cline-yes">10x</span>
1659
- <span class="cline-any cline-yes">2x</span>
1660
- <span class="cline-any cline-yes">2x</span>
1661
- <span class="cline-any cline-yes">1x</span>
1662
- <span class="cline-any cline-yes">1x</span>
1663
- <span class="cline-any cline-yes">1x</span>
1664
- <span class="cline-any cline-yes">1x</span>
1665
- <span class="cline-any cline-yes">1x</span>
1666
- <span class="cline-any cline-yes">1x</span>
1667
- <span class="cline-any cline-yes">1x</span>
1668
- <span class="cline-any cline-yes">1x</span>
1669
- <span class="cline-any cline-yes">1x</span>
1670
- <span class="cline-any cline-yes">1x</span>
1671
- <span class="cline-any cline-yes">1x</span>
1672
- <span class="cline-any cline-yes">1x</span>
1673
- <span class="cline-any cline-yes">1x</span>
1674
- <span class="cline-any cline-yes">1x</span>
1675
- <span class="cline-any cline-yes">1x</span>
1676
- <span class="cline-any cline-yes">1x</span>
1677
- <span class="cline-any cline-yes">1x</span>
1678
- <span class="cline-any cline-yes">1x</span>
1679
- <span class="cline-any cline-yes">1x</span>
1680
- <span class="cline-any cline-yes">1x</span>
1681
- <span class="cline-any cline-no">&nbsp;</span>
1682
- <span class="cline-any cline-no">&nbsp;</span>
1683
- <span class="cline-any cline-no">&nbsp;</span>
1684
- <span class="cline-any cline-no">&nbsp;</span>
1685
- <span class="cline-any cline-no">&nbsp;</span>
1686
- <span class="cline-any cline-yes">1x</span>
1687
- <span class="cline-any cline-yes">2x</span>
1688
- <span class="cline-any cline-yes">10x</span>
1689
- <span class="cline-any cline-neutral">&nbsp;</span>
1690
- <span class="cline-any cline-neutral">&nbsp;</span>
1691
- <span class="cline-any cline-neutral">&nbsp;</span>
1692
- <span class="cline-any cline-yes">10x</span>
1693
- <span class="cline-any cline-yes">10x</span>
1694
- <span class="cline-any cline-yes">9x</span>
1695
- <span class="cline-any cline-yes">11x</span>
1696
- <span class="cline-any cline-no">&nbsp;</span>
1697
- <span class="cline-any cline-no">&nbsp;</span>
1698
- <span class="cline-any cline-no">&nbsp;</span>
1699
- <span class="cline-any cline-no">&nbsp;</span>
1700
- <span class="cline-any cline-no">&nbsp;</span>
1701
- <span class="cline-any cline-no">&nbsp;</span>
1702
- <span class="cline-any cline-neutral">&nbsp;</span>
1703
- <span class="cline-any cline-yes">9x</span>
1704
- <span class="cline-any cline-yes">9x</span>
1705
- <span class="cline-any cline-yes">9x</span>
1706
- <span class="cline-any cline-yes">11x</span>
1707
- <span class="cline-any cline-yes">8x</span>
1708
- <span class="cline-any cline-yes">8x</span>
1709
- <span class="cline-any cline-yes">8x</span>
1710
- <span class="cline-any cline-yes">2x</span>
1711
- <span class="cline-any cline-yes">2x</span>
1712
- <span class="cline-any cline-yes">2x</span>
1713
- <span class="cline-any cline-yes">2x</span>
1714
- <span class="cline-any cline-yes">8x</span>
1715
- <span class="cline-any cline-yes">6x</span>
1716
- <span class="cline-any cline-yes">6x</span>
1717
- <span class="cline-any cline-yes">8x</span>
1718
- <span class="cline-any cline-yes">7x</span>
1719
- <span class="cline-any cline-yes">7x</span>
1720
- <span class="cline-any cline-yes">7x</span>
1721
- <span class="cline-any cline-yes">7x</span>
1722
- <span class="cline-any cline-yes">7x</span>
1723
- <span class="cline-any cline-yes">10x</span>
1724
- <span class="cline-any cline-yes">10x</span>
1725
- <span class="cline-any cline-yes">10x</span>
1726
- <span class="cline-any cline-yes">10x</span>
1727
- <span class="cline-any cline-yes">7x</span>
1728
- <span class="cline-any cline-yes">7x</span>
1729
- <span class="cline-any cline-yes">7x</span>
1730
- <span class="cline-any cline-yes">8x</span>
1731
- <span class="cline-any cline-yes">8x</span>
1732
- <span class="cline-any cline-yes">8x</span>
1733
- <span class="cline-any cline-yes">8x</span>
1734
- <span class="cline-any cline-yes">8x</span>
1735
- <span class="cline-any cline-yes">8x</span>
1736
- <span class="cline-any cline-yes">8x</span>
1737
- <span class="cline-any cline-neutral">&nbsp;</span>
1738
- <span class="cline-any cline-neutral">&nbsp;</span>
1739
- <span class="cline-any cline-yes">11x</span>
1740
- <span class="cline-any cline-yes">9x</span>
1741
- <span class="cline-any cline-yes">9x</span>
1742
- <span class="cline-any cline-yes">9x</span>
1743
- <span class="cline-any cline-yes">9x</span>
1744
- <span class="cline-any cline-yes">9x</span>
1745
- <span class="cline-any cline-yes">9x</span>
1746
- <span class="cline-any cline-yes">9x</span>
1747
- <span class="cline-any cline-yes">9x</span>
1748
- <span class="cline-any cline-yes">9x</span>
1749
- <span class="cline-any cline-yes">9x</span>
1750
- <span class="cline-any cline-yes">9x</span>
1751
- <span class="cline-any cline-yes">9x</span>
1752
- <span class="cline-any cline-yes">11x</span>
1753
- <span class="cline-any cline-neutral">&nbsp;</span>
1754
- <span class="cline-any cline-neutral">&nbsp;</span>
1755
- <span class="cline-any cline-yes">21x</span>
1756
- <span class="cline-any cline-yes">3x</span>
1757
- <span class="cline-any cline-yes">2x</span>
1758
- <span class="cline-any cline-yes">2x</span>
1759
- <span class="cline-any cline-yes">2x</span>
1760
- <span class="cline-any cline-yes">2x</span>
1761
- <span class="cline-any cline-yes">2x</span>
1762
- <span class="cline-any cline-yes">2x</span>
1763
- <span class="cline-any cline-yes">2x</span>
1764
- <span class="cline-any cline-yes">3x</span>
1765
- <span class="cline-any cline-neutral">&nbsp;</span>
1766
- <span class="cline-any cline-neutral">&nbsp;</span>
1767
- <span class="cline-any cline-neutral">&nbsp;</span>
1768
- <span class="cline-any cline-neutral">&nbsp;</span>
1769
- <span class="cline-any cline-neutral">&nbsp;</span>
1770
- <span class="cline-any cline-neutral">&nbsp;</span>
1771
- <span class="cline-any cline-yes">21x</span>
1772
- <span class="cline-any cline-yes">78x</span>
1773
- <span class="cline-any cline-yes">72x</span>
1774
- <span class="cline-any cline-yes">72x</span>
1775
- <span class="cline-any cline-yes">72x</span>
1776
- <span class="cline-any cline-yes">78x</span>
1777
- <span class="cline-any cline-neutral">&nbsp;</span>
1778
- <span class="cline-any cline-yes">21x</span>
1779
- <span class="cline-any cline-yes">72x</span>
1780
- <span class="cline-any cline-yes">7x</span>
1781
- <span class="cline-any cline-yes">3x</span>
1782
- <span class="cline-any cline-yes">1x</span>
1783
- <span class="cline-any cline-yes">7x</span>
1784
- <span class="cline-any cline-neutral">&nbsp;</span>
1785
- <span class="cline-any cline-yes">72x</span>
1786
- <span class="cline-any cline-neutral">&nbsp;</span>
1787
- <span class="cline-any cline-neutral">&nbsp;</span>
1788
- <span class="cline-any cline-no">&nbsp;</span>
1789
- <span class="cline-any cline-no">&nbsp;</span>
1790
- <span class="cline-any cline-no">&nbsp;</span>
1791
- <span class="cline-any cline-no">&nbsp;</span>
1792
- <span class="cline-any cline-no">&nbsp;</span>
1793
- <span class="cline-any cline-no">&nbsp;</span>
1794
- <span class="cline-any cline-no">&nbsp;</span>
1795
- <span class="cline-any cline-no">&nbsp;</span>
1796
- <span class="cline-any cline-yes">72x</span>
1797
- <span class="cline-any cline-neutral">&nbsp;</span>
1798
- <span class="cline-any cline-neutral">&nbsp;</span>
1799
- <span class="cline-any cline-yes">21x</span>
1800
- <span class="cline-any cline-yes">4x</span>
1801
- <span class="cline-any cline-yes">2x</span>
1802
- <span class="cline-any cline-yes">2x</span>
1803
- <span class="cline-any cline-yes">2x</span>
1804
- <span class="cline-any cline-yes">4x</span>
1805
- <span class="cline-any cline-no">&nbsp;</span>
1806
- <span class="cline-any cline-no">&nbsp;</span>
1807
- <span class="cline-any cline-no">&nbsp;</span>
1808
- <span class="cline-any cline-yes">4x</span>
1809
- <span class="cline-any cline-yes">4x</span>
1810
- <span class="cline-any cline-yes">4x</span>
1811
- <span class="cline-any cline-yes">4x</span>
1812
- <span class="cline-any cline-neutral">&nbsp;</span>
1813
- <span class="cline-any cline-neutral">&nbsp;</span>
1814
- <span class="cline-any cline-neutral">&nbsp;</span>
1815
- <span class="cline-any cline-neutral">&nbsp;</span>
1816
- <span class="cline-any cline-neutral">&nbsp;</span>
1817
- <span class="cline-any cline-neutral">&nbsp;</span>
1818
- <span class="cline-any cline-neutral">&nbsp;</span>
1819
- <span class="cline-any cline-yes">21x</span>
1820
- <span class="cline-any cline-yes">4x</span>
1821
- <span class="cline-any cline-yes">4x</span>
1822
- <span class="cline-any cline-yes">4x</span>
1823
- <span class="cline-any cline-yes">4x</span>
1824
- <span class="cline-any cline-yes">4x</span>
1825
- <span class="cline-any cline-yes">4x</span>
1826
- <span class="cline-any cline-yes">4x</span>
1827
- <span class="cline-any cline-neutral">&nbsp;</span>
1828
- <span class="cline-any cline-yes">21x</span>
1829
- <span class="cline-any cline-yes">4x</span>
1830
- <span class="cline-any cline-yes">4x</span>
1831
- <span class="cline-any cline-yes">4x</span>
1832
- <span class="cline-any cline-no">&nbsp;</span>
1833
- <span class="cline-any cline-no">&nbsp;</span>
1834
- <span class="cline-any cline-yes">3x</span>
1835
- <span class="cline-any cline-yes">3x</span>
1836
- <span class="cline-any cline-yes">3x</span>
1837
- <span class="cline-any cline-yes">3x</span>
1838
- <span class="cline-any cline-yes">3x</span>
1839
- <span class="cline-any cline-yes">3x</span>
1840
- <span class="cline-any cline-yes">3x</span>
1841
- <span class="cline-any cline-yes">3x</span>
1842
- <span class="cline-any cline-yes">3x</span>
1843
- <span class="cline-any cline-yes">3x</span>
1844
- <span class="cline-any cline-no">&nbsp;</span>
1845
- <span class="cline-any cline-no">&nbsp;</span>
1846
- <span class="cline-any cline-yes">4x</span>
1847
- <span class="cline-any cline-no">&nbsp;</span>
1848
- <span class="cline-any cline-no">&nbsp;</span>
1849
- <span class="cline-any cline-no">&nbsp;</span>
1850
- <span class="cline-any cline-yes">3x</span>
1851
- <span class="cline-any cline-yes">3x</span>
1852
- <span class="cline-any cline-yes">3x</span>
1853
- <span class="cline-any cline-yes">3x</span>
1854
- <span class="cline-any cline-yes">3x</span>
1855
- <span class="cline-any cline-yes">4x</span>
1856
- <span class="cline-any cline-yes">4x</span>
1857
- <span class="cline-any cline-neutral">&nbsp;</span>
1858
- <span class="cline-any cline-neutral">&nbsp;</span>
1859
- <span class="cline-any cline-neutral">&nbsp;</span>
1860
- <span class="cline-any cline-yes">4x</span>
1861
- <span class="cline-any cline-yes">2x</span>
1862
- <span class="cline-any cline-yes">2x</span>
1863
- <span class="cline-any cline-yes">2x</span>
1864
- <span class="cline-any cline-yes">2x</span>
1865
- <span class="cline-any cline-yes">2x</span>
1866
- <span class="cline-any cline-yes">2x</span>
1867
- <span class="cline-any cline-yes">2x</span>
1868
- <span class="cline-any cline-yes">2x</span>
1869
- <span class="cline-any cline-yes">2x</span>
1870
- <span class="cline-any cline-yes">2x</span>
1871
- <span class="cline-any cline-yes">2x</span>
1872
- <span class="cline-any cline-yes">2x</span>
1873
- <span class="cline-any cline-yes">4x</span>
1874
- <span class="cline-any cline-no">&nbsp;</span>
1875
- <span class="cline-any cline-no">&nbsp;</span>
1876
- <span class="cline-any cline-no">&nbsp;</span>
1877
- <span class="cline-any cline-no">&nbsp;</span>
1878
- <span class="cline-any cline-no">&nbsp;</span>
1879
- <span class="cline-any cline-yes">4x</span>
1880
- <span class="cline-any cline-neutral">&nbsp;</span>
1881
- <span class="cline-any cline-neutral">&nbsp;</span>
1882
- <span class="cline-any cline-neutral">&nbsp;</span>
1883
- <span class="cline-any cline-neutral">&nbsp;</span>
1884
- <span class="cline-any cline-neutral">&nbsp;</span>
1885
- <span class="cline-any cline-neutral">&nbsp;</span>
1886
- <span class="cline-any cline-neutral">&nbsp;</span>
1887
- <span class="cline-any cline-yes">21x</span>
1888
- <span class="cline-any cline-yes">1x</span>
1889
- <span class="cline-any cline-yes">1x</span>
1890
- <span class="cline-any cline-yes">1x</span>
1891
- <span class="cline-any cline-yes">1x</span>
1892
- <span class="cline-any cline-yes">1x</span>
1893
- <span class="cline-any cline-yes">1x</span>
1894
- <span class="cline-any cline-no">&nbsp;</span>
1895
- <span class="cline-any cline-no">&nbsp;</span>
1896
- <span class="cline-any cline-no">&nbsp;</span>
1897
- <span class="cline-any cline-no">&nbsp;</span>
1898
- <span class="cline-any cline-yes">1x</span>
1899
- <span class="cline-any cline-yes">1x</span>
1900
- <span class="cline-any cline-neutral">&nbsp;</span>
1901
- <span class="cline-any cline-yes">21x</span>
1902
- <span class="cline-any cline-yes">1x</span>
1903
- <span class="cline-any cline-yes">1x</span>
1904
- <span class="cline-any cline-no">&nbsp;</span>
1905
- <span class="cline-any cline-no">&nbsp;</span>
1906
- <span class="cline-any cline-no">&nbsp;</span>
1907
- <span class="cline-any cline-yes">1x</span>
1908
- <span class="cline-any cline-yes">1x</span>
1909
- <span class="cline-any cline-yes">1x</span>
1910
- <span class="cline-any cline-yes">1x</span>
1911
- <span class="cline-any cline-yes">1x</span>
1912
- <span class="cline-any cline-yes">1x</span>
1913
- <span class="cline-any cline-yes">1x</span>
1914
- <span class="cline-any cline-yes">1x</span>
1915
- <span class="cline-any cline-yes">1x</span>
1916
- <span class="cline-any cline-yes">1x</span>
1917
- <span class="cline-any cline-yes">1x</span>
1918
- <span class="cline-any cline-yes">1x</span>
1919
- <span class="cline-any cline-yes">1x</span>
1920
- <span class="cline-any cline-yes">1x</span>
1921
- <span class="cline-any cline-yes">1x</span>
1922
- <span class="cline-any cline-yes">2x</span>
1923
- <span class="cline-any cline-yes">2x</span>
1924
- <span class="cline-any cline-yes">2x</span>
1925
- <span class="cline-any cline-yes">2x</span>
1926
- <span class="cline-any cline-yes">1x</span>
1927
- <span class="cline-any cline-yes">1x</span>
1928
- <span class="cline-any cline-yes">1x</span>
1929
- <span class="cline-any cline-yes">1x</span>
1930
- <span class="cline-any cline-yes">1x</span>
1931
- <span class="cline-any cline-yes">1x</span>
1932
- <span class="cline-any cline-yes">1x</span>
1933
- <span class="cline-any cline-yes">1x</span>
1934
- <span class="cline-any cline-yes">1x</span>
1935
- <span class="cline-any cline-neutral">&nbsp;</span>
1936
- <span class="cline-any cline-neutral">&nbsp;</span>
1937
- <span class="cline-any cline-neutral">&nbsp;</span>
1938
- <span class="cline-any cline-neutral">&nbsp;</span>
1939
- <span class="cline-any cline-neutral">&nbsp;</span>
1940
- <span class="cline-any cline-neutral">&nbsp;</span>
1941
- <span class="cline-any cline-yes">21x</span>
1942
- <span class="cline-any cline-no">&nbsp;</span>
1943
- <span class="cline-any cline-no">&nbsp;</span>
1944
- <span class="cline-any cline-no">&nbsp;</span>
1945
- <span class="cline-any cline-no">&nbsp;</span>
1946
- <span class="cline-any cline-no">&nbsp;</span>
1947
- <span class="cline-any cline-no">&nbsp;</span>
1948
- <span class="cline-any cline-no">&nbsp;</span>
1949
- <span class="cline-any cline-no">&nbsp;</span>
1950
- <span class="cline-any cline-no">&nbsp;</span>
1951
- <span class="cline-any cline-no">&nbsp;</span>
1952
- <span class="cline-any cline-no">&nbsp;</span>
1953
- <span class="cline-any cline-no">&nbsp;</span>
1954
- <span class="cline-any cline-no">&nbsp;</span>
1955
- <span class="cline-any cline-no">&nbsp;</span>
1956
- <span class="cline-any cline-no">&nbsp;</span>
1957
- <span class="cline-any cline-no">&nbsp;</span>
1958
- <span class="cline-any cline-no">&nbsp;</span>
1959
- <span class="cline-any cline-neutral">&nbsp;</span>
1960
- <span class="cline-any cline-neutral">&nbsp;</span>
1961
- <span class="cline-any cline-neutral">&nbsp;</span>
1962
- <span class="cline-any cline-neutral">&nbsp;</span>
1963
- <span class="cline-any cline-neutral">&nbsp;</span>
1964
- <span class="cline-any cline-neutral">&nbsp;</span>
1965
- <span class="cline-any cline-neutral">&nbsp;</span>
1966
- <span class="cline-any cline-neutral">&nbsp;</span>
1967
- <span class="cline-any cline-neutral">&nbsp;</span>
1968
- <span class="cline-any cline-neutral">&nbsp;</span>
1969
- <span class="cline-any cline-neutral">&nbsp;</span>
1970
- <span class="cline-any cline-yes">21x</span>
1971
- <span class="cline-any cline-no">&nbsp;</span>
1972
- <span class="cline-any cline-no">&nbsp;</span>
1973
- <span class="cline-any cline-no">&nbsp;</span>
1974
- <span class="cline-any cline-no">&nbsp;</span>
1975
- <span class="cline-any cline-no">&nbsp;</span>
1976
- <span class="cline-any cline-no">&nbsp;</span>
1977
- <span class="cline-any cline-no">&nbsp;</span>
1978
- <span class="cline-any cline-no">&nbsp;</span>
1979
- <span class="cline-any cline-no">&nbsp;</span>
1980
- <span class="cline-any cline-no">&nbsp;</span>
1981
- <span class="cline-any cline-neutral">&nbsp;</span>
1982
- <span class="cline-any cline-neutral">&nbsp;</span>
1983
- <span class="cline-any cline-neutral">&nbsp;</span>
1984
- <span class="cline-any cline-neutral">&nbsp;</span>
1985
- <span class="cline-any cline-neutral">&nbsp;</span>
1986
- <span class="cline-any cline-neutral">&nbsp;</span>
1987
- <span class="cline-any cline-yes">21x</span>
1988
- <span class="cline-any cline-yes">74x</span>
1989
- <span class="cline-any cline-yes">74x</span>
1990
- <span class="cline-any cline-yes">74x</span>
1991
- <span class="cline-any cline-yes">74x</span>
1992
- <span class="cline-any cline-yes">74x</span>
1993
- <span class="cline-any cline-yes">74x</span>
1994
- <span class="cline-any cline-yes">74x</span>
1995
- <span class="cline-any cline-yes">74x</span>
1996
- <span class="cline-any cline-yes">74x</span>
1997
- <span class="cline-any cline-yes">74x</span>
1998
- <span class="cline-any cline-yes">74x</span>
1999
- <span class="cline-any cline-yes">74x</span>
2000
- <span class="cline-any cline-yes">74x</span>
2001
- <span class="cline-any cline-yes">74x</span>
2002
- <span class="cline-any cline-neutral">&nbsp;</span>
2003
- <span class="cline-any cline-yes">74x</span>
2004
- <span class="cline-any cline-no">&nbsp;</span>
2005
- <span class="cline-any cline-no">&nbsp;</span>
2006
- <span class="cline-any cline-no">&nbsp;</span>
2007
- <span class="cline-any cline-no">&nbsp;</span>
2008
- <span class="cline-any cline-no">&nbsp;</span>
2009
- <span class="cline-any cline-no">&nbsp;</span>
2010
- <span class="cline-any cline-neutral">&nbsp;</span>
2011
- <span class="cline-any cline-yes">74x</span>
2012
- <span class="cline-any cline-yes">74x</span>
2013
- <span class="cline-any cline-neutral">&nbsp;</span>
2014
- <span class="cline-any cline-yes">74x</span>
2015
- <span class="cline-any cline-yes">74x</span>
2016
- <span class="cline-any cline-yes">74x</span>
2017
- <span class="cline-any cline-yes">74x</span>
2018
- <span class="cline-any cline-yes">74x</span>
2019
- <span class="cline-any cline-yes">74x</span>
2020
- <span class="cline-any cline-yes">74x</span>
2021
- <span class="cline-any cline-yes">74x</span>
2022
- <span class="cline-any cline-yes">74x</span>
2023
- <span class="cline-any cline-yes">74x</span>
2024
- <span class="cline-any cline-yes">74x</span>
2025
- <span class="cline-any cline-yes">74x</span>
2026
- <span class="cline-any cline-yes">74x</span>
2027
- <span class="cline-any cline-yes">74x</span>
2028
- <span class="cline-any cline-neutral">&nbsp;</span>
2029
- <span class="cline-any cline-yes">74x</span>
2030
- <span class="cline-any cline-yes">10x</span>
2031
- <span class="cline-any cline-yes">11x</span>
2032
- <span class="cline-any cline-yes">11x</span>
2033
- <span class="cline-any cline-neutral">&nbsp;</span>
2034
- <span class="cline-any cline-yes">11x</span>
2035
- <span class="cline-any cline-yes">11x</span>
2036
- <span class="cline-any cline-yes">11x</span>
2037
- <span class="cline-any cline-yes">11x</span>
2038
- <span class="cline-any cline-yes">11x</span>
2039
- <span class="cline-any cline-yes">10x</span>
2040
- <span class="cline-any cline-neutral">&nbsp;</span>
2041
- <span class="cline-any cline-yes">10x</span>
2042
- <span class="cline-any cline-yes">10x</span>
2043
- <span class="cline-any cline-neutral">&nbsp;</span>
2044
- <span class="cline-any cline-neutral">&nbsp;</span>
2045
- <span class="cline-any cline-yes">74x</span>
2046
- <span class="cline-any cline-yes">66x</span>
2047
- <span class="cline-any cline-yes">66x</span>
2048
- <span class="cline-any cline-yes">74x</span>
2049
- <span class="cline-any cline-yes">74x</span>
2050
- <span class="cline-any cline-no">&nbsp;</span>
2051
- <span class="cline-any cline-no">&nbsp;</span>
2052
- <span class="cline-any cline-no">&nbsp;</span>
2053
- <span class="cline-any cline-no">&nbsp;</span>
2054
- <span class="cline-any cline-no">&nbsp;</span>
2055
- <span class="cline-any cline-no">&nbsp;</span>
2056
- <span class="cline-any cline-yes">74x</span>
2057
- <span class="cline-any cline-neutral">&nbsp;</span>
2058
- <span class="cline-any cline-neutral">&nbsp;</span>
2059
- <span class="cline-any cline-neutral">&nbsp;</span>
2060
- <span class="cline-any cline-neutral">&nbsp;</span>
2061
- <span class="cline-any cline-neutral">&nbsp;</span>
2062
- <span class="cline-any cline-yes">21x</span>
2063
- <span class="cline-any cline-yes">4x</span>
2064
- <span class="cline-any cline-no">&nbsp;</span>
2065
- <span class="cline-any cline-no">&nbsp;</span>
2066
- <span class="cline-any cline-no">&nbsp;</span>
2067
- <span class="cline-any cline-no">&nbsp;</span>
2068
- <span class="cline-any cline-no">&nbsp;</span>
2069
- <span class="cline-any cline-no">&nbsp;</span>
2070
- <span class="cline-any cline-neutral">&nbsp;</span>
2071
- <span class="cline-any cline-yes">4x</span>
2072
- <span class="cline-any cline-yes">4x</span>
2073
- <span class="cline-any cline-yes">4x</span>
2074
- <span class="cline-any cline-yes">4x</span>
2075
- <span class="cline-any cline-yes">4x</span>
2076
- <span class="cline-any cline-yes">4x</span>
2077
- <span class="cline-any cline-yes">4x</span>
2078
- <span class="cline-any cline-yes">4x</span>
2079
- <span class="cline-any cline-yes">4x</span>
2080
- <span class="cline-any cline-neutral">&nbsp;</span>
2081
- <span class="cline-any cline-yes">4x</span>
2082
- <span class="cline-any cline-yes">4x</span>
2083
- <span class="cline-any cline-neutral">&nbsp;</span>
2084
- <span class="cline-any cline-neutral">&nbsp;</span>
2085
- <span class="cline-any cline-neutral">&nbsp;</span>
2086
- <span class="cline-any cline-neutral">&nbsp;</span>
2087
- <span class="cline-any cline-neutral">&nbsp;</span>
2088
- <span class="cline-any cline-neutral">&nbsp;</span>
2089
- <span class="cline-any cline-neutral">&nbsp;</span>
2090
- <span class="cline-any cline-neutral">&nbsp;</span>
2091
- <span class="cline-any cline-yes">4x</span>
2092
- <span class="cline-any cline-yes">4x</span>
2093
- <span class="cline-any cline-yes">4x</span>
2094
- <span class="cline-any cline-yes">4x</span>
2095
- <span class="cline-any cline-yes">4x</span>
2096
- <span class="cline-any cline-neutral">&nbsp;</span>
2097
- <span class="cline-any cline-yes">4x</span>
2098
- <span class="cline-any cline-yes">4x</span>
2099
- <span class="cline-any cline-yes">4x</span>
2100
- <span class="cline-any cline-yes">4x</span>
2101
- <span class="cline-any cline-yes">4x</span>
2102
- <span class="cline-any cline-yes">4x</span>
2103
- <span class="cline-any cline-yes">4x</span>
2104
- <span class="cline-any cline-yes">4x</span>
2105
- <span class="cline-any cline-neutral">&nbsp;</span>
2106
- <span class="cline-any cline-yes">4x</span>
2107
- <span class="cline-any cline-yes">4x</span>
2108
- <span class="cline-any cline-yes">4x</span>
2109
- <span class="cline-any cline-yes">4x</span>
2110
- <span class="cline-any cline-neutral">&nbsp;</span>
2111
- <span class="cline-any cline-yes">4x</span>
2112
- <span class="cline-any cline-no">&nbsp;</span>
2113
- <span class="cline-any cline-no">&nbsp;</span>
2114
- <span class="cline-any cline-yes">4x</span>
2115
- <span class="cline-any cline-yes">4x</span>
2116
- <span class="cline-any cline-yes">4x</span>
2117
- <span class="cline-any cline-yes">4x</span>
2118
- <span class="cline-any cline-yes">4x</span>
2119
- <span class="cline-any cline-yes">4x</span>
2120
- <span class="cline-any cline-yes">4x</span>
2121
- <span class="cline-any cline-yes">4x</span>
2122
- <span class="cline-any cline-yes">4x</span>
2123
- <span class="cline-any cline-yes">4x</span>
2124
- <span class="cline-any cline-yes">1x</span>
2125
- <span class="cline-any cline-yes">1x</span>
2126
- <span class="cline-any cline-yes">4x</span>
2127
- <span class="cline-any cline-yes">4x</span>
2128
- <span class="cline-any cline-yes">4x</span>
2129
- <span class="cline-any cline-yes">4x</span>
2130
- <span class="cline-any cline-yes">4x</span>
2131
- <span class="cline-any cline-yes">4x</span>
2132
- <span class="cline-any cline-yes">4x</span>
2133
- <span class="cline-any cline-yes">4x</span>
2134
- <span class="cline-any cline-yes">4x</span>
2135
- <span class="cline-any cline-yes">4x</span>
2136
- <span class="cline-any cline-yes">4x</span>
2137
- <span class="cline-any cline-no">&nbsp;</span>
2138
- <span class="cline-any cline-no">&nbsp;</span>
2139
- <span class="cline-any cline-no">&nbsp;</span>
2140
- <span class="cline-any cline-no">&nbsp;</span>
2141
- <span class="cline-any cline-no">&nbsp;</span>
2142
- <span class="cline-any cline-no">&nbsp;</span>
2143
- <span class="cline-any cline-yes">4x</span>
2144
- <span class="cline-any cline-neutral">&nbsp;</span>
2145
- <span class="cline-any cline-neutral">&nbsp;</span>
2146
- <span class="cline-any cline-neutral">&nbsp;</span>
2147
- <span class="cline-any cline-neutral">&nbsp;</span>
2148
- <span class="cline-any cline-yes">21x</span>
2149
- <span class="cline-any cline-yes">2x</span>
2150
- <span class="cline-any cline-yes">2x</span>
2151
- <span class="cline-any cline-yes">2x</span>
2152
- <span class="cline-any cline-yes">2x</span>
2153
- <span class="cline-any cline-no">&nbsp;</span>
2154
- <span class="cline-any cline-no">&nbsp;</span>
2155
- <span class="cline-any cline-no">&nbsp;</span>
2156
- <span class="cline-any cline-no">&nbsp;</span>
2157
- <span class="cline-any cline-no">&nbsp;</span>
2158
- <span class="cline-any cline-yes">2x</span>
2159
- <span class="cline-any cline-neutral">&nbsp;</span>
2160
- <span class="cline-any cline-yes">21x</span>
2161
- <span class="cline-any cline-yes">219x</span>
2162
- <span class="cline-any cline-neutral">&nbsp;</span>
2163
- <span class="cline-any cline-yes">219x</span>
2164
- <span class="cline-any cline-neutral">&nbsp;</span>
2165
- <span class="cline-any cline-neutral">&nbsp;</span>
2166
- <span class="cline-any cline-neutral">&nbsp;</span>
2167
- <span class="cline-any cline-neutral">&nbsp;</span>
2168
- <span class="cline-any cline-neutral">&nbsp;</span>
2169
- <span class="cline-any cline-neutral">&nbsp;</span>
2170
- <span class="cline-any cline-neutral">&nbsp;</span>
2171
- <span class="cline-any cline-yes">93x</span>
2172
- <span class="cline-any cline-yes">93x</span>
2173
- <span class="cline-any cline-yes">93x</span>
2174
- <span class="cline-any cline-yes">93x</span>
2175
- <span class="cline-any cline-yes">93x</span>
2176
- <span class="cline-any cline-no">&nbsp;</span>
2177
- <span class="cline-any cline-no">&nbsp;</span>
2178
- <span class="cline-any cline-neutral">&nbsp;</span>
2179
- <span class="cline-any cline-neutral">&nbsp;</span>
2180
- <span class="cline-any cline-neutral">&nbsp;</span>
2181
- <span class="cline-any cline-neutral">&nbsp;</span>
2182
- <span class="cline-any cline-yes">93x</span>
2183
- <span class="cline-any cline-yes">93x</span>
2184
- <span class="cline-any cline-yes">93x</span>
2185
- <span class="cline-any cline-yes">93x</span>
2186
- <span class="cline-any cline-neutral">&nbsp;</span>
2187
- <span class="cline-any cline-yes">93x</span>
2188
- <span class="cline-any cline-no">&nbsp;</span>
2189
- <span class="cline-any cline-no">&nbsp;</span>
2190
- <span class="cline-any cline-no">&nbsp;</span>
2191
- <span class="cline-any cline-no">&nbsp;</span>
2192
- <span class="cline-any cline-no">&nbsp;</span>
2193
- <span class="cline-any cline-no">&nbsp;</span>
2194
- <span class="cline-any cline-no">&nbsp;</span>
2195
- <span class="cline-any cline-neutral">&nbsp;</span>
2196
- <span class="cline-any cline-neutral">&nbsp;</span>
2197
- <span class="cline-any cline-yes">93x</span>
2198
- <span class="cline-any cline-no">&nbsp;</span>
2199
- <span class="cline-any cline-no">&nbsp;</span>
2200
- <span class="cline-any cline-neutral">&nbsp;</span>
2201
- <span class="cline-any cline-neutral">&nbsp;</span>
2202
- <span class="cline-any cline-yes">93x</span>
2203
- <span class="cline-any cline-no">&nbsp;</span>
2204
- <span class="cline-any cline-no">&nbsp;</span>
2205
- <span class="cline-any cline-neutral">&nbsp;</span>
2206
- <span class="cline-any cline-neutral">&nbsp;</span>
2207
- <span class="cline-any cline-yes">93x</span>
2208
- <span class="cline-any cline-yes">93x</span>
2209
- <span class="cline-any cline-yes">93x</span>
2210
- <span class="cline-any cline-yes">126x</span>
2211
- <span class="cline-any cline-yes">126x</span>
2212
- <span class="cline-any cline-yes">93x</span>
2213
- <span class="cline-any cline-yes">93x</span>
2214
- <span class="cline-any cline-yes">93x</span>
2215
- <span class="cline-any cline-yes">126x</span>
2216
- <span class="cline-any cline-yes">219x</span>
2217
- <span class="cline-any cline-yes">21x</span>
2218
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">// oxlint-disable-next-line no-named-as-default -- WASM module default export convention
2219
- import init, { Sp00kyProcessor } from '@spooky-sync/ssp-wasm';
2220
- import type { EventDefinition, EventSystem } from '../../events/index';
2221
- import type { Logger } from 'pino';
2222
- import type { LocalStore } from '../database/index';
2223
- import type { WasmProcessor, WasmStreamUpdate } from './wasm-types';
2224
- import type { Duration } from 'surrealdb';
2225
- import type { QueryTimeToLive, RecordVersionArray } from '../../types';
2226
- import { encodeRecordId } from '../../utils/index';
2227
- &nbsp;
2228
- // Simple interface for query plan registration (replaces Incantation class)
2229
- interface QueryPlanConfig {
2230
- queryHash: string;
2231
- surql: string;
2232
- params: Record&lt;string, any&gt;;
2233
- ttl: QueryTimeToLive | Duration;
2234
- lastActiveAt: Date;
2235
- localArray: RecordVersionArray;
2236
- remoteArray: RecordVersionArray;
2237
- meta: {
2238
- tableName: string;
2239
- involvedTables?: string[];
2240
- };
2241
- }
2242
- &nbsp;
2243
- // Define the shape of an update from the Wasm module
2244
- // Matches MaterializedViewUpdate struct
2245
- export interface StreamUpdate {
2246
- queryHash: string;
2247
- localArray: RecordVersionArray;
2248
- op?: 'CREATE' | 'UPDATE' | 'DELETE'; // Operation type for conditional debouncing
2249
- /**
2250
- * Client-internal: not from the circuit. A membership-only change that
2251
- * needed no fetch is re-materialized through this same path so it cannot
2252
- * race a real update (DataModule.scheduleRematerialize). Carries the last
2253
- * known `localArray`; consumers that describe an INGEST (persist, metrics,
2254
- * devtools events) skip it.
2255
- */
2256
- synthetic?: boolean;
2257
- /**
2258
- * End-to-end ingest latency for the WASM call that produced this update,
2259
- * in milliseconds. Populated by StreamProcessorService.ingest. Undefined
2260
- * for the initial register_view snapshot.
2261
- */
2262
- materializationTimeMs?: number;
2263
- /** SSP internal sub-phase timings (ms) for this ingest, from the WASM binding. */
2264
- storeApplyMs?: number;
2265
- circuitStepMs?: number;
2266
- transformMs?: number;
2267
- /**
2268
- * One-shot registration timings (ms). Only set on the StreamUpdate returned
2269
- * by `registerQueryPlan` (the register_view snapshot), not on ingest updates.
2270
- */
2271
- registration?: { parseMs: number; planMs: number; snapshotMs: number };
2272
- }
2273
- &nbsp;
2274
- // Define events map (kept for DevTools compatibility)
2275
- export type StreamProcessorEvents = {
2276
- stream_update: EventDefinition&lt;'stream_update', StreamUpdate[]&gt;;
2277
- };
2278
- /**
2279
- * Interface for receiving stream updates directly.
2280
- * Implemented by DataManager and DevToolsService for direct coupling.
2281
- */
2282
- export interface StreamUpdateReceiver {
2283
- onStreamUpdate(update: StreamUpdate): void;
2284
- }
2285
- &nbsp;
2286
- /** One row change in the shape `ingestMany` consumes. */
2287
- export interface IngestRecord {
2288
- table: string;
2289
- /** `MERGE` overlays the given fields on the stored row (projection widening). */
2290
- op: 'CREATE' | 'UPDATE' | 'DELETE' | 'MERGE';
2291
- id: string;
2292
- record: any;
2293
- }
2294
- &nbsp;
2295
- /**
2296
- * What the boot-time prime needs from the client: which tables to walk, how
2297
- * to recognise a snapshot written under a different schema, and which rows'
2298
- * local `_00_rv` must not be reported as the server's.
2299
- */
2300
- export interface CircuitPrimeContext {
2301
- tables: string[];
2302
- schemaHash: string;
2303
- /** Encoded ids with an unsettled local mutation (their `_00_rv` was bumped
2304
- * locally and may exceed the server's next version). */
2305
- pendingIds: Set&lt;string&gt;;
2306
- /** Receives every `(id, rv)` the prime put into the circuit, per table, so
2307
- * the sync layer can skip re-downloading bodies it already has. */
2308
- onVersions?: (table: string, entries: [string, number][]) =&gt; void;
2309
- }
2310
- &nbsp;
2311
- /** Storage key of the circuit snapshot inside the local store. */
2312
- export const CIRCUIT_SNAPSHOT_KEY = 'circuit';
2313
- /** Bump when the bytes `load_store_state` reads change shape. */
2314
- export const CIRCUIT_SNAPSHOT_FORMAT = 1;
2315
- /** Rows per `ingest_many` call. Bounds the transient the wasm side allocates
2316
- * to parse a batch (measured: one 7700-row call of 20 KB bodies peaked at
2317
- * 500 MB, 128-row chunks at 335 MB, and under projection at 24 MB). */
2318
- const INGEST_CHUNK = 128;
2319
- /** Ids per `selectByIds` when priming bodies out of the local store. */
2320
- const PRIME_CHUNK = 256;
2321
- /** Rows the SurrealDB (main-thread, IndexedDB) engine is allowed to prime
2322
- * through; above this the circuit boots empty as it always did. */
2323
- const SURREAL_PRIME_ROW_CAP = 20_000;
2324
- /** Below this many changed rows the checkpoint timer stays quiet. */
2325
- const CHECKPOINT_MIN_ROWS = 50;
2326
- &nbsp;
2327
- /** Stable `table:id` for a row id that may already be a string. */
2328
- function idString(id: unknown): string {
2329
- return typeof id === 'string' ? <span class="branch-0 cbranch-no" title="branch not covered" >id : encodeRecordId(id as any);</span>
2330
- }
2331
- &nbsp;
2332
- function chunks&lt;T&gt;(items: T[], size: number): T[][] {
2333
- const out: T[][] = [];
2334
- for (let i = 0; i &lt; items.length; i += size) out.push(items.slice(i, i + size));
2335
- return out;
2336
- }
2337
- &nbsp;
2338
- export class StreamProcessorService {
2339
- private logger: Logger;
2340
- private processor: WasmProcessor | undefined;
2341
- private isInitialized = false;
2342
- private receivers: StreamUpdateReceiver[] = [];
2343
- // When true, `notifyUpdates` coalesces updates into `batchBuffer` (keyed by
2344
- // queryHash) instead of dispatching them. Used to collapse the per-record
2345
- // stream updates produced by a batched ingest into a single notification per
2346
- // query, so the UI updates once after the whole batch rather than row-by-row.
2347
- private batching = false;
2348
- private batchBuffer: Map&lt;string, StreamUpdate&gt; = new Map();
2349
- // Current session's auth identity, injected into every `register_view`'s
2350
- // params so the in-browser SSP can resolve `$auth`/`$access` in table
2351
- // permission predicates (mirrors the server's `fn::query::register`). Empty
2352
- // strings when logged out — a non-null `auth` keeps `permission_inject` from
2353
- // rejecting `$auth`-gated tables; the predicate just degrades to its public
2354
- // branch. Set via `setSessionAuth` on every auth state change.
2355
- private sessionAuth: { authId: string; access: string } = { authId: '', access: '' };
2356
- // Bumped by `reset()`. Anything captured before a reset (a checkpoint's
2357
- // bytes, a prime's chunk, a widening read) must not land on the NEW
2358
- // processor, which belongs to a different bucket.
2359
- private stateGeneration = 0;
2360
- // Shared-tabs: follower circuits are in-memory ONLY. Only the tab that owns
2361
- // the store writes its snapshot; a promoted follower flips this back on.
2362
- private persistState = true;
2363
- // Snapshot persistence. Store-only bytes, written by the checkpoint timer
2364
- // and on the page going hidden, never per ingest: `save_store_state` walks
2365
- // every row. The snapshot is what lets a reload restore the circuit and
2366
- // step in only what changed since (`reconcile`), instead of re-downloading
2367
- // and re-ingesting the whole working set.
2368
- private persistCircuit = false;
2369
- private checkpointMs = 30_000;
2370
- private checkpointTimer: ReturnType&lt;typeof setInterval&gt; | null = null;
2371
- private snapshotDirty = false;
2372
- private dirtyRows = 0;
2373
- private hideHandler: (() =&gt; void) | null = null;
2374
- private checkpointInFlight: Promise&lt;void&gt; | null = null;
2375
- // Keep only the fields registered plans evaluate per stored row. The client
2376
- // renders bodies from the local store, so a 20 KB game row in the circuit
2377
- // is ~150 B of predicate/sort fields under projection.
2378
- private projection = true;
2379
- // Prime state: `primed` resolves when the boot-time prime (snapshot restore
2380
- // + reconcile, or a full read of the local store) has finished, aborted or
2381
- // been skipped. Sync waits on it before its first diff.
2382
- private primed: Promise&lt;void&gt; = Promise.resolve();
2383
- private schemaHash: string | null = null;
2384
- // Projection widening, serialised: fields a new view evaluates that stored
2385
- // rows lack are merged in table by table.
2386
- private widenQueue: Promise&lt;void&gt; = Promise.resolve();
2387
- private widenPending: Map&lt;string, Set&lt;string&gt;&gt; = new Map();
2388
- &nbsp;
2389
- constructor(
2390
- public events: EventSystem&lt;StreamProcessorEvents&gt;,
2391
- private db: LocalStore,
2392
- logger: Logger
2393
- ) {
2394
- this.logger = logger.child({ name: 'StreamProcessorService' });
2395
- }
2396
- &nbsp;
2397
- /**
2398
- * Add a receiver for stream updates.
2399
- * Multiple receivers can be registered (DataManager, DevTools, etc.)
2400
- */
2401
- addReceiver(receiver: StreamUpdateReceiver) {
2402
- this.receivers.push(receiver);
2403
- }
2404
- &nbsp;
2405
- private notifyUpdates(updates: StreamUpdate[]) {
2406
- if (this.batching) {
2407
- // Coalesce by queryHash instead of dispatching. The WASM `result_data`
2408
- // (localArray) is the full materialized array, so last-write-wins
2409
- // already reflects every prior ingest in the batch. We sum the
2410
- // materialization times so the single recorded sample reflects the
2411
- // batch's total work, and emit `op: 'CREATE'` on flush so the coalesced
2412
- // update takes DataModule's immediate (non-debounced) path.
2413
- for (const update of updates) {
2414
- const prev = this.batchBuffer.get(update.queryHash);
2415
- const sum = (a?: number, b?: number) =&gt; (a ?? 0) + (b ?? 0);
2416
- this.batchBuffer.set(update.queryHash, {
2417
- ...update,
2418
- op: 'CREATE',
2419
- materializationTimeMs: sum(prev?.materializationTimeMs, update.materializationTimeMs),
2420
- storeApplyMs: sum(prev?.storeApplyMs, update.storeApplyMs),
2421
- circuitStepMs: sum(prev?.circuitStepMs, update.circuitStepMs),
2422
- transformMs: sum(prev?.transformMs, update.transformMs),
2423
- });
2424
- }
2425
- return;
2426
- }
2427
- &nbsp;
2428
- this.dispatchUpdates(updates);
2429
- }
2430
- &nbsp;
2431
- private dispatchUpdates(updates: StreamUpdate[]) {
2432
- for (const update of updates) {
2433
- for (const receiver of this.receivers) {
2434
- receiver.onStreamUpdate(update);
2435
- }
2436
- }
2437
- }
2438
- &nbsp;
2439
- /**
2440
- * Ingest a batch of record changes, firing one coalesced `StreamUpdate` per
2441
- * affected query once every record has been ingested. Use this whenever
2442
- * multiple records land at once (sync fetching N rows, the boot prime).
2443
- *
2444
- * The batch is fed to the wasm side in chunks of {@link INGEST_CHUNK}: one
2445
- * circuit step per chunk (a step walks every registered view, so per-record
2446
- * ingest paid that fixed cost N times), but never the whole batch at once,
2447
- * because the wasm side has to hold every parsed row of a call at the same
2448
- * time and wasm32 dlmalloc never returns that peak.
2449
- *
2450
- * Returns the records that were ingested. A chunk that fails is reported
2451
- * and skipped, not retried (a retry would double-apply whatever the failed
2452
- * step already committed), and the remaining chunks still run.
2453
- */
2454
- ingestMany(records: IngestRecord[]): IngestRecord[] {
2455
- if (records.length === 0) return [];
2456
- &nbsp;
2457
- if (!this.processor) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
2458
- <span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
2459
- <span class="cstat-no" title="statement not covered" > { Category: 'sp00ky-client::StreamProcessorService::ingestMany' },</span>
2460
- <span class="cstat-no" title="statement not covered" > 'Not initialized, skipping ingest'</span>
2461
- <span class="cstat-no" title="statement not covered" > );</span>
2462
- <span class="cstat-no" title="statement not covered" > return [];</span>
2463
- <span class="cstat-no" title="statement not covered" > }</span>
2464
- &nbsp;
2465
- const bulkIngest = this.processor.ingest_many;
2466
- if (typeof bulkIngest !== 'function') {
2467
- // Stale wasm build: per-record steps, still coalesced into one update.
2468
- this.beginCoalescing();
2469
- try {
2470
- for (const record of records) {
2471
- this.ingest(record.table, record.op, record.id, record.record);
2472
- }
2473
- } finally {
2474
- this.flushCoalescing();
2475
- }
2476
- return records;
2477
- }
2478
- &nbsp;
2479
- const ingested: IngestRecord[] = [];
2480
- this.beginCoalescing();
2481
- try {
2482
- for (const chunk of chunks(records, INGEST_CHUNK)) {
2483
- try {
2484
- const items = chunk.map((record) =&gt; ({
2485
- table: record.table,
2486
- op: record.op,
2487
- id: record.id,
2488
- record: this.normalizeValue(record.record),
2489
- }));
2490
- const t0 = performance.now();
2491
- const rawUpdates = bulkIngest.call(this.processor, items<span class="branch-0 cbranch-no" title="branch not covered" >) ?? [];</span>
2492
- const materializationTimeMs = performance.now() - t0;
2493
- if (rawUpdates.length &gt; 0) {
2494
- this.notifyUpdates(
2495
- rawUpdates.map((u: WasmStreamUpdate) =&gt; ({
2496
- queryHash: u.query_id,
2497
- localArray: u.result_data,
2498
- op: 'CREATE' as const,
2499
- materializationTimeMs,
2500
- storeApplyMs: u.timing_store_apply_ms,
2501
- circuitStepMs: u.timing_circuit_step_ms,
2502
- transformMs: u.timing_transform_ms,
2503
- }))
2504
- );
2505
- }
2506
- ingested.push(...chunk);
2507
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (e) {</span>
2508
- <span class="cstat-no" title="statement not covered" > this.logger.error(</span>
2509
- <span class="cstat-no" title="statement not covered" > { error: e, count: chunk.length, Category: 'sp00ky-client::StreamProcessorService::ingestMany' },</span>
2510
- <span class="cstat-no" title="statement not covered" > 'Ingesting chunk into ssp failed'</span>
2511
- <span class="cstat-no" title="statement not covered" > );</span>
2512
- <span class="cstat-no" title="statement not covered" > }</span>
2513
- }
2514
- } finally {
2515
- this.flushCoalescing();
2516
- }
2517
- this.logger.debug(
2518
- { count: records.length, ingested: ingested.length, Category: 'sp00ky-client::StreamProcessorService::ingestMany' },
2519
- 'Ingested batch into ssp'
2520
- );
2521
- this.markSnapshotDirty(ingested.length);
2522
- return ingested;
2523
- }
2524
- &nbsp;
2525
- /**
2526
- * Open a coalescing window. While open, the per-record stream updates
2527
- * emitted by `ingest` are buffered (one entry per queryHash) instead of
2528
- * dispatched. Always paired with `flushCoalescing()` in a try/finally by
2529
- * `ingestMany` so the window always closes — otherwise the processor stays
2530
- * stuck buffering forever.
2531
- *
2532
- * No-op if a window is already open (nested batches aren't expected here).
2533
- */
2534
- private beginCoalescing() {
2535
- if (this.batching) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
2536
- this.batching = true;
2537
- this.batchBuffer.clear();
2538
- }
2539
- &nbsp;
2540
- /**
2541
- * Close the coalescing window and flush: dispatch one coalesced
2542
- * `StreamUpdate` per buffered queryHash, then persist processor state once
2543
- * for the whole batch (instead of once per ingest).
2544
- */
2545
- private flushCoalescing() {
2546
- if (!this.batching) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
2547
- this.batching = false;
2548
- const buffered = Array.from(this.batchBuffer.values());
2549
- this.batchBuffer.clear();
2550
- if (buffered.length &gt; 0) {
2551
- this.dispatchUpdates(buffered);
2552
- }
2553
- }
2554
- &nbsp;
2555
- /**
2556
- * Initialize the WASM module and processor.
2557
- * This must be called before using other methods.
2558
- */
2559
- async init() {
2560
- if (this.isInitialized) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
2561
- &nbsp;
2562
- this.logger.info(
2563
- { Category: 'sp00ky-client::StreamProcessorService::init' },
2564
- 'Initializing WASM...'
2565
- );
2566
- try {
2567
- await init(); // Initialize the WASM module (web target)
2568
- // We cast the generated Sp00kyProcessor to our interface which is safer
2569
- this.processor = new Sp00kyProcessor() as unknown as WasmProcessor;
2570
- this.applyProjection();
2571
- &nbsp;
2572
- this.isInitialized = true;
2573
- this.logger.info(
2574
- { Category: 'sp00ky-client::StreamProcessorService::init' },
2575
- 'Initialized successfully'
2576
- );
2577
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (e) {</span>
2578
- <span class="cstat-no" title="statement not covered" > this.logger.error(</span>
2579
- <span class="cstat-no" title="statement not covered" > { error: e, Category: 'sp00ky-client::StreamProcessorService::init' },</span>
2580
- <span class="cstat-no" title="statement not covered" > 'Failed to initialize'</span>
2581
- <span class="cstat-no" title="statement not covered" > );</span>
2582
- <span class="cstat-no" title="statement not covered" > throw e;</span>
2583
- <span class="cstat-no" title="statement not covered" > }</span>
2584
- }
2585
- &nbsp;
2586
- /**
2587
- * Drop the current WASM processor and start a fresh, empty circuit. Used on
2588
- * local-bucket switches: the old circuit holds the previous user's rows AND
2589
- * views registered with the previous `$auth` context, so neither may survive.
2590
- * Deliberately loads nothing: the snapshot in the store being swapped away
2591
- * from belongs to the previous bucket; the caller primes the new bucket's
2592
- * circuit (`primeFromLocal`) once its store is open, and the DataModule
2593
- * rebind re-registers every live view against this fresh processor. Caller
2594
- * must re-seed `setPermissions` afterwards (a fresh circuit default-denies
2595
- * every table).
2596
- */
2597
- async reset(): Promise&lt;void&gt; {
2598
- if (!this.isInitialized) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
2599
- this.stateGeneration++;
2600
- this.batching = false;
2601
- this.batchBuffer.clear();
2602
- this.snapshotDirty = false;
2603
- this.dirtyRows = 0;
2604
- this.widenPending.clear();
2605
- const previous = this.processor;
2606
- this.processor = new Sp00kyProcessor() as unknown as WasmProcessor;
2607
- this.applyProjection();
2608
- this.freeProcessor(previous);
2609
- this.logger.info(
2610
- { Category: 'sp00ky-client::StreamProcessorService::reset' },
2611
- 'Stream processor reset (fresh circuit)'
2612
- );
2613
- }
2614
- &nbsp;
2615
- /**
2616
- * Release the wasm circuit and stop checkpointing. Call when the client is
2617
- * torn down; a recreated client (provider remount, HMR) would otherwise stack
2618
- * one full circuit per instance.
2619
- */
2620
- <span class="fstat-no" title="function not covered" > dispose(): void {</span>
2621
- <span class="cstat-no" title="statement not covered" > this.stopCheckpoints();</span>
2622
- <span class="cstat-no" title="statement not covered" > const previous = this.processor;</span>
2623
- <span class="cstat-no" title="statement not covered" > this.processor = undefined;</span>
2624
- <span class="cstat-no" title="statement not covered" > this.isInitialized = false;</span>
2625
- <span class="cstat-no" title="statement not covered" > this.batching = false;</span>
2626
- <span class="cstat-no" title="statement not covered" > this.batchBuffer.clear();</span>
2627
- <span class="cstat-no" title="statement not covered" > this.receivers = [];</span>
2628
- <span class="cstat-no" title="statement not covered" > this.freeProcessor(previous);</span>
2629
- <span class="cstat-no" title="statement not covered" > }</span>
2630
- &nbsp;
2631
- /**
2632
- * Explicitly run the wasm-bindgen destructor. Guarded: stale wasm builds may
2633
- * not expose `free`, and a double free must not take the app down.
2634
- */
2635
- private freeProcessor(processor: WasmProcessor | undefined): void {
2636
- if (!processor || typeof processor.free !== 'function') <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
2637
- try {
2638
- processor.free();
2639
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (e) {</span>
2640
- <span class="cstat-no" title="statement not covered" > this.logger.debug(</span>
2641
- <span class="cstat-no" title="statement not covered" > { error: e, Category: 'sp00ky-client::StreamProcessorService::freeProcessor' },</span>
2642
- <span class="cstat-no" title="statement not covered" > 'Failed to free previous wasm circuit'</span>
2643
- <span class="cstat-no" title="statement not covered" > );</span>
2644
- <span class="cstat-no" title="statement not covered" > }</span>
2645
- }
2646
- &nbsp;
2647
- /** Toggle circuit-state persistence (shared-tabs follower/leader role). */
2648
- setPersistenceEnabled(enabled: boolean): void {
2649
- this.persistState = enabled;
2650
- if (!enabled) this.stopCheckpoints();
2651
- }
2652
- &nbsp;
2653
- /**
2654
- * Snapshot persistence (`persistCircuit`). When on, the circuit's store is
2655
- * written to the local store on a checkpoint interval and when the page
2656
- * goes hidden, and restored by {@link primeFromLocal} on the next boot.
2657
- */
2658
- configureCircuitPersistence(enabled: boolean, checkpointMs?: number): void {
2659
- this.persistCircuit = enabled;
2660
- if (checkpointMs &amp;&amp; checkpointMs &gt; 0) this.checkpointMs = checkpointMs;
2661
- if (!enabled) this.stopCheckpoints();
2662
- }
2663
- &nbsp;
2664
- /**
2665
- * Field projection (`circuitProjection`, default on). Takes effect on the
2666
- * next processor (`init`/`reset`) and on rows written after that.
2667
- */
2668
- <span class="fstat-no" title="function not covered" > configureProjection(enabled: boolean): void {</span>
2669
- <span class="cstat-no" title="statement not covered" > this.projection = enabled;</span>
2670
- <span class="cstat-no" title="statement not covered" > this.applyProjection();</span>
2671
- <span class="cstat-no" title="statement not covered" > }</span>
2672
- &nbsp;
2673
- private applyProjection(): void {
2674
- if (!this.processor || typeof this.processor.set_projection !== 'function') <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
2675
- try {
2676
- this.processor.set_projection(this.projection);
2677
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (e) {</span>
2678
- <span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
2679
- <span class="cstat-no" title="statement not covered" > { error: e, Category: 'sp00ky-client::StreamProcessorService::applyProjection' },</span>
2680
- <span class="cstat-no" title="statement not covered" > 'set_projection failed'</span>
2681
- <span class="cstat-no" title="statement not covered" > );</span>
2682
- <span class="cstat-no" title="statement not covered" > }</span>
2683
- }
2684
- &nbsp;
2685
- /** Resolves once the boot-time prime has finished (or was skipped). */
2686
- whenPrimed(): Promise&lt;void&gt; {
2687
- return this.primed;
2688
- }
2689
- &nbsp;
2690
- /**
2691
- * Fill the circuit from the LOCAL store, in the background.
2692
- *
2693
- * With a usable snapshot: install it under whatever views have registered
2694
- * meanwhile (`load_store_state` re-primes them), then `reconcile` each table
2695
- * against the store's `(id, rv)` list so rows deleted since the checkpoint
2696
- * are stepped out and only rows added or changed since are read back and
2697
- * ingested. Without one: read every row and ingest it, chunked.
2698
- *
2699
- * Either way the circuit ends up equal to the local store without touching
2700
- * the network, so the first sync diff is a real delta rather than "fetch
2701
- * everything". The returned promise never rejects; `whenPrimed` gates on it.
2702
- */
2703
- primeFromLocal(ctx: CircuitPrimeContext): Promise&lt;void&gt; {
2704
- this.schemaHash = ctx.schemaHash;
2705
- const run = this.runPrime(ctx).catch((e) =&gt; {
2706
- <span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
2707
- <span class="cstat-no" title="statement not covered" > { error: e, Category: 'sp00ky-client::StreamProcessorService::primeFromLocal' },</span>
2708
- <span class="cstat-no" title="statement not covered" > 'Circuit prime failed; the circuit fills from sync instead'</span>
2709
- <span class="cstat-no" title="statement not covered" > );</span>
2710
- });
2711
- this.primed = run;
2712
- return run;
2713
- }
2714
- &nbsp;
2715
- private async runPrime(ctx: CircuitPrimeContext): Promise&lt;void&gt; {
2716
- const processor = this.processor;
2717
- if (!processor || typeof this.db.scanVersions !== 'function') return;
2718
- const generation = this.stateGeneration;
2719
- const epoch = this.db.epoch;
2720
- // A bucket switch replaces the processor and the store under us; every
2721
- // step re-checks so a stale chunk never lands in the new bucket.
2722
- const alive = () =&gt;
2723
- this.processor === processor &amp;&amp; generation === this.stateGeneration &amp;&amp; epoch === this.db.epoch;
2724
- const t0 = performance.now();
2725
- &nbsp;
2726
- let restored = false;
2727
- if (
2728
- this.persistCircuit &amp;&amp;
2729
- typeof this.db.getSnapshot === 'function' &amp;&amp;
2730
- typeof processor.load_store_state === 'function'
2731
- ) {
2732
- const snapshot = await this.db.getSnapshot(CIRCUIT_SNAPSHOT_KEY);
2733
- if (!alive()) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
2734
- if (snapshot) {
2735
- const { meta } = snapshot;
2736
- if (meta.formatVersion !== CIRCUIT_SNAPSHOT_FORMAT || meta.schemaHash !== ctx.schemaHash) {
2737
- this.logger.info(
2738
- { meta, Category: 'sp00ky-client::StreamProcessorService::primeFromLocal' },
2739
- 'Circuit snapshot is from another format or schema; priming from rows'
2740
- );
2741
- } else {
2742
- try {
2743
- const tLoad = performance.now();
2744
- const updates = processor.load_store_state(snapshot.bytes);
2745
- this.dispatchWasmUpdates(updates);
2746
- restored = true;
2747
- this.logger.info(
2748
- {
2749
- bytes: snapshot.bytes.byteLength,
2750
- views: updates.length,
2751
- loadMs: Math.round(performance.now() - tLoad),
2752
- Category: 'sp00ky-client::StreamProcessorService::primeFromLocal',
2753
- },
2754
- 'Circuit snapshot restored'
2755
- );
2756
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (e) {</span>
2757
- <span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
2758
- <span class="cstat-no" title="statement not covered" > { error: e, Category: 'sp00ky-client::StreamProcessorService::primeFromLocal' },</span>
2759
- <span class="cstat-no" title="statement not covered" > 'Circuit snapshot unreadable; priming from rows'</span>
2760
- <span class="cstat-no" title="statement not covered" > );</span>
2761
- <span class="cstat-no" title="statement not covered" > }</span>
2762
- }
2763
- }
2764
- }
2765
- &nbsp;
2766
- // Read the versions AFTER the snapshot: a batch the leader writes between
2767
- // the two can only make the store side newer, which reconcile handles.
2768
- const versions = await this.db.scanVersions(ctx.tables);
2769
- if (!alive()) return;
2770
- const total = Object.values(versions).reduce((n, v) =&gt; n + v.length, 0);
2771
- if (!restored &amp;&amp; this.db.engineKind !== <span class="branch-0 cbranch-no" title="branch not covered" >'sqlite' &amp;&amp; total &gt; SURREAL_PRIME_ROW_CAP) <span class="branch-0 cbranch-no" title="branch not covered" >{</span></span>
2772
- <span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
2773
- <span class="cstat-no" title="statement not covered" > { total, cap: SURREAL_PRIME_ROW_CAP, Category: 'sp00ky-client::StreamProcessorService::primeFromLocal' },</span>
2774
- <span class="cstat-no" title="statement not covered" > 'Too many cached rows to prime through the main-thread engine; circuit fills from sync'</span>
2775
- <span class="cstat-no" title="statement not covered" > );</span>
2776
- <span class="cstat-no" title="statement not covered" > return;</span>
2777
- <span class="cstat-no" title="statement not covered" > }</span>
2778
- &nbsp;
2779
- let ingested = 0;
2780
- let fetched = 0;
2781
- let deleted = 0;
2782
- for (const table of ctx.tables) {
2783
- const entries = versions[table<span class="branch-0 cbranch-no" title="branch not covered" >] ?? [];</span>
2784
- let toFetch: string[];
2785
- if (restored &amp;&amp; typeof processor.reconcile === 'function') {
2786
- const result = processor.reconcile(table, entries);
2787
- this.dispatchWasmUpdates(result.updates);
2788
- deleted += result.deleted;
2789
- toFetch = result.fetch;
2790
- } else {
2791
- toFetch = entries.map(([id]) =&gt; id);
2792
- }
2793
- for (const chunk of chunks(toFetch, PRIME_CHUNK)) {
2794
- const rows = await this.db.selectByIds(table, chunk);
2795
- if (!alive()) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
2796
- fetched += rows.length;
2797
- ingested += this.ingestMany(
2798
- rows.map((row) =&gt; ({
2799
- table,
2800
- op: 'CREATE' as const,
2801
- id: idString(row.id),
2802
- record: row,
2803
- }))
2804
- ).length;
2805
- }
2806
- if (entries.length &gt; 0) {
2807
- ctx.onVersions?.(
2808
- table,
2809
- entries.filter(([id]) =&gt; !ctx.pendingIds.has(id))
2810
- );
2811
- }
2812
- }
2813
- // A prime from rows leaves the store with no snapshot to fall back on;
2814
- // let the next checkpoint write one even if nothing else changes.
2815
- if (!restored &amp;&amp; ingested &gt; 0) this.markSnapshotDirty(Math.max(ingested, CHECKPOINT_MIN_ROWS));
2816
- this.logger.info(
2817
- {
2818
- restored,
2819
- rows: total,
2820
- fetched,
2821
- ingested,
2822
- deleted,
2823
- ms: Math.round(performance.now() - t0),
2824
- Category: 'sp00ky-client::StreamProcessorService::primeFromLocal',
2825
- },
2826
- 'Circuit primed from the local store'
2827
- );
2828
- }
2829
- &nbsp;
2830
- /** Publish wasm updates produced outside an ingest (restore, reconcile). */
2831
- private dispatchWasmUpdates(updates: WasmStreamUpdate[] | undefined): void {
2832
- if (!updates || updates.length === 0) return;
2833
- this.dispatchUpdates(
2834
- updates.map((u) =&gt; ({
2835
- queryHash: u.query_id,
2836
- localArray: u.result_data,
2837
- op: 'CREATE' as const,
2838
- }))
2839
- );
2840
- }
2841
- &nbsp;
2842
- /**
2843
- * Record that the circuit changed by `rows` rows. Cheap; the snapshot is
2844
- * deferred to the checkpoint timer and skipped entirely when `persistCircuit`
2845
- * is off.
2846
- */
2847
- private markSnapshotDirty(rows = 1): void {
2848
- if (!this.persistCircuit || !this.persistState) return;
2849
- this.snapshotDirty = true;
2850
- this.dirtyRows += rows;
2851
- this.startCheckpoints();
2852
- }
2853
- &nbsp;
2854
- private startCheckpoints(): void {
2855
- if (this.checkpointTimer) return;
2856
- this.checkpointTimer = setInterval(() =&gt; {
2857
- if (!this.snapshotDirty || this.dirtyRows &lt; CHECKPOINT_MIN_ROWS) return;
2858
- void this.checkpoint('interval');
2859
- }, this.checkpointMs);
2860
- // Node/test environments have no `window`; the interval alone is enough there.
2861
- if (typeof window !== <span class="branch-0 cbranch-no" title="branch not covered" >'undefined' &amp;&amp; !this.hideHandler) <span class="branch-0 cbranch-no" title="branch not covered" >{</span></span>
2862
- // `visibilitychange: hidden` is the reliable last chance: a 100 MB write
2863
- // cannot finish inside `pagehide`, which is kept only as best effort.
2864
- <span class="cstat-no" title="statement not covered" > this.hideHandler = <span class="fstat-no" title="function not covered" >() =&gt; {</span></span>
2865
- <span class="cstat-no" title="statement not covered" > if (!this.snapshotDirty) return;</span>
2866
- <span class="cstat-no" title="statement not covered" > if (typeof document !== 'undefined' &amp;&amp; document.visibilityState === 'visible') return;</span>
2867
- <span class="cstat-no" title="statement not covered" > void this.checkpoint('hidden');</span>
2868
- <span class="cstat-no" title="statement not covered" > };</span>
2869
- <span class="cstat-no" title="statement not covered" > window.addEventListener('visibilitychange', this.hideHandler);</span>
2870
- <span class="cstat-no" title="statement not covered" > window.addEventListener('pagehide', this.hideHandler);</span>
2871
- <span class="cstat-no" title="statement not covered" > }</span>
2872
- }
2873
- &nbsp;
2874
- /** Stop checkpointing and drop the visibility listeners. */
2875
- stopCheckpoints(): void {
2876
- if (this.checkpointTimer) {
2877
- clearInterval(this.checkpointTimer);
2878
- this.checkpointTimer = null;
2879
- }
2880
- if (this.<span class="branch-0 cbranch-no" title="branch not covered" >hideHandler &amp;&amp; typeof window !== 'undefined') <span class="branch-0 cbranch-no" title="branch not covered" >{</span></span>
2881
- <span class="cstat-no" title="statement not covered" > window.removeEventListener('visibilitychange', this.hideHandler);</span>
2882
- <span class="cstat-no" title="statement not covered" > window.removeEventListener('pagehide', this.hideHandler);</span>
2883
- <span class="cstat-no" title="statement not covered" > }</span>
2884
- this.hideHandler = null;
2885
- this.snapshotDirty = false;
2886
- this.dirtyRows = 0;
2887
- }
2888
- &nbsp;
2889
- /**
2890
- * Write the circuit's store to the local store as a snapshot. Compacts the
2891
- * row arena first when dead bytes outweigh live ones. Serialised: a second
2892
- * call while one is in flight joins it. No-op unless persistence is on, this
2893
- * tab owns the store, and the engine can hold a snapshot.
2894
- */
2895
- checkpoint(reason = 'manual'): Promise&lt;void&gt; {
2896
- if (this.checkpointInFlight) <span class="branch-0 cbranch-no" title="branch not covered" >return this.checkpointInFlight;</span>
2897
- const run = this.runCheckpoint(reason).finally(() =&gt; {
2898
- this.checkpointInFlight = null;
2899
- });
2900
- this.checkpointInFlight = run;
2901
- return run;
2902
- }
2903
- &nbsp;
2904
- private async runCheckpoint(reason: string): Promise&lt;void&gt; {
2905
- const processor = this.processor;
2906
- if (!processor || !this.persistState || !this.persistCircuit || !this.schemaHash) return;
2907
- if (typeof this.db.putSnapshot !== 'function' || typeof processor.save_store_state !== 'function') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
2908
- <span class="cstat-no" title="statement not covered" > return;</span>
2909
- <span class="cstat-no" title="statement not covered" > }</span>
2910
- const generation = this.stateGeneration;
2911
- const epoch = this.db.epoch;
2912
- const rows = this.dirtyRows;
2913
- this.snapshotDirty = false;
2914
- this.dirtyRows = 0;
2915
- try {
2916
- const t0 = performance.now();
2917
- let reclaimed = 0;
2918
- if (
2919
- typeof processor.compact === <span class="branch-0 cbranch-no" title="branch not covered" >'function' &amp;&amp;</span>
2920
- <span class="cstat-no" title="statement not covered" > typeof processor.dead_bytes === <span class="branch-0 cbranch-no" title="branch not covered" >'function' &amp;&amp;</span></span>
2921
- <span class="cstat-no" title="statement not covered" > typeof processor.live_bytes === 'function'</span>
2922
- ) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
2923
- <span class="cstat-no" title="statement not covered" > const dead = processor.dead_bytes();</span>
2924
- <span class="cstat-no" title="statement not covered" > if (dead &gt; 1_000_000 &amp;&amp; dead &gt; processor.live_bytes()) reclaimed = processor.compact();</span>
2925
- <span class="cstat-no" title="statement not covered" > }</span>
2926
- const bytes = processor.save_store_state();
2927
- const meta = {
2928
- formatVersion: CIRCUIT_SNAPSHOT_FORMAT,
2929
- schemaHash: this.schemaHash,
2930
- savedAt: Date.now(),
2931
- maxRv: typeof processor.max_row_versions === <span class="branch-0 cbranch-no" title="branch not covered" >'function' ? processor.max_row_versions() : u</span>ndefined,
2932
- };
2933
- // A reset or bucket switch landed while we serialised: this snapshot
2934
- // describes the OLD bucket's circuit and must not be written into the
2935
- // new bucket's store.
2936
- if (generation !== this.stateGeneration || epoch !== this.db.epoch) return;
2937
- await this.db.putSnapshot(CIRCUIT_SNAPSHOT_KEY, bytes, meta);
2938
- this.logger.info(
2939
- {
2940
- reason,
2941
- rows,
2942
- bytes: bytes.byteLength,
2943
- reclaimed,
2944
- ms: Math.round(performance.now() - t0),
2945
- Category: 'sp00ky-client::StreamProcessorService::checkpoint',
2946
- },
2947
- 'Circuit snapshot written'
2948
- );
2949
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (e) {</span>
2950
- <span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
2951
- <span class="cstat-no" title="statement not covered" > { error: e, reason, Category: 'sp00ky-client::StreamProcessorService::checkpoint' },</span>
2952
- <span class="cstat-no" title="statement not covered" > 'Circuit snapshot failed'</span>
2953
- <span class="cstat-no" title="statement not covered" > );</span>
2954
- <span class="cstat-no" title="statement not covered" > }</span>
2955
- }
2956
- &nbsp;
2957
- /**
2958
- * Projection widening: a newly registered view evaluates fields that rows
2959
- * already in the circuit were stored without. Merge just those fields in,
2960
- * table by table, from the local store. The view registered against what
2961
- * was present and converges as the merges step through.
2962
- */
2963
- private scheduleWiden(missing: Record&lt;string, string[]&gt;): void {
2964
- for (const [table, fields] of Object.entries(missing)) {
2965
- const set = this.widenPending.get(table) ?? new Set&lt;string&gt;();
2966
- for (const f of fields) set.add(f);
2967
- this.widenPending.set(table, set);
2968
- }
2969
- this.widenQueue = this.widenQueue.then(() =&gt; this.runWiden()).catch((e) =&gt; {
2970
- <span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
2971
- <span class="cstat-no" title="statement not covered" > { error: e, Category: 'sp00ky-client::StreamProcessorService::widen' },</span>
2972
- <span class="cstat-no" title="statement not covered" > 'Projection widening failed'</span>
2973
- <span class="cstat-no" title="statement not covered" > );</span>
2974
- });
2975
- }
2976
- &nbsp;
2977
- private async runWiden(): Promise&lt;void&gt; {
2978
- const processor = this.processor;
2979
- if (!processor || typeof this.db.scanVersions !== 'function') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
2980
- <span class="cstat-no" title="statement not covered" > this.widenPending.clear();</span>
2981
- <span class="cstat-no" title="statement not covered" > return;</span>
2982
- <span class="cstat-no" title="statement not covered" > }</span>
2983
- const generation = this.stateGeneration;
2984
- const epoch = this.db.epoch;
2985
- while (this.widenPending.size &gt; 0) {
2986
- const [table, fields] = this.widenPending.entries().next().value as [string, Set&lt;string&gt;];
2987
- this.widenPending.delete(table);
2988
- const select = Array.from(fields);
2989
- const versions = await this.db.scanVersions([table]);
2990
- if (this.processor !== processor || generation !== this.stateGeneration || epoch !== this.db.epoch) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
2991
- const ids = (versions[table<span class="branch-0 cbranch-no" title="branch not covered" >] ?? []).m</span>ap(([id]) =&gt; id);
2992
- let merged = 0;
2993
- for (const chunk of chunks(ids, PRIME_CHUNK)) {
2994
- const rows = await this.db.selectByIds(table, chunk, { select });
2995
- if (this.processor !== processor || generation !== this.stateGeneration || epoch !== this.db.epoch) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
2996
- merged += this.ingestMany(
2997
- rows.map((row) =&gt; ({
2998
- table,
2999
- op: 'MERGE' as const,
3000
- id: idString(row.id),
3001
- record: row,
3002
- }))
3003
- ).length;
3004
- }
3005
- this.logger.info(
3006
- { table, fields: select, merged, Category: 'sp00ky-client::StreamProcessorService::widen' },
3007
- 'Widened projected rows with newly evaluated fields'
3008
- );
3009
- }
3010
- }
3011
- &nbsp;
3012
- /**
3013
- * Seed per-table `select` permission predicates ({ [table]: whereText }).
3014
- * Must run after the processor exists and before any `register_view`, else
3015
- * non-`_00_` tables are default-denied and registration fails.
3016
- */
3017
- <span class="fstat-no" title="function not covered" > setPermissions(permissions: Record&lt;string, string&gt;) {</span>
3018
- <span class="cstat-no" title="statement not covered" > if (!this.processor) return;</span>
3019
- <span class="cstat-no" title="statement not covered" > if (typeof this.processor.set_permissions !== 'function') {</span>
3020
- <span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
3021
- <span class="cstat-no" title="statement not covered" > { Category: 'sp00ky-client::StreamProcessorService::setPermissions' },</span>
3022
- <span class="cstat-no" title="statement not covered" > 'set_permissions not found on processor (stale WASM build?)'</span>
3023
- <span class="cstat-no" title="statement not covered" > );</span>
3024
- <span class="cstat-no" title="statement not covered" > return;</span>
3025
- <span class="cstat-no" title="statement not covered" > }</span>
3026
- <span class="cstat-no" title="statement not covered" > this.processor.set_permissions(permissions);</span>
3027
- <span class="cstat-no" title="statement not covered" > this.logger.info(</span>
3028
- <span class="cstat-no" title="statement not covered" > {</span>
3029
- <span class="cstat-no" title="statement not covered" > tables: Object.keys(permissions).length,</span>
3030
- <span class="cstat-no" title="statement not covered" > Category: 'sp00ky-client::StreamProcessorService::setPermissions',</span>
3031
- <span class="cstat-no" title="statement not covered" > },</span>
3032
- <span class="cstat-no" title="statement not covered" > 'Seeded table permissions'</span>
3033
- <span class="cstat-no" title="statement not covered" > );</span>
3034
- <span class="cstat-no" title="statement not covered" > }</span>
3035
- &nbsp;
3036
- /**
3037
- * Set the current session's auth identity for permission injection,
3038
- * mirroring the server's `fn::query::register`
3039
- * (`object::extend(params, { auth: { id: $auth.id }, access: $access })`).
3040
- * Stored as strings (empty when logged out) and applied to every
3041
- * `register_view` in {@link registerQueryPlan}. Must be set before a
3042
- * `$auth`-gated query registers (and re-set on auth state changes), or the
3043
- * in-browser SSP's `permission_inject` rejects it with
3044
- * "requires $auth but registration params lack it".
3045
- */
3046
- <span class="fstat-no" title="function not covered" > setSessionAuth(authId: string | null, access: string | null) {</span>
3047
- <span class="cstat-no" title="statement not covered" > this.sessionAuth = { authId: authId ?? '', access: access ?? '' };</span>
3048
- <span class="cstat-no" title="statement not covered" > this.logger.debug(</span>
3049
- <span class="cstat-no" title="statement not covered" > {</span>
3050
- <span class="cstat-no" title="statement not covered" > authId: this.sessionAuth.authId,</span>
3051
- <span class="cstat-no" title="statement not covered" > access: this.sessionAuth.access,</span>
3052
- <span class="cstat-no" title="statement not covered" > Category: 'sp00ky-client::StreamProcessorService::setSessionAuth',</span>
3053
- <span class="cstat-no" title="statement not covered" > },</span>
3054
- <span class="cstat-no" title="statement not covered" > 'Session auth context updated'</span>
3055
- <span class="cstat-no" title="statement not covered" > );</span>
3056
- <span class="cstat-no" title="statement not covered" > }</span>
3057
- &nbsp;
3058
- /**
3059
- * Ingest a record change into the processor.
3060
- * Emits 'stream_update' event if materialized views are affected.
3061
- * @param isOptimistic true = local mutation (increment versions), false = remote sync (keep versions)
3062
- */
3063
- ingest(
3064
- table: string,
3065
- op: IngestRecord['op'],
3066
- id: string,
3067
- record: any
3068
- ): WasmStreamUpdate[] {
3069
- this.logger.debug(
3070
- {
3071
- table,
3072
- op,
3073
- id,
3074
- Category: 'sp00ky-client::StreamProcessorService::ingest',
3075
- },
3076
- 'Ingesting into ssp'
3077
- );
3078
- &nbsp;
3079
- if (!this.processor) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
3080
- <span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
3081
- <span class="cstat-no" title="statement not covered" > { Category: 'sp00ky-client::StreamProcessorService::ingest' },</span>
3082
- <span class="cstat-no" title="statement not covered" > 'Not initialized, skipping ingest'</span>
3083
- <span class="cstat-no" title="statement not covered" > );</span>
3084
- <span class="cstat-no" title="statement not covered" > return [];</span>
3085
- <span class="cstat-no" title="statement not covered" > }</span>
3086
- &nbsp;
3087
- try {
3088
- const normalizedRecord = this.normalizeValue(record);
3089
- &nbsp;
3090
- const t0 = performance.now();
3091
- const rawUpdates = this.processor.ingest(table, op, id, normalizedRecord);
3092
- const materializationTimeMs = performance.now() - t0;
3093
- this.logger.debug(
3094
- {
3095
- table,
3096
- op,
3097
- id,
3098
- rawUpdates: rawUpdates.length,
3099
- materializationTimeMs,
3100
- Category: 'sp00ky-client::StreamProcessorService::ingest',
3101
- },
3102
- 'Ingesting into ssp done'
3103
- );
3104
- &nbsp;
3105
- if (rawUpdates &amp;&amp; Array.isArray(rawUpdates) &amp;&amp; rawUpdates.length &gt; 0) {
3106
- const updates: StreamUpdate[] = rawUpdates.map((u: WasmStreamUpdate) =&gt; ({
3107
- queryHash: u.query_id,
3108
- localArray: u.result_data,
3109
- // A MERGE is a content update as far as consumers are concerned.
3110
- op: op === <span class="branch-0 cbranch-no" title="branch not covered" >'MERGE' ? 'UPDATE' : o</span>p,
3111
- materializationTimeMs,
3112
- storeApplyMs: u.timing_store_apply_ms,
3113
- circuitStepMs: u.timing_circuit_step_ms,
3114
- transformMs: u.timing_transform_ms,
3115
- }));
3116
- // Direct handler call instead of event
3117
- this.notifyUpdates(updates);
3118
- }
3119
- // While batching (inside `ingestMany`), `flushCoalescing` marks dirty once
3120
- // for the whole batch, skip the redundant per-record mark here.
3121
- if (!this.batching) {
3122
- this.markSnapshotDirty();
3123
- }
3124
- return rawUpdates;
3125
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (e) {</span>
3126
- <span class="cstat-no" title="statement not covered" > this.logger.error(</span>
3127
- <span class="cstat-no" title="statement not covered" > { error: e, Category: 'sp00ky-client::StreamProcessorService::ingest' },</span>
3128
- <span class="cstat-no" title="statement not covered" > 'Ingesting into ssp failed'</span>
3129
- <span class="cstat-no" title="statement not covered" > );</span>
3130
- <span class="cstat-no" title="statement not covered" > }</span>
3131
- <span class="cstat-no" title="statement not covered" > return [];</span>
3132
- }
3133
- &nbsp;
3134
- /**
3135
- * Register a new query plan.
3136
- * Emits 'stream_update' with the initial result.
3137
- */
3138
- registerQueryPlan(queryPlan: QueryPlanConfig) {
3139
- if (!this.processor) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
3140
- <span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
3141
- <span class="cstat-no" title="statement not covered" > { Category: 'sp00ky-client::StreamProcessorService::registerQueryPlan' },</span>
3142
- <span class="cstat-no" title="statement not covered" > 'Not initialized, skipping registration'</span>
3143
- <span class="cstat-no" title="statement not covered" > );</span>
3144
- <span class="cstat-no" title="statement not covered" > return;</span>
3145
- <span class="cstat-no" title="statement not covered" > }</span>
3146
- &nbsp;
3147
- this.logger.debug(
3148
- {
3149
- queryHash: queryPlan.queryHash,
3150
- surql: queryPlan.surql,
3151
- params: queryPlan.params,
3152
- Category: 'sp00ky-client::StreamProcessorService::registerQueryPlan',
3153
- },
3154
- 'Registering query plan'
3155
- );
3156
- &nbsp;
3157
- try {
3158
- const normalizedParams = this.normalizeValue(queryPlan.params);
3159
- &nbsp;
3160
- // Mirror the server's `fn::query::register` auth injection so the
3161
- // in-browser SSP can resolve `$auth`/`$access` in a table's permission
3162
- // predicate. Without this, any `$auth`-gated table (e.g. `thread`) is
3163
- // rejected by `permission_inject` and its local view never materializes.
3164
- // Injected only into the params handed to the in-browser SSP — never into
3165
- // the persisted `queryState.config.params` / query hash / server payload
3166
- // (the server does its own injection), so the view id stays shared.
3167
- const paramsWithAuth = {
3168
- ...(normalizedParams as Record&lt;string, unknown&gt;),
3169
- auth: { id: this.sessionAuth.authId },
3170
- access: this.sessionAuth.access,
3171
- };
3172
- &nbsp;
3173
- const initialUpdate = this.processor.register_view({
3174
- id: queryPlan.queryHash,
3175
- surql: queryPlan.surql,
3176
- params: paramsWithAuth,
3177
- clientId: 'local',
3178
- ttl: queryPlan.ttl.toString(),
3179
- lastActiveAt: new Date().toISOString(),
3180
- });
3181
- &nbsp;
3182
- this.logger.debug(
3183
- { initialUpdate, Category: 'sp00ky-client::StreamProcessorService::registerQueryPlan' },
3184
- 'register_view result'
3185
- );
3186
- &nbsp;
3187
- if (!initialUpdate) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
3188
- <span class="cstat-no" title="statement not covered" > throw new Error('Failed to register query plan');</span>
3189
- <span class="cstat-no" title="statement not covered" > }</span>
3190
- const update: StreamUpdate = {
3191
- queryHash: initialUpdate.query_id,
3192
- localArray: initialUpdate.result_data,
3193
- registration: {
3194
- parseMs: initialUpdate.timing_parse_ms ?? 0,
3195
- planMs: initialUpdate.timing_plan_ms ?? 0,
3196
- snapshotMs: initialUpdate.timing_snapshot_ms ?? 0,
3197
- },
3198
- };
3199
- if (initialUpdate.missing_fields &amp;&amp; Object.keys(initialUpdate.missing_fields).length &gt; 0) {
3200
- this.scheduleWiden(initialUpdate.missing_fields);
3201
- }
3202
- this.logger.debug(
3203
- {
3204
- queryHash: queryPlan.queryHash,
3205
- surql: queryPlan.surql,
3206
- params: queryPlan.params,
3207
- Category: 'sp00ky-client::StreamProcessorService::registerQueryPlan',
3208
- },
3209
- 'Registered query plan'
3210
- );
3211
- return update;
3212
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (e) {</span>
3213
- <span class="cstat-no" title="statement not covered" > this.logger.error(</span>
3214
- <span class="cstat-no" title="statement not covered" > { error: e, Category: 'sp00ky-client::StreamProcessorService::registerQueryPlan' },</span>
3215
- <span class="cstat-no" title="statement not covered" > 'Error registering query plan'</span>
3216
- <span class="cstat-no" title="statement not covered" > );</span>
3217
- <span class="cstat-no" title="statement not covered" > throw e;</span>
3218
- <span class="cstat-no" title="statement not covered" > }</span>
3219
- }
3220
- &nbsp;
3221
- /**
3222
- * Unregister a query plan by ID.
3223
- */
3224
- unregisterQueryPlan(queryHash: string) {
3225
- if (!this.processor) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
3226
- try {
3227
- this.processor.unregister_view(queryHash);
3228
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (e) {</span>
3229
- <span class="cstat-no" title="statement not covered" > this.logger.error(</span>
3230
- <span class="cstat-no" title="statement not covered" > { error: e, Category: 'sp00ky-client::StreamProcessorService::unregisterQueryPlan' },</span>
3231
- <span class="cstat-no" title="statement not covered" > 'Error unregistering query plan'</span>
3232
- <span class="cstat-no" title="statement not covered" > );</span>
3233
- <span class="cstat-no" title="statement not covered" > }</span>
3234
- }
3235
- &nbsp;
3236
- private normalizeValue(value: any): any {
3237
- if (value === null || value === undefined) <span class="branch-0 cbranch-no" title="branch not covered" >return value;</span>
3238
- &nbsp;
3239
- if (typeof value === 'object') {
3240
- // CRDT snapshots arrive as `Uint8Array` (or `ArrayBuffer` /
3241
- // typed-array views). `serde_wasm_bindgen::from_value` rejects
3242
- // those when deserializing into `serde_json::Value` (JSON has no
3243
- // binary variant), and the SSP can't filter on opaque bytes
3244
- // anyway. Replace with `null` so the row still flows through the
3245
- // ingest path with its other columns intact, and downstream
3246
- // predicates referencing the bytes column simply don't match.
3247
- if (
3248
- value instanceof Uint8Array ||
3249
- value instanceof ArrayBuffer ||
3250
- ArrayBuffer.isView(value)
3251
- ) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
3252
- <span class="cstat-no" title="statement not covered" > return null;</span>
3253
- <span class="cstat-no" title="statement not covered" > }</span>
3254
- &nbsp;
3255
- // RecordId detection using duck typing (constructor.name may be minified)
3256
- // SurrealDB's RecordId has: table (getter returning Table), id, and toString()
3257
- // Check for table getter that has its own toString AND id property
3258
- const hasTable = 'table' in <span class="branch-0 cbranch-no" title="branch not covered" >value &amp;&amp; typeof value.table?.toString === 'function';</span>
3259
- const hasId = 'id' in value;
3260
- const hasToString = typeof value.toString === 'function';
3261
- const isNotPlainObject = value.constructor !== Object;
3262
- &nbsp;
3263
- if (<span class="branch-0 cbranch-no" title="branch not covered" >hasTable &amp;&amp; <span class="branch-0 cbranch-no" title="branch not covered" >hasId &amp;&amp; <span class="branch-0 cbranch-no" title="branch not covered" >h</span>asToString &amp;&amp; i</span>sNotPlainObject) <span class="branch-0 cbranch-no" title="branch not covered" >{</span></span>
3264
- <span class="cstat-no" title="statement not covered" > const result = value.toString();</span>
3265
- <span class="cstat-no" title="statement not covered" > this.logger.trace(</span>
3266
- <span class="cstat-no" title="statement not covered" > { result, Category: 'sp00ky-client::StreamProcessorService::normalizeValue' },</span>
3267
- <span class="cstat-no" title="statement not covered" > 'RecordId detected'</span>
3268
- <span class="cstat-no" title="statement not covered" > );</span>
3269
- <span class="cstat-no" title="statement not covered" > return result;</span>
3270
- <span class="cstat-no" title="statement not covered" > }</span>
3271
- &nbsp;
3272
- // Fallback: old check for objects with tb and id (some internal representations)
3273
- if ('tb' in <span class="branch-0 cbranch-no" title="branch not covered" >value &amp;&amp; 'id' in <span class="branch-0 cbranch-no" title="branch not covered" >value &amp;&amp; !</span>('table' in value)) <span class="branch-0 cbranch-no" title="branch not covered" >{</span></span>
3274
- <span class="cstat-no" title="statement not covered" > return `${value.tb}:${value.id}`;</span>
3275
- <span class="cstat-no" title="statement not covered" > }</span>
3276
- &nbsp;
3277
- // Handle arrays recursively
3278
- if (Array.isArray(value)) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
3279
- <span class="cstat-no" title="statement not covered" > return value.map((v) =&gt; this.normalizeValue(v));</span>
3280
- <span class="cstat-no" title="statement not covered" > }</span>
3281
- &nbsp;
3282
- // Handle plain objects recursively
3283
- if (value.constructor === Object) {
3284
- const out: any = {};
3285
- for (const k in value) {
3286
- out[k] = this.normalizeValue(value[k]);
3287
- }
3288
- return out;
3289
- }
3290
- }
3291
- return value;
3292
- }
3293
- }
3294
- &nbsp;</pre></td></tr></table></pre>
3295
-
3296
- <div class='push'></div><!-- for sticky footer -->
3297
- </div><!-- /wrapper -->
3298
- <div class='footer quiet pad2 space-top1 center small'>
3299
- Code coverage generated by
3300
- <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
3301
- at 2026-09-09T09:49:51.780Z
3302
- </div>
3303
- <script src="../../../prettify.js"></script>
3304
- <script>
3305
- window.onload = function () {
3306
- prettyPrint();
3307
- };
3308
- </script>
3309
- <script src="../../../sorter.js"></script>
3310
- <script src="../../../block-navigation.js"></script>
3311
- </body>
3312
- </html>
3313
-