@rebasepro/server-core 0.0.1-canary.4d4fb3e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +6 -0
- package/README.md +40 -0
- package/build-errors.txt +52 -0
- package/coverage/clover.xml +3739 -0
- package/coverage/coverage-final.json +31 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +266 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/src/api/ast-schema-editor.ts.html +952 -0
- package/coverage/lcov-report/src/api/errors.ts.html +472 -0
- package/coverage/lcov-report/src/api/graphql/graphql-schema-generator.ts.html +1069 -0
- package/coverage/lcov-report/src/api/graphql/index.html +116 -0
- package/coverage/lcov-report/src/api/index.html +176 -0
- package/coverage/lcov-report/src/api/openapi-generator.ts.html +565 -0
- package/coverage/lcov-report/src/api/rest/api-generator.ts.html +994 -0
- package/coverage/lcov-report/src/api/rest/index.html +131 -0
- package/coverage/lcov-report/src/api/rest/query-parser.ts.html +550 -0
- package/coverage/lcov-report/src/api/schema-editor-routes.ts.html +202 -0
- package/coverage/lcov-report/src/api/server.ts.html +823 -0
- package/coverage/lcov-report/src/auth/admin-routes.ts.html +973 -0
- package/coverage/lcov-report/src/auth/index.html +176 -0
- package/coverage/lcov-report/src/auth/jwt.ts.html +574 -0
- package/coverage/lcov-report/src/auth/middleware.ts.html +745 -0
- package/coverage/lcov-report/src/auth/password.ts.html +310 -0
- package/coverage/lcov-report/src/auth/services.ts.html +2074 -0
- package/coverage/lcov-report/src/collections/index.html +116 -0
- package/coverage/lcov-report/src/collections/loader.ts.html +232 -0
- package/coverage/lcov-report/src/db/auth-schema.ts.html +523 -0
- package/coverage/lcov-report/src/db/data-transformer.ts.html +1753 -0
- package/coverage/lcov-report/src/db/entityService.ts.html +700 -0
- package/coverage/lcov-report/src/db/index.html +146 -0
- package/coverage/lcov-report/src/db/services/EntityFetchService.ts.html +4048 -0
- package/coverage/lcov-report/src/db/services/EntityPersistService.ts.html +883 -0
- package/coverage/lcov-report/src/db/services/RelationService.ts.html +3121 -0
- package/coverage/lcov-report/src/db/services/entity-helpers.ts.html +442 -0
- package/coverage/lcov-report/src/db/services/index.html +176 -0
- package/coverage/lcov-report/src/db/services/index.ts.html +124 -0
- package/coverage/lcov-report/src/generate-drizzle-schema-logic.ts.html +1960 -0
- package/coverage/lcov-report/src/index.html +116 -0
- package/coverage/lcov-report/src/services/driver-registry.ts.html +631 -0
- package/coverage/lcov-report/src/services/index.html +131 -0
- package/coverage/lcov-report/src/services/postgresDataDriver.ts.html +3025 -0
- package/coverage/lcov-report/src/storage/LocalStorageController.ts.html +1189 -0
- package/coverage/lcov-report/src/storage/S3StorageController.ts.html +970 -0
- package/coverage/lcov-report/src/storage/index.html +161 -0
- package/coverage/lcov-report/src/storage/storage-registry.ts.html +646 -0
- package/coverage/lcov-report/src/storage/types.ts.html +451 -0
- package/coverage/lcov-report/src/utils/drizzle-conditions.ts.html +3082 -0
- package/coverage/lcov-report/src/utils/index.html +116 -0
- package/coverage/lcov.info +7179 -0
- package/dist/common/src/collections/CollectionRegistry.d.ts +48 -0
- package/dist/common/src/collections/index.d.ts +1 -0
- package/dist/common/src/data/buildRebaseData.d.ts +14 -0
- package/dist/common/src/index.d.ts +3 -0
- package/dist/common/src/util/builders.d.ts +57 -0
- package/dist/common/src/util/callbacks.d.ts +6 -0
- package/dist/common/src/util/collections.d.ts +11 -0
- package/dist/common/src/util/common.d.ts +2 -0
- package/dist/common/src/util/conditions.d.ts +26 -0
- package/dist/common/src/util/entities.d.ts +36 -0
- package/dist/common/src/util/enums.d.ts +3 -0
- package/dist/common/src/util/index.d.ts +16 -0
- package/dist/common/src/util/navigation_from_path.d.ts +34 -0
- package/dist/common/src/util/navigation_utils.d.ts +20 -0
- package/dist/common/src/util/parent_references_from_path.d.ts +6 -0
- package/dist/common/src/util/paths.d.ts +14 -0
- package/dist/common/src/util/permissions.d.ts +5 -0
- package/dist/common/src/util/references.d.ts +2 -0
- package/dist/common/src/util/relations.d.ts +12 -0
- package/dist/common/src/util/resolutions.d.ts +72 -0
- package/dist/common/src/util/storage.d.ts +24 -0
- package/dist/index-BeMqpmfQ.js +239 -0
- package/dist/index-BeMqpmfQ.js.map +1 -0
- package/dist/index-bl4J3lNb.js +55823 -0
- package/dist/index-bl4J3lNb.js.map +1 -0
- package/dist/index.es.js +58 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +56062 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/server-core/src/api/ast-schema-editor.d.ts +21 -0
- package/dist/server-core/src/api/collections_for_test/callbacks_test_collection.d.ts +2 -0
- package/dist/server-core/src/api/errors.d.ts +35 -0
- package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts +35 -0
- package/dist/server-core/src/api/graphql/index.d.ts +1 -0
- package/dist/server-core/src/api/index.d.ts +9 -0
- package/dist/server-core/src/api/openapi-generator.d.ts +2 -0
- package/dist/server-core/src/api/rest/api-generator.d.ts +64 -0
- package/dist/server-core/src/api/rest/index.d.ts +1 -0
- package/dist/server-core/src/api/rest/query-parser.d.ts +9 -0
- package/dist/server-core/src/api/schema-editor-routes.d.ts +3 -0
- package/dist/server-core/src/api/server.d.ts +40 -0
- package/dist/server-core/src/api/types.d.ts +90 -0
- package/dist/server-core/src/auth/admin-routes.d.ts +7 -0
- package/dist/server-core/src/auth/google-oauth.d.ts +20 -0
- package/dist/server-core/src/auth/index.d.ts +12 -0
- package/dist/server-core/src/auth/interfaces.d.ts +270 -0
- package/dist/server-core/src/auth/jwt.d.ts +42 -0
- package/dist/server-core/src/auth/middleware.d.ts +56 -0
- package/dist/server-core/src/auth/password.d.ts +22 -0
- package/dist/server-core/src/auth/rate-limiter.d.ts +31 -0
- package/dist/server-core/src/auth/routes.d.ts +17 -0
- package/dist/server-core/src/bootstrappers/index.d.ts +0 -0
- package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts +13 -0
- package/dist/server-core/src/collections/loader.d.ts +5 -0
- package/dist/server-core/src/db/interfaces.d.ts +18 -0
- package/dist/server-core/src/email/index.d.ts +6 -0
- package/dist/server-core/src/email/smtp-email-service.d.ts +25 -0
- package/dist/server-core/src/email/templates.d.ts +33 -0
- package/dist/server-core/src/email/types.d.ts +110 -0
- package/dist/server-core/src/functions/function-loader.d.ts +17 -0
- package/dist/server-core/src/functions/function-routes.d.ts +10 -0
- package/dist/server-core/src/functions/index.d.ts +3 -0
- package/dist/server-core/src/history/history-routes.d.ts +23 -0
- package/dist/server-core/src/history/index.d.ts +1 -0
- package/dist/server-core/src/index.d.ts +24 -0
- package/dist/server-core/src/init.d.ts +49 -0
- package/dist/server-core/src/serve-spa.d.ts +30 -0
- package/dist/server-core/src/services/driver-registry.d.ts +78 -0
- package/dist/server-core/src/storage/LocalStorageController.d.ts +46 -0
- package/dist/server-core/src/storage/S3StorageController.d.ts +36 -0
- package/dist/server-core/src/storage/index.d.ts +18 -0
- package/dist/server-core/src/storage/routes.d.ts +38 -0
- package/dist/server-core/src/storage/storage-registry.d.ts +78 -0
- package/dist/server-core/src/storage/types.d.ts +91 -0
- package/dist/server-core/src/types/index.d.ts +11 -0
- package/dist/server-core/src/utils/logging.d.ts +9 -0
- package/dist/server-core/src/utils/sql.d.ts +27 -0
- package/dist/types/src/controllers/analytics_controller.d.ts +7 -0
- package/dist/types/src/controllers/auth.d.ts +117 -0
- package/dist/types/src/controllers/client.d.ts +58 -0
- package/dist/types/src/controllers/collection_registry.d.ts +44 -0
- package/dist/types/src/controllers/customization_controller.d.ts +54 -0
- package/dist/types/src/controllers/data.d.ts +141 -0
- package/dist/types/src/controllers/data_driver.d.ts +168 -0
- package/dist/types/src/controllers/database_admin.d.ts +11 -0
- package/dist/types/src/controllers/dialogs_controller.d.ts +36 -0
- package/dist/types/src/controllers/effective_role.d.ts +4 -0
- package/dist/types/src/controllers/index.d.ts +17 -0
- package/dist/types/src/controllers/local_config_persistence.d.ts +20 -0
- package/dist/types/src/controllers/navigation.d.ts +213 -0
- package/dist/types/src/controllers/registry.d.ts +51 -0
- package/dist/types/src/controllers/side_dialogs_controller.d.ts +67 -0
- package/dist/types/src/controllers/side_entity_controller.d.ts +89 -0
- package/dist/types/src/controllers/snackbar.d.ts +24 -0
- package/dist/types/src/controllers/storage.d.ts +173 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/rebase_context.d.ts +101 -0
- package/dist/types/src/types/backend.d.ts +533 -0
- package/dist/types/src/types/builders.d.ts +14 -0
- package/dist/types/src/types/chips.d.ts +5 -0
- package/dist/types/src/types/collections.d.ts +812 -0
- package/dist/types/src/types/data_source.d.ts +64 -0
- package/dist/types/src/types/entities.d.ts +145 -0
- package/dist/types/src/types/entity_actions.d.ts +98 -0
- package/dist/types/src/types/entity_callbacks.d.ts +173 -0
- package/dist/types/src/types/entity_link_builder.d.ts +7 -0
- package/dist/types/src/types/entity_overrides.d.ts +9 -0
- package/dist/types/src/types/entity_views.d.ts +61 -0
- package/dist/types/src/types/export_import.d.ts +21 -0
- package/dist/types/src/types/index.d.ts +22 -0
- package/dist/types/src/types/locales.d.ts +4 -0
- package/dist/types/src/types/modify_collections.d.ts +5 -0
- package/dist/types/src/types/plugins.d.ts +225 -0
- package/dist/types/src/types/properties.d.ts +1091 -0
- package/dist/types/src/types/property_config.d.ts +70 -0
- package/dist/types/src/types/relations.d.ts +336 -0
- package/dist/types/src/types/slots.d.ts +228 -0
- package/dist/types/src/types/translations.d.ts +826 -0
- package/dist/types/src/types/user_management_delegate.d.ts +120 -0
- package/dist/types/src/types/websockets.d.ts +78 -0
- package/dist/types/src/users/index.d.ts +2 -0
- package/dist/types/src/users/roles.d.ts +22 -0
- package/dist/types/src/users/user.d.ts +46 -0
- package/history_diff.log +385 -0
- package/jest.config.cjs +16 -0
- package/package.json +86 -0
- package/scratch.ts +8 -0
- package/src/api/ast-schema-editor.ts +289 -0
- package/src/api/collections_for_test/callbacks_test_collection.ts +57 -0
- package/src/api/errors.ts +155 -0
- package/src/api/graphql/graphql-schema-generator.ts +334 -0
- package/src/api/graphql/index.ts +2 -0
- package/src/api/index.ts +11 -0
- package/src/api/openapi-generator.ts +160 -0
- package/src/api/rest/api-generator.ts +466 -0
- package/src/api/rest/index.ts +2 -0
- package/src/api/rest/query-parser.ts +155 -0
- package/src/api/schema-editor-routes.ts +39 -0
- package/src/api/server.ts +245 -0
- package/src/api/types.ts +90 -0
- package/src/auth/admin-routes.ts +488 -0
- package/src/auth/google-oauth.ts +60 -0
- package/src/auth/index.ts +21 -0
- package/src/auth/interfaces.ts +316 -0
- package/src/auth/jwt.ts +164 -0
- package/src/auth/middleware.ts +235 -0
- package/src/auth/password.ts +75 -0
- package/src/auth/rate-limiter.ts +129 -0
- package/src/auth/routes.ts +730 -0
- package/src/bootstrappers/index.ts +1 -0
- package/src/collections/BackendCollectionRegistry.ts +20 -0
- package/src/collections/loader.ts +49 -0
- package/src/db/interfaces.ts +60 -0
- package/src/email/index.ts +17 -0
- package/src/email/smtp-email-service.ts +88 -0
- package/src/email/templates.ts +301 -0
- package/src/email/types.ts +112 -0
- package/src/functions/function-loader.ts +91 -0
- package/src/functions/function-routes.ts +31 -0
- package/src/functions/index.ts +3 -0
- package/src/history/history-routes.ts +128 -0
- package/src/history/index.ts +2 -0
- package/src/index.ts +56 -0
- package/src/init.ts +309 -0
- package/src/serve-spa.ts +81 -0
- package/src/services/driver-registry.ts +182 -0
- package/src/storage/LocalStorageController.ts +368 -0
- package/src/storage/S3StorageController.ts +295 -0
- package/src/storage/index.ts +32 -0
- package/src/storage/routes.ts +247 -0
- package/src/storage/storage-registry.ts +187 -0
- package/src/storage/types.ts +122 -0
- package/src/types/index.ts +27 -0
- package/src/utils/logging.ts +35 -0
- package/src/utils/sql.ts +38 -0
- package/test/admin-routes.test.ts +591 -0
- package/test/api-generator.test.ts +458 -0
- package/test/ast-schema-editor.test.ts +61 -0
- package/test/auth-middleware-hono.test.ts +321 -0
- package/test/auth-routes.test.ts +868 -0
- package/test/driver-registry.test.ts +280 -0
- package/test/errors-hono.test.ts +133 -0
- package/test/errors.test.ts +150 -0
- package/test/jwt-security.test.ts +173 -0
- package/test/jwt.test.ts +311 -0
- package/test/middleware.test.ts +295 -0
- package/test/password.test.ts +165 -0
- package/test/query-parser.test.ts +258 -0
- package/test/rate-limiter.test.ts +102 -0
- package/test/storage-local.test.ts +278 -0
- package/test/storage-registry.test.ts +280 -0
- package/test/storage-routes.test.ts +218 -0
- package/test/storage-s3.test.ts +301 -0
- package/test-ast.ts +28 -0
- package/test_output.txt +1133 -0
- package/tsconfig.json +49 -0
- package/tsconfig.prod.json +20 -0
- package/vite.config.ts +78 -0
- package/vite.config.ts.timestamp-1775065397568-8a853255edf6e.mjs +46 -0
|
@@ -0,0 +1,1960 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for src/generate-drizzle-schema-logic.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</a> generate-drizzle-schema-logic.ts</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">84.7% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>288/340</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">73.07% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>190/260</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">86.11% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>31/36</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">84.54% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>268/317</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
<p class="quiet">
|
|
55
|
+
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
+
</p>
|
|
57
|
+
<template id="filterTemplate">
|
|
58
|
+
<div class="quiet">
|
|
59
|
+
Filter:
|
|
60
|
+
<input type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line high'></div>
|
|
65
|
+
<pre><table class="coverage">
|
|
66
|
+
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
+
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
+
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
+
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
+
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
+
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
+
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
+
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
+
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
+
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
+
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
+
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
+
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
+
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
+
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
+
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
+
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
+
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
+
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
+
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
+
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
+
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
+
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
+
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
+
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
+
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
+
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
+
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
+
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
+
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
+
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
+
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
+
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
+
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
+
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
+
<a name='L36'></a><a href='#L36'>36</a>
|
|
102
|
+
<a name='L37'></a><a href='#L37'>37</a>
|
|
103
|
+
<a name='L38'></a><a href='#L38'>38</a>
|
|
104
|
+
<a name='L39'></a><a href='#L39'>39</a>
|
|
105
|
+
<a name='L40'></a><a href='#L40'>40</a>
|
|
106
|
+
<a name='L41'></a><a href='#L41'>41</a>
|
|
107
|
+
<a name='L42'></a><a href='#L42'>42</a>
|
|
108
|
+
<a name='L43'></a><a href='#L43'>43</a>
|
|
109
|
+
<a name='L44'></a><a href='#L44'>44</a>
|
|
110
|
+
<a name='L45'></a><a href='#L45'>45</a>
|
|
111
|
+
<a name='L46'></a><a href='#L46'>46</a>
|
|
112
|
+
<a name='L47'></a><a href='#L47'>47</a>
|
|
113
|
+
<a name='L48'></a><a href='#L48'>48</a>
|
|
114
|
+
<a name='L49'></a><a href='#L49'>49</a>
|
|
115
|
+
<a name='L50'></a><a href='#L50'>50</a>
|
|
116
|
+
<a name='L51'></a><a href='#L51'>51</a>
|
|
117
|
+
<a name='L52'></a><a href='#L52'>52</a>
|
|
118
|
+
<a name='L53'></a><a href='#L53'>53</a>
|
|
119
|
+
<a name='L54'></a><a href='#L54'>54</a>
|
|
120
|
+
<a name='L55'></a><a href='#L55'>55</a>
|
|
121
|
+
<a name='L56'></a><a href='#L56'>56</a>
|
|
122
|
+
<a name='L57'></a><a href='#L57'>57</a>
|
|
123
|
+
<a name='L58'></a><a href='#L58'>58</a>
|
|
124
|
+
<a name='L59'></a><a href='#L59'>59</a>
|
|
125
|
+
<a name='L60'></a><a href='#L60'>60</a>
|
|
126
|
+
<a name='L61'></a><a href='#L61'>61</a>
|
|
127
|
+
<a name='L62'></a><a href='#L62'>62</a>
|
|
128
|
+
<a name='L63'></a><a href='#L63'>63</a>
|
|
129
|
+
<a name='L64'></a><a href='#L64'>64</a>
|
|
130
|
+
<a name='L65'></a><a href='#L65'>65</a>
|
|
131
|
+
<a name='L66'></a><a href='#L66'>66</a>
|
|
132
|
+
<a name='L67'></a><a href='#L67'>67</a>
|
|
133
|
+
<a name='L68'></a><a href='#L68'>68</a>
|
|
134
|
+
<a name='L69'></a><a href='#L69'>69</a>
|
|
135
|
+
<a name='L70'></a><a href='#L70'>70</a>
|
|
136
|
+
<a name='L71'></a><a href='#L71'>71</a>
|
|
137
|
+
<a name='L72'></a><a href='#L72'>72</a>
|
|
138
|
+
<a name='L73'></a><a href='#L73'>73</a>
|
|
139
|
+
<a name='L74'></a><a href='#L74'>74</a>
|
|
140
|
+
<a name='L75'></a><a href='#L75'>75</a>
|
|
141
|
+
<a name='L76'></a><a href='#L76'>76</a>
|
|
142
|
+
<a name='L77'></a><a href='#L77'>77</a>
|
|
143
|
+
<a name='L78'></a><a href='#L78'>78</a>
|
|
144
|
+
<a name='L79'></a><a href='#L79'>79</a>
|
|
145
|
+
<a name='L80'></a><a href='#L80'>80</a>
|
|
146
|
+
<a name='L81'></a><a href='#L81'>81</a>
|
|
147
|
+
<a name='L82'></a><a href='#L82'>82</a>
|
|
148
|
+
<a name='L83'></a><a href='#L83'>83</a>
|
|
149
|
+
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
|
+
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
|
+
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
+
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
+
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
+
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
+
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
+
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
+
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
+
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
+
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
+
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
+
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
+
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
+
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
+
<a name='L99'></a><a href='#L99'>99</a>
|
|
165
|
+
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
+
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
+
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
+
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
+
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
+
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
+
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
+
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
+
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
+
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
+
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
+
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
+
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
+
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
+
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
+
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
+
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
+
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
+
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
|
+
<a name='L119'></a><a href='#L119'>119</a>
|
|
185
|
+
<a name='L120'></a><a href='#L120'>120</a>
|
|
186
|
+
<a name='L121'></a><a href='#L121'>121</a>
|
|
187
|
+
<a name='L122'></a><a href='#L122'>122</a>
|
|
188
|
+
<a name='L123'></a><a href='#L123'>123</a>
|
|
189
|
+
<a name='L124'></a><a href='#L124'>124</a>
|
|
190
|
+
<a name='L125'></a><a href='#L125'>125</a>
|
|
191
|
+
<a name='L126'></a><a href='#L126'>126</a>
|
|
192
|
+
<a name='L127'></a><a href='#L127'>127</a>
|
|
193
|
+
<a name='L128'></a><a href='#L128'>128</a>
|
|
194
|
+
<a name='L129'></a><a href='#L129'>129</a>
|
|
195
|
+
<a name='L130'></a><a href='#L130'>130</a>
|
|
196
|
+
<a name='L131'></a><a href='#L131'>131</a>
|
|
197
|
+
<a name='L132'></a><a href='#L132'>132</a>
|
|
198
|
+
<a name='L133'></a><a href='#L133'>133</a>
|
|
199
|
+
<a name='L134'></a><a href='#L134'>134</a>
|
|
200
|
+
<a name='L135'></a><a href='#L135'>135</a>
|
|
201
|
+
<a name='L136'></a><a href='#L136'>136</a>
|
|
202
|
+
<a name='L137'></a><a href='#L137'>137</a>
|
|
203
|
+
<a name='L138'></a><a href='#L138'>138</a>
|
|
204
|
+
<a name='L139'></a><a href='#L139'>139</a>
|
|
205
|
+
<a name='L140'></a><a href='#L140'>140</a>
|
|
206
|
+
<a name='L141'></a><a href='#L141'>141</a>
|
|
207
|
+
<a name='L142'></a><a href='#L142'>142</a>
|
|
208
|
+
<a name='L143'></a><a href='#L143'>143</a>
|
|
209
|
+
<a name='L144'></a><a href='#L144'>144</a>
|
|
210
|
+
<a name='L145'></a><a href='#L145'>145</a>
|
|
211
|
+
<a name='L146'></a><a href='#L146'>146</a>
|
|
212
|
+
<a name='L147'></a><a href='#L147'>147</a>
|
|
213
|
+
<a name='L148'></a><a href='#L148'>148</a>
|
|
214
|
+
<a name='L149'></a><a href='#L149'>149</a>
|
|
215
|
+
<a name='L150'></a><a href='#L150'>150</a>
|
|
216
|
+
<a name='L151'></a><a href='#L151'>151</a>
|
|
217
|
+
<a name='L152'></a><a href='#L152'>152</a>
|
|
218
|
+
<a name='L153'></a><a href='#L153'>153</a>
|
|
219
|
+
<a name='L154'></a><a href='#L154'>154</a>
|
|
220
|
+
<a name='L155'></a><a href='#L155'>155</a>
|
|
221
|
+
<a name='L156'></a><a href='#L156'>156</a>
|
|
222
|
+
<a name='L157'></a><a href='#L157'>157</a>
|
|
223
|
+
<a name='L158'></a><a href='#L158'>158</a>
|
|
224
|
+
<a name='L159'></a><a href='#L159'>159</a>
|
|
225
|
+
<a name='L160'></a><a href='#L160'>160</a>
|
|
226
|
+
<a name='L161'></a><a href='#L161'>161</a>
|
|
227
|
+
<a name='L162'></a><a href='#L162'>162</a>
|
|
228
|
+
<a name='L163'></a><a href='#L163'>163</a>
|
|
229
|
+
<a name='L164'></a><a href='#L164'>164</a>
|
|
230
|
+
<a name='L165'></a><a href='#L165'>165</a>
|
|
231
|
+
<a name='L166'></a><a href='#L166'>166</a>
|
|
232
|
+
<a name='L167'></a><a href='#L167'>167</a>
|
|
233
|
+
<a name='L168'></a><a href='#L168'>168</a>
|
|
234
|
+
<a name='L169'></a><a href='#L169'>169</a>
|
|
235
|
+
<a name='L170'></a><a href='#L170'>170</a>
|
|
236
|
+
<a name='L171'></a><a href='#L171'>171</a>
|
|
237
|
+
<a name='L172'></a><a href='#L172'>172</a>
|
|
238
|
+
<a name='L173'></a><a href='#L173'>173</a>
|
|
239
|
+
<a name='L174'></a><a href='#L174'>174</a>
|
|
240
|
+
<a name='L175'></a><a href='#L175'>175</a>
|
|
241
|
+
<a name='L176'></a><a href='#L176'>176</a>
|
|
242
|
+
<a name='L177'></a><a href='#L177'>177</a>
|
|
243
|
+
<a name='L178'></a><a href='#L178'>178</a>
|
|
244
|
+
<a name='L179'></a><a href='#L179'>179</a>
|
|
245
|
+
<a name='L180'></a><a href='#L180'>180</a>
|
|
246
|
+
<a name='L181'></a><a href='#L181'>181</a>
|
|
247
|
+
<a name='L182'></a><a href='#L182'>182</a>
|
|
248
|
+
<a name='L183'></a><a href='#L183'>183</a>
|
|
249
|
+
<a name='L184'></a><a href='#L184'>184</a>
|
|
250
|
+
<a name='L185'></a><a href='#L185'>185</a>
|
|
251
|
+
<a name='L186'></a><a href='#L186'>186</a>
|
|
252
|
+
<a name='L187'></a><a href='#L187'>187</a>
|
|
253
|
+
<a name='L188'></a><a href='#L188'>188</a>
|
|
254
|
+
<a name='L189'></a><a href='#L189'>189</a>
|
|
255
|
+
<a name='L190'></a><a href='#L190'>190</a>
|
|
256
|
+
<a name='L191'></a><a href='#L191'>191</a>
|
|
257
|
+
<a name='L192'></a><a href='#L192'>192</a>
|
|
258
|
+
<a name='L193'></a><a href='#L193'>193</a>
|
|
259
|
+
<a name='L194'></a><a href='#L194'>194</a>
|
|
260
|
+
<a name='L195'></a><a href='#L195'>195</a>
|
|
261
|
+
<a name='L196'></a><a href='#L196'>196</a>
|
|
262
|
+
<a name='L197'></a><a href='#L197'>197</a>
|
|
263
|
+
<a name='L198'></a><a href='#L198'>198</a>
|
|
264
|
+
<a name='L199'></a><a href='#L199'>199</a>
|
|
265
|
+
<a name='L200'></a><a href='#L200'>200</a>
|
|
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></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
692
|
+
<span class="cline-any cline-neutral"> </span>
|
|
693
|
+
<span class="cline-any cline-yes">2x</span>
|
|
694
|
+
<span class="cline-any cline-neutral"> </span>
|
|
695
|
+
<span class="cline-any cline-neutral"> </span>
|
|
696
|
+
<span class="cline-any cline-neutral"> </span>
|
|
697
|
+
<span class="cline-any cline-neutral"> </span>
|
|
698
|
+
<span class="cline-any cline-neutral"> </span>
|
|
699
|
+
<span class="cline-any cline-neutral"> </span>
|
|
700
|
+
<span class="cline-any cline-neutral"> </span>
|
|
701
|
+
<span class="cline-any cline-neutral"> </span>
|
|
702
|
+
<span class="cline-any cline-neutral"> </span>
|
|
703
|
+
<span class="cline-any cline-yes">2x</span>
|
|
704
|
+
<span class="cline-any cline-yes">43x</span>
|
|
705
|
+
<span class="cline-any cline-yes">65x</span>
|
|
706
|
+
<span class="cline-any cline-yes">43x</span>
|
|
707
|
+
<span class="cline-any cline-yes">3x</span>
|
|
708
|
+
<span class="cline-any cline-neutral"> </span>
|
|
709
|
+
<span class="cline-any cline-neutral"> </span>
|
|
710
|
+
<span class="cline-any cline-neutral"> </span>
|
|
711
|
+
<span class="cline-any cline-yes">40x</span>
|
|
712
|
+
<span class="cline-any cline-yes">40x</span>
|
|
713
|
+
<span class="cline-any cline-no"> </span>
|
|
714
|
+
<span class="cline-any cline-neutral"> </span>
|
|
715
|
+
<span class="cline-any cline-yes">40x</span>
|
|
716
|
+
<span class="cline-any cline-neutral"> </span>
|
|
717
|
+
<span class="cline-any cline-neutral"> </span>
|
|
718
|
+
<span class="cline-any cline-yes">2x</span>
|
|
719
|
+
<span class="cline-any cline-yes">14x</span>
|
|
720
|
+
<span class="cline-any cline-neutral"> </span>
|
|
721
|
+
<span class="cline-any cline-neutral"> </span>
|
|
722
|
+
<span class="cline-any cline-yes">2x</span>
|
|
723
|
+
<span class="cline-any cline-yes">29x</span>
|
|
724
|
+
<span class="cline-any cline-neutral"> </span>
|
|
725
|
+
<span class="cline-any cline-neutral"> </span>
|
|
726
|
+
<span class="cline-any cline-yes">2x</span>
|
|
727
|
+
<span class="cline-any cline-yes">86x</span>
|
|
728
|
+
<span class="cline-any cline-neutral"> </span>
|
|
729
|
+
<span class="cline-any cline-neutral"> </span>
|
|
730
|
+
<span class="cline-any cline-yes">175x</span>
|
|
731
|
+
<span class="cline-any cline-yes">77x</span>
|
|
732
|
+
<span class="cline-any cline-neutral"> </span>
|
|
733
|
+
<span class="cline-any cline-neutral"> </span>
|
|
734
|
+
<span class="cline-any cline-yes">2x</span>
|
|
735
|
+
<span class="cline-any cline-yes">114x</span>
|
|
736
|
+
<span class="cline-any cline-neutral"> </span>
|
|
737
|
+
<span class="cline-any cline-neutral"> </span>
|
|
738
|
+
<span class="cline-any cline-yes">114x</span>
|
|
739
|
+
<span class="cline-any cline-neutral"> </span>
|
|
740
|
+
<span class="cline-any cline-yes">68x</span>
|
|
741
|
+
<span class="cline-any cline-yes">68x</span>
|
|
742
|
+
<span class="cline-any cline-no"> </span>
|
|
743
|
+
<span class="cline-any cline-no"> </span>
|
|
744
|
+
<span class="cline-any cline-yes">68x</span>
|
|
745
|
+
<span class="cline-any cline-yes">2x</span>
|
|
746
|
+
<span class="cline-any cline-yes">66x</span>
|
|
747
|
+
<span class="cline-any cline-yes">2x</span>
|
|
748
|
+
<span class="cline-any cline-yes">64x</span>
|
|
749
|
+
<span class="cline-any cline-yes">2x</span>
|
|
750
|
+
<span class="cline-any cline-neutral"> </span>
|
|
751
|
+
<span class="cline-any cline-yes">62x</span>
|
|
752
|
+
<span class="cline-any cline-neutral"> </span>
|
|
753
|
+
<span class="cline-any cline-yes">68x</span>
|
|
754
|
+
<span class="cline-any cline-yes">6x</span>
|
|
755
|
+
<span class="cline-any cline-neutral"> </span>
|
|
756
|
+
<span class="cline-any cline-yes">68x</span>
|
|
757
|
+
<span class="cline-any cline-yes">3x</span>
|
|
758
|
+
<span class="cline-any cline-yes">2x</span>
|
|
759
|
+
<span class="cline-any cline-yes">1x</span>
|
|
760
|
+
<span class="cline-any cline-no"> </span>
|
|
761
|
+
<span class="cline-any cline-yes">1x</span>
|
|
762
|
+
<span class="cline-any cline-yes">1x</span>
|
|
763
|
+
<span class="cline-any cline-neutral"> </span>
|
|
764
|
+
<span class="cline-any cline-neutral"> </span>
|
|
765
|
+
<span class="cline-any cline-yes">1x</span>
|
|
766
|
+
<span class="cline-any cline-neutral"> </span>
|
|
767
|
+
<span class="cline-any cline-neutral"> </span>
|
|
768
|
+
<span class="cline-any cline-yes">68x</span>
|
|
769
|
+
<span class="cline-any cline-yes">1x</span>
|
|
770
|
+
<span class="cline-any cline-neutral"> </span>
|
|
771
|
+
<span class="cline-any cline-yes">68x</span>
|
|
772
|
+
<span class="cline-any cline-neutral"> </span>
|
|
773
|
+
<span class="cline-any cline-neutral"> </span>
|
|
774
|
+
<span class="cline-any cline-yes">18x</span>
|
|
775
|
+
<span class="cline-any cline-yes">18x</span>
|
|
776
|
+
<span class="cline-any cline-neutral"> </span>
|
|
777
|
+
<span class="cline-any cline-yes">18x</span>
|
|
778
|
+
<span class="cline-any cline-yes">18x</span>
|
|
779
|
+
<span class="cline-any cline-yes">9x</span>
|
|
780
|
+
<span class="cline-any cline-yes">8x</span>
|
|
781
|
+
<span class="cline-any cline-neutral"> </span>
|
|
782
|
+
<span class="cline-any cline-neutral"> </span>
|
|
783
|
+
<span class="cline-any cline-yes">18x</span>
|
|
784
|
+
<span class="cline-any cline-yes">2x</span>
|
|
785
|
+
<span class="cline-any cline-yes">16x</span>
|
|
786
|
+
<span class="cline-any cline-no"> </span>
|
|
787
|
+
<span class="cline-any cline-no"> </span>
|
|
788
|
+
<span class="cline-any cline-neutral"> </span>
|
|
789
|
+
<span class="cline-any cline-neutral"> </span>
|
|
790
|
+
<span class="cline-any cline-no"> </span>
|
|
791
|
+
<span class="cline-any cline-neutral"> </span>
|
|
792
|
+
<span class="cline-any cline-yes">16x</span>
|
|
793
|
+
<span class="cline-any cline-neutral"> </span>
|
|
794
|
+
<span class="cline-any cline-neutral"> </span>
|
|
795
|
+
<span class="cline-any cline-yes">18x</span>
|
|
796
|
+
<span class="cline-any cline-yes">3x</span>
|
|
797
|
+
<span class="cline-any cline-neutral"> </span>
|
|
798
|
+
<span class="cline-any cline-yes">18x</span>
|
|
799
|
+
<span class="cline-any cline-yes">1x</span>
|
|
800
|
+
<span class="cline-any cline-neutral"> </span>
|
|
801
|
+
<span class="cline-any cline-yes">18x</span>
|
|
802
|
+
<span class="cline-any cline-neutral"> </span>
|
|
803
|
+
<span class="cline-any cline-neutral"> </span>
|
|
804
|
+
<span class="cline-any cline-yes">3x</span>
|
|
805
|
+
<span class="cline-any cline-yes">3x</span>
|
|
806
|
+
<span class="cline-any cline-neutral"> </span>
|
|
807
|
+
<span class="cline-any cline-yes">5x</span>
|
|
808
|
+
<span class="cline-any cline-yes">5x</span>
|
|
809
|
+
<span class="cline-any cline-yes">1x</span>
|
|
810
|
+
<span class="cline-any cline-yes">4x</span>
|
|
811
|
+
<span class="cline-any cline-yes">1x</span>
|
|
812
|
+
<span class="cline-any cline-neutral"> </span>
|
|
813
|
+
<span class="cline-any cline-yes">3x</span>
|
|
814
|
+
<span class="cline-any cline-neutral"> </span>
|
|
815
|
+
<span class="cline-any cline-yes">5x</span>
|
|
816
|
+
<span class="cline-any cline-neutral"> </span>
|
|
817
|
+
<span class="cline-any cline-neutral"> </span>
|
|
818
|
+
<span class="cline-any cline-neutral"> </span>
|
|
819
|
+
<span class="cline-any cline-yes">6x</span>
|
|
820
|
+
<span class="cline-any cline-yes">6x</span>
|
|
821
|
+
<span class="cline-any cline-yes">2x</span>
|
|
822
|
+
<span class="cline-any cline-neutral"> </span>
|
|
823
|
+
<span class="cline-any cline-yes">4x</span>
|
|
824
|
+
<span class="cline-any cline-neutral"> </span>
|
|
825
|
+
<span class="cline-any cline-yes">6x</span>
|
|
826
|
+
<span class="cline-any cline-neutral"> </span>
|
|
827
|
+
<span class="cline-any cline-neutral"> </span>
|
|
828
|
+
<span class="cline-any cline-yes">14x</span>
|
|
829
|
+
<span class="cline-any cline-yes">14x</span>
|
|
830
|
+
<span class="cline-any cline-yes">14x</span>
|
|
831
|
+
<span class="cline-any cline-neutral"> </span>
|
|
832
|
+
<span class="cline-any cline-neutral"> </span>
|
|
833
|
+
<span class="cline-any cline-yes">14x</span>
|
|
834
|
+
<span class="cline-any cline-yes">8x</span>
|
|
835
|
+
<span class="cline-any cline-neutral"> </span>
|
|
836
|
+
<span class="cline-any cline-neutral"> </span>
|
|
837
|
+
<span class="cline-any cline-neutral"> </span>
|
|
838
|
+
<span class="cline-any cline-yes">6x</span>
|
|
839
|
+
<span class="cline-any cline-no"> </span>
|
|
840
|
+
<span class="cline-any cline-no"> </span>
|
|
841
|
+
<span class="cline-any cline-neutral"> </span>
|
|
842
|
+
<span class="cline-any cline-neutral"> </span>
|
|
843
|
+
<span class="cline-any cline-neutral"> </span>
|
|
844
|
+
<span class="cline-any cline-neutral"> </span>
|
|
845
|
+
<span class="cline-any cline-yes">6x</span>
|
|
846
|
+
<span class="cline-any cline-no"> </span>
|
|
847
|
+
<span class="cline-any cline-neutral"> </span>
|
|
848
|
+
<span class="cline-any cline-neutral"> </span>
|
|
849
|
+
<span class="cline-any cline-neutral"> </span>
|
|
850
|
+
<span class="cline-any cline-yes">6x</span>
|
|
851
|
+
<span class="cline-any cline-yes">6x</span>
|
|
852
|
+
<span class="cline-any cline-neutral"> </span>
|
|
853
|
+
<span class="cline-any cline-no"> </span>
|
|
854
|
+
<span class="cline-any cline-neutral"> </span>
|
|
855
|
+
<span class="cline-any cline-neutral"> </span>
|
|
856
|
+
<span class="cline-any cline-yes">6x</span>
|
|
857
|
+
<span class="cline-any cline-yes">6x</span>
|
|
858
|
+
<span class="cline-any cline-yes">6x</span>
|
|
859
|
+
<span class="cline-any cline-yes">6x</span>
|
|
860
|
+
<span class="cline-any cline-neutral"> </span>
|
|
861
|
+
<span class="cline-any cline-yes">6x</span>
|
|
862
|
+
<span class="cline-any cline-yes">6x</span>
|
|
863
|
+
<span class="cline-any cline-yes">6x</span>
|
|
864
|
+
<span class="cline-any cline-yes">6x</span>
|
|
865
|
+
<span class="cline-any cline-neutral"> </span>
|
|
866
|
+
<span class="cline-any cline-yes">6x</span>
|
|
867
|
+
<span class="cline-any cline-yes">6x</span>
|
|
868
|
+
<span class="cline-any cline-neutral"> </span>
|
|
869
|
+
<span class="cline-any cline-yes">6x</span>
|
|
870
|
+
<span class="cline-any cline-neutral"> </span>
|
|
871
|
+
<span class="cline-any cline-yes">6x</span>
|
|
872
|
+
<span class="cline-any cline-no"> </span>
|
|
873
|
+
<span class="cline-any cline-neutral"> </span>
|
|
874
|
+
<span class="cline-any cline-neutral"> </span>
|
|
875
|
+
<span class="cline-any cline-yes">6x</span>
|
|
876
|
+
<span class="cline-any cline-neutral"> </span>
|
|
877
|
+
<span class="cline-any cline-neutral"> </span>
|
|
878
|
+
<span class="cline-any cline-no"> </span>
|
|
879
|
+
<span class="cline-any cline-neutral"> </span>
|
|
880
|
+
<span class="cline-any cline-neutral"> </span>
|
|
881
|
+
<span class="cline-any cline-yes">100x</span>
|
|
882
|
+
<span class="cline-any cline-yes">2x</span>
|
|
883
|
+
<span class="cline-any cline-neutral"> </span>
|
|
884
|
+
<span class="cline-any cline-neutral"> </span>
|
|
885
|
+
<span class="cline-any cline-yes">100x</span>
|
|
886
|
+
<span class="cline-any cline-neutral"> </span>
|
|
887
|
+
<span class="cline-any cline-neutral"> </span>
|
|
888
|
+
<span class="cline-any cline-neutral"> </span>
|
|
889
|
+
<span class="cline-any cline-neutral"> </span>
|
|
890
|
+
<span class="cline-any cline-neutral"> </span>
|
|
891
|
+
<span class="cline-any cline-neutral"> </span>
|
|
892
|
+
<span class="cline-any cline-yes">2x</span>
|
|
893
|
+
<span class="cline-any cline-neutral"> </span>
|
|
894
|
+
<span class="cline-any cline-yes">8x</span>
|
|
895
|
+
<span class="cline-any cline-yes">8x</span>
|
|
896
|
+
<span class="cline-any cline-neutral"> </span>
|
|
897
|
+
<span class="cline-any cline-neutral"> </span>
|
|
898
|
+
<span class="cline-any cline-neutral"> </span>
|
|
899
|
+
<span class="cline-any cline-neutral"> </span>
|
|
900
|
+
<span class="cline-any cline-neutral"> </span>
|
|
901
|
+
<span class="cline-any cline-neutral"> </span>
|
|
902
|
+
<span class="cline-any cline-yes">2x</span>
|
|
903
|
+
<span class="cline-any cline-yes">5x</span>
|
|
904
|
+
<span class="cline-any cline-yes">4x</span>
|
|
905
|
+
<span class="cline-any cline-yes">4x</span>
|
|
906
|
+
<span class="cline-any cline-neutral"> </span>
|
|
907
|
+
<span class="cline-any cline-neutral"> </span>
|
|
908
|
+
<span class="cline-any cline-neutral"> </span>
|
|
909
|
+
<span class="cline-any cline-neutral"> </span>
|
|
910
|
+
<span class="cline-any cline-neutral"> </span>
|
|
911
|
+
<span class="cline-any cline-yes">2x</span>
|
|
912
|
+
<span class="cline-any cline-yes">4x</span>
|
|
913
|
+
<span class="cline-any cline-yes">4x</span>
|
|
914
|
+
<span class="cline-any cline-neutral"> </span>
|
|
915
|
+
<span class="cline-any cline-neutral"> </span>
|
|
916
|
+
<span class="cline-any cline-neutral"> </span>
|
|
917
|
+
<span class="cline-any cline-neutral"> </span>
|
|
918
|
+
<span class="cline-any cline-neutral"> </span>
|
|
919
|
+
<span class="cline-any cline-yes">2x</span>
|
|
920
|
+
<span class="cline-any cline-yes">35x</span>
|
|
921
|
+
<span class="cline-any cline-yes">7x</span>
|
|
922
|
+
<span class="cline-any cline-neutral"> </span>
|
|
923
|
+
<span class="cline-any cline-yes">28x</span>
|
|
924
|
+
<span class="cline-any cline-yes">12x</span>
|
|
925
|
+
<span class="cline-any cline-neutral"> </span>
|
|
926
|
+
<span class="cline-any cline-yes">16x</span>
|
|
927
|
+
<span class="cline-any cline-yes">12x</span>
|
|
928
|
+
<span class="cline-any cline-neutral"> </span>
|
|
929
|
+
<span class="cline-any cline-yes">4x</span>
|
|
930
|
+
<span class="cline-any cline-neutral"> </span>
|
|
931
|
+
<span class="cline-any cline-neutral"> </span>
|
|
932
|
+
<span class="cline-any cline-neutral"> </span>
|
|
933
|
+
<span class="cline-any cline-neutral"> </span>
|
|
934
|
+
<span class="cline-any cline-neutral"> </span>
|
|
935
|
+
<span class="cline-any cline-neutral"> </span>
|
|
936
|
+
<span class="cline-any cline-yes">2x</span>
|
|
937
|
+
<span class="cline-any cline-yes">9x</span>
|
|
938
|
+
<span class="cline-any cline-yes">1x</span>
|
|
939
|
+
<span class="cline-any cline-neutral"> </span>
|
|
940
|
+
<span class="cline-any cline-neutral"> </span>
|
|
941
|
+
<span class="cline-any cline-yes">8x</span>
|
|
942
|
+
<span class="cline-any cline-neutral"> </span>
|
|
943
|
+
<span class="cline-any cline-neutral"> </span>
|
|
944
|
+
<span class="cline-any cline-neutral"> </span>
|
|
945
|
+
<span class="cline-any cline-neutral"> </span>
|
|
946
|
+
<span class="cline-any cline-neutral"> </span>
|
|
947
|
+
<span class="cline-any cline-neutral"> </span>
|
|
948
|
+
<span class="cline-any cline-neutral"> </span>
|
|
949
|
+
<span class="cline-any cline-neutral"> </span>
|
|
950
|
+
<span class="cline-any cline-neutral"> </span>
|
|
951
|
+
<span class="cline-any cline-neutral"> </span>
|
|
952
|
+
<span class="cline-any cline-neutral"> </span>
|
|
953
|
+
<span class="cline-any cline-neutral"> </span>
|
|
954
|
+
<span class="cline-any cline-yes">2x</span>
|
|
955
|
+
<span class="cline-any cline-neutral"> </span>
|
|
956
|
+
<span class="cline-any cline-yes">27x</span>
|
|
957
|
+
<span class="cline-any cline-neutral"> </span>
|
|
958
|
+
<span class="cline-any cline-neutral"> </span>
|
|
959
|
+
<span class="cline-any cline-neutral"> </span>
|
|
960
|
+
<span class="cline-any cline-neutral"> </span>
|
|
961
|
+
<span class="cline-any cline-yes">27x</span>
|
|
962
|
+
<span class="cline-any cline-yes">31x</span>
|
|
963
|
+
<span class="cline-any cline-neutral"> </span>
|
|
964
|
+
<span class="cline-any cline-neutral"> </span>
|
|
965
|
+
<span class="cline-any cline-neutral"> </span>
|
|
966
|
+
<span class="cline-any cline-yes">31x</span>
|
|
967
|
+
<span class="cline-any cline-neutral"> </span>
|
|
968
|
+
<span class="cline-any cline-neutral"> </span>
|
|
969
|
+
<span class="cline-any cline-neutral"> </span>
|
|
970
|
+
<span class="cline-any cline-neutral"> </span>
|
|
971
|
+
<span class="cline-any cline-neutral"> </span>
|
|
972
|
+
<span class="cline-any cline-neutral"> </span>
|
|
973
|
+
<span class="cline-any cline-yes">2x</span>
|
|
974
|
+
<span class="cline-any cline-yes">31x</span>
|
|
975
|
+
<span class="cline-any cline-yes">31x</span>
|
|
976
|
+
<span class="cline-any cline-neutral"> </span>
|
|
977
|
+
<span class="cline-any cline-neutral"> </span>
|
|
978
|
+
<span class="cline-any cline-neutral"> </span>
|
|
979
|
+
<span class="cline-any cline-neutral"> </span>
|
|
980
|
+
<span class="cline-any cline-neutral"> </span>
|
|
981
|
+
<span class="cline-any cline-yes">31x</span>
|
|
982
|
+
<span class="cline-any cline-yes">31x</span>
|
|
983
|
+
<span class="cline-any cline-neutral"> </span>
|
|
984
|
+
<span class="cline-any cline-yes">31x</span>
|
|
985
|
+
<span class="cline-any cline-yes">31x</span>
|
|
986
|
+
<span class="cline-any cline-neutral"> </span>
|
|
987
|
+
<span class="cline-any cline-neutral"> </span>
|
|
988
|
+
<span class="cline-any cline-neutral"> </span>
|
|
989
|
+
<span class="cline-any cline-yes">31x</span>
|
|
990
|
+
<span class="cline-any cline-yes">8x</span>
|
|
991
|
+
<span class="cline-any cline-yes">4x</span>
|
|
992
|
+
<span class="cline-any cline-yes">4x</span>
|
|
993
|
+
<span class="cline-any cline-neutral"> </span>
|
|
994
|
+
<span class="cline-any cline-yes">6x</span>
|
|
995
|
+
<span class="cline-any cline-yes">4x</span>
|
|
996
|
+
<span class="cline-any cline-neutral"> </span>
|
|
997
|
+
<span class="cline-any cline-yes">8x</span>
|
|
998
|
+
<span class="cline-any cline-no"> </span>
|
|
999
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1000
|
+
<span class="cline-any cline-no"> </span>
|
|
1001
|
+
<span class="cline-any cline-no"> </span>
|
|
1002
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1003
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1004
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1005
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1006
|
+
<span class="cline-any cline-yes">31x</span>
|
|
1007
|
+
<span class="cline-any cline-no"> </span>
|
|
1008
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1009
|
+
<span class="cline-any cline-yes">31x</span>
|
|
1010
|
+
<span class="cline-any cline-no"> </span>
|
|
1011
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1012
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1013
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1014
|
+
<span class="cline-any cline-yes">31x</span>
|
|
1015
|
+
<span class="cline-any cline-yes">31x</span>
|
|
1016
|
+
<span class="cline-any cline-yes">31x</span>
|
|
1017
|
+
<span class="cline-any cline-yes">31x</span>
|
|
1018
|
+
<span class="cline-any cline-yes">32x</span>
|
|
1019
|
+
<span class="cline-any cline-yes">31x</span>
|
|
1020
|
+
<span class="cline-any cline-yes">31x</span>
|
|
1021
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1022
|
+
<span class="cline-any cline-yes">31x</span>
|
|
1023
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1024
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1025
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1026
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1027
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1028
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1029
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1030
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1031
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1032
|
+
<span class="cline-any cline-yes">114x</span>
|
|
1033
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1034
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1035
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1036
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1037
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1038
|
+
<span class="cline-any cline-yes">111x</span>
|
|
1039
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1040
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1041
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1042
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1043
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1044
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1045
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1046
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1047
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1048
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1049
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1050
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1051
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1052
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1053
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1054
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1055
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1056
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1057
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1058
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1059
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1060
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1061
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1062
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1063
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1064
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1065
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1066
|
+
<span class="cline-any cline-yes">114x</span>
|
|
1067
|
+
<span class="cline-any cline-no"> </span>
|
|
1068
|
+
<span class="cline-any cline-no"> </span>
|
|
1069
|
+
<span class="cline-any cline-no"> </span>
|
|
1070
|
+
<span class="cline-any cline-no"> </span>
|
|
1071
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1072
|
+
<span class="cline-any cline-no"> </span>
|
|
1073
|
+
<span class="cline-any cline-no"> </span>
|
|
1074
|
+
<span class="cline-any cline-no"> </span>
|
|
1075
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1076
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1077
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1078
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1079
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1080
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1081
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1082
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1083
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1084
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1085
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1086
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1087
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1088
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1089
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1090
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1091
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1092
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1093
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1094
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1095
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1096
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1097
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1098
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1099
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1100
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1101
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1102
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1103
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1104
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1105
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1106
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1107
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1108
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1109
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1110
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1111
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1112
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1113
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1114
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1115
|
+
<span class="cline-any cline-yes">72x</span>
|
|
1116
|
+
<span class="cline-any cline-yes">72x</span>
|
|
1117
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1118
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1119
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1120
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1121
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1122
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1123
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1124
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1125
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1126
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1127
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1128
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1129
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1130
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1131
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1132
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1133
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1134
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1135
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1136
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1137
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1138
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1139
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1140
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1141
|
+
<span class="cline-any cline-yes">114x</span>
|
|
1142
|
+
<span class="cline-any cline-yes">114x</span>
|
|
1143
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1144
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1145
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1146
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1147
|
+
<span class="cline-any cline-yes">105x</span>
|
|
1148
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1149
|
+
<span class="cline-any cline-yes">59x</span>
|
|
1150
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1151
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1152
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1153
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1154
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1155
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1156
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1157
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1158
|
+
<span class="cline-any cline-yes">27x</span>
|
|
1159
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1160
|
+
<span class="cline-any cline-yes">24x</span>
|
|
1161
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1162
|
+
<span class="cline-any cline-yes">44x</span>
|
|
1163
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1164
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1165
|
+
<span class="cline-any cline-yes">72x</span>
|
|
1166
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1167
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1168
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1169
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1170
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1171
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1172
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1173
|
+
<span class="cline-any cline-yes">72x</span>
|
|
1174
|
+
<span class="cline-any cline-yes">72x</span>
|
|
1175
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1176
|
+
<span class="cline-any cline-yes">72x</span>
|
|
1177
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1178
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1179
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1180
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1181
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1182
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1183
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1184
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1185
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1186
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1187
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1188
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1189
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1190
|
+
<span class="cline-any cline-no"> </span>
|
|
1191
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1192
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1193
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1194
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1195
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1196
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1197
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1198
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1199
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1200
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1201
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1202
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1203
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1204
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1205
|
+
<span class="cline-any cline-no"> </span>
|
|
1206
|
+
<span class="cline-any cline-no"> </span>
|
|
1207
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1208
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1209
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1210
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1211
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1212
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1213
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1214
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1215
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1216
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1217
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1218
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1219
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1220
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1221
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1222
|
+
<span class="cline-any cline-yes">68x</span>
|
|
1223
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1224
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1225
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1226
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1227
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1228
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1229
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1230
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1231
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1232
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1233
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1234
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1235
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1236
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1237
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1238
|
+
<span class="cline-any cline-no"> </span>
|
|
1239
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1240
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1241
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1242
|
+
<span class="cline-any cline-no"> </span>
|
|
1243
|
+
<span class="cline-any cline-no"> </span>
|
|
1244
|
+
<span class="cline-any cline-no"> </span>
|
|
1245
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1246
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1247
|
+
<span class="cline-any cline-no"> </span>
|
|
1248
|
+
<span class="cline-any cline-no"> </span>
|
|
1249
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1250
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1251
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1252
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1253
|
+
<span class="cline-any cline-no"> </span>
|
|
1254
|
+
<span class="cline-any cline-no"> </span>
|
|
1255
|
+
<span class="cline-any cline-no"> </span>
|
|
1256
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1257
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1258
|
+
<span class="cline-any cline-no"> </span>
|
|
1259
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1260
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1261
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1262
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1263
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1264
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1265
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1266
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1267
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1268
|
+
<span class="cline-any cline-yes">4x</span>
|
|
1269
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1270
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1271
|
+
<span class="cline-any cline-no"> </span>
|
|
1272
|
+
<span class="cline-any cline-no"> </span>
|
|
1273
|
+
<span class="cline-any cline-no"> </span>
|
|
1274
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1275
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1276
|
+
<span class="cline-any cline-no"> </span>
|
|
1277
|
+
<span class="cline-any cline-no"> </span>
|
|
1278
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1279
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1280
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1281
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1282
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1283
|
+
<span class="cline-any cline-no"> </span>
|
|
1284
|
+
<span class="cline-any cline-no"> </span>
|
|
1285
|
+
<span class="cline-any cline-no"> </span>
|
|
1286
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1287
|
+
<span class="cline-any cline-no"> </span>
|
|
1288
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1289
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1290
|
+
<span class="cline-any cline-no"> </span>
|
|
1291
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1292
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1293
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1294
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1295
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1296
|
+
<span class="cline-any cline-no"> </span>
|
|
1297
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1298
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1299
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1300
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1301
|
+
<span class="cline-any cline-yes">72x</span>
|
|
1302
|
+
<span class="cline-any cline-yes">16x</span>
|
|
1303
|
+
<span class="cline-any cline-yes">16x</span>
|
|
1304
|
+
<span class="cline-any cline-yes">16x</span>
|
|
1305
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1306
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1307
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1308
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1309
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1310
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1311
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1312
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1313
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1314
|
+
<span class="cline-any cline-yes">56x</span>
|
|
1315
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1316
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { EntityCollection, NumberProperty, Property, Relation, RelationProperty, SecurityOperation, SecurityRule, StringProperty } from "@rebasepro/types";
|
|
1317
|
+
import { getPrimaryKeys } from "./db/services/entity-helpers";
|
|
1318
|
+
import {
|
|
1319
|
+
getEnumVarName,
|
|
1320
|
+
getTableName,
|
|
1321
|
+
getTableVarName,
|
|
1322
|
+
resolveCollectionRelations,
|
|
1323
|
+
toSnakeCase
|
|
1324
|
+
} from "@rebasepro/common";
|
|
1325
|
+
|
|
1326
|
+
// --- Helper Functions ---
|
|
1327
|
+
|
|
1328
|
+
const getPrimaryKeyProp = (collection: EntityCollection): { name: string, type: "string" | "number" } => {
|
|
1329
|
+
if (collection.properties) {
|
|
1330
|
+
const idPropEntry = Object.entries(collection.properties).find(([_, prop]) => "isId" in (prop as object) && Boolean((prop as unknown as Record<string, unknown>).isId));
|
|
1331
|
+
if (idPropEntry) {
|
|
1332
|
+
return { name: idPropEntry[0], type: (idPropEntry[1] as Property).type === "number" ? <span class="branch-0 cbranch-no" title="branch not covered" >"number" </span>: "string" };
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
// Fallback
|
|
1336
|
+
const idProp = collection.properties?.["id"] as Property | undefined;
|
|
1337
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (idProp?.type === "number") {
|
|
1338
|
+
<span class="cstat-no" title="statement not covered" > return { name: "id", type: "number" };</span>
|
|
1339
|
+
}
|
|
1340
|
+
return { name: "id", type: "string" };
|
|
1341
|
+
};
|
|
1342
|
+
|
|
1343
|
+
const isNumericId = (collection: EntityCollection): boolean => {
|
|
1344
|
+
return getPrimaryKeyProp(collection).type === "number";
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1347
|
+
const getPrimaryKeyName = (collection: EntityCollection): string => {
|
|
1348
|
+
return getPrimaryKeyProp(collection).name;
|
|
1349
|
+
};
|
|
1350
|
+
|
|
1351
|
+
const isIdProperty = (propName: string, prop: Property, collection: EntityCollection): boolean => {
|
|
1352
|
+
if ("isId" in prop && Boolean(prop.isId)) return true;
|
|
1353
|
+
|
|
1354
|
+
// We only fallback to "id" if NO property is explicitly marked with `isId: true` or a generator string
|
|
1355
|
+
const hasExplicitId = Object.values(collection.properties ?? <span class="branch-1 cbranch-no" title="branch not covered" >{})</span>.some(p => "isId" in (p as object) && Boolean((p as unknown as Record<string, unknown>).isId));
|
|
1356
|
+
return !hasExplicitId && propName === "id";
|
|
1357
|
+
};
|
|
1358
|
+
|
|
1359
|
+
const getDrizzleColumn = (propName: string, prop: Property, collection: EntityCollection): string | null => {
|
|
1360
|
+
const colName = toSnakeCase(propName);
|
|
1361
|
+
let columnDefinition: string;
|
|
1362
|
+
|
|
1363
|
+
switch (prop.type) {
|
|
1364
|
+
case "string": {
|
|
1365
|
+
const stringProp = prop as StringProperty;
|
|
1366
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (stringProp.enum) {
|
|
1367
|
+
const enumName = <span class="cstat-no" title="statement not covered" >getEnumVarName(getTableName(collection), propName);</span>
|
|
1368
|
+
<span class="cstat-no" title="statement not covered" > columnDefinition = `${enumName}("${colName}")`;</span>
|
|
1369
|
+
} else if ("isId" in stringProp && stringProp.isId === "uuid") {
|
|
1370
|
+
columnDefinition = `uuid("${colName}")`;
|
|
1371
|
+
} else if (stringProp.columnType === "text") {
|
|
1372
|
+
columnDefinition = `text("${colName}")`;
|
|
1373
|
+
} else if (stringProp.columnType === "char") {
|
|
1374
|
+
columnDefinition = `char("${colName}")`;
|
|
1375
|
+
} else {
|
|
1376
|
+
columnDefinition = `varchar("${colName}")`;
|
|
1377
|
+
}
|
|
1378
|
+
if (isIdProperty(propName, prop, collection)) {
|
|
1379
|
+
columnDefinition += `.primaryKey()`;
|
|
1380
|
+
}
|
|
1381
|
+
if ("isId" in stringProp && stringProp.isId !== "manual" && stringProp.isId !== true) {
|
|
1382
|
+
if (stringProp.isId === "uuid") {
|
|
1383
|
+
columnDefinition += `.defaultRandom()`;
|
|
1384
|
+
} else <span class="missing-if-branch" title="if path not taken" >I</span>if (stringProp.isId === "cuid") {
|
|
1385
|
+
<span class="cstat-no" title="statement not covered" > columnDefinition += `.default(sql\`cuid()\`)`;</span>
|
|
1386
|
+
} else if (typeof stringProp.isId === "string") {
|
|
1387
|
+
const sqlContent = stringProp.isId.startsWith("sql`") && stringProp.isId.endsWith("`")
|
|
1388
|
+
? stringProp.isId.substring(4, stringProp.isId.length - 1)
|
|
1389
|
+
: <span class="branch-1 cbranch-no" title="branch not covered" >stringProp.isId;</span>
|
|
1390
|
+
columnDefinition += `.default(sql\`${sqlContent}\`)`;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
if (stringProp.validation?.unique) {
|
|
1394
|
+
columnDefinition += `.unique()`;
|
|
1395
|
+
}
|
|
1396
|
+
break;
|
|
1397
|
+
}
|
|
1398
|
+
case "number": {
|
|
1399
|
+
const numProp = prop as NumberProperty;
|
|
1400
|
+
const isId = isIdProperty(propName, prop, collection);
|
|
1401
|
+
|
|
1402
|
+
let baseType = (numProp.validation?.integer || isId) ? `integer("${colName}")` : `numeric("${colName}")`;
|
|
1403
|
+
if (numProp.columnType) {
|
|
1404
|
+
if (numProp.columnType === "double precision") baseType = `doublePrecision("${colName}")`;
|
|
1405
|
+
else baseType = `${numProp.columnType}("${colName}")`;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
if ("isId" in numProp && numProp.isId === "increment") {
|
|
1409
|
+
columnDefinition = `${baseType}.generatedByDefaultAsIdentity()`;
|
|
1410
|
+
} else <span class="missing-if-branch" title="if path not taken" >I</span>if ("isId" in numProp && typeof numProp.isId === "string" && <span class="branch-2 cbranch-no" title="branch not covered" >numProp.isId !== "manual")</span> {
|
|
1411
|
+
<span class="cstat-no" title="statement not covered" > columnDefinition = baseType;</span>
|
|
1412
|
+
const sqlContent = <span class="cstat-no" title="statement not covered" >numProp.isId.startsWith("sql`") && numProp.isId.endsWith("`")</span>
|
|
1413
|
+
? numProp.isId.substring(4, numProp.isId.length - 1)
|
|
1414
|
+
: numProp.isId;
|
|
1415
|
+
<span class="cstat-no" title="statement not covered" > columnDefinition += `.default(sql\`${sqlContent}\`)`;</span>
|
|
1416
|
+
} else {
|
|
1417
|
+
columnDefinition = baseType;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
if (isId) {
|
|
1421
|
+
columnDefinition += `.primaryKey()`;
|
|
1422
|
+
}
|
|
1423
|
+
if (numProp.validation?.unique) {
|
|
1424
|
+
columnDefinition += `.unique()`;
|
|
1425
|
+
}
|
|
1426
|
+
break;
|
|
1427
|
+
}
|
|
1428
|
+
case "boolean":
|
|
1429
|
+
columnDefinition = `boolean("${colName}")`;
|
|
1430
|
+
break;
|
|
1431
|
+
case "date": {
|
|
1432
|
+
const dateProp = prop as import("@rebasepro/types").DateProperty;
|
|
1433
|
+
if (dateProp.columnType === "date") {
|
|
1434
|
+
columnDefinition = `date("${colName}", { mode: 'string' })`;
|
|
1435
|
+
} else if (dateProp.columnType === "time") {
|
|
1436
|
+
columnDefinition = `time("${colName}")`;
|
|
1437
|
+
} else {
|
|
1438
|
+
columnDefinition = `timestamp("${colName}", { withTimezone: true, mode: 'string' })`;
|
|
1439
|
+
}
|
|
1440
|
+
break;
|
|
1441
|
+
}
|
|
1442
|
+
case "map":
|
|
1443
|
+
case "array": {
|
|
1444
|
+
const arrayOrMapProp = prop as import("@rebasepro/types").ArrayProperty | import("@rebasepro/types").MapProperty;
|
|
1445
|
+
if (arrayOrMapProp.columnType === "json") {
|
|
1446
|
+
columnDefinition = `json("${colName}")`;
|
|
1447
|
+
} else {
|
|
1448
|
+
columnDefinition = `jsonb("${colName}")`;
|
|
1449
|
+
}
|
|
1450
|
+
break;
|
|
1451
|
+
}
|
|
1452
|
+
case "relation": {
|
|
1453
|
+
const refProp = prop as RelationProperty;
|
|
1454
|
+
const resolvedRelations = resolveCollectionRelations(collection);
|
|
1455
|
+
const relation = resolvedRelations[refProp.relationName ?? <span class="branch-1 cbranch-no" title="branch not covered" >propName]</span>;
|
|
1456
|
+
|
|
1457
|
+
// Only owning one-to-one/many-to-one relations create a column here.
|
|
1458
|
+
if (!relation || relation.direction !== "owning" || relation.cardinality !== "one") {
|
|
1459
|
+
return null;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
// The localKey property is the source of truth for the FK column name.
|
|
1463
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!relation.localKey) {
|
|
1464
|
+
<span class="cstat-no" title="statement not covered" > console.warn(`Could not generate column for owning relation '${relation.relationName}' on '${collection.name}': 'localKey' is not defined.`);</span>
|
|
1465
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
// If the localKey property is defined elsewhere in the properties, it will be handled there.
|
|
1469
|
+
// This logic is for when the relation property itself defines the FK.
|
|
1470
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (collection.properties[relation.localKey] && <span class="branch-1 cbranch-no" title="branch not covered" >propName !== relation.localKey)</span> {
|
|
1471
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
let targetCollection: EntityCollection;
|
|
1475
|
+
try {
|
|
1476
|
+
targetCollection = relation.target();
|
|
1477
|
+
} catch {
|
|
1478
|
+
<span class="cstat-no" title="statement not covered" > return null; </span>// Cannot resolve target
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
const fkColumnName = toSnakeCase(relation.localKey);
|
|
1482
|
+
const targetTableVar = getTableVarName(getTableName(targetCollection));
|
|
1483
|
+
const targetIdField = getPrimaryKeyName(targetCollection);
|
|
1484
|
+
const baseColumn = isNumericId(targetCollection) ? <span class="branch-0 cbranch-no" title="branch not covered" >`integer(\"${fkColumnName}\")` </span>: `varchar(\"${fkColumnName}\")`;
|
|
1485
|
+
|
|
1486
|
+
const onUpdate = relation.onUpdate ? <span class="branch-0 cbranch-no" title="branch not covered" >`onUpdate: \"${relation.onUpdate}\"` </span>: "";
|
|
1487
|
+
const required = prop.validation?.required;
|
|
1488
|
+
const onDeleteVal = relation.onDelete ?? (required ? <span class="branch-0 cbranch-no" title="branch not covered" >"cascade" </span>: "set null");
|
|
1489
|
+
const onDelete = `onDelete: \"${onDeleteVal}\"`;
|
|
1490
|
+
|
|
1491
|
+
const refOptionsParts = [onUpdate, onDelete].filter(Boolean);
|
|
1492
|
+
const refOptions = refOptionsParts.length > 0 ? `{ ${refOptionsParts.join(", ")} }` : <span class="branch-1 cbranch-no" title="branch not covered" >"";</span>
|
|
1493
|
+
|
|
1494
|
+
let columnDef = `${baseColumn}.references(() => ${targetTableVar}.${targetIdField}${refOptions ? `, ${refOptions}` : <span class="branch-1 cbranch-no" title="branch not covered" >""}</span>)`;
|
|
1495
|
+
|
|
1496
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (required) {
|
|
1497
|
+
<span class="cstat-no" title="statement not covered" > columnDef += ".notNull()";</span>
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
return ` ${relation.localKey}: ${columnDef}`;
|
|
1501
|
+
}
|
|
1502
|
+
<span class="branch-7 cbranch-no" title="branch not covered" > default:</span>
|
|
1503
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
if (prop.validation?.required) {
|
|
1507
|
+
columnDefinition += ".notNull()";
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
return ` ${propName}: ${columnDefinition}`;
|
|
1511
|
+
};
|
|
1512
|
+
|
|
1513
|
+
/**
|
|
1514
|
+
* Resolves a raw SQL string, replacing `{column_name}` with `${table.column_name}`.
|
|
1515
|
+
* The result is wrapped in a Drizzle sql`` template literal.
|
|
1516
|
+
*/
|
|
1517
|
+
const resolveRawSql = (expression: string): string => {
|
|
1518
|
+
// Replace {column_name} with ${table.column_name}
|
|
1519
|
+
const resolved = expression.replace(/\{(\w+)\}/g, (_, col) => `\${table.${col}}`);
|
|
1520
|
+
return `sql\`${resolved}\``;
|
|
1521
|
+
};
|
|
1522
|
+
|
|
1523
|
+
/**
|
|
1524
|
+
* Wraps a SQL clause with a role check using AND.
|
|
1525
|
+
* Generates: `(<clause>) AND (string_to_array(auth.roles(), ',') && ARRAY['<role1>','<role2>'])`
|
|
1526
|
+
*/
|
|
1527
|
+
const wrapWithRoleCheck = (clause: string, roles: string[]): string => {
|
|
1528
|
+
const rolesArrayString = `ARRAY[${roles.map(r => `'${r}'`).join(',')}]`;
|
|
1529
|
+
const roleCondition = `string_to_array(auth.roles(), ',') @> ${rolesArrayString}`;
|
|
1530
|
+
return `sql\`(${unwrapSql(clause)}) AND (${roleCondition})\``;
|
|
1531
|
+
};
|
|
1532
|
+
|
|
1533
|
+
/**
|
|
1534
|
+
* Extracts the inner expression from a `sql\`...\`` wrapper.
|
|
1535
|
+
*/
|
|
1536
|
+
const unwrapSql = (sqlExpr: string): string => {
|
|
1537
|
+
const match = sqlExpr.match(/^sql`(.*)`$/s);
|
|
1538
|
+
return match ? match[1] : <span class="branch-1 cbranch-no" title="branch not covered" >sqlExpr;</span>
|
|
1539
|
+
};
|
|
1540
|
+
|
|
1541
|
+
/**
|
|
1542
|
+
* Builds the USING clause for a policy based on shortcuts or raw SQL.
|
|
1543
|
+
*/
|
|
1544
|
+
const buildUsingClause = (rule: SecurityRule): string | null => {
|
|
1545
|
+
if (rule.using) {
|
|
1546
|
+
return resolveRawSql(rule.using);
|
|
1547
|
+
}
|
|
1548
|
+
if (rule.access === "public") {
|
|
1549
|
+
return `sql\`true\``;
|
|
1550
|
+
}
|
|
1551
|
+
if (rule.ownerField) {
|
|
1552
|
+
return `sql\`\${table.${rule.ownerField}} = auth.uid()\``;
|
|
1553
|
+
}
|
|
1554
|
+
return null;
|
|
1555
|
+
};
|
|
1556
|
+
|
|
1557
|
+
/**
|
|
1558
|
+
* Builds the WITH CHECK clause for a policy based on shortcuts or raw SQL.
|
|
1559
|
+
* Falls back to the USING clause if not explicitly provided.
|
|
1560
|
+
*/
|
|
1561
|
+
const buildWithCheckClause = (rule: SecurityRule): string | null => {
|
|
1562
|
+
if (rule.withCheck) {
|
|
1563
|
+
return resolveRawSql(rule.withCheck);
|
|
1564
|
+
}
|
|
1565
|
+
// For insert/update/all, fall back to using clause if withCheck not specified
|
|
1566
|
+
return buildUsingClause(rule);
|
|
1567
|
+
};
|
|
1568
|
+
|
|
1569
|
+
/**
|
|
1570
|
+
* Generates Drizzle pgPolicy() calls from a declarative SecurityRule definition.
|
|
1571
|
+
*
|
|
1572
|
+
* Supports the full spectrum:
|
|
1573
|
+
* - Convenience shortcuts: ownerField, access, roles
|
|
1574
|
+
* - Raw SQL: using, withCheck
|
|
1575
|
+
* - Mode: permissive (default) or restrictive
|
|
1576
|
+
* - operations[] array: generates one policy per operation
|
|
1577
|
+
* - Combinations: roles + ownerField, roles + raw SQL, etc.
|
|
1578
|
+
*/
|
|
1579
|
+
const generatePolicyCode = (tableName: string, rule: SecurityRule, index: number): string => {
|
|
1580
|
+
// Resolve operations: operations[] takes precedence over operation (singular)
|
|
1581
|
+
const ops: SecurityOperation[] = rule.operations && rule.operations.length > 0
|
|
1582
|
+
? rule.operations
|
|
1583
|
+
: [rule.operation ?? <span class="branch-1 cbranch-no" title="branch not covered" >"all"]</span>;
|
|
1584
|
+
|
|
1585
|
+
// Generate one pgPolicy per operation
|
|
1586
|
+
return ops.map((op, opIdx) => {
|
|
1587
|
+
const policyName = rule.name
|
|
1588
|
+
? (ops.length > 1 ? `${rule.name}_${op}` : rule.name)
|
|
1589
|
+
: `${tableName}_${op}_policy_${index}${ops.length > 1 ? `_${opIdx}` : ""}`;
|
|
1590
|
+
|
|
1591
|
+
return generateSinglePolicyCode(tableName, rule, op, policyName);
|
|
1592
|
+
}).join("");
|
|
1593
|
+
};
|
|
1594
|
+
|
|
1595
|
+
/**
|
|
1596
|
+
* Generates a single pgPolicy() call for one specific operation.
|
|
1597
|
+
*/
|
|
1598
|
+
const generateSinglePolicyCode = (tableName: string, rule: SecurityRule, operation: SecurityOperation, policyName: string): string => {
|
|
1599
|
+
const mode = rule.mode ?? "permissive";
|
|
1600
|
+
const roles = rule.roles;
|
|
1601
|
+
|
|
1602
|
+
// Determine which clauses this operation needs:
|
|
1603
|
+
// SELECT, DELETE → USING only
|
|
1604
|
+
// INSERT → WITH CHECK only
|
|
1605
|
+
// UPDATE, ALL → both USING and WITH CHECK
|
|
1606
|
+
const needsUsing = operation !== "insert";
|
|
1607
|
+
const needsWithCheck = operation !== "select" && operation !== "delete";
|
|
1608
|
+
|
|
1609
|
+
let usingClause = needsUsing ? buildUsingClause(rule) : null;
|
|
1610
|
+
let withCheckClause = needsWithCheck ? buildWithCheckClause(rule) : null;
|
|
1611
|
+
|
|
1612
|
+
// If roles are specified, wrap existing clauses with role check,
|
|
1613
|
+
// or generate a roles-only clause.
|
|
1614
|
+
if (roles && roles.length > 0) {
|
|
1615
|
+
if (usingClause) {
|
|
1616
|
+
usingClause = wrapWithRoleCheck(usingClause, roles);
|
|
1617
|
+
} else if (needsUsing) {
|
|
1618
|
+
// Roles-only rule (e.g. { operation: "select", roles: ["admin"] })
|
|
1619
|
+
const rolesArrayString = `ARRAY[${roles.map(r => `'${r}'`).join(',')}]`;
|
|
1620
|
+
usingClause = `sql\`string_to_array(auth.roles(), ',') @> ${rolesArrayString}\``;
|
|
1621
|
+
}
|
|
1622
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (withCheckClause) {
|
|
1623
|
+
<span class="cstat-no" title="statement not covered" > withCheckClause = wrapWithRoleCheck(withCheckClause, roles);</span>
|
|
1624
|
+
} else <span class="missing-if-branch" title="if path not taken" >I</span>if (needsWithCheck) {
|
|
1625
|
+
const rolesArrayString = <span class="cstat-no" title="statement not covered" >`ARRAY[${roles.map(<span class="fstat-no" title="function not covered" >r </span>=> <span class="cstat-no" title="statement not covered" >`'${r}'`)</span>.join(',')}]`;</span>
|
|
1626
|
+
<span class="cstat-no" title="statement not covered" > withCheckClause = `sql\`string_to_array(auth.roles(), ',') @> ${rolesArrayString}\``;</span>
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
// Fallback: if we still have no clauses, deny all (safety net)
|
|
1631
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!usingClause && needsUsing) {
|
|
1632
|
+
<span class="cstat-no" title="statement not covered" > usingClause = `sql\`false\``;</span>
|
|
1633
|
+
}
|
|
1634
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!withCheckClause && needsWithCheck) {
|
|
1635
|
+
<span class="cstat-no" title="statement not covered" > withCheckClause = `sql\`false\``;</span>
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
// Build the policy options object
|
|
1639
|
+
const parts: string[] = [];
|
|
1640
|
+
parts.push(`as: "${mode}"`);
|
|
1641
|
+
parts.push(`for: "${operation}"`);
|
|
1642
|
+
const toRoles = rule.pgRoles ?? ["public"];
|
|
1643
|
+
parts.push(`to: [${toRoles.map(r => `"${r}"`).join(", ")}]`);
|
|
1644
|
+
if (usingClause) parts.push(`using: ${usingClause}`);
|
|
1645
|
+
if (withCheckClause) parts.push(`withCheck: ${withCheckClause}`);
|
|
1646
|
+
|
|
1647
|
+
return ` pgPolicy("${policyName}", { ${parts.join(", ")} }),\n`;
|
|
1648
|
+
};
|
|
1649
|
+
|
|
1650
|
+
// --- Main Schema Generation Logic ---
|
|
1651
|
+
export const generateSchema = async (collections: EntityCollection[]): Promise<string> => {
|
|
1652
|
+
let schemaContent = "// This file is auto-generated by the Rebase Drizzle generator. Do not edit manually.\n\n";
|
|
1653
|
+
|
|
1654
|
+
const hasRLS = collections.some(c => c.securityRules && c.securityRules.length > 0);
|
|
1655
|
+
const hasUuid = collections.some(c =>
|
|
1656
|
+
c.properties && Object.values(c.properties).some(
|
|
1657
|
+
(p: Property) => p.type === "string" && ((p as unknown as Record<string, unknown>).autoValue === "uuid" || (p as unknown as Record<string, unknown>).isId === "uuid")
|
|
1658
|
+
)
|
|
1659
|
+
);
|
|
1660
|
+
|
|
1661
|
+
const hasJson = collections.some(c =>
|
|
1662
|
+
c.properties && Object.values(c.properties).some(
|
|
1663
|
+
(p: Property) => (p.type === "map" || p.type === "array") && (p as unknown as Record<string, unknown>).columnType === "json"
|
|
1664
|
+
)
|
|
1665
|
+
);
|
|
1666
|
+
|
|
1667
|
+
const pgCoreImports = ["primaryKey", "pgTable", "integer", "varchar", "text", "char", "boolean", "timestamp", "date", "time", "jsonb", "json", "pgEnum", "numeric", "real", "doublePrecision", "bigint", "serial", "bigserial"];
|
|
1668
|
+
if (hasRLS) pgCoreImports.push("pgPolicy");
|
|
1669
|
+
if (hasUuid) pgCoreImports.push("uuid");
|
|
1670
|
+
schemaContent += `import { ${pgCoreImports.join(", ")} } from 'drizzle-orm/pg-core';\n`;
|
|
1671
|
+
|
|
1672
|
+
const drizzleOrmImports = ["relations as drizzleRelations"];
|
|
1673
|
+
if (hasRLS) drizzleOrmImports.push("sql");
|
|
1674
|
+
schemaContent += `import { ${drizzleOrmImports.join(", ")} } from 'drizzle-orm';\n\n`;
|
|
1675
|
+
|
|
1676
|
+
const exportedTableVars: string[] = [];
|
|
1677
|
+
const exportedEnumVars: string[] = [];
|
|
1678
|
+
const exportedRelationVars: string[] = [];
|
|
1679
|
+
|
|
1680
|
+
const allTablesToGenerate = new Map<string, {
|
|
1681
|
+
collection: EntityCollection,
|
|
1682
|
+
isJunction?: boolean,
|
|
1683
|
+
relation?: Relation,
|
|
1684
|
+
sourceCollection?: EntityCollection
|
|
1685
|
+
}>();
|
|
1686
|
+
|
|
1687
|
+
// 1. Generate Enums
|
|
1688
|
+
collections.forEach(collection => {
|
|
1689
|
+
const collectionPath = getTableName(collection);
|
|
1690
|
+
Object.entries(collection.properties ?? <span class="branch-1 cbranch-no" title="branch not covered" >{})</span>.forEach(([propName, prop]) => {
|
|
1691
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (("enum" in prop) && (<span class="branch-1 cbranch-no" title="branch not covered" >prop.type === "string" </span>|| <span class="branch-2 cbranch-no" title="branch not covered" >prop.type === "number")</span> && <span class="branch-3 cbranch-no" title="branch not covered" >prop.enum)</span> {
|
|
1692
|
+
const enumVarName = <span class="cstat-no" title="statement not covered" >getEnumVarName(collectionPath, propName);</span>
|
|
1693
|
+
const enumDbName = <span class="cstat-no" title="statement not covered" >`${collectionPath}_${toSnakeCase(propName)}`;</span>
|
|
1694
|
+
const values = <span class="cstat-no" title="statement not covered" >Array.isArray(prop.enum)</span>
|
|
1695
|
+
? prop.enum.map(<span class="fstat-no" title="function not covered" >v </span>=> <span class="cstat-no" title="statement not covered" >String(v.id ?? v))</span>
|
|
1696
|
+
: Object.keys(prop.enum);
|
|
1697
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (values.length > 0) {</span>
|
|
1698
|
+
<span class="cstat-no" title="statement not covered" > schemaContent += `export const ${enumVarName} = pgEnum(\"${enumDbName}\", [${values.map(<span class="fstat-no" title="function not covered" >v </span>=> <span class="cstat-no" title="statement not covered" >`'${v}'`)</span>.join(", ")}]);\n`;</span>
|
|
1699
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!exportedEnumVars.includes(enumVarName)) <span class="cstat-no" title="statement not covered" >exportedEnumVars.push(enumVarName);</span></span>
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
});
|
|
1703
|
+
});
|
|
1704
|
+
schemaContent += "\n";
|
|
1705
|
+
|
|
1706
|
+
// 2. Identify all tables (collections and junction tables only)
|
|
1707
|
+
for (const collection of collections) {
|
|
1708
|
+
const tableName = getTableName(collection);
|
|
1709
|
+
if (tableName) {
|
|
1710
|
+
allTablesToGenerate.set(tableName, { collection });
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
const resolvedRelations = resolveCollectionRelations(collection);
|
|
1714
|
+
for (const relation of Object.values(resolvedRelations)) {
|
|
1715
|
+
if (relation.through) { // Standard M2M junction table
|
|
1716
|
+
const junctionTableName = relation.through.table;
|
|
1717
|
+
if (!allTablesToGenerate.has(junctionTableName)) {
|
|
1718
|
+
allTablesToGenerate.set(junctionTableName, {
|
|
1719
|
+
collection: {
|
|
1720
|
+
dbPath: junctionTableName,
|
|
1721
|
+
properties: {}
|
|
1722
|
+
} as EntityCollection,
|
|
1723
|
+
isJunction: true,
|
|
1724
|
+
relation: relation,
|
|
1725
|
+
sourceCollection: collection
|
|
1726
|
+
});
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
// joinPath relations use existing user-controlled tables - no generation needed
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
// 3. Generate pgTable definitions for all unique tables
|
|
1734
|
+
for (const [tableName, {
|
|
1735
|
+
collection,
|
|
1736
|
+
isJunction,
|
|
1737
|
+
relation,
|
|
1738
|
+
sourceCollection
|
|
1739
|
+
}] of allTablesToGenerate.entries()) {
|
|
1740
|
+
const tableVarName = getTableVarName(tableName);
|
|
1741
|
+
if (isJunction && relation && sourceCollection && relation.through) {
|
|
1742
|
+
const targetCollection = relation.target();
|
|
1743
|
+
const {
|
|
1744
|
+
sourceColumn,
|
|
1745
|
+
targetColumn
|
|
1746
|
+
} = relation.through;
|
|
1747
|
+
|
|
1748
|
+
const onDelete = relation.onDelete ?? "cascade";
|
|
1749
|
+
const refOptions = `{ onDelete: \"${onDelete}\" }`;
|
|
1750
|
+
|
|
1751
|
+
const sourceColType = isNumericId(sourceCollection) ? <span class="branch-0 cbranch-no" title="branch not covered" >"integer" </span>: "varchar";
|
|
1752
|
+
const targetColType = isNumericId(targetCollection) ? <span class="branch-0 cbranch-no" title="branch not covered" >"integer" </span>: "varchar";
|
|
1753
|
+
const sourceId = getPrimaryKeyName(sourceCollection);
|
|
1754
|
+
const targetId = getPrimaryKeyName(targetCollection);
|
|
1755
|
+
|
|
1756
|
+
schemaContent += `export const ${tableVarName} = pgTable(\"${tableName}\", {\n`;
|
|
1757
|
+
schemaContent += ` ${sourceColumn}: ${sourceColType}(\"${toSnakeCase(sourceColumn)}\").notNull().references(() => ${getTableVarName(getTableName(sourceCollection))}.${sourceId}, ${refOptions}),\n`;
|
|
1758
|
+
schemaContent += ` ${targetColumn}: ${targetColType}(\"${toSnakeCase(targetColumn)}\").notNull().references(() => ${getTableVarName(getTableName(targetCollection))}.${targetId}, ${refOptions}),\n`;
|
|
1759
|
+
schemaContent += `}, (table) => ({\n`;
|
|
1760
|
+
schemaContent += ` pk: primaryKey({ columns: [table.${sourceColumn}, table.${targetColumn}] })\n`;
|
|
1761
|
+
schemaContent += `}));\n\n`;
|
|
1762
|
+
} else if (!isJunction) {
|
|
1763
|
+
schemaContent += `export const ${tableVarName} = pgTable(\"${tableName}\", {\n`;
|
|
1764
|
+
const columns = new Set<string>();
|
|
1765
|
+
Object.entries(collection.properties ?? <span class="branch-1 cbranch-no" title="branch not covered" >{})</span>.forEach(([propName, prop]) => {
|
|
1766
|
+
const columnString = getDrizzleColumn(propName, prop as Property, collection);
|
|
1767
|
+
if (columnString) columns.add(columnString);
|
|
1768
|
+
});
|
|
1769
|
+
|
|
1770
|
+
// Backwards compatibility: if no id/primary key column is found in properties, but `id` wasn't explicitly provided
|
|
1771
|
+
// We should generate a basic id column if one was completely omitted.
|
|
1772
|
+
const hasIdColumn = Array.from(columns).some(col => col.includes(".primaryKey()"));
|
|
1773
|
+
if (!hasIdColumn) {
|
|
1774
|
+
columns.add(` id: varchar(\"id\").primaryKey()`);
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
schemaContent += `${Array.from(columns).join(",\n")}`;
|
|
1778
|
+
|
|
1779
|
+
const securityRules = collection.securityRules;
|
|
1780
|
+
if (securityRules && securityRules.length > 0) {
|
|
1781
|
+
schemaContent += "\n}, (table) => ([\n";
|
|
1782
|
+
securityRules.forEach((rule, idx) => {
|
|
1783
|
+
schemaContent += generatePolicyCode(tableName, rule, idx);
|
|
1784
|
+
});
|
|
1785
|
+
schemaContent += "]));\n\n";
|
|
1786
|
+
} else {
|
|
1787
|
+
schemaContent += "\n});\n\n";
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
if (!exportedTableVars.includes(tableVarName)) exportedTableVars.push(tableVarName);
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
// 4. Generate Drizzle Relations
|
|
1794
|
+
for (const [tableName, {
|
|
1795
|
+
collection,
|
|
1796
|
+
isJunction
|
|
1797
|
+
}] of allTablesToGenerate.entries()) {
|
|
1798
|
+
const tableVarName = getTableVarName(tableName);
|
|
1799
|
+
const tableRelations: string[] = [];
|
|
1800
|
+
|
|
1801
|
+
if (isJunction) {
|
|
1802
|
+
const relationInfo = Array.from(allTablesToGenerate.values()).find(v => v.isJunction && getTableName(v.collection) === tableName);
|
|
1803
|
+
if (relationInfo && relationInfo.relation && relationInfo.sourceCollection && relationInfo.relation.through) {
|
|
1804
|
+
const {
|
|
1805
|
+
relation,
|
|
1806
|
+
sourceCollection
|
|
1807
|
+
} = relationInfo;
|
|
1808
|
+
const targetCollection = relation.target();
|
|
1809
|
+
const sourceTableVar = getTableVarName(getTableName(sourceCollection));
|
|
1810
|
+
const targetTableVar = getTableVarName(getTableName(targetCollection));
|
|
1811
|
+
const sourceId = getPrimaryKeyName(sourceCollection);
|
|
1812
|
+
const targetId = getPrimaryKeyName(targetCollection);
|
|
1813
|
+
|
|
1814
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!relation?.through)
|
|
1815
|
+
<span class="cstat-no" title="statement not covered" > throw new Error("Internal, the relation should have a through property. Relations passed to this script should sanitized first with sanitizeRelation().");</span>
|
|
1816
|
+
|
|
1817
|
+
// The owning relation's name — used on the source side of the junction
|
|
1818
|
+
const owningRelationName = relation.relationName ?? <span class="branch-1 cbranch-no" title="branch not covered" >toSnakeCase(getTableName(targetCollection));</span>
|
|
1819
|
+
|
|
1820
|
+
// Find the inverse relation name on the target collection (if any)
|
|
1821
|
+
// This is needed so the junction's target-side one() can pair with the
|
|
1822
|
+
// inverse many() on the target table.
|
|
1823
|
+
let inverseRelationName: string | null = null;
|
|
1824
|
+
try {
|
|
1825
|
+
const targetRelations = resolveCollectionRelations(targetCollection);
|
|
1826
|
+
for (const [, targetRel] of Object.entries(targetRelations)) {
|
|
1827
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (targetRel.direction === "inverse" &&
|
|
1828
|
+
<span class="branch-1 cbranch-no" title="branch not covered" > targetRel.cardinality === "many" </span>&&
|
|
1829
|
+
<span class="branch-2 cbranch-no" title="branch not covered" > targetRel.inverseRelationName === owningRelationName)</span> {
|
|
1830
|
+
<span class="cstat-no" title="statement not covered" > inverseRelationName = targetRel.relationName ?? null;</span>
|
|
1831
|
+
<span class="cstat-no" title="statement not covered" > break;</span>
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
} catch {
|
|
1835
|
+
// ignore — inverse side may not exist
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
// Source side one(): pairs with owning table's many(junctionTable, { relationName })
|
|
1839
|
+
tableRelations.push(` ${relation.through.sourceColumn}: one(${sourceTableVar}, {\n fields: [${tableVarName}.${relation.through.sourceColumn}],\n references: [${sourceTableVar}.${sourceId}],\n relationName: \"${owningRelationName}\"\n })`);
|
|
1840
|
+
|
|
1841
|
+
// Target side one(): pairs with inverse table's many(junctionTable, { relationName })
|
|
1842
|
+
const targetRelName = inverseRelationName ?? owningRelationName;
|
|
1843
|
+
tableRelations.push(` ${relation.through.targetColumn}: one(${targetTableVar}, {\n fields: [${tableVarName}.${relation.through.targetColumn}],\n references: [${targetTableVar}.${targetId}],\n relationName: \"${targetRelName}\"\n })`);
|
|
1844
|
+
}
|
|
1845
|
+
} else {
|
|
1846
|
+
const resolvedRelations = resolveCollectionRelations(collection);
|
|
1847
|
+
for (const [relationKey, rel] of Object.entries(resolvedRelations)) {
|
|
1848
|
+
try {
|
|
1849
|
+
const target = rel.target();
|
|
1850
|
+
const targetTableVar = getTableVarName(getTableName(target));
|
|
1851
|
+
const relationName = rel.relationName ?? <span class="branch-1 cbranch-no" title="branch not covered" >relationKey;</span>
|
|
1852
|
+
|
|
1853
|
+
// Determine the correct relation name for Drizzle
|
|
1854
|
+
// For inverse relations, we should use the current relation's name, not the inverse name
|
|
1855
|
+
const drizzleRelationName = relationName;
|
|
1856
|
+
|
|
1857
|
+
if (rel.cardinality === "one") {
|
|
1858
|
+
if (rel.direction === "owning" && rel.localKey) {
|
|
1859
|
+
tableRelations.push(` ${relationKey}: one(${targetTableVar}, {\n fields: [${tableVarName}.${rel.localKey}],\n references: [${targetTableVar}.${getPrimaryKeyName(target)}],\n relationName: \"${drizzleRelationName}\"\n })`);
|
|
1860
|
+
} else if (rel.direction === "inverse" && rel.foreignKeyOnTarget) {
|
|
1861
|
+
const sourceIdField = getPrimaryKeyName(collection);
|
|
1862
|
+
tableRelations.push(` ${relationKey}: one(${targetTableVar}, {\n fields: [${tableVarName}.${sourceIdField}],\n references: [${targetTableVar}.${rel.foreignKeyOnTarget}],\n relationName: \"${drizzleRelationName}\"\n })`);
|
|
1863
|
+
} else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="if path not taken" >I</span><span class="missing-if-branch" title="else path not taken" >E</span>if (rel.direction === "inverse" && !rel.foreignKeyOnTarget) {</span>
|
|
1864
|
+
// Handle inverse one-to-one relations where the FK is on the target table
|
|
1865
|
+
// but foreignKeyOnTarget is not explicitly specified
|
|
1866
|
+
// In this case, we need to find the corresponding owning relation on the target
|
|
1867
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1868
|
+
const targetCollection = <span class="cstat-no" title="statement not covered" >rel.target();</span>
|
|
1869
|
+
const targetResolvedRelations = <span class="cstat-no" title="statement not covered" >resolveCollectionRelations(targetCollection);</span>
|
|
1870
|
+
|
|
1871
|
+
// Find the owning relation on the target that points back to this collection
|
|
1872
|
+
const correspondingRelation = <span class="cstat-no" title="statement not covered" >Object.values(targetResolvedRelations).find(<span class="fstat-no" title="function not covered" >targetRel </span>=></span>
|
|
1873
|
+
<span class="cstat-no" title="statement not covered" > targetRel.direction === "owning" &&</span>
|
|
1874
|
+
targetRel.cardinality === "one" &&
|
|
1875
|
+
targetRel.target().slug === collection.slug
|
|
1876
|
+
);
|
|
1877
|
+
|
|
1878
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (correspondingRelation && correspondingRelation.localKey) {</span>
|
|
1879
|
+
const sourceIdField = <span class="cstat-no" title="statement not covered" >getPrimaryKeyName(collection);</span>
|
|
1880
|
+
<span class="cstat-no" title="statement not covered" > tableRelations.push(` ${relationKey}: one(${targetTableVar}, {\n fields: [${tableVarName}.${sourceIdField}],\n references: [${targetTableVar}.${correspondingRelation.localKey}],\n relationName: \"${drizzleRelationName}\"\n })`);</span>
|
|
1881
|
+
}
|
|
1882
|
+
} catch (e) {
|
|
1883
|
+
<span class="cstat-no" title="statement not covered" > console.warn(`Could not resolve inverse one-to-one relation '${relationKey}':`, e);</span>
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
} else if (rel.cardinality === "many") {
|
|
1887
|
+
if (rel.direction === "inverse" && rel.foreignKeyOnTarget) {
|
|
1888
|
+
// One-to-many inverse relation
|
|
1889
|
+
tableRelations.push(` ${relationKey}: many(${targetTableVar}, { relationName: \"${drizzleRelationName}\" })`);
|
|
1890
|
+
} else if (rel.through) {
|
|
1891
|
+
// Many-to-many owning relation with explicit junction table
|
|
1892
|
+
const junctionTableVar = getTableVarName(rel.through.table);
|
|
1893
|
+
tableRelations.push(` ${relationKey}: many(${junctionTableVar}, { relationName: \"${drizzleRelationName}\" })`);
|
|
1894
|
+
} else <span class="missing-if-branch" title="if path not taken" >I</span>if (rel.direction === "inverse" && rel.inverseRelationName) {
|
|
1895
|
+
// Many-to-many inverse relation - find the corresponding owning relation's junction table
|
|
1896
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1897
|
+
const targetCollection = <span class="cstat-no" title="statement not covered" >rel.target();</span>
|
|
1898
|
+
const targetResolvedRelations = <span class="cstat-no" title="statement not covered" >resolveCollectionRelations(targetCollection);</span>
|
|
1899
|
+
|
|
1900
|
+
// Find the corresponding owning many-to-many relation on the target
|
|
1901
|
+
const correspondingRelation = <span class="cstat-no" title="statement not covered" >Object.values(targetResolvedRelations).find(<span class="fstat-no" title="function not covered" >targetRel </span>=></span>
|
|
1902
|
+
<span class="cstat-no" title="statement not covered" > targetRel.direction === "owning" &&</span>
|
|
1903
|
+
targetRel.cardinality === "many" &&
|
|
1904
|
+
targetRel.through &&
|
|
1905
|
+
targetRel.relationName === rel.inverseRelationName
|
|
1906
|
+
);
|
|
1907
|
+
|
|
1908
|
+
<span class="cstat-no" title="statement not covered" > if (correspondingRelation && correspondingRelation.through) {</span>
|
|
1909
|
+
const junctionTableVar = <span class="cstat-no" title="statement not covered" >getTableVarName(correspondingRelation.through.table);</span>
|
|
1910
|
+
<span class="cstat-no" title="statement not covered" > tableRelations.push(` ${relationKey}: many(${junctionTableVar}, { relationName: \"${drizzleRelationName}\" })`);</span>
|
|
1911
|
+
} else {
|
|
1912
|
+
<span class="cstat-no" title="statement not covered" > console.warn(`Could not find corresponding owning many-to-many relation for inverse relation '${relationKey}' on '${collection.name}'`);</span>
|
|
1913
|
+
}
|
|
1914
|
+
} catch (e) {
|
|
1915
|
+
<span class="cstat-no" title="statement not covered" > console.warn(`Could not resolve inverse many-to-many relation '${relationKey}':`, e);</span>
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
// joinPath relations don't generate Drizzle relations - they use existing user tables
|
|
1919
|
+
}
|
|
1920
|
+
} catch (e) {
|
|
1921
|
+
<span class="cstat-no" title="statement not covered" > console.warn(`Could not generate relation ${relationKey} for ${collection.name}:`, e);</span>
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
if (tableRelations.length > 0) {
|
|
1927
|
+
const relVarName = `${tableVarName}Relations`;
|
|
1928
|
+
schemaContent += `export const ${relVarName} = drizzleRelations(${tableVarName}, ({ one, many }) => ({\n${tableRelations.join(",\n")}\n}));\n\n`;
|
|
1929
|
+
if (!exportedRelationVars.includes(relVarName)) exportedRelationVars.push(relVarName);
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
// <<< ADDED: Final aggregated exports block
|
|
1934
|
+
const tablesExport = `export const tables = { ${exportedTableVars.join(", ")} };\n`;
|
|
1935
|
+
const enumsExport = `export const enums = { ${exportedEnumVars.join(", ")} };\n`;
|
|
1936
|
+
const relationsExport = `export const relations = { ${exportedRelationVars.join(", ")} };\n\n`;
|
|
1937
|
+
schemaContent += tablesExport + enumsExport + relationsExport;
|
|
1938
|
+
|
|
1939
|
+
return schemaContent;
|
|
1940
|
+
};
|
|
1941
|
+
</pre></td></tr></table></pre>
|
|
1942
|
+
|
|
1943
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
1944
|
+
</div><!-- /wrapper -->
|
|
1945
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
1946
|
+
Code coverage generated by
|
|
1947
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1948
|
+
at 2026-04-06T04:35:23.770Z
|
|
1949
|
+
</div>
|
|
1950
|
+
<script src="../prettify.js"></script>
|
|
1951
|
+
<script>
|
|
1952
|
+
window.onload = function () {
|
|
1953
|
+
prettyPrint();
|
|
1954
|
+
};
|
|
1955
|
+
</script>
|
|
1956
|
+
<script src="../sorter.js"></script>
|
|
1957
|
+
<script src="../block-navigation.js"></script>
|
|
1958
|
+
</body>
|
|
1959
|
+
</html>
|
|
1960
|
+
|