dsl-to-sql 1.0.0-fabric-1p-development.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/.turbo/turbo-build.log +9 -0
  2. package/.turbo/turbo-check-types.log +4 -0
  3. package/.turbo/turbo-lint.log +126 -0
  4. package/README.md +45 -0
  5. package/coverage/base.css +224 -0
  6. package/coverage/block-navigation.js +87 -0
  7. package/coverage/favicon.png +0 -0
  8. package/coverage/index.html +236 -0
  9. package/coverage/prettify.css +1 -0
  10. package/coverage/prettify.js +2 -0
  11. package/coverage/sort-arrow-sprite.png +0 -0
  12. package/coverage/sorter.js +210 -0
  13. package/coverage/src/constants.ts.html +826 -0
  14. package/coverage/src/database_types.ts.html +136 -0
  15. package/coverage/src/epm-query-builder/EpmQueryBuilder.ts.html +166 -0
  16. package/coverage/src/epm-query-builder/base/BaseAdvancedAggregations.ts.html +568 -0
  17. package/coverage/src/epm-query-builder/base/BaseAnalyticalFunctions.ts.html +694 -0
  18. package/coverage/src/epm-query-builder/base/BaseCTEGenerator.ts.html +1459 -0
  19. package/coverage/src/epm-query-builder/base/BaseCountQueryBuilder.ts.html +400 -0
  20. package/coverage/src/epm-query-builder/base/BaseMeasureBuilder.ts.html +295 -0
  21. package/coverage/src/epm-query-builder/base/BaseOrderBuilder.ts.html +670 -0
  22. package/coverage/src/epm-query-builder/base/BasePaginationBuilder.ts.html +364 -0
  23. package/coverage/src/epm-query-builder/base/BaseQueryBuilder.ts.html +238 -0
  24. package/coverage/src/epm-query-builder/base/BaseRollupBuilder.ts.html +532 -0
  25. package/coverage/src/epm-query-builder/base/BaseSqlBuilder.ts.html +601 -0
  26. package/coverage/src/epm-query-builder/base/BaseSuperFilterBuilder.ts.html +1966 -0
  27. package/coverage/src/epm-query-builder/base/BaseUtilities.ts.html +1798 -0
  28. package/coverage/src/epm-query-builder/base/ColumnRefUtils.ts.html +211 -0
  29. package/coverage/src/epm-query-builder/base/RelationshipResolver.ts.html +706 -0
  30. package/coverage/src/epm-query-builder/base/SharedFilterBuilder.ts.html +1717 -0
  31. package/coverage/src/epm-query-builder/base/index.html +326 -0
  32. package/coverage/src/epm-query-builder/constants/Aggregations.ts.html +133 -0
  33. package/coverage/src/epm-query-builder/constants/Database.ts.html +103 -0
  34. package/coverage/src/epm-query-builder/constants/Source.ts.html +106 -0
  35. package/coverage/src/epm-query-builder/constants/index.html +146 -0
  36. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbAdvancedAggregations.ts.html +286 -0
  37. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbJoinBuilder.ts.html +280 -0
  38. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbMeasureBuilder.ts.html +1924 -0
  39. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbOrderBuilder.ts.html +769 -0
  40. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbPaginationBuilder.ts.html +643 -0
  41. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbQueryBuilder.ts.html +2644 -0
  42. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbRollupBuilder.ts.html +478 -0
  43. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbSuperFilterBuilder.ts.html +1195 -0
  44. package/coverage/src/epm-query-builder/dialects/duckdb/index.html +221 -0
  45. package/coverage/src/epm-query-builder/errors/QueryBuilderErrors.ts.html +280 -0
  46. package/coverage/src/epm-query-builder/errors/index.html +116 -0
  47. package/coverage/src/epm-query-builder/index.html +116 -0
  48. package/coverage/src/epm-query-builder/interfaces/IDatabaseQueryBuilder.ts.html +100 -0
  49. package/coverage/src/epm-query-builder/interfaces/index.html +131 -0
  50. package/coverage/src/epm-query-builder/interfaces/index.ts.html +88 -0
  51. package/coverage/src/epm-query-builder/utils/format.ts.html +151 -0
  52. package/coverage/src/epm-query-builder/utils/index.html +146 -0
  53. package/coverage/src/epm-query-builder/utils/sql.ts.html +247 -0
  54. package/coverage/src/epm-query-builder/utils/validation.ts.html +124 -0
  55. package/coverage/src/epm-query-builder/validation/QueryOptionsValidator.ts.html +631 -0
  56. package/coverage/src/epm-query-builder/validation/SqlQueryValidator.ts.html +475 -0
  57. package/coverage/src/epm-query-builder/validation/index.html +131 -0
  58. package/coverage/src/filters/FilterConditionBuilder.ts.html +427 -0
  59. package/coverage/src/filters/filter-types.ts.html +484 -0
  60. package/coverage/src/filters/index.html +131 -0
  61. package/coverage/src/index.html +176 -0
  62. package/coverage/src/index.ts.html +103 -0
  63. package/coverage/src/js-lib/JsToSqlParser.ts.html +736 -0
  64. package/coverage/src/js-lib/ParseContext.ts.html +532 -0
  65. package/coverage/src/js-lib/db/azuresql/AzureSqlCallExpressionVisitor.ts.html +196 -0
  66. package/coverage/src/js-lib/db/azuresql/index.html +116 -0
  67. package/coverage/src/js-lib/db/base/ArrayExpressionVisitor.ts.html +133 -0
  68. package/coverage/src/js-lib/db/base/AssignmentExpressionVisitor.ts.html +187 -0
  69. package/coverage/src/js-lib/db/base/BinaryExpressionVisitor.ts.html +223 -0
  70. package/coverage/src/js-lib/db/base/CallExpressionVisitor.ts.html +5479 -0
  71. package/coverage/src/js-lib/db/base/IdentifierVisitor.ts.html +283 -0
  72. package/coverage/src/js-lib/db/base/LiteralVisitor.ts.html +199 -0
  73. package/coverage/src/js-lib/db/base/MemberExpressionVisitor.ts.html +193 -0
  74. package/coverage/src/js-lib/db/base/ProgramVisitor.ts.html +139 -0
  75. package/coverage/src/js-lib/db/base/UnaryExpressionVisitor.ts.html +181 -0
  76. package/coverage/src/js-lib/db/base/VisitorInterface.ts.html +103 -0
  77. package/coverage/src/js-lib/db/base/index.html +251 -0
  78. package/coverage/src/js-lib/db/bigquery/BigQueryCallExpressionVisitor.ts.html +1747 -0
  79. package/coverage/src/js-lib/db/bigquery/index.html +116 -0
  80. package/coverage/src/js-lib/db/commonTransforms.ts.html +2074 -0
  81. package/coverage/src/js-lib/db/databricks/DatabricksCallExpressionVisitor.ts.html +1303 -0
  82. package/coverage/src/js-lib/db/databricks/index.html +116 -0
  83. package/coverage/src/js-lib/db/fabricsql/FabricSqlCallExpressionVisitor.ts.html +196 -0
  84. package/coverage/src/js-lib/db/fabricsql/index.html +116 -0
  85. package/coverage/src/js-lib/db/fabricwarehouse/FabricWarehouseCallExpressionVisitor.ts.html +292 -0
  86. package/coverage/src/js-lib/db/fabricwarehouse/index.html +116 -0
  87. package/coverage/src/js-lib/db/index.html +116 -0
  88. package/coverage/src/js-lib/db/postgresql/PostgreSqlCallExpressionVisitor.ts.html +985 -0
  89. package/coverage/src/js-lib/db/postgresql/index.html +116 -0
  90. package/coverage/src/js-lib/db/redshift/RedshiftCallExpressionVisitor.ts.html +685 -0
  91. package/coverage/src/js-lib/db/redshift/index.html +116 -0
  92. package/coverage/src/js-lib/db/sample/SampleCallExpressionVisitor.ts.html +196 -0
  93. package/coverage/src/js-lib/db/sample/index.html +116 -0
  94. package/coverage/src/js-lib/db/snowflake/SnowflakeCallExpressionVisitor.ts.html +1447 -0
  95. package/coverage/src/js-lib/db/snowflake/index.html +116 -0
  96. package/coverage/src/js-lib/db/validator/FormulaValidator.ts.html +4162 -0
  97. package/coverage/src/js-lib/db/validator/index.html +116 -0
  98. package/coverage/src/js-lib/index.html +131 -0
  99. package/coverage/src/js-lib/objects/BaseObject.ts.html +169 -0
  100. package/coverage/src/js-lib/objects/DateObject.ts.html +169 -0
  101. package/coverage/src/js-lib/objects/PctObject.ts.html +178 -0
  102. package/coverage/src/js-lib/objects/index.html +146 -0
  103. package/coverage/src/query-builder/PaginationBuilder.ts.html +142 -0
  104. package/coverage/src/query-builder/QueryBuilder.ts.html +3118 -0
  105. package/coverage/src/query-builder/SuperFilterBuilder.ts.html +1969 -0
  106. package/coverage/src/query-builder/index.html +146 -0
  107. package/coverage/src/runtime_var.ts.html +109 -0
  108. package/coverage/src/sql-lib/binary_expr.ts.html +133 -0
  109. package/coverage/src/sql-lib/case.ts.html +133 -0
  110. package/coverage/src/sql-lib/column.ts.html +139 -0
  111. package/coverage/src/sql-lib/else.ts.html +124 -0
  112. package/coverage/src/sql-lib/function.ts.html +112 -0
  113. package/coverage/src/sql-lib/index.html +251 -0
  114. package/coverage/src/sql-lib/join.ts.html +127 -0
  115. package/coverage/src/sql-lib/literal.ts.html +130 -0
  116. package/coverage/src/sql-lib/select.ts.html +547 -0
  117. package/coverage/src/sql-lib/unary_expr.ts.html +112 -0
  118. package/coverage/src/sql-lib/when.ts.html +130 -0
  119. package/coverage/src/sql_query_gen.ts.html +535 -0
  120. package/coverage/src/superFilter/DateFilterFactory.ts.html +625 -0
  121. package/coverage/src/superFilter/dateFunction.ts.html +193 -0
  122. package/coverage/src/superFilter/index.html +131 -0
  123. package/coverage/src/utils.ts.html +571 -0
  124. package/dist/index.cjs +8440 -0
  125. package/dist/index.d.cts +927 -0
  126. package/dist/index.d.cts.map +1 -0
  127. package/dist/index.d.ts +927 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +8387 -0
  130. package/dist/index.js.map +1 -0
  131. package/eslint.config.js +4 -0
  132. package/jest.config.ts +44 -0
  133. package/package.json +45 -0
  134. package/src/constants.ts +247 -0
  135. package/src/epm-query-builder/EpmQueryBuilder.ts +27 -0
  136. package/src/epm-query-builder/base/BaseAdvancedAggregations.ts +161 -0
  137. package/src/epm-query-builder/base/BaseAnalyticalFunctions.ts +203 -0
  138. package/src/epm-query-builder/base/BaseCTEGenerator.ts +458 -0
  139. package/src/epm-query-builder/base/BaseCountQueryBuilder.ts +105 -0
  140. package/src/epm-query-builder/base/BaseMeasureBuilder.ts +87 -0
  141. package/src/epm-query-builder/base/BaseOrderBuilder.ts +195 -0
  142. package/src/epm-query-builder/base/BasePaginationBuilder.ts +93 -0
  143. package/src/epm-query-builder/base/BaseQueryBuilder.ts +51 -0
  144. package/src/epm-query-builder/base/BaseRollupBuilder.ts +149 -0
  145. package/src/epm-query-builder/base/BaseSqlBuilder.ts +172 -0
  146. package/src/epm-query-builder/base/BaseSuperFilterBuilder.ts +627 -0
  147. package/src/epm-query-builder/base/BaseUtilities.ts +571 -0
  148. package/src/epm-query-builder/base/ColumnRefUtils.ts +42 -0
  149. package/src/epm-query-builder/base/RelationshipResolver.ts +207 -0
  150. package/src/epm-query-builder/base/SharedFilterBuilder.ts +544 -0
  151. package/src/epm-query-builder/constants/Aggregations.ts +16 -0
  152. package/src/epm-query-builder/constants/Database.ts +6 -0
  153. package/src/epm-query-builder/constants/Source.ts +7 -0
  154. package/src/epm-query-builder/dialects/duckdb/DuckDbAdvancedAggregations.ts +67 -0
  155. package/src/epm-query-builder/dialects/duckdb/DuckDbJoinBuilder.ts +65 -0
  156. package/src/epm-query-builder/dialects/duckdb/DuckDbMeasureBuilder.ts +626 -0
  157. package/src/epm-query-builder/dialects/duckdb/DuckDbOrderBuilder.ts +228 -0
  158. package/src/epm-query-builder/dialects/duckdb/DuckDbPaginationBuilder.ts +186 -0
  159. package/src/epm-query-builder/dialects/duckdb/DuckDbQueryBuilder.ts +853 -0
  160. package/src/epm-query-builder/dialects/duckdb/DuckDbRollupBuilder.ts +131 -0
  161. package/src/epm-query-builder/dialects/duckdb/DuckDbSuperFilterBuilder.ts +370 -0
  162. package/src/epm-query-builder/errors/QueryBuilderErrors.ts +65 -0
  163. package/src/epm-query-builder/interfaces/IDatabaseQueryBuilder.ts +5 -0
  164. package/src/epm-query-builder/interfaces/index.ts +1 -0
  165. package/src/epm-query-builder/types/query-builder-types.d.ts +289 -0
  166. package/src/epm-query-builder/utils/format.ts +22 -0
  167. package/src/epm-query-builder/utils/sql.ts +54 -0
  168. package/src/epm-query-builder/utils/validation.ts +13 -0
  169. package/src/epm-query-builder/validation/QueryOptionsValidator.ts +182 -0
  170. package/src/epm-query-builder/validation/SqlQueryValidator.ts +130 -0
  171. package/src/filters/FilterConditionBuilder.ts +114 -0
  172. package/src/filters/filter-types.ts +133 -0
  173. package/src/index.ts +10 -0
  174. package/src/js-lib/JsToSqlParser.ts +217 -0
  175. package/src/js-lib/ParseContext.ts +149 -0
  176. package/src/js-lib/db/base/ArrayExpressionVisitor.ts +16 -0
  177. package/src/js-lib/db/base/AssignmentExpressionVisitor.ts +34 -0
  178. package/src/js-lib/db/base/BinaryExpressionVisitor.ts +46 -0
  179. package/src/js-lib/db/base/CallExpressionVisitor.ts +1798 -0
  180. package/src/js-lib/db/base/IdentifierVisitor.ts +66 -0
  181. package/src/js-lib/db/base/LiteralVisitor.ts +38 -0
  182. package/src/js-lib/db/base/MemberExpressionVisitor.ts +36 -0
  183. package/src/js-lib/db/base/ProgramVisitor.ts +18 -0
  184. package/src/js-lib/db/base/UnaryExpressionVisitor.ts +32 -0
  185. package/src/js-lib/db/base/VisitorInterface.ts +6 -0
  186. package/src/js-lib/db/validator/FormulaValidator.ts +1235 -0
  187. package/src/js-lib/objects/BaseObject.ts +28 -0
  188. package/src/js-lib/objects/DateObject.ts +28 -0
  189. package/src/js-lib/objects/PctObject.ts +31 -0
  190. package/src/query-builder/PaginationBuilder.ts +19 -0
  191. package/src/query-builder/QueryBuilder.ts +1035 -0
  192. package/src/query-builder/SuperFilterBuilder.ts +628 -0
  193. package/src/runtime_var.ts +8 -0
  194. package/src/sql-lib/binary_expr.ts +16 -0
  195. package/src/sql-lib/case.ts +16 -0
  196. package/src/sql-lib/column.ts +18 -0
  197. package/src/sql-lib/else.ts +13 -0
  198. package/src/sql-lib/function.ts +9 -0
  199. package/src/sql-lib/join.ts +14 -0
  200. package/src/sql-lib/literal.ts +15 -0
  201. package/src/sql-lib/select.ts +154 -0
  202. package/src/sql-lib/unary_expr.ts +9 -0
  203. package/src/sql-lib/when.ts +15 -0
  204. package/src/sql-types.d.ts +565 -0
  205. package/src/sql_query_gen.ts +150 -0
  206. package/src/superFilter/DateFilterFactory.ts +180 -0
  207. package/src/superFilter/dateFunction.ts +36 -0
  208. package/src/utils.ts +354 -0
  209. package/test-output/report/junit.xml +329 -0
  210. package/tests/JsToSqlParser.test.ts +163 -0
  211. package/tests/QueryBuilder.test.ts +1320 -0
  212. package/tests/js-lib/CallExpressionVisitor.test.ts +820 -0
  213. package/tests/mocks/MockQueryResolver.ts +14 -0
  214. package/tests/sanity.test.ts +146 -0
  215. package/tests/sql-lib/binary_expr.test.ts +75 -0
  216. package/tests/sql-lib/case.test.ts +117 -0
  217. package/tests/sql-lib/column.test.ts +87 -0
  218. package/tests/sql-lib/else.test.ts +56 -0
  219. package/tests/sql-lib/function.test.ts +96 -0
  220. package/tests/sql-lib/literal.test.ts +75 -0
  221. package/tests/sql-lib/select.test.ts +245 -0
  222. package/tests/sql-lib/unary_expr.test.ts +32 -0
  223. package/tests/utils.test.ts +13 -0
  224. package/tsconfig.json +24 -0
  225. package/tsdown.config.ts +23 -0
@@ -0,0 +1,1924 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/epm-query-builder/dialects/duckdb/DuckDbMeasureBuilder.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/epm-query-builder/dialects/duckdb</a> DuckDbMeasureBuilder.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">0% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>0/269</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">0% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>0/225</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">0% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>0/48</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">0% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>0/265</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 low'></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></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
680
+ <span class="cline-any cline-neutral">&nbsp;</span>
681
+ <span class="cline-any cline-neutral">&nbsp;</span>
682
+ <span class="cline-any cline-neutral">&nbsp;</span>
683
+ <span class="cline-any cline-neutral">&nbsp;</span>
684
+ <span class="cline-any cline-neutral">&nbsp;</span>
685
+ <span class="cline-any cline-neutral">&nbsp;</span>
686
+ <span class="cline-any cline-neutral">&nbsp;</span>
687
+ <span class="cline-any cline-no">&nbsp;</span>
688
+ <span class="cline-any cline-no">&nbsp;</span>
689
+ <span class="cline-any cline-no">&nbsp;</span>
690
+ <span class="cline-any cline-no">&nbsp;</span>
691
+ <span class="cline-any cline-neutral">&nbsp;</span>
692
+ <span class="cline-any cline-neutral">&nbsp;</span>
693
+ <span class="cline-any cline-no">&nbsp;</span>
694
+ <span class="cline-any cline-no">&nbsp;</span>
695
+ <span class="cline-any cline-no">&nbsp;</span>
696
+ <span class="cline-any cline-neutral">&nbsp;</span>
697
+ <span class="cline-any cline-no">&nbsp;</span>
698
+ <span class="cline-any cline-no">&nbsp;</span>
699
+ <span class="cline-any cline-neutral">&nbsp;</span>
700
+ <span class="cline-any cline-no">&nbsp;</span>
701
+ <span class="cline-any cline-no">&nbsp;</span>
702
+ <span class="cline-any cline-neutral">&nbsp;</span>
703
+ <span class="cline-any cline-no">&nbsp;</span>
704
+ <span class="cline-any cline-no">&nbsp;</span>
705
+ <span class="cline-any cline-neutral">&nbsp;</span>
706
+ <span class="cline-any cline-neutral">&nbsp;</span>
707
+ <span class="cline-any cline-no">&nbsp;</span>
708
+ <span class="cline-any cline-neutral">&nbsp;</span>
709
+ <span class="cline-any cline-no">&nbsp;</span>
710
+ <span class="cline-any cline-no">&nbsp;</span>
711
+ <span class="cline-any cline-no">&nbsp;</span>
712
+ <span class="cline-any cline-no">&nbsp;</span>
713
+ <span class="cline-any cline-no">&nbsp;</span>
714
+ <span class="cline-any cline-neutral">&nbsp;</span>
715
+ <span class="cline-any cline-neutral">&nbsp;</span>
716
+ <span class="cline-any cline-no">&nbsp;</span>
717
+ <span class="cline-any cline-no">&nbsp;</span>
718
+ <span class="cline-any cline-no">&nbsp;</span>
719
+ <span class="cline-any cline-neutral">&nbsp;</span>
720
+ <span class="cline-any cline-neutral">&nbsp;</span>
721
+ <span class="cline-any cline-no">&nbsp;</span>
722
+ <span class="cline-any cline-no">&nbsp;</span>
723
+ <span class="cline-any cline-no">&nbsp;</span>
724
+ <span class="cline-any cline-neutral">&nbsp;</span>
725
+ <span class="cline-any cline-no">&nbsp;</span>
726
+ <span class="cline-any cline-no">&nbsp;</span>
727
+ <span class="cline-any cline-no">&nbsp;</span>
728
+ <span class="cline-any cline-no">&nbsp;</span>
729
+ <span class="cline-any cline-neutral">&nbsp;</span>
730
+ <span class="cline-any cline-neutral">&nbsp;</span>
731
+ <span class="cline-any cline-no">&nbsp;</span>
732
+ <span class="cline-any cline-no">&nbsp;</span>
733
+ <span class="cline-any cline-no">&nbsp;</span>
734
+ <span class="cline-any cline-neutral">&nbsp;</span>
735
+ <span class="cline-any cline-no">&nbsp;</span>
736
+ <span class="cline-any cline-no">&nbsp;</span>
737
+ <span class="cline-any cline-no">&nbsp;</span>
738
+ <span class="cline-any cline-no">&nbsp;</span>
739
+ <span class="cline-any cline-no">&nbsp;</span>
740
+ <span class="cline-any cline-no">&nbsp;</span>
741
+ <span class="cline-any cline-neutral">&nbsp;</span>
742
+ <span class="cline-any cline-no">&nbsp;</span>
743
+ <span class="cline-any cline-no">&nbsp;</span>
744
+ <span class="cline-any cline-no">&nbsp;</span>
745
+ <span class="cline-any cline-no">&nbsp;</span>
746
+ <span class="cline-any cline-no">&nbsp;</span>
747
+ <span class="cline-any cline-neutral">&nbsp;</span>
748
+ <span class="cline-any cline-no">&nbsp;</span>
749
+ <span class="cline-any cline-neutral">&nbsp;</span>
750
+ <span class="cline-any cline-neutral">&nbsp;</span>
751
+ <span class="cline-any cline-no">&nbsp;</span>
752
+ <span class="cline-any cline-no">&nbsp;</span>
753
+ <span class="cline-any cline-no">&nbsp;</span>
754
+ <span class="cline-any cline-no">&nbsp;</span>
755
+ <span class="cline-any cline-no">&nbsp;</span>
756
+ <span class="cline-any cline-no">&nbsp;</span>
757
+ <span class="cline-any cline-no">&nbsp;</span>
758
+ <span class="cline-any cline-no">&nbsp;</span>
759
+ <span class="cline-any cline-no">&nbsp;</span>
760
+ <span class="cline-any cline-no">&nbsp;</span>
761
+ <span class="cline-any cline-no">&nbsp;</span>
762
+ <span class="cline-any cline-no">&nbsp;</span>
763
+ <span class="cline-any cline-neutral">&nbsp;</span>
764
+ <span class="cline-any cline-no">&nbsp;</span>
765
+ <span class="cline-any cline-no">&nbsp;</span>
766
+ <span class="cline-any cline-neutral">&nbsp;</span>
767
+ <span class="cline-any cline-no">&nbsp;</span>
768
+ <span class="cline-any cline-neutral">&nbsp;</span>
769
+ <span class="cline-any cline-neutral">&nbsp;</span>
770
+ <span class="cline-any cline-no">&nbsp;</span>
771
+ <span class="cline-any cline-neutral">&nbsp;</span>
772
+ <span class="cline-any cline-no">&nbsp;</span>
773
+ <span class="cline-any cline-neutral">&nbsp;</span>
774
+ <span class="cline-any cline-neutral">&nbsp;</span>
775
+ <span class="cline-any cline-no">&nbsp;</span>
776
+ <span class="cline-any cline-no">&nbsp;</span>
777
+ <span class="cline-any cline-no">&nbsp;</span>
778
+ <span class="cline-any cline-neutral">&nbsp;</span>
779
+ <span class="cline-any cline-neutral">&nbsp;</span>
780
+ <span class="cline-any cline-no">&nbsp;</span>
781
+ <span class="cline-any cline-no">&nbsp;</span>
782
+ <span class="cline-any cline-no">&nbsp;</span>
783
+ <span class="cline-any cline-neutral">&nbsp;</span>
784
+ <span class="cline-any cline-neutral">&nbsp;</span>
785
+ <span class="cline-any cline-no">&nbsp;</span>
786
+ <span class="cline-any cline-no">&nbsp;</span>
787
+ <span class="cline-any cline-neutral">&nbsp;</span>
788
+ <span class="cline-any cline-no">&nbsp;</span>
789
+ <span class="cline-any cline-no">&nbsp;</span>
790
+ <span class="cline-any cline-neutral">&nbsp;</span>
791
+ <span class="cline-any cline-neutral">&nbsp;</span>
792
+ <span class="cline-any cline-no">&nbsp;</span>
793
+ <span class="cline-any cline-neutral">&nbsp;</span>
794
+ <span class="cline-any cline-no">&nbsp;</span>
795
+ <span class="cline-any cline-neutral">&nbsp;</span>
796
+ <span class="cline-any cline-neutral">&nbsp;</span>
797
+ <span class="cline-any cline-no">&nbsp;</span>
798
+ <span class="cline-any cline-neutral">&nbsp;</span>
799
+ <span class="cline-any cline-neutral">&nbsp;</span>
800
+ <span class="cline-any cline-no">&nbsp;</span>
801
+ <span class="cline-any cline-neutral">&nbsp;</span>
802
+ <span class="cline-any cline-no">&nbsp;</span>
803
+ <span class="cline-any cline-neutral">&nbsp;</span>
804
+ <span class="cline-any cline-no">&nbsp;</span>
805
+ <span class="cline-any cline-no">&nbsp;</span>
806
+ <span class="cline-any cline-neutral">&nbsp;</span>
807
+ <span class="cline-any cline-no">&nbsp;</span>
808
+ <span class="cline-any cline-no">&nbsp;</span>
809
+ <span class="cline-any cline-neutral">&nbsp;</span>
810
+ <span class="cline-any cline-no">&nbsp;</span>
811
+ <span class="cline-any cline-no">&nbsp;</span>
812
+ <span class="cline-any cline-neutral">&nbsp;</span>
813
+ <span class="cline-any cline-no">&nbsp;</span>
814
+ <span class="cline-any cline-no">&nbsp;</span>
815
+ <span class="cline-any cline-neutral">&nbsp;</span>
816
+ <span class="cline-any cline-no">&nbsp;</span>
817
+ <span class="cline-any cline-no">&nbsp;</span>
818
+ <span class="cline-any cline-neutral">&nbsp;</span>
819
+ <span class="cline-any cline-no">&nbsp;</span>
820
+ <span class="cline-any cline-neutral">&nbsp;</span>
821
+ <span class="cline-any cline-neutral">&nbsp;</span>
822
+ <span class="cline-any cline-no">&nbsp;</span>
823
+ <span class="cline-any cline-no">&nbsp;</span>
824
+ <span class="cline-any cline-no">&nbsp;</span>
825
+ <span class="cline-any cline-no">&nbsp;</span>
826
+ <span class="cline-any cline-neutral">&nbsp;</span>
827
+ <span class="cline-any cline-no">&nbsp;</span>
828
+ <span class="cline-any cline-neutral">&nbsp;</span>
829
+ <span class="cline-any cline-no">&nbsp;</span>
830
+ <span class="cline-any cline-no">&nbsp;</span>
831
+ <span class="cline-any cline-neutral">&nbsp;</span>
832
+ <span class="cline-any cline-no">&nbsp;</span>
833
+ <span class="cline-any cline-neutral">&nbsp;</span>
834
+ <span class="cline-any cline-neutral">&nbsp;</span>
835
+ <span class="cline-any cline-no">&nbsp;</span>
836
+ <span class="cline-any cline-no">&nbsp;</span>
837
+ <span class="cline-any cline-no">&nbsp;</span>
838
+ <span class="cline-any cline-neutral">&nbsp;</span>
839
+ <span class="cline-any cline-neutral">&nbsp;</span>
840
+ <span class="cline-any cline-neutral">&nbsp;</span>
841
+ <span class="cline-any cline-neutral">&nbsp;</span>
842
+ <span class="cline-any cline-neutral">&nbsp;</span>
843
+ <span class="cline-any cline-neutral">&nbsp;</span>
844
+ <span class="cline-any cline-neutral">&nbsp;</span>
845
+ <span class="cline-any cline-neutral">&nbsp;</span>
846
+ <span class="cline-any cline-neutral">&nbsp;</span>
847
+ <span class="cline-any cline-neutral">&nbsp;</span>
848
+ <span class="cline-any cline-neutral">&nbsp;</span>
849
+ <span class="cline-any cline-neutral">&nbsp;</span>
850
+ <span class="cline-any cline-neutral">&nbsp;</span>
851
+ <span class="cline-any cline-neutral">&nbsp;</span>
852
+ <span class="cline-any cline-neutral">&nbsp;</span>
853
+ <span class="cline-any cline-neutral">&nbsp;</span>
854
+ <span class="cline-any cline-neutral">&nbsp;</span>
855
+ <span class="cline-any cline-neutral">&nbsp;</span>
856
+ <span class="cline-any cline-neutral">&nbsp;</span>
857
+ <span class="cline-any cline-neutral">&nbsp;</span>
858
+ <span class="cline-any cline-neutral">&nbsp;</span>
859
+ <span class="cline-any cline-no">&nbsp;</span>
860
+ <span class="cline-any cline-neutral">&nbsp;</span>
861
+ <span class="cline-any cline-neutral">&nbsp;</span>
862
+ <span class="cline-any cline-no">&nbsp;</span>
863
+ <span class="cline-any cline-no">&nbsp;</span>
864
+ <span class="cline-any cline-neutral">&nbsp;</span>
865
+ <span class="cline-any cline-no">&nbsp;</span>
866
+ <span class="cline-any cline-no">&nbsp;</span>
867
+ <span class="cline-any cline-no">&nbsp;</span>
868
+ <span class="cline-any cline-neutral">&nbsp;</span>
869
+ <span class="cline-any cline-neutral">&nbsp;</span>
870
+ <span class="cline-any cline-no">&nbsp;</span>
871
+ <span class="cline-any cline-no">&nbsp;</span>
872
+ <span class="cline-any cline-no">&nbsp;</span>
873
+ <span class="cline-any cline-no">&nbsp;</span>
874
+ <span class="cline-any cline-no">&nbsp;</span>
875
+ <span class="cline-any cline-no">&nbsp;</span>
876
+ <span class="cline-any cline-neutral">&nbsp;</span>
877
+ <span class="cline-any cline-no">&nbsp;</span>
878
+ <span class="cline-any cline-neutral">&nbsp;</span>
879
+ <span class="cline-any cline-neutral">&nbsp;</span>
880
+ <span class="cline-any cline-no">&nbsp;</span>
881
+ <span class="cline-any cline-no">&nbsp;</span>
882
+ <span class="cline-any cline-neutral">&nbsp;</span>
883
+ <span class="cline-any cline-neutral">&nbsp;</span>
884
+ <span class="cline-any cline-no">&nbsp;</span>
885
+ <span class="cline-any cline-no">&nbsp;</span>
886
+ <span class="cline-any cline-neutral">&nbsp;</span>
887
+ <span class="cline-any cline-neutral">&nbsp;</span>
888
+ <span class="cline-any cline-neutral">&nbsp;</span>
889
+ <span class="cline-any cline-neutral">&nbsp;</span>
890
+ <span class="cline-any cline-no">&nbsp;</span>
891
+ <span class="cline-any cline-no">&nbsp;</span>
892
+ <span class="cline-any cline-no">&nbsp;</span>
893
+ <span class="cline-any cline-neutral">&nbsp;</span>
894
+ <span class="cline-any cline-no">&nbsp;</span>
895
+ <span class="cline-any cline-no">&nbsp;</span>
896
+ <span class="cline-any cline-no">&nbsp;</span>
897
+ <span class="cline-any cline-no">&nbsp;</span>
898
+ <span class="cline-any cline-no">&nbsp;</span>
899
+ <span class="cline-any cline-no">&nbsp;</span>
900
+ <span class="cline-any cline-no">&nbsp;</span>
901
+ <span class="cline-any cline-neutral">&nbsp;</span>
902
+ <span class="cline-any cline-no">&nbsp;</span>
903
+ <span class="cline-any cline-no">&nbsp;</span>
904
+ <span class="cline-any cline-no">&nbsp;</span>
905
+ <span class="cline-any cline-neutral">&nbsp;</span>
906
+ <span class="cline-any cline-neutral">&nbsp;</span>
907
+ <span class="cline-any cline-neutral">&nbsp;</span>
908
+ <span class="cline-any cline-neutral">&nbsp;</span>
909
+ <span class="cline-any cline-neutral">&nbsp;</span>
910
+ <span class="cline-any cline-neutral">&nbsp;</span>
911
+ <span class="cline-any cline-neutral">&nbsp;</span>
912
+ <span class="cline-any cline-no">&nbsp;</span>
913
+ <span class="cline-any cline-no">&nbsp;</span>
914
+ <span class="cline-any cline-neutral">&nbsp;</span>
915
+ <span class="cline-any cline-no">&nbsp;</span>
916
+ <span class="cline-any cline-no">&nbsp;</span>
917
+ <span class="cline-any cline-no">&nbsp;</span>
918
+ <span class="cline-any cline-no">&nbsp;</span>
919
+ <span class="cline-any cline-neutral">&nbsp;</span>
920
+ <span class="cline-any cline-neutral">&nbsp;</span>
921
+ <span class="cline-any cline-no">&nbsp;</span>
922
+ <span class="cline-any cline-neutral">&nbsp;</span>
923
+ <span class="cline-any cline-neutral">&nbsp;</span>
924
+ <span class="cline-any cline-no">&nbsp;</span>
925
+ <span class="cline-any cline-neutral">&nbsp;</span>
926
+ <span class="cline-any cline-neutral">&nbsp;</span>
927
+ <span class="cline-any cline-no">&nbsp;</span>
928
+ <span class="cline-any cline-no">&nbsp;</span>
929
+ <span class="cline-any cline-no">&nbsp;</span>
930
+ <span class="cline-any cline-neutral">&nbsp;</span>
931
+ <span class="cline-any cline-no">&nbsp;</span>
932
+ <span class="cline-any cline-no">&nbsp;</span>
933
+ <span class="cline-any cline-no">&nbsp;</span>
934
+ <span class="cline-any cline-neutral">&nbsp;</span>
935
+ <span class="cline-any cline-no">&nbsp;</span>
936
+ <span class="cline-any cline-no">&nbsp;</span>
937
+ <span class="cline-any cline-no">&nbsp;</span>
938
+ <span class="cline-any cline-no">&nbsp;</span>
939
+ <span class="cline-any cline-no">&nbsp;</span>
940
+ <span class="cline-any cline-no">&nbsp;</span>
941
+ <span class="cline-any cline-no">&nbsp;</span>
942
+ <span class="cline-any cline-no">&nbsp;</span>
943
+ <span class="cline-any cline-no">&nbsp;</span>
944
+ <span class="cline-any cline-no">&nbsp;</span>
945
+ <span class="cline-any cline-neutral">&nbsp;</span>
946
+ <span class="cline-any cline-no">&nbsp;</span>
947
+ <span class="cline-any cline-neutral">&nbsp;</span>
948
+ <span class="cline-any cline-neutral">&nbsp;</span>
949
+ <span class="cline-any cline-no">&nbsp;</span>
950
+ <span class="cline-any cline-no">&nbsp;</span>
951
+ <span class="cline-any cline-no">&nbsp;</span>
952
+ <span class="cline-any cline-neutral">&nbsp;</span>
953
+ <span class="cline-any cline-neutral">&nbsp;</span>
954
+ <span class="cline-any cline-no">&nbsp;</span>
955
+ <span class="cline-any cline-neutral">&nbsp;</span>
956
+ <span class="cline-any cline-neutral">&nbsp;</span>
957
+ <span class="cline-any cline-no">&nbsp;</span>
958
+ <span class="cline-any cline-no">&nbsp;</span>
959
+ <span class="cline-any cline-neutral">&nbsp;</span>
960
+ <span class="cline-any cline-neutral">&nbsp;</span>
961
+ <span class="cline-any cline-no">&nbsp;</span>
962
+ <span class="cline-any cline-no">&nbsp;</span>
963
+ <span class="cline-any cline-no">&nbsp;</span>
964
+ <span class="cline-any cline-no">&nbsp;</span>
965
+ <span class="cline-any cline-neutral">&nbsp;</span>
966
+ <span class="cline-any cline-no">&nbsp;</span>
967
+ <span class="cline-any cline-no">&nbsp;</span>
968
+ <span class="cline-any cline-neutral">&nbsp;</span>
969
+ <span class="cline-any cline-neutral">&nbsp;</span>
970
+ <span class="cline-any cline-no">&nbsp;</span>
971
+ <span class="cline-any cline-no">&nbsp;</span>
972
+ <span class="cline-any cline-no">&nbsp;</span>
973
+ <span class="cline-any cline-no">&nbsp;</span>
974
+ <span class="cline-any cline-no">&nbsp;</span>
975
+ <span class="cline-any cline-no">&nbsp;</span>
976
+ <span class="cline-any cline-no">&nbsp;</span>
977
+ <span class="cline-any cline-neutral">&nbsp;</span>
978
+ <span class="cline-any cline-neutral">&nbsp;</span>
979
+ <span class="cline-any cline-no">&nbsp;</span>
980
+ <span class="cline-any cline-no">&nbsp;</span>
981
+ <span class="cline-any cline-no">&nbsp;</span>
982
+ <span class="cline-any cline-no">&nbsp;</span>
983
+ <span class="cline-any cline-no">&nbsp;</span>
984
+ <span class="cline-any cline-no">&nbsp;</span>
985
+ <span class="cline-any cline-no">&nbsp;</span>
986
+ <span class="cline-any cline-neutral">&nbsp;</span>
987
+ <span class="cline-any cline-neutral">&nbsp;</span>
988
+ <span class="cline-any cline-no">&nbsp;</span>
989
+ <span class="cline-any cline-no">&nbsp;</span>
990
+ <span class="cline-any cline-neutral">&nbsp;</span>
991
+ <span class="cline-any cline-no">&nbsp;</span>
992
+ <span class="cline-any cline-neutral">&nbsp;</span>
993
+ <span class="cline-any cline-neutral">&nbsp;</span>
994
+ <span class="cline-any cline-neutral">&nbsp;</span>
995
+ <span class="cline-any cline-neutral">&nbsp;</span>
996
+ <span class="cline-any cline-neutral">&nbsp;</span>
997
+ <span class="cline-any cline-no">&nbsp;</span>
998
+ <span class="cline-any cline-neutral">&nbsp;</span>
999
+ <span class="cline-any cline-neutral">&nbsp;</span>
1000
+ <span class="cline-any cline-no">&nbsp;</span>
1001
+ <span class="cline-any cline-no">&nbsp;</span>
1002
+ <span class="cline-any cline-no">&nbsp;</span>
1003
+ <span class="cline-any cline-no">&nbsp;</span>
1004
+ <span class="cline-any cline-no">&nbsp;</span>
1005
+ <span class="cline-any cline-no">&nbsp;</span>
1006
+ <span class="cline-any cline-neutral">&nbsp;</span>
1007
+ <span class="cline-any cline-neutral">&nbsp;</span>
1008
+ <span class="cline-any cline-neutral">&nbsp;</span>
1009
+ <span class="cline-any cline-neutral">&nbsp;</span>
1010
+ <span class="cline-any cline-no">&nbsp;</span>
1011
+ <span class="cline-any cline-no">&nbsp;</span>
1012
+ <span class="cline-any cline-neutral">&nbsp;</span>
1013
+ <span class="cline-any cline-neutral">&nbsp;</span>
1014
+ <span class="cline-any cline-neutral">&nbsp;</span>
1015
+ <span class="cline-any cline-no">&nbsp;</span>
1016
+ <span class="cline-any cline-neutral">&nbsp;</span>
1017
+ <span class="cline-any cline-no">&nbsp;</span>
1018
+ <span class="cline-any cline-neutral">&nbsp;</span>
1019
+ <span class="cline-any cline-neutral">&nbsp;</span>
1020
+ <span class="cline-any cline-no">&nbsp;</span>
1021
+ <span class="cline-any cline-no">&nbsp;</span>
1022
+ <span class="cline-any cline-no">&nbsp;</span>
1023
+ <span class="cline-any cline-no">&nbsp;</span>
1024
+ <span class="cline-any cline-no">&nbsp;</span>
1025
+ <span class="cline-any cline-no">&nbsp;</span>
1026
+ <span class="cline-any cline-neutral">&nbsp;</span>
1027
+ <span class="cline-any cline-no">&nbsp;</span>
1028
+ <span class="cline-any cline-neutral">&nbsp;</span>
1029
+ <span class="cline-any cline-neutral">&nbsp;</span>
1030
+ <span class="cline-any cline-neutral">&nbsp;</span>
1031
+ <span class="cline-any cline-neutral">&nbsp;</span>
1032
+ <span class="cline-any cline-no">&nbsp;</span>
1033
+ <span class="cline-any cline-neutral">&nbsp;</span>
1034
+ <span class="cline-any cline-neutral">&nbsp;</span>
1035
+ <span class="cline-any cline-neutral">&nbsp;</span>
1036
+ <span class="cline-any cline-neutral">&nbsp;</span>
1037
+ <span class="cline-any cline-neutral">&nbsp;</span>
1038
+ <span class="cline-any cline-neutral">&nbsp;</span>
1039
+ <span class="cline-any cline-neutral">&nbsp;</span>
1040
+ <span class="cline-any cline-neutral">&nbsp;</span>
1041
+ <span class="cline-any cline-neutral">&nbsp;</span>
1042
+ <span class="cline-any cline-neutral">&nbsp;</span>
1043
+ <span class="cline-any cline-neutral">&nbsp;</span>
1044
+ <span class="cline-any cline-neutral">&nbsp;</span>
1045
+ <span class="cline-any cline-neutral">&nbsp;</span>
1046
+ <span class="cline-any cline-no">&nbsp;</span>
1047
+ <span class="cline-any cline-neutral">&nbsp;</span>
1048
+ <span class="cline-any cline-neutral">&nbsp;</span>
1049
+ <span class="cline-any cline-no">&nbsp;</span>
1050
+ <span class="cline-any cline-neutral">&nbsp;</span>
1051
+ <span class="cline-any cline-neutral">&nbsp;</span>
1052
+ <span class="cline-any cline-neutral">&nbsp;</span>
1053
+ <span class="cline-any cline-neutral">&nbsp;</span>
1054
+ <span class="cline-any cline-neutral">&nbsp;</span>
1055
+ <span class="cline-any cline-neutral">&nbsp;</span>
1056
+ <span class="cline-any cline-neutral">&nbsp;</span>
1057
+ <span class="cline-any cline-neutral">&nbsp;</span>
1058
+ <span class="cline-any cline-neutral">&nbsp;</span>
1059
+ <span class="cline-any cline-neutral">&nbsp;</span>
1060
+ <span class="cline-any cline-neutral">&nbsp;</span>
1061
+ <span class="cline-any cline-neutral">&nbsp;</span>
1062
+ <span class="cline-any cline-neutral">&nbsp;</span>
1063
+ <span class="cline-any cline-neutral">&nbsp;</span>
1064
+ <span class="cline-any cline-neutral">&nbsp;</span>
1065
+ <span class="cline-any cline-neutral">&nbsp;</span>
1066
+ <span class="cline-any cline-neutral">&nbsp;</span>
1067
+ <span class="cline-any cline-neutral">&nbsp;</span>
1068
+ <span class="cline-any cline-neutral">&nbsp;</span>
1069
+ <span class="cline-any cline-no">&nbsp;</span>
1070
+ <span class="cline-any cline-neutral">&nbsp;</span>
1071
+ <span class="cline-any cline-neutral">&nbsp;</span>
1072
+ <span class="cline-any cline-no">&nbsp;</span>
1073
+ <span class="cline-any cline-neutral">&nbsp;</span>
1074
+ <span class="cline-any cline-no">&nbsp;</span>
1075
+ <span class="cline-any cline-neutral">&nbsp;</span>
1076
+ <span class="cline-any cline-no">&nbsp;</span>
1077
+ <span class="cline-any cline-neutral">&nbsp;</span>
1078
+ <span class="cline-any cline-no">&nbsp;</span>
1079
+ <span class="cline-any cline-neutral">&nbsp;</span>
1080
+ <span class="cline-any cline-no">&nbsp;</span>
1081
+ <span class="cline-any cline-neutral">&nbsp;</span>
1082
+ <span class="cline-any cline-no">&nbsp;</span>
1083
+ <span class="cline-any cline-neutral">&nbsp;</span>
1084
+ <span class="cline-any cline-no">&nbsp;</span>
1085
+ <span class="cline-any cline-neutral">&nbsp;</span>
1086
+ <span class="cline-any cline-no">&nbsp;</span>
1087
+ <span class="cline-any cline-neutral">&nbsp;</span>
1088
+ <span class="cline-any cline-no">&nbsp;</span>
1089
+ <span class="cline-any cline-neutral">&nbsp;</span>
1090
+ <span class="cline-any cline-no">&nbsp;</span>
1091
+ <span class="cline-any cline-neutral">&nbsp;</span>
1092
+ <span class="cline-any cline-no">&nbsp;</span>
1093
+ <span class="cline-any cline-neutral">&nbsp;</span>
1094
+ <span class="cline-any cline-no">&nbsp;</span>
1095
+ <span class="cline-any cline-neutral">&nbsp;</span>
1096
+ <span class="cline-any cline-no">&nbsp;</span>
1097
+ <span class="cline-any cline-neutral">&nbsp;</span>
1098
+ <span class="cline-any cline-no">&nbsp;</span>
1099
+ <span class="cline-any cline-neutral">&nbsp;</span>
1100
+ <span class="cline-any cline-neutral">&nbsp;</span>
1101
+ <span class="cline-any cline-neutral">&nbsp;</span>
1102
+ <span class="cline-any cline-no">&nbsp;</span>
1103
+ <span class="cline-any cline-neutral">&nbsp;</span>
1104
+ <span class="cline-any cline-no">&nbsp;</span>
1105
+ <span class="cline-any cline-neutral">&nbsp;</span>
1106
+ <span class="cline-any cline-no">&nbsp;</span>
1107
+ <span class="cline-any cline-neutral">&nbsp;</span>
1108
+ <span class="cline-any cline-no">&nbsp;</span>
1109
+ <span class="cline-any cline-no">&nbsp;</span>
1110
+ <span class="cline-any cline-neutral">&nbsp;</span>
1111
+ <span class="cline-any cline-neutral">&nbsp;</span>
1112
+ <span class="cline-any cline-no">&nbsp;</span>
1113
+ <span class="cline-any cline-no">&nbsp;</span>
1114
+ <span class="cline-any cline-neutral">&nbsp;</span>
1115
+ <span class="cline-any cline-neutral">&nbsp;</span>
1116
+ <span class="cline-any cline-no">&nbsp;</span>
1117
+ <span class="cline-any cline-no">&nbsp;</span>
1118
+ <span class="cline-any cline-neutral">&nbsp;</span>
1119
+ <span class="cline-any cline-neutral">&nbsp;</span>
1120
+ <span class="cline-any cline-no">&nbsp;</span>
1121
+ <span class="cline-any cline-neutral">&nbsp;</span>
1122
+ <span class="cline-any cline-no">&nbsp;</span>
1123
+ <span class="cline-any cline-neutral">&nbsp;</span>
1124
+ <span class="cline-any cline-no">&nbsp;</span>
1125
+ <span class="cline-any cline-neutral">&nbsp;</span>
1126
+ <span class="cline-any cline-no">&nbsp;</span>
1127
+ <span class="cline-any cline-neutral">&nbsp;</span>
1128
+ <span class="cline-any cline-no">&nbsp;</span>
1129
+ <span class="cline-any cline-neutral">&nbsp;</span>
1130
+ <span class="cline-any cline-no">&nbsp;</span>
1131
+ <span class="cline-any cline-neutral">&nbsp;</span>
1132
+ <span class="cline-any cline-neutral">&nbsp;</span>
1133
+ <span class="cline-any cline-neutral">&nbsp;</span>
1134
+ <span class="cline-any cline-no">&nbsp;</span>
1135
+ <span class="cline-any cline-no">&nbsp;</span>
1136
+ <span class="cline-any cline-neutral">&nbsp;</span>
1137
+ <span class="cline-any cline-no">&nbsp;</span>
1138
+ <span class="cline-any cline-neutral">&nbsp;</span>
1139
+ <span class="cline-any cline-no">&nbsp;</span>
1140
+ <span class="cline-any cline-no">&nbsp;</span>
1141
+ <span class="cline-any cline-no">&nbsp;</span>
1142
+ <span class="cline-any cline-neutral">&nbsp;</span>
1143
+ <span class="cline-any cline-neutral">&nbsp;</span>
1144
+ <span class="cline-any cline-no">&nbsp;</span>
1145
+ <span class="cline-any cline-no">&nbsp;</span>
1146
+ <span class="cline-any cline-no">&nbsp;</span>
1147
+ <span class="cline-any cline-no">&nbsp;</span>
1148
+ <span class="cline-any cline-no">&nbsp;</span>
1149
+ <span class="cline-any cline-no">&nbsp;</span>
1150
+ <span class="cline-any cline-no">&nbsp;</span>
1151
+ <span class="cline-any cline-neutral">&nbsp;</span>
1152
+ <span class="cline-any cline-neutral">&nbsp;</span>
1153
+ <span class="cline-any cline-no">&nbsp;</span>
1154
+ <span class="cline-any cline-no">&nbsp;</span>
1155
+ <span class="cline-any cline-neutral">&nbsp;</span>
1156
+ <span class="cline-any cline-neutral">&nbsp;</span>
1157
+ <span class="cline-any cline-no">&nbsp;</span>
1158
+ <span class="cline-any cline-no">&nbsp;</span>
1159
+ <span class="cline-any cline-no">&nbsp;</span>
1160
+ <span class="cline-any cline-no">&nbsp;</span>
1161
+ <span class="cline-any cline-neutral">&nbsp;</span>
1162
+ <span class="cline-any cline-neutral">&nbsp;</span>
1163
+ <span class="cline-any cline-no">&nbsp;</span>
1164
+ <span class="cline-any cline-no">&nbsp;</span>
1165
+ <span class="cline-any cline-neutral">&nbsp;</span>
1166
+ <span class="cline-any cline-neutral">&nbsp;</span>
1167
+ <span class="cline-any cline-no">&nbsp;</span>
1168
+ <span class="cline-any cline-no">&nbsp;</span>
1169
+ <span class="cline-any cline-no">&nbsp;</span>
1170
+ <span class="cline-any cline-no">&nbsp;</span>
1171
+ <span class="cline-any cline-neutral">&nbsp;</span>
1172
+ <span class="cline-any cline-neutral">&nbsp;</span>
1173
+ <span class="cline-any cline-no">&nbsp;</span>
1174
+ <span class="cline-any cline-no">&nbsp;</span>
1175
+ <span class="cline-any cline-neutral">&nbsp;</span>
1176
+ <span class="cline-any cline-neutral">&nbsp;</span>
1177
+ <span class="cline-any cline-no">&nbsp;</span>
1178
+ <span class="cline-any cline-no">&nbsp;</span>
1179
+ <span class="cline-any cline-no">&nbsp;</span>
1180
+ <span class="cline-any cline-neutral">&nbsp;</span>
1181
+ <span class="cline-any cline-neutral">&nbsp;</span>
1182
+ <span class="cline-any cline-no">&nbsp;</span>
1183
+ <span class="cline-any cline-neutral">&nbsp;</span>
1184
+ <span class="cline-any cline-neutral">&nbsp;</span>
1185
+ <span class="cline-any cline-no">&nbsp;</span>
1186
+ <span class="cline-any cline-neutral">&nbsp;</span>
1187
+ <span class="cline-any cline-neutral">&nbsp;</span>
1188
+ <span class="cline-any cline-neutral">&nbsp;</span>
1189
+ <span class="cline-any cline-neutral">&nbsp;</span>
1190
+ <span class="cline-any cline-neutral">&nbsp;</span>
1191
+ <span class="cline-any cline-neutral">&nbsp;</span>
1192
+ <span class="cline-any cline-neutral">&nbsp;</span>
1193
+ <span class="cline-any cline-neutral">&nbsp;</span>
1194
+ <span class="cline-any cline-neutral">&nbsp;</span>
1195
+ <span class="cline-any cline-neutral">&nbsp;</span>
1196
+ <span class="cline-any cline-neutral">&nbsp;</span>
1197
+ <span class="cline-any cline-neutral">&nbsp;</span>
1198
+ <span class="cline-any cline-neutral">&nbsp;</span>
1199
+ <span class="cline-any cline-neutral">&nbsp;</span>
1200
+ <span class="cline-any cline-neutral">&nbsp;</span>
1201
+ <span class="cline-any cline-neutral">&nbsp;</span>
1202
+ <span class="cline-any cline-neutral">&nbsp;</span>
1203
+ <span class="cline-any cline-neutral">&nbsp;</span>
1204
+ <span class="cline-any cline-neutral">&nbsp;</span>
1205
+ <span class="cline-any cline-neutral">&nbsp;</span>
1206
+ <span class="cline-any cline-neutral">&nbsp;</span>
1207
+ <span class="cline-any cline-neutral">&nbsp;</span>
1208
+ <span class="cline-any cline-neutral">&nbsp;</span>
1209
+ <span class="cline-any cline-neutral">&nbsp;</span>
1210
+ <span class="cline-any cline-neutral">&nbsp;</span>
1211
+ <span class="cline-any cline-neutral">&nbsp;</span>
1212
+ <span class="cline-any cline-neutral">&nbsp;</span>
1213
+ <span class="cline-any cline-neutral">&nbsp;</span>
1214
+ <span class="cline-any cline-neutral">&nbsp;</span>
1215
+ <span class="cline-any cline-neutral">&nbsp;</span>
1216
+ <span class="cline-any cline-neutral">&nbsp;</span>
1217
+ <span class="cline-any cline-neutral">&nbsp;</span>
1218
+ <span class="cline-any cline-neutral">&nbsp;</span>
1219
+ <span class="cline-any cline-neutral">&nbsp;</span>
1220
+ <span class="cline-any cline-neutral">&nbsp;</span>
1221
+ <span class="cline-any cline-neutral">&nbsp;</span>
1222
+ <span class="cline-any cline-neutral">&nbsp;</span>
1223
+ <span class="cline-any cline-neutral">&nbsp;</span>
1224
+ <span class="cline-any cline-neutral">&nbsp;</span>
1225
+ <span class="cline-any cline-neutral">&nbsp;</span>
1226
+ <span class="cline-any cline-neutral">&nbsp;</span>
1227
+ <span class="cline-any cline-neutral">&nbsp;</span>
1228
+ <span class="cline-any cline-neutral">&nbsp;</span>
1229
+ <span class="cline-any cline-neutral">&nbsp;</span>
1230
+ <span class="cline-any cline-neutral">&nbsp;</span>
1231
+ <span class="cline-any cline-neutral">&nbsp;</span>
1232
+ <span class="cline-any cline-neutral">&nbsp;</span>
1233
+ <span class="cline-any cline-neutral">&nbsp;</span>
1234
+ <span class="cline-any cline-neutral">&nbsp;</span>
1235
+ <span class="cline-any cline-neutral">&nbsp;</span>
1236
+ <span class="cline-any cline-neutral">&nbsp;</span>
1237
+ <span class="cline-any cline-neutral">&nbsp;</span>
1238
+ <span class="cline-any cline-neutral">&nbsp;</span>
1239
+ <span class="cline-any cline-neutral">&nbsp;</span>
1240
+ <span class="cline-any cline-neutral">&nbsp;</span>
1241
+ <span class="cline-any cline-neutral">&nbsp;</span>
1242
+ <span class="cline-any cline-neutral">&nbsp;</span>
1243
+ <span class="cline-any cline-neutral">&nbsp;</span>
1244
+ <span class="cline-any cline-neutral">&nbsp;</span>
1245
+ <span class="cline-any cline-neutral">&nbsp;</span>
1246
+ <span class="cline-any cline-neutral">&nbsp;</span>
1247
+ <span class="cline-any cline-neutral">&nbsp;</span>
1248
+ <span class="cline-any cline-neutral">&nbsp;</span>
1249
+ <span class="cline-any cline-neutral">&nbsp;</span>
1250
+ <span class="cline-any cline-neutral">&nbsp;</span>
1251
+ <span class="cline-any cline-neutral">&nbsp;</span>
1252
+ <span class="cline-any cline-neutral">&nbsp;</span>
1253
+ <span class="cline-any cline-neutral">&nbsp;</span>
1254
+ <span class="cline-any cline-neutral">&nbsp;</span>
1255
+ <span class="cline-any cline-neutral">&nbsp;</span>
1256
+ <span class="cline-any cline-neutral">&nbsp;</span>
1257
+ <span class="cline-any cline-neutral">&nbsp;</span>
1258
+ <span class="cline-any cline-neutral">&nbsp;</span>
1259
+ <span class="cline-any cline-neutral">&nbsp;</span>
1260
+ <span class="cline-any cline-neutral">&nbsp;</span>
1261
+ <span class="cline-any cline-neutral">&nbsp;</span>
1262
+ <span class="cline-any cline-neutral">&nbsp;</span>
1263
+ <span class="cline-any cline-neutral">&nbsp;</span>
1264
+ <span class="cline-any cline-neutral">&nbsp;</span>
1265
+ <span class="cline-any cline-neutral">&nbsp;</span>
1266
+ <span class="cline-any cline-neutral">&nbsp;</span>
1267
+ <span class="cline-any cline-neutral">&nbsp;</span>
1268
+ <span class="cline-any cline-neutral">&nbsp;</span>
1269
+ <span class="cline-any cline-neutral">&nbsp;</span>
1270
+ <span class="cline-any cline-neutral">&nbsp;</span>
1271
+ <span class="cline-any cline-neutral">&nbsp;</span>
1272
+ <span class="cline-any cline-neutral">&nbsp;</span>
1273
+ <span class="cline-any cline-neutral">&nbsp;</span>
1274
+ <span class="cline-any cline-neutral">&nbsp;</span>
1275
+ <span class="cline-any cline-neutral">&nbsp;</span>
1276
+ <span class="cline-any cline-neutral">&nbsp;</span>
1277
+ <span class="cline-any cline-neutral">&nbsp;</span>
1278
+ <span class="cline-any cline-neutral">&nbsp;</span>
1279
+ <span class="cline-any cline-neutral">&nbsp;</span>
1280
+ <span class="cline-any cline-neutral">&nbsp;</span>
1281
+ <span class="cline-any cline-neutral">&nbsp;</span>
1282
+ <span class="cline-any cline-neutral">&nbsp;</span>
1283
+ <span class="cline-any cline-neutral">&nbsp;</span>
1284
+ <span class="cline-any cline-neutral">&nbsp;</span>
1285
+ <span class="cline-any cline-neutral">&nbsp;</span>
1286
+ <span class="cline-any cline-neutral">&nbsp;</span>
1287
+ <span class="cline-any cline-neutral">&nbsp;</span>
1288
+ <span class="cline-any cline-neutral">&nbsp;</span>
1289
+ <span class="cline-any cline-neutral">&nbsp;</span>
1290
+ <span class="cline-any cline-neutral">&nbsp;</span>
1291
+ <span class="cline-any cline-neutral">&nbsp;</span>
1292
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { BaseMeasureBuilder } from '@epm-query-builder/base/BaseMeasureBuilder';
1293
+ import {
1294
+ MeasureConfig,
1295
+ FilterConfig,
1296
+ EpmQueryBuilderOptions,
1297
+ SuperFilterChild,
1298
+ } from '@epm-query-builder/types/query-builder-types';
1299
+ impo<span class="fstat-no" title="function not covered" >rt</span> { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';
1300
+ import {<span class="cstat-no" title="statement not covered" > BaseAnalyticalF</span>unctions } from '@epm-query-builder/base/BaseAnalyticalFunctions';
1301
+ import {<span class="cstat-no" title="statement not covered" > BaseAdvancedAggregations } from '@epm-query-builder/base/BaseAdv</span>ancedAggregations';
1302
+ import {<span class="cstat-no" title="statement not covered" > DuckDbAdvancedAggregations } from './DuckDbAdvancedAggregations';</span>
1303
+ import {<span class="cstat-no" title="statement not covered" > SOURCE_TYPES } from '@epm-query-builder/constants/Source';</span>
1304
+ &nbsp;
1305
+ expo<span class="fstat-no" title="function not covered" >rt</span> class DuckDbMeasureBuilder extends BaseMeasureBuilder {
1306
+ private analyticalFunct<span class="cstat-no" title="statement not covered" >ions: BaseAnalytica</span>lFunctions;
1307
+ private advancedAggreg<span class="cstat-no" title="statement not covered" >ati</span>ons: BaseAdvancedAggregations;
1308
+ privat<span class="cstat-no" title="statement not covered" >e duckDbAdvancedA<span class="fstat-no" title="function not covered" >gg</span>regations: DuckDbAdvancedAggregations;</span>
1309
+ &nbsp;
1310
+ constructo<span class="cstat-no" title="statement not covered" >r(options: EpmQueryBuilderOptions) {</span>
1311
+ super(option<span class="cstat-no" title="statement not covered" >s);</span>
1312
+ this.analyticalFunctions = new BaseAnalyticalFunctions(options);
1313
+ this.advanced<span class="cstat-no" title="statement not covered" >Aggregations = new BaseAdvancedAggregations(options);</span>
1314
+ this.duckDbA<span class="cstat-no" title="statement not covered" >dvancedAggregations = new DuckDbAdvancedAggregations(options);</span>
1315
+ }
1316
+ <span class="cstat-no" title="statement not covered" ></span>
1317
+ buildMeasureSe<span class="cstat-no" title="statement not covered" >lects(): string[] {</span>
1318
+ const measures = this.getMeasures();
1319
+ const columns: string[] = [];
1320
+ <span class="cstat-no" title="statement not covered" ></span>
1321
+ measures.forEach((measure) =&gt; {
1322
+ let me<span class="cstat-no" title="statement not covered" >asureExpr: string;</span>
1323
+ if (th<span class="cstat-no" title="statement not covered" >is.isMeasureType(measure)) {</span>
1324
+ measureExpr = this.buildCalculatedM<span class="cstat-no" title="statement not covered" >easure(measure);</span>
1325
+ } else if (this.isAnalyt<span class="cstat-no" title="statement not covered" >icalMeasure(measure)) {</span>
1326
+ measureE<span class="cstat-no" title="statement not covered" >xpr = this.buildAnalyticalMeasure(measure, measure.aggregationType |</span>| 'SUM');
1327
+ } else if (this.isAdvancedAggregation(measure)) {
1328
+ measureExpr = this.buildAdvancedAggregation(measure, measure.aggregationType || 'SUM');
1329
+ } <span class="cstat-no" title="statement not covered" >else {</span>
1330
+ <span class="cstat-no" title="statement not covered" > measureExpr = this.buildDuckDbAggregat</span>ion(measure);
1331
+ }<span class="cstat-no" title="statement not covered" ></span>
1332
+ &nbsp;
1333
+ <span class="fstat-no" title="function not covered" ></span> columns.push(measureExpr);
1334
+ <span class="cstat-no" title="statement not covered" ></span>
1335
+ if<span class="cstat-no" title="statement not covered" > (this.options.isCrossHighlightEnabled &amp;&amp; this.hasCrossHighlightFilters()) {</span>
1336
+ cons<span class="cstat-no" title="statement not covered" >t crossHigh</span>lightExpr = this.buildCrossHighlightMeasure(measure);
1337
+ const alias = measure.label || measure.columnName;
1338
+ columns.push(`${cro<span class="cstat-no" title="statement not covered" >ssHighlightExpr} AS "${alias}_CrossHighlight"`);</span>
1339
+ }<span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ></span></span>
1340
+ });<span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ></span></span>
1341
+ <span class="cstat-no" title="statement not covered" ></span>
1342
+ this.addCustomMeasures(columns);
1343
+ <span class="fstat-no" title="function not covered" > th</span>is.addDimensionIdMeasures(columns);
1344
+ <span class="cstat-no" title="statement not covered" ></span>
1345
+ retu<span class="cstat-no" title="statement not covered" >rn columns;</span>
1346
+ }<span class="cstat-no" title="statement not covered" ></span>
1347
+ &nbsp;
1348
+ buildMeasureFilterCTE(): <span class="cstat-no" title="statement not covered" >string {</span>
1349
+ const measureFil<span class="fstat-no" title="function not covered" >te</span>rs = this.<span class="cstat-no" title="statement not covered" >extractMeasureFilters()</span>;
1350
+ <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ></span></span>
1351
+ if (measureFilte<span class="fstat-no" title="function not covered" >rs</span>.length === 0<span class="cstat-no" title="statement not covered" >) {</span>
1352
+ re<span class="cstat-no" title="statement not covered" >turn '';</span>
1353
+ }<span class="cstat-no" title="statement not covered" ></span>
1354
+ &nbsp;
1355
+ const filterCTEs = me<span class="cstat-no" title="statement not covered" >asureFilters</span>
1356
+ .filter((filter<span class="cstat-no" title="statement not covered" >): filter is FilterConfig</span> =&gt; 'filterType' in filter)
1357
+ .m<span class="cstat-no" title="statement not covered" >ap((filter, index) =&gt; this.generateMeasureFilterCTE(filter, index + 1));</span>
1358
+ <span class="cstat-no" title="statement not covered" ><span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ></span></span></span>
1359
+ return f<span class="cstat-no" title="statement not covered" >ilterCTEs.join(',\n');</span>
1360
+ }
1361
+ <span class="cstat-no" title="statement not covered" ></span>
1362
+ buildHavingClause(): string {
1363
+ <span class="fstat-no" title="function not covered" > co</span>nst measureFilters = this.extractMeasureFilters();
1364
+ <span class="cstat-no" title="statement not covered" ></span>
1365
+ if (measureFilters.lengt<span class="cstat-no" title="statement not covered" >h === 0) {</span>
1366
+ return '';<span class="cstat-no" title="statement not covered" ></span>
1367
+ }<span class="cstat-no" title="statement not covered" ></span>
1368
+ <span class="cstat-no" title="statement not covered" ></span>
1369
+ const conditions = measureFilte<span class="cstat-no" title="statement not covered" >rs</span>
1370
+ .filter((filter): filter is <span class="cstat-no" title="statement not covered" >FilterConfig =&gt; 'filterType' in filter)</span>
1371
+ .map((filter) =&gt; this.buil<span class="cstat-no" title="statement not covered" >dMeasureFilterCondition(filter))</span>
1372
+ .filter((condition) =&gt; c<span class="cstat-no" title="statement not covered" >ondition);</span>
1373
+ <span class="cstat-no" title="statement not covered" ></span>
1374
+ if (cond<span class="cstat-no" title="statement not covered" >itions.length === 0) {</span>
1375
+ return '';<span class="cstat-no" title="statement not covered" ></span>
1376
+ }
1377
+ <span class="cstat-no" title="statement not covered" ></span>
1378
+ const combin<span class="cstat-no" title="statement not covered" >ed = BaseUtilities.combineConditions(conditions, 'AND'</span>);
1379
+ &nbsp;
1380
+ const di<span class="cstat-no" title="statement not covered" >ms = this.extractDimensions();</span>
1381
+ if (dims.length &gt; 0) {
1382
+ const isLeaf = dims.map((d) =&gt; `GROUPING(${d}) = 0`).join(' AND ');
1383
+ return `((<span class="cstat-no" title="statement not covered" >${isLeaf}) AND (${combined})) OR (NOT (${isLeaf}))`;</span>
1384
+ }
1385
+ <span class="cstat-no" title="statement not covered" ></span>
1386
+ return combined;
1387
+ }
1388
+ <span class="cstat-no" title="statement not covered" ></span>
1389
+ protected buildDuckDbAggregation(<span class="cstat-no" title="statement not covered" >measure: MeasureConfig): string {</span>
1390
+ const ag<span class="cstat-no" title="statement not covered" >gregationType = this.mapDuckDbAggre</span>gationType(measure.aggregationType);
1391
+ const originalAgg = measure.aggregationType?.toUpperCase();
1392
+ &nbsp;
1393
+ const source = BaseUtilities.ge<span class="cstat-no" title="statement not covered" >tSource(this.options);</span>
1394
+ const isBlend = source === SOURCE_TY<span class="cstat-no" title="statement not covered" >PES.BLEND;</span>
1395
+ if (isBl<span class="cstat-no" title="statement not covered" >end) {</span>
1396
+ const actualColumnId = BaseUtilities.extractColumnIdFromHierarchy(measure.id);
1397
+ const tableForBlend =
1398
+ <span class="cstat-no" title="statement not covered" > measure.tableName || BaseUtilities.getDefaultTableNameFromOptions(this.options) || '';</span>
1399
+ const <span class="cstat-no" title="statement not covered" >aliasPrefix = (measure.aggregationType || aggregationType).toUpperCase();</span>
1400
+ const aliasName = `${aliasPrefix}__${actualColumnId}`;
1401
+ const q<span class="cstat-no" title="statement not covered" >ualifiedInnerRef = `"${tableForBlend}"."${aliasName}"`;</span>
1402
+ <span class="cstat-no" title="statement not covered" ></span>
1403
+ if (originalAgg === 'FIRST') {
1404
+ return `MIN(${qualifiedInnerRef}) as "${aliasName}"`;
1405
+ }<span class="cstat-no" title="statement not covered" ></span>
1406
+ if (originalAgg === 'LAST') {
1407
+ return `MAX(<span class="cstat-no" title="statement not covered" >${qualifiedInnerRef}) as "${aliasName}"`;</span>
1408
+ }
1409
+ if (
1410
+ originalAgg === <span class="cstat-no" title="statement not covered" >'COUNT_DISTINCT' ||</span>
1411
+ originalAgg === 'DISTINCT_COUNT' ||
1412
+ originalAgg === 'DISTINCTCOUNT'
1413
+ ) {<span class="cstat-no" title="statement not covered" ></span>
1414
+ return `COUNT(DISTINCT ${qualifiedInnerRef}) as "${aliasName}"`;
1415
+ }<span class="cstat-no" title="statement not covered" ></span>
1416
+ &nbsp;
1417
+ return `${aggr<span class="cstat-no" title="statement not covered" >egationType}(${qualifiedInnerRef}) as "${aliasName}"`;</span>
1418
+ }<span class="cstat-no" title="statement not covered" ></span>
1419
+ &nbsp;
1420
+ let columnRef: s<span class="cstat-no" title="statement not covered" >tring;</span>
1421
+ if (this.options<span class="cstat-no" title="statement not covered" >.databa</span>seDetails?.databaseType === 'duckdb') {
1422
+ const actualColumnId = BaseUtilities.extractColumnIdFromHierarchy(measure.id);
1423
+ columnRef = `"<span class="cstat-no" title="statement not covered" >${actualColumnId}"`;</span>
1424
+ } else {<span class="cstat-no" title="statement not covered" ></span>
1425
+ const actualColumnId = BaseUtilities.extractColumnIdFromHierarchy(measure.id);
1426
+ const effectiv<span class="cstat-no" title="statement not covered" >eColumnName = measure.columnName || actualColumnId;</span>
1427
+ columnRef = `$<span class="cstat-no" title="statement not covered" >{measur</span>e.tableName}.${effectiveColumnName}`;
1428
+ }
1429
+ <span class="cstat-no" title="statement not covered" ></span>
1430
+ let aggregationE<span class="cstat-no" title="statement not covered" >xpr: st</span>ring;
1431
+ &nbsp;
1432
+ if (originalAgg <span class="cstat-no" title="statement not covered" >=== 'FIRST') {</span>
1433
+ aggregationExpr = `MIN(${columnRef}) as "FIRST__${columnRef.replace(/"/g, '')}"`;
1434
+ } else if (originalAgg === 'LAST') {
1435
+ ag<span class="cstat-no" title="statement not covered" >gregationExpr = `MAX(${columnRef}) as "LAST__${columnRef.replace(/"/g, '')}"`;</span>
1436
+ } else {<span class="cstat-no" title="statement not covered" ></span>
1437
+ switch<span class="cstat-no" title="statement not covered" > (aggregationType) {</span>
1438
+ case 'CO<span class="cstat-no" title="statement not covered" >UNT':</span>
1439
+ if (
1440
+ <span class="cstat-no" title="statement not covered" > measure.aggregationType?.toUpperCase() === 'COUNT_DISTINCT' ||</span>
1441
+ measure.aggregationType?.toUpperCase() === 'DISTINCT_COUNT' ||
1442
+ <span class="cstat-no" title="statement not covered" > measure.aggregationType?.toUpperCase() === 'DISTINCTCOUNT'</span>
1443
+ ) <span class="cstat-no" title="statement not covered" >{</span>
1444
+ aggregationExpr = `COUNT(DISTINCT ${columnRef}) as "COUNT_DISTINCT__${columnRef.replace(/"/g, '')}"`;
1445
+ <span class="cstat-no" title="statement not covered" > } else {</span>
1446
+ aggregationExpr = `COUNT(${columnRef}) as "COUNT__${columnRef.replace(/"/g, '')}"`;
1447
+ <span class="fstat-no" title="function not covered" ></span> }
1448
+ <span class="cstat-no" title="statement not covered" > break;</span>
1449
+ case<span class="cstat-no" title="statement not covered" > 'STRING_AGG':</span>
1450
+ aggregationExpr = `S<span class="cstat-no" title="statement not covered" >TRING_AGG(${columnRef}) as "STRING_AGG__${columnRef.replace(/"/g, '')}"`;</span>
1451
+ break;
1452
+ case 'MEDIAN':
1453
+ aggregationExpr = `MEDIAN(${columnRef}) as "MEDIAN__${columnRef.replace(/"/g, '')}"`;
1454
+ break;
1455
+ case 'MODE':
1456
+ aggregationExpr = `MODE(${columnRef}) as "MODE__${columnRef.replace(/"/g, '')}"`;
1457
+ break;
1458
+ case 'CONCATENATED':
1459
+ aggregationExpr = `STRING_AGG(${columnRef}) as "CONCATENATED__${columnRef.replace(/"/g, '')}"`;
1460
+ break;
1461
+ case 'CONCATENATED_IDS':
1462
+ aggregationExpr = `STRING_AGG(${columnRef}) as "CONCATENATED_IDS__${columnRef.replace(/"/g, '')}"`;
1463
+ break;
1464
+ default:
1465
+ aggregationExpr = `${aggregationType}(${columnRef}) as "${aggregationType}__${columnRef.replace(/"/g, '')}"`;
1466
+ }
1467
+ }
1468
+ &nbsp;
1469
+ if (this.needsFilterClause()) {
1470
+ const filterCondition = this.buildMeasureFilterForAggregation();
1471
+ if (this.options.databaseDetails?.databaseType === 'duckdb') {
1472
+ <span class="cstat-no" title="statement not covered" > return `${aggregationExpr} FILTER (WHERE ${filterCondition})`;</span>
1473
+ }
1474
+ <span class="fstat-no" title="function not covered" ></span> return `${aggregationExpr} FILTER (WHERE ${filterCondition}) AS "${measure.label}"`;
1475
+ }<span class="cstat-no" title="statement not covered" ></span>
1476
+ <span class="cstat-no" title="statement not covered" ></span>
1477
+ if (this.options.databaseDetails?.databaseType === 'duckdb') {
1478
+ return aggregationExpr;<span class="cstat-no" title="statement not covered" ></span>
1479
+ }<span class="cstat-no" title="statement not covered" ></span>
1480
+ retu<span class="cstat-no" title="statement not covered" >rn `${aggregationExpr} </span>AS "${measure.label}"`;
1481
+ }
1482
+ <span class="fstat-no" title="function not covered" ></span>
1483
+ privat<span class="cstat-no" title="statement not covered" >e mapDuckDbAggreg<span class="fstat-no" title="function not covered" >at</span>ionType(aggregationType?: string): string {</span>
1484
+ if (!agg<span class="cstat-no" title="statement not covered" >regationType) return 'SUM';</span>
1485
+ <span class="cstat-no" title="statement not covered" ></span>
1486
+ const duckDbMapping: Record&lt;string, stri<span class="cstat-no" title="statement not covered" >ng&gt; = {</span>
1487
+ SUM: 'SUM',<span class="cstat-no" title="statement not covered" ></span>
1488
+ COUNT: 'COUNT',<span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ></span></span>
1489
+ AVG: 'AVG',
1490
+ MIN: 'MIN',<span class="cstat-no" title="statement not covered" ></span>
1491
+ MAX: 'MAX',
1492
+ &nbsp;
1493
+ FIRST: 'MI<span class="cstat-no" title="statement not covered" >N',</span>
1494
+ LAST: 'MAX',<span class="cstat-no" title="statement not covered" ></span>
1495
+ STANDARD_DEVIATION: 'STDDEV_POP',
1496
+ VARIANCE: 'VAR_POP',
1497
+ COUNT_<span class="cstat-no" title="statement not covered" >DISTINCT: 'COUNT',</span>
1498
+ MEDIAN: 'M<span class="cstat-no" title="statement not covered" >EDIAN',</span>
1499
+ MODE: 'MODE',
1500
+ &nbsp;
1501
+ CONCATENATED: 'STRING_AGG',
1502
+ <span class="fstat-no" title="function not covered" ></span> CONCATENATED_IDS: 'STRING_AGG',
1503
+ <span class="cstat-no" title="statement not covered" ></span>
1504
+ DI<span class="cstat-no" title="statement not covered" >STINCTCOUNT: 'COUNT',</span>
1505
+ DISTIN<span class="cstat-no" title="statement not covered" >CT_COUNT: '</span>COUNT',
1506
+ COUNTA: 'COUNT',
1507
+ AVERAGE: 'AVG',<span class="cstat-no" title="statement not covered" ></span>
1508
+ MINIMUM: 'MIN',<span class="cstat-no" title="statement not covered" ></span>
1509
+ MAXIMUM: 'MAX',<span class="cstat-no" title="statement not covered" ></span>
1510
+ };<span class="cstat-no" title="statement not covered" ></span>
1511
+ <span class="cstat-no" title="statement not covered" ></span>
1512
+ retu<span class="cstat-no" title="statement not covered" >rn duckDbMapping[aggregationType.toUpperCase()] || aggregationType.toUpperCase();</span>
1513
+ }<span class="cstat-no" title="statement not covered" ></span>
1514
+ &nbsp;
1515
+ private extractMeasureFil<span class="cstat-no" title="statement not covered" >ters(): F<span class="fstat-no" title="function not covered" >il</span>terConfig[<span class="cstat-no" title="statement not covered" >] {</span></span>
1516
+ if (!this.options.superF<span class="cstat-no" title="statement not covered" >ilters?.children</span>) {
1517
+ re<span class="cstat-no" title="statement not covered" >turn [];</span>
1518
+ }
1519
+ &nbsp;
1520
+ const measureFilters: FilterConfig[] = [];
1521
+ this.extractMeasureFiltersRecursively(this.options.superFilters.children, measureFilters);
1522
+ return measureFilters;
1523
+ }
1524
+ <span class="fstat-no" title="function not covered" ></span>
1525
+ privat<span class="cstat-no" title="statement not covered" >e extractMeasureFiltersRecursively(</span>
1526
+ children<span class="cstat-no" title="statement not covered" >: SuperFilt</span>erChild[],
1527
+ measureFilters: FilterConfig[],
1528
+ ): void {<span class="cstat-no" title="statement not covered" ></span>
1529
+ children.forEach((chil<span class="cstat-no" title="statement not covered" >d) =&gt; {</span>
1530
+ if (child.filters) {<span class="cstat-no" title="statement not covered" ></span>
1531
+ <span class="cstat-no" title="statement not covered" > const filter = child.filters;</span>
1532
+ const isMeasureFilterType = filter.filterType === 'MEASURE';
1533
+ <span class="fstat-no" title="function not covered" ></span> const hasMeasureColumnType = Array.isArray(filter.columnType)
1534
+ <span class="cstat-no" title="statement not covered" > ? filter.col</span>umnType.some((type) =&gt; type?.toUpperCase() === 'MEASURE')
1535
+ : false;
1536
+ <span class="fstat-no" title="function not covered" ></span> const isAggregatedRange =
1537
+ <span class="cstat-no" title="statement not covered" > filter.filte</span>rType === 'RANGE' &amp;&amp;
1538
+ Array.isArray(filter.aggregationType) &amp;&amp;
1539
+ <span class="fstat-no" title="function not covered" ></span> filter.aggregationType.length &gt; 0;
1540
+ <span class="cstat-no" title="statement not covered" ></span>
1541
+ <span class="cstat-no" title="statement not covered" > if (isMeasureFilterType || hasMeasureColumnType || isAggregatedRange) {</span>
1542
+ me<span class="cstat-no" title="statement not covered" >asureFilter</span>s.push(filter);
1543
+ }
1544
+ }<span class="cstat-no" title="statement not covered" ></span>
1545
+ <span class="cstat-no" title="statement not covered" ></span>
1546
+ if (ch<span class="cstat-no" title="statement not covered" >ild.childre</span>n) {
1547
+ this.extractMeasureFiltersRecursively(child.children, measureFilters);
1548
+ }<span class="cstat-no" title="statement not covered" ></span>
1549
+ });<span class="cstat-no" title="statement not covered" ></span>
1550
+ }<span class="cstat-no" title="statement not covered" ></span>
1551
+ <span class="cstat-no" title="statement not covered" ></span>
1552
+ private genera<span class="cstat-no" title="statement not covered" >teMeasureF</span>ilterCTE(filter: FilterConfig, counter: number): string {
1553
+ const va<span class="cstat-no" title="statement not covered" >riableName = `measure_filter_${counter}`;</span>
1554
+ <span class="cstat-no" title="statement not covered" ></span>
1555
+ if (!fil<span class="cstat-no" title="statement not covered" >ter.rangeFilte</span>r?.length) {
1556
+ return '';<span class="cstat-no" title="statement not covered" ><span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ></span></span></span>
1557
+ }<span class="cstat-no" title="statement not covered" ></span>
1558
+ &nbsp;
1559
+ cons<span class="cstat-no" title="statement not covered" >t tableName = filter.tableNames?.[0] || '';</span>
1560
+ const aggregationType = this.mapDuckDbAggregationType(filter.aggregationType?.[0]);
1561
+ <span class="fstat-no" title="function not covered" > co</span>nst columnRef = this.resolveColumnRef(filter);
1562
+ <span class="cstat-no" title="statement not covered" ></span>
1563
+ const conditions = this.build<span class="cstat-no" title="statement not covered" >RangeConditionsForAggregation(columnRef, filter, aggregationType);</span>
1564
+ <span class="cstat-no" title="statement not covered" ></span>
1565
+ const dims = this.extractDimensions();
1566
+ <span class="fstat-no" title="function not covered" > if</span> (dims.length === 0) {<span class="branch-0 cbranch-no" title="branch not covered" ></span>
1567
+ re<span class="cstat-no" title="statement not covered" >turn '';</span>
1568
+ }
1569
+ <span class="fstat-no" title="function not covered" > co</span>nst selectDims = dims.map((d, idx) =&gt; `${d} AS __mf_dim${idx + 1}`).join(', ');
1570
+ cons<span class="cstat-no" title="statement not covered" >t groupByDims = dims.join(', ');<span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ></span></span></span>
1571
+ <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ></span></span>
1572
+ return `${variableName} AS (
1573
+ <span class="fstat-no" title="function not covered" ></span> SELECT ${selectDims}
1574
+ FROM ${tableName}<span class="cstat-no" title="statement not covered" ></span>
1575
+ GROUP BY ${groupByDims}<span class="cstat-no" title="statement not covered" ></span>
1576
+ <span class="cstat-no" title="statement not covered" > HAVING ${conditions.join(' AND ')}</span>
1577
+ )`;<span class="cstat-no" title="statement not covered" ></span>
1578
+ }
1579
+ <span class="cstat-no" title="statement not covered" ></span>
1580
+ privat<span class="cstat-no" title="statement not covered" >e buildMeasureFilterCondition(filter: FilterConfig): string {</span>
1581
+ if (!filter.rangeFilter?.length) {
1582
+ <span class="fstat-no" title="function not covered" ></span> return '';
1583
+ }<span class="cstat-no" title="statement not covered" ></span>
1584
+ <span class="cstat-no" title="statement not covered" ></span>
1585
+ const ag<span class="cstat-no" title="statement not covered" >gregationType = thi</span>s.mapDuckDbAggregationType(filter.aggregationType?.[0]);
1586
+ cons<span class="cstat-no" title="statement not covered" >t columnRef = this.resolveColumnRef(filter)<span class="fstat-no" title="function not covered" >;</span></span>
1587
+ const co<span class="cstat-no" title="statement not covered" >nditions = this.buildRangeConditionsForAggregation(columnRef, filter, aggregationType);</span>
1588
+ return condi<span class="cstat-no" title="statement not covered" >tions.length === 1 ? c<span class="fstat-no" title="function not covered" >on</span>ditions[0] : `(${conditions.join(' AND ')})`;</span>
1589
+ }<span class="cstat-no" title="statement not covered" ></span>
1590
+ &nbsp;
1591
+ private needsFilterClause(): boolean {
1592
+ return false;<span class="cstat-no" title="statement not covered" ></span>
1593
+ }<span class="cstat-no" title="statement not covered" ></span>
1594
+ <span class="cstat-no" title="statement not covered" ></span>
1595
+ private buildMeasureFi<span class="cstat-no" title="statement not covered" >lterForAggregation(): string {</span>
1596
+ return '1=1';<span class="cstat-no" title="statement not covered" ></span>
1597
+ }<span class="cstat-no" title="statement not covered" ></span>
1598
+ <span class="cstat-no" title="statement not covered" ></span>
1599
+ buildMeasureFilterWhereClause(): string {
1600
+ const measureFilters = this.extractMeasureFilters();
1601
+ if (measureFilters.length === 0) {<span class="cstat-no" title="statement not covered" ></span>
1602
+ return '';<span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ></span></span>
1603
+ }
1604
+ const dims = this.extrac<span class="cstat-no" title="statement not covered" >tDimensions();</span>
1605
+ if (dims.length === 0) {
1606
+ return '';
1607
+ }
1608
+ &nbsp;
1609
+ const clauses: string[] = [];
1610
+ let <span class="cstat-no" title="statement not covered" >counter = 0;</span>
1611
+ for (const f of measureFilters) {
1612
+ <span class="fstat-no" title="function not covered" ></span> if (!('filterType' in f)) continue;
1613
+ if<span class="cstat-no" title="statement not covered" > (!f.rangeFilter?.length) continue;</span>
1614
+ counte<span class="cstat-no" title="statement not covered" >r += 1;</span>
1615
+ co<span class="cstat-no" title="statement not covered" >nst eqs = dims.map((d, idx) =&gt; `${d}<span class="fstat-no" title="function not covered" > =</span> mf.__mf_dim${idx + 1}`).join(' AND ');</span>
1616
+ clauses.push(`EXISTS (SELECT<span class="cstat-no" title="statement not covered" > 1 FROM measure_filter_${counter} mf WHER</span>E ${eqs})`);
1617
+ }<span class="cstat-no" title="statement not covered" ></span>
1618
+ return BaseU<span class="cstat-no" title="statement not covered" >tilities.combineConditions(cl</span>auses.filter(Boolean), 'AND');
1619
+ }
1620
+ &nbsp;
1621
+ private extractDimensions(): string[] {
1622
+ <span class="fstat-no" title="function not covered" > co</span>nst rowDimensions = BaseUtilities.buildDimensionReference(this.options.rows, this.options);
1623
+ cons<span class="cstat-no" title="statement not covered" >t columnDimensions = BaseUtilities.buildDimensionReference(</span>
1624
+ this.options.columns,<span class="cstat-no" title="statement not covered" ></span>
1625
+ this.options,
1626
+ );
1627
+ return [...rowDimensions, ...columnDimensions];
1628
+ }<span class="cstat-no" title="statement not covered" ></span>
1629
+ &nbsp;
1630
+ privat<span class="cstat-no" title="statement not covered" >e combineFilterC</span>onditions(conditions: string[], operator: 'AND' | 'OR' = 'AND'): string {
1631
+ return BaseUtilities.combineConditions(conditions, operator);
1632
+ }<span class="fstat-no" title="function not covered" ></span>
1633
+ <span class="cstat-no" title="statement not covered" ></span>
1634
+ private ha<span class="cstat-no" title="statement not covered" >sCrossHi</span>ghlightFilters(): boolean {
1635
+ retu<span class="cstat-no" title="statement not covered" >rn Boolean(<span class="fstat-no" title="function not covered" ></span></span>
1636
+ this.o<span class="cstat-no" title="statement not covered" >ptions.superFilters?.children?.some(</span>
1637
+ (child) =&gt;<span class="cstat-no" title="statement not covered" ></span>
1638
+ Array.isArray(c<span class="fstat-no" title="function not covered" >hi</span>ld.filters)<span class="cstat-no" title="statement not covered" > &amp;&amp;</span>
1639
+ child.filters.some((filter: FilterConfig) =&gt; filter.isCrossHighlight),
1640
+ ),<span class="cstat-no" title="statement not covered" ></span>
1641
+ );
1642
+ }
1643
+ &nbsp;
1644
+ pr<span class="fstat-no" title="function not covered" >iv</span>ate buildCrossHighlightMeasure(measure: MeasureConfig): string {
1645
+ const baseAggregation = this<span class="cstat-no" title="statement not covered" >.buildDuckDbAggregation(measure);</span>
1646
+ const crossHighlightConditions = this.getCrossHighlightConditions();
1647
+ &nbsp;
1648
+ if (!crossHighlightConditions.length) {
1649
+ return baseAggregation;
1650
+ }
1651
+ &nbsp;
1652
+ const whereClause = crossHighlightConditions.join(' AND ');
1653
+ return `CASE WHEN ${whereClause} THEN ${baseAggregation} ELSE NULL END`;
1654
+ }
1655
+ &nbsp;
1656
+ private getCrossHighlightConditions(): string[] {
1657
+ const conditions: string[] = [];
1658
+ &nbsp;
1659
+ if (<span class="cstat-no" title="statement not covered" >!this.options.superFilters?.children) return conditions;</span>
1660
+ &nbsp;
1661
+ <span class="fstat-no" title="function not covered" > th</span>is.options.superFilters.children.forEach((child) =&gt; {
1662
+ if (Array.isArray(child.<span class="cstat-no" title="statement not covered" >filters)) {</span>
1663
+ child.filters.forEach((filter: FilterConfig) =&gt; {
1664
+ if (
1665
+ filter.isCrossHighlight &amp;&amp;
1666
+ filter.columnNames?.length &amp;&amp;
1667
+ filter.valuesFilter?.length
1668
+ ) {
1669
+ const tableName =
1670
+ filter.tableNames?.[0] || BaseUtilities.getDefaultTableNameFromOptions(this.options);
1671
+ const columnName = filter.columnNames[0];
1672
+ const columnRef = `"${tableName}"."${columnName}"`;
1673
+ &nbsp;
1674
+ if (filter.valuesFilter.length === 1) {
1675
+ const value = filter.valuesFilter[0];
1676
+ const displayValue = typeof value === 'object' ? value.id : value;
1677
+ conditions.push(`${columnRef} = '${displayValue}'`);
1678
+ } else {
1679
+ const valuesList = filter.valuesFilter
1680
+ .map((v) =&gt; `'${typeof v === 'object' ? v.id : v}'`)
1681
+ .join(', ');
1682
+ <span class="cstat-no" title="statement not covered" > conditions.push(`${columnRef} IN (${valuesList})`);</span>
1683
+ }
1684
+ <span class="fstat-no" title="function not covered" ></span> }
1685
+ <span class="cstat-no" title="statement not covered" > });</span>
1686
+ }
1687
+ });<span class="cstat-no" title="statement not covered" ></span>
1688
+ &nbsp;
1689
+ return condi<span class="cstat-no" title="statement not covered" >tions;</span>
1690
+ }
1691
+ <span class="cstat-no" title="statement not covered" ></span>
1692
+ private addCustomMeasures(columns: string[]): void {
1693
+ if (!this.op<span class="cstat-no" title="statement not covered" >tions.customMeasures?.length) return;</span>
1694
+ &nbsp;
1695
+ this.options<span class="cstat-no" title="statement not covered" >.customMeasures.forEach((customMeasure) =&gt; {</span>
1696
+ const duckDbMeasure = this.convertCustomMeasure(customMeasure);
1697
+ if (duckDb<span class="cstat-no" title="statement not covered" >Measure &amp;&amp; duckDbMeasure.trim()) {</span>
1698
+ columns.push(duckDbMeasure);
1699
+ }<span class="cstat-no" title="statement not covered" ></span>
1700
+ });
1701
+ }<span class="cstat-no" title="statement not covered" ></span>
1702
+ &nbsp;
1703
+ private conver<span class="cstat-no" title="statement not covered" >tCustomMeasure(measure: string): string {</span>
1704
+ if (measure.includes('CONCATENATEX')) {
1705
+ const conv<span class="cstat-no" title="statement not covered" >ertedMeasure = measure</span>
1706
+ .replace(/CONCATENATEX\s*\(/gi, 'STRING_AGG(')
1707
+ .replace<span class="cstat-no" title="statement not covered" >(/,\s*","\s*\)/gi, ", ',' ORDER BY 1)")</span>
1708
+ .replace(/,\s*"\|"\s*\)/gi, ", '|' ORDER BY 1)");
1709
+ return con<span class="cstat-no" title="statement not covered" >vertedMeasure;</span>
1710
+ }
1711
+ <span class="cstat-no" title="statement not covered" ></span>
1712
+ return measure;
1713
+ }
1714
+ <span class="fstat-no" title="function not covered" ></span>
1715
+ privat<span class="cstat-no" title="statement not covered" >e addDimensionIdMeasures(columns: string[]): void {</span>
1716
+ if (!this.options.dimensionIdMappings) return;
1717
+ <span class="cstat-no" title="statement not covered" ></span>
1718
+ Object.entries(this.options.dimensionIdMappings).forEach(([tableName, mappings]) =&gt; {
1719
+ if (mappin<span class="cstat-no" title="statement not covered" >gs &amp;&amp; mappings.length &gt; 0) {</span>
1720
+ const concatenatedColumns = mappings
1721
+ .map((mapping) =&gt; `"${t<span class="cstat-no" title="statement not covered" >ableName}"."${mapping.ta</span>rgetField}"`)
1722
+ .join(<span class="cstat-no" title="statement not covered" >" || '|' || ");</span>
1723
+ &nbsp;
1724
+ columns.push(`${concatenatedColumns} AS "${tableName}_ConcatenatedIds"`);
1725
+ }<span class="cstat-no" title="statement not covered" ></span>
1726
+ });<span class="cstat-no" title="statement not covered" ></span>
1727
+ }
1728
+ &nbsp;
1729
+ private isAnalyticalMeasure(measu<span class="cstat-no" title="statement not covered" >re: MeasureConfig): boolean</span> {
1730
+ const analyt<span class="cstat-no" title="statement not covered" >icalTypes = [</span>
1731
+ 'ROW_NUMBER',
1732
+ 'RANK',
1733
+ 'DENSE_RAN<span class="cstat-no" title="statement not covered" >K',</span>
1734
+ 'PERCENT_RANK',
1735
+ 'LAG',<span class="cstat-no" title="statement not covered" ></span>
1736
+ 'LEAD',
1737
+ 'CUMULATIV<span class="cstat-no" title="statement not covered" >E_SUM',</span>
1738
+ 'CUMULATIVE_COUNT',
1739
+ 'MOVING_AV<span class="cstat-no" title="statement not covered" >G',</span>
1740
+ 'PERCENTILE_25',
1741
+ 'PERCENTIL<span class="cstat-no" title="statement not covered" >E_75',</span>
1742
+ 'MEDIAN',
1743
+ ];<span class="cstat-no" title="statement not covered" ></span>
1744
+ return Boolean(
1745
+ measure.aggregationType &amp;&amp; analyticalTypes.includes(measure.aggregationType.toUpperCase()),
1746
+ <span class="fstat-no" title="function not covered" > );</span>
1747
+ }<span class="cstat-no" title="statement not covered" ></span>
1748
+ <span class="cstat-no" title="statement not covered" ></span>
1749
+ private isAdvancedAggregation(measure: MeasureConfig): boolean {
1750
+ const ad<span class="cstat-no" title="statement not covered" >vancedTypes = [</span>
1751
+ 'ARRAY_AGG',
1752
+ 'ARRAY_AGG_DISTINCT'<span class="cstat-no" title="statement not covered" >,</span>
1753
+ 'JSON_AGG',<span class="cstat-no" title="statement not covered" ></span>
1754
+ 'A<span class="cstat-no" title="statement not covered" >PPROX_COUNT_DISTINCT',</span>
1755
+ 'PRODUCT',
1756
+ <span class="fstat-no" title="function not covered" ></span> 'GEOMETRIC_MEAN',
1757
+ 'HARMONIC_MEAN',<span class="cstat-no" title="statement not covered" ></span>
1758
+ 'M<span class="cstat-no" title="statement not covered" >AD',<span class="fstat-no" title="function not covered" ></span></span>
1759
+ 'STRING_AGG_SEMICOLON',<span class="cstat-no" title="statement not covered" ></span>
1760
+ 'STRIN<span class="cstat-no" title="statement not covered" >G_AGG_PIPE',</span>
1761
+ 'HISTOGRAM',<span class="cstat-no" title="statement not covered" ></span>
1762
+ 'QUANTILES<span class="cstat-no" title="statement not covered" >',</span>
1763
+ 'RESERVOIR_SAM<span class="cstat-no" title="statement not covered" >PLE',</span>
1764
+ 'BIT_AND',
1765
+ 'BIT_OR',
1766
+ 'BIT_XOR',<span class="cstat-no" title="statement not covered" ></span>
1767
+ 'BOOL_AND',<span class="cstat-no" title="statement not covered" ></span>
1768
+ 'BOOL_OR',
1769
+ ];
1770
+ return B<span class="cstat-no" title="statement not covered" >oolean(</span>
1771
+ measure.aggregationTy<span class="cstat-no" title="statement not covered" >pe &amp;&amp; advancedTypes.includes(measure.aggre</span>gationType.toUpperCase()),
1772
+ );<span class="cstat-no" title="statement not covered" ></span>
1773
+ }<span class="cstat-no" title="statement not covered" ></span>
1774
+ &nbsp;
1775
+ buildAnalyticalMeasure(measure: MeasureConfig, analyticalType: string): string {
1776
+ switch (analyticalType.toUpper<span class="cstat-no" title="statement not covered" >Case()) {</span>
1777
+ case 'ROW_NUMB<span class="cstat-no" title="statement not covered" >ER':</span>
1778
+ return this.analyticalFunctions.buildRankingFunction(measure, 'ROW_NUMBER');
1779
+ case 'RANK':
1780
+ retu<span class="cstat-no" title="statement not covered" >rn this.analyticalFunctions.buildRankingFunction(measure, 'RANK');</span>
1781
+ case 'DENSE_RANK':<span class="cstat-no" title="statement not covered" ></span>
1782
+ return t<span class="cstat-no" title="statement not covered" >his.analyticalFunctions.buildRankingFunction(measure, 'DENSE_RANK');</span>
1783
+ case 'PERCENT_<span class="cstat-no" title="statement not covered" >RANK':</span>
1784
+ return this.analyticalFunctions.buildRankingFunction(measure, 'PERCENT_RANK');
1785
+ case 'LAG':
1786
+ return this.analyticalFunc<span class="cstat-no" title="statement not covered" >tions.buildLagLeadFunction(measure, 'LAG', 1);</span>
1787
+ case 'LEAD':<span class="cstat-no" title="statement not covered" ></span>
1788
+ return this.analyticalFunctions.buildLagLeadFunction(measure, 'LEAD', 1);
1789
+ case 'CUMULATIVE_SUM':
1790
+ retu<span class="cstat-no" title="statement not covered" >rn this.analyticalFunctions.buildCumulativeAggregation(measure, 'SUM');</span>
1791
+ case 'CUMULATIVE_COUNT':<span class="cstat-no" title="statement not covered" ></span>
1792
+ return t<span class="cstat-no" title="statement not covered" >his.analyticalFunctions.buildCumulativeAggregation(measure, 'COUNT');</span>
1793
+ case 'MOVING_AVG':
1794
+ return this.analyticalFunctions.buildMovingAggregation(measure, 'AVG', 3);
1795
+ ca<span class="cstat-no" title="statement not covered" >se 'PERCENTILE_25':</span>
1796
+ return this.analyticalFunctions.buildPercentileFunction(measure, 0.25);
1797
+ <span class="fstat-no" title="function not covered" ></span> case 'PERCENTILE_75':
1798
+ <span class="cstat-no" title="statement not covered" > return this.analyticalFunctions.buildPercentileFunctio</span>n(measure, 0.75);
1799
+ case 'MEDIAN':
1800
+ return this.buildDuckDbAggregation(measure);
1801
+ default:
1802
+ return this.buildDuckDbAggregation(measure);
1803
+ }
1804
+ }
1805
+ &nbsp;
1806
+ buildAdvancedAggregation(
1807
+ measure: MeasureConfig,
1808
+ aggregationType: string,
1809
+ options?: Record&lt;string, unknown&gt;,
1810
+ ): string {
1811
+ switch (aggregationType.toUpperCase()) {
1812
+ case 'STRING_AGG_SEMICOLON':
1813
+ return this.advancedAggregations.buildStringAggregation(measure, '; ', false);
1814
+ case 'STRING_AGG_PIPE':
1815
+ return this.advancedAggregations.buildStringAggregation(measure, ' | ', false);
1816
+ case 'HISTOGRAM': {
1817
+ const binCount = (options?.binCount as number) || 10;
1818
+ return this.duckDbAdvancedAggregations.buildHistogramAggregation(measure, binCount);
1819
+ }
1820
+ case 'QUANTILES': {
1821
+ const quantiles = (options?.quantiles as number[]) || [0.25, 0.5, 0.75];
1822
+ return this.duckDbAdvancedAggregations.buildQuantileAggregation(measure, quantiles);
1823
+ }
1824
+ case 'RESERVOIR_SAMPLE': {
1825
+ const sampleSize = (options?.sampleSize as number) || 100;
1826
+ return this.duckDbAdvancedAggregations.buildReservoirSample(measure, sampleSize);
1827
+ }
1828
+ case 'BIT_AND':
1829
+ return this.advancedAggregations.buildBitAggregations(measure, 'AND');
1830
+ case 'BIT_OR':
1831
+ return this.advancedAggregations.buildBitAggregations(measure, 'OR');
1832
+ case 'BIT_XOR':
1833
+ return this.advancedAggregations.buildBitAggregations(measure, 'XOR');
1834
+ case 'BOOL_AND':
1835
+ return this.advancedAggregations.buildBoolAggregations(measure, 'AND');
1836
+ case 'BOOL_OR':
1837
+ return this.advancedAggregations.buildBoolAggregations(measure, 'OR');
1838
+ default:
1839
+ return this.buildDuckDbAggregation(measure);
1840
+ }
1841
+ }
1842
+ &nbsp;
1843
+ private resolveColumnRef(filter: FilterConfig): string {
1844
+ if (this.options.databaseDetails?.databaseType === 'duckdb') {
1845
+ const actualId = BaseUtilities.extractColumnIdFromHierarchy(
1846
+ filter.columnIds?.[0] ||
1847
+ `${filter.tableNames?.[0] || ''}[${filter.columnNames?.[0] || ''}]`,
1848
+ );
1849
+ return `"${actualId}"`;
1850
+ }
1851
+ const tableName = filter.tableNames?.[0] || '';
1852
+ const column = filter.columnNames?.[0] || '';
1853
+ return `${tableName}.${column}`;
1854
+ }
1855
+ &nbsp;
1856
+ private buildRangeConditionsForAggregation(
1857
+ columnRef: string,
1858
+ filter: FilterConfig,
1859
+ aggregationType: string,
1860
+ ): string[] {
1861
+ const conditions: string[] = [];
1862
+ filter.rangeFilter?.forEach((range) =&gt; {
1863
+ const rangeParts: string[] = [];
1864
+ if (range.from !== undefined &amp;&amp; range.fromCondition) {
1865
+ const op = this.normalizeOperator(range.fromCondition);
1866
+ if (op === 'IS NULL' || op === 'IS NOT NULL') {
1867
+ rangeParts.push(`${aggregationType}(${columnRef}) ${op}`);
1868
+ } else {
1869
+ const value = typeof range.from === 'string' ? `'${range.from}'` : range.from;
1870
+ rangeParts.push(`${aggregationType}(${columnRef}) ${op} ${value}`);
1871
+ }
1872
+ }
1873
+ if (range.to !== undefined &amp;&amp; range.toCondition) {
1874
+ const op = this.normalizeOperator(range.toCondition);
1875
+ if (op === 'IS NULL' || op === 'IS NOT NULL') {
1876
+ rangeParts.push(`${aggregationType}(${columnRef}) ${op}`);
1877
+ } else {
1878
+ const value = typeof range.to === 'string' ? `'${range.to}'` : range.to;
1879
+ rangeParts.push(`${aggregationType}(${columnRef}) ${op} ${value}`);
1880
+ }
1881
+ }
1882
+ if (rangeParts.length === 0 &amp;&amp; range.operator &amp;&amp; range.value !== undefined) {
1883
+ const op = this.normalizeOperator(range.operator);
1884
+ if (op === 'IS NULL' || op === 'IS NOT NULL') {
1885
+ rangeParts.push(`${aggregationType}(${columnRef}) ${op}`);
1886
+ } else {
1887
+ const value = typeof range.value === 'string' ? `'${range.value}'` : range.value;
1888
+ rangeParts.push(`${aggregationType}(${columnRef}) ${op} ${value}`);
1889
+ }
1890
+ }
1891
+ if (rangeParts.length &gt; 0) {
1892
+ const joiner = (range.logicalOperator || 'AND').toUpperCase() === 'OR' ? 'OR' : 'AND';
1893
+ conditions.push(
1894
+ rangeParts.length === 1 ? rangeParts[0] : `(${rangeParts.join(` ${joiner} `)})`,
1895
+ );
1896
+ }
1897
+ });
1898
+ return conditions;
1899
+ }
1900
+ &nbsp;
1901
+ private normalizeOperator(op: string): string {
1902
+ return BaseUtilities.normalizeComparisonOperator(op);
1903
+ }
1904
+ }
1905
+ &nbsp;</pre></td></tr></table></pre>
1906
+
1907
+ <div class='push'></div><!-- for sticky footer -->
1908
+ </div><!-- /wrapper -->
1909
+ <div class='footer quiet pad2 space-top1 center small'>
1910
+ Code coverage generated by
1911
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1912
+ at 2025-12-03T07:39:44.024Z
1913
+ </div>
1914
+ <script src="../../../../prettify.js"></script>
1915
+ <script>
1916
+ window.onload = function () {
1917
+ prettyPrint();
1918
+ };
1919
+ </script>
1920
+ <script src="../../../../sorter.js"></script>
1921
+ <script src="../../../../block-navigation.js"></script>
1922
+ </body>
1923
+ </html>
1924
+